diff --git a/DEPS b/DEPS
index 4734cee..a4bee8e 100644
--- a/DEPS
+++ b/DEPS
@@ -79,11 +79,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': '81419f1a694c5fe289f072c14b7aa5a0db6b9f09',
+  'skia_revision': '76546506d19534bf8373989bab6bca26f4f9c759',
   # 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': '67393339f65e0fddf51d0c1bee29cc7cffb5faa1',
+  'v8_revision': 'e466ab96bed6713190136f6abdcbcb8908dc2b57',
   # 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.
@@ -103,7 +103,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': '6183a6e7693b7aeb9763eaa130b43269b13a02d7',
+  'pdfium_revision': 'b0fb8cc23c0ae555726f873101961676f96f6f07',
   # 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.
@@ -131,11 +131,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': '036bdc0c9a4fb55b4fe5a7276e97b70b95c8a260',
+  'freetype_revision': '4a03f17449ae45f0dacf4de4694ccd6e5e1b24d1',
   # 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': 'b4a4bed9ad918ec47b8ecc0bb6b611ebe9038392',
+  'catapult_revision': 'aa41a69e728232222f4c696dab70af09eb2213e0',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -652,7 +652,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a182a9ad3078aca566d8355eabf2d9f56f70ee82',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '6780c51b23516803dc27173d10ba98d018780447', # commit position 21742
+    Var('webrtc_git') + '/src.git' + '@' + '6f7bc08457fd89868c3bd14335905d4b195065e7', # commit position 21742
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/WATCHLISTS b/WATCHLISTS
index e6dddd4..afec4fd 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1284,6 +1284,9 @@
                   '|chrome/browser/content_settings/permission*'\
                   '|permission_context',
     },
+    'picture_in_picture': {
+      'filepath': 'third_party/WebKit/Source/modules/picture_in_picture/'
+    },
     'plugin': {
       'filepath': 'chrome/browser/plugin|chrome/plugin/|'\
         'chrome/common/plugin',
@@ -2202,6 +2205,7 @@
                     'mlamouri+watch-permissions@chromium.org',
                     'raymes+watch@chromium.org',
                     'timloh+watch@chromium.org'],
+    'picture_in_picture': ['beaufort.francois+pip@gmail.com'],
     'plugin': ['jam@chromium.org'],
     'polymer': ['michaelpg+watch-polymer@chromium.org'],
     'popup_blocker': ['csharrison+watch-popups@chromium.org'],
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index d570037..3bc0ba5 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -387,6 +387,9 @@
   ]
   configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
   configs += [ "//build/config/android:hide_all_but_jni" ]
+  if (use_order_profiling) {
+    deps += [ "//tools/cygprofile" ]
+  }
 }
 
 if (android_64bit_target_cpu) {
diff --git a/ash/frame/custom_frame_view_ash.cc b/ash/frame/custom_frame_view_ash.cc
index 2b3de8ff..c683e2ad 100644
--- a/ash/frame/custom_frame_view_ash.cc
+++ b/ash/frame/custom_frame_view_ash.cc
@@ -488,7 +488,7 @@
 void CustomFrameViewAsh::MaybePaintHeaderForSplitview(
     SplitViewController::State state) {
   if (state == SplitViewController::NO_SNAP) {
-    header_view_->SetShouldPaintHeader(/*paint=*/false);
+    SetShouldPaintHeader(/*paint=*/false);
     return;
   }
 
@@ -502,7 +502,7 @@
   // TODO(sammiequon): This works for now, but we may have to check if
   // |frame_|'s native window is in the overview list instead.
   if (window && window == frame_->GetNativeWindow())
-    header_view_->SetShouldPaintHeader(/*paint=*/true);
+    SetShouldPaintHeader(/*paint=*/true);
 }
 
 void CustomFrameViewAsh::SetShouldPaintHeader(bool paint) {
diff --git a/ash/wm/base_state.cc b/ash/wm/base_state.cc
index ba9fedc..057ee83d 100644
--- a/ash/wm/base_state.cc
+++ b/ash/wm/base_state.cc
@@ -5,7 +5,10 @@
 #include "ash/wm/base_state.h"
 
 #include "ash/public/cpp/window_state_type.h"
+#include "ash/shell.h"
+#include "ash/wm/splitview/split_view_controller.h"
 #include "ash/wm/window_animation_types.h"
+#include "ash/wm/window_positioning_utils.h"
 #include "ash/wm/wm_event.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/window.h"
@@ -116,5 +119,23 @@
   }
 }
 
+gfx::Rect BaseState::GetSnappedWindowBoundsInParent(
+    aura::Window* window,
+    const mojom::WindowStateType state_type) {
+  gfx::Rect bounds_in_parent;
+  if (SplitViewController::ShouldAllowSplitView()) {
+    bounds_in_parent =
+        Shell::Get()->split_view_controller()->GetSnappedWindowBoundsInParent(
+            window, (state_type == mojom::WindowStateType::LEFT_SNAPPED)
+                        ? SplitViewController::LEFT
+                        : SplitViewController::RIGHT);
+  } else {
+    bounds_in_parent = (state_type == mojom::WindowStateType::LEFT_SNAPPED)
+                           ? GetDefaultLeftSnappedWindowBoundsInParent(window)
+                           : GetDefaultRightSnappedWindowBoundsInParent(window);
+  }
+  return bounds_in_parent;
+}
+
 }  // namespace wm
 }  // namespace ash
diff --git a/ash/wm/base_state.h b/ash/wm/base_state.h
index 56e6060..27b886d 100644
--- a/ash/wm/base_state.h
+++ b/ash/wm/base_state.h
@@ -5,6 +5,10 @@
 #include "ash/wm/window_state.h"
 #include "base/macros.h"
 
+namespace aura {
+class Window;
+}  // namespace aura
+
 namespace ash {
 namespace wm {
 
@@ -23,27 +27,32 @@
   static mojom::WindowStateType GetStateForTransitionEvent(
       const WMEvent* event);
 
-  // Handle workspace related events, such as DISPLAY_BOUNDS_CHANGED.
+  // Handles workspace related events, such as DISPLAY_BOUNDS_CHANGED.
   virtual void HandleWorkspaceEvents(WindowState* window_state,
                                      const WMEvent* event) = 0;
 
-  // Handle state dependent events, such as TOGGLE_MAXIMIZED,
+  // Handles state dependent events, such as TOGGLE_MAXIMIZED,
   // TOGGLE_FULLSCREEN.
   virtual void HandleCompoundEvents(WindowState* window_state,
                                     const WMEvent* event) = 0;
 
-  // Handle bounds change events: SET_BOUNDS and CENTER.
+  // Handles bounds change events: SET_BOUNDS and CENTER.
   virtual void HandleBoundsEvents(WindowState* window_state,
                                   const WMEvent* event) = 0;
 
-  // Handle state transition events, such as MAXIMZIED, MINIMIZED.
+  // Handles state transition events, such as MAXIMZIED, MINIMIZED.
   virtual void HandleTransitionEvents(WindowState* window_state,
                                       const WMEvent* event) = 0;
 
-  // Show/Hide window when minimized state changes.
+  // Shows/Hides window when minimized state changes.
   void UpdateMinimizedState(WindowState* window_state,
                             mojom::WindowStateType previous_state_type);
 
+  // Returns the window bounds for snapped window state.
+  gfx::Rect GetSnappedWindowBoundsInParent(
+      aura::Window* window,
+      const mojom::WindowStateType state_type);
+
   // The current type of the window.
   mojom::WindowStateType state_type_;
 
diff --git a/ash/wm/client_controlled_state.cc b/ash/wm/client_controlled_state.cc
index 664d290f..ffa901e 100644
--- a/ash/wm/client_controlled_state.cc
+++ b/ash/wm/client_controlled_state.cc
@@ -65,9 +65,7 @@
     case WM_EVENT_NORMAL:
     case WM_EVENT_MAXIMIZE:
     case WM_EVENT_MINIMIZE:
-    case WM_EVENT_FULLSCREEN:
-    case WM_EVENT_SNAP_LEFT:
-    case WM_EVENT_SNAP_RIGHT: {
+    case WM_EVENT_FULLSCREEN: {
       // Reset window state
       window_state->UpdateWindowPropertiesFromStateType();
       mojom::WindowStateType next_state = GetStateForTransitionEvent(event);
@@ -77,6 +75,27 @@
       delegate_->HandleWindowStateRequest(window_state, next_state);
       break;
     }
+    case WM_EVENT_SNAP_LEFT:
+    case WM_EVENT_SNAP_RIGHT: {
+      if (window_state->CanSnap()) {
+        // Get the desired window bounds for the snap state.
+        gfx::Rect bounds = GetSnappedWindowBoundsInParent(
+            window_state->window(),
+            event->type() == WM_EVENT_SNAP_LEFT
+                ? mojom::WindowStateType::LEFT_SNAPPED
+                : mojom::WindowStateType::RIGHT_SNAPPED);
+        window_state->set_bounds_changed_by_user(true);
+
+        window_state->UpdateWindowPropertiesFromStateType();
+        mojom::WindowStateType next_state = GetStateForTransitionEvent(event);
+        VLOG(1) << "Processing State Transtion: event=" << event->type()
+                << ", state=" << state_type_ << ", next_state=" << next_state;
+
+        // Then ask delegate to set the desired bounds for the snap state.
+        delegate_->HandleBoundsRequest(window_state, next_state, bounds);
+      }
+      break;
+    }
     case WM_EVENT_SHOW_INACTIVE:
       NOTREACHED();
       break;
@@ -159,7 +178,8 @@
         // In pinned state, it should ignore the SetBounds from window manager
         // or user.
       } else {
-        delegate_->HandleBoundsRequest(window_state, bounds);
+        delegate_->HandleBoundsRequest(window_state,
+                                       window_state->GetStateType(), bounds);
       }
       break;
     }
diff --git a/ash/wm/client_controlled_state.h b/ash/wm/client_controlled_state.h
index 9f57b14d..9f83f31 100644
--- a/ash/wm/client_controlled_state.h
+++ b/ash/wm/client_controlled_state.h
@@ -36,10 +36,12 @@
     virtual void HandleWindowStateRequest(
         WindowState* window_state,
         mojom::WindowStateType requested_state) = 0;
-    // Handles the bounds change request for |window_state|.  Delegate
-    // may choose to ignore the request, set the given bounds, or set
-    // the different bounds.
+    // Handles the bounds change request for |window_state|. The bounds change
+    // might come from a state change request |requested_state| (currently it
+    // should only be a snapped window state). Delegate may choose to ignore the
+    // request, set the given bounds, or set the different bounds.
     virtual void HandleBoundsRequest(WindowState* window_state,
+                                     mojom::WindowStateType requested_state,
                                      const gfx::Rect& requested_bounds) = 0;
   };
 
diff --git a/ash/wm/client_controlled_state_unittest.cc b/ash/wm/client_controlled_state_unittest.cc
index c6c93bb..9543860 100644
--- a/ash/wm/client_controlled_state_unittest.cc
+++ b/ash/wm/client_controlled_state_unittest.cc
@@ -35,8 +35,15 @@
   }
 
   void HandleBoundsRequest(WindowState* window_state,
+                           ash::mojom::WindowStateType requested_state,
                            const gfx::Rect& bounds) override {
     requested_bounds_ = bounds;
+    if (requested_state != window_state->GetStateType()) {
+      DCHECK(requested_state == ash::mojom::WindowStateType::LEFT_SNAPPED ||
+             requested_state == ash::mojom::WindowStateType::RIGHT_SNAPPED);
+      old_state_ = window_state->GetStateType();
+      new_state_ = requested_state;
+    }
   }
 
   mojom::WindowStateType old_state() const { return old_state_; }
diff --git a/ash/wm/default_state.cc b/ash/wm/default_state.cc
index 92aac5b..7f98981 100644
--- a/ash/wm/default_state.cc
+++ b/ash/wm/default_state.cc
@@ -369,11 +369,10 @@
   }
 
   if (next_state_type == current_state_type && window_state->IsSnapped()) {
-    aura::Window* window = window_state->window();
-    gfx::Rect snapped_bounds =
-        event->type() == WM_EVENT_SNAP_LEFT
-            ? GetDefaultLeftSnappedWindowBoundsInParent(window)
-            : GetDefaultRightSnappedWindowBoundsInParent(window);
+    gfx::Rect snapped_bounds = GetSnappedWindowBoundsInParent(
+        window_state->window(), event->type() == WM_EVENT_SNAP_LEFT
+                                    ? mojom::WindowStateType::LEFT_SNAPPED
+                                    : mojom::WindowStateType::RIGHT_SNAPPED);
     window_state->SetBoundsDirectAnimated(snapped_bounds);
     return;
   }
@@ -550,9 +549,7 @@
     case mojom::WindowStateType::LEFT_SNAPPED:
     case mojom::WindowStateType::RIGHT_SNAPPED:
       bounds_in_parent =
-          state_type_ == mojom::WindowStateType::LEFT_SNAPPED
-              ? GetDefaultLeftSnappedWindowBoundsInParent(window)
-              : GetDefaultRightSnappedWindowBoundsInParent(window);
+          GetSnappedWindowBoundsInParent(window_state->window(), state_type_);
       break;
 
     case mojom::WindowStateType::DEFAULT:
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index 744c092..0e11892 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -201,7 +201,6 @@
   const wm::WMEvent event((snap_position == LEFT) ? wm::WM_EVENT_SNAP_LEFT
                                                   : wm::WM_EVENT_SNAP_RIGHT);
   wm::GetWindowState(window)->OnWMEvent(&event);
-  wm::ActivateWindow(window);
 
   // Stack the other snapped window below the current active window so that
   // the snapped two windows are always the top two windows while resizing.
@@ -418,7 +417,9 @@
     ash::mojom::WindowStateType old_type) {
   DCHECK(IsSplitViewModeActive());
 
-  if (window_state->IsFullscreen() || window_state->IsMaximized()) {
+  if (window_state->IsSnapped()) {
+    wm::ActivateWindow(window_state->window());
+  } else if (window_state->IsFullscreen() || window_state->IsMaximized()) {
     // End split view mode if one of the snapped windows gets maximized /
     // full-screened. Also end overview mode if overview mode is active at the
     // moment.
@@ -489,10 +490,8 @@
         Shell::Get()->mru_window_tracker()->BuildMruWindowList();
     for (auto* window : windows) {
       if (CanSnap(window) && window != GetDefaultSnappedWindow()) {
-        if (default_snap_position_ == LEFT)
-          SnapWindow(window, SplitViewController::RIGHT);
-        else if (default_snap_position_ == RIGHT)
-          SnapWindow(window, SplitViewController::LEFT);
+        // OnWindowActivated() will do the right thing to snap the |window|.
+        wm::ActivateWindow(window);
         break;
       }
     }
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager.cc b/ash/wm/tablet_mode/tablet_mode_window_manager.cc
index 18bd83d..e80bb67 100644
--- a/ash/wm/tablet_mode/tablet_mode_window_manager.cc
+++ b/ash/wm/tablet_mode/tablet_mode_window_manager.cc
@@ -95,12 +95,15 @@
 }
 
 void TabletModeWindowManager::OnSplitViewModeEnded() {
-  // Maximize all snapped windows upon exiting split view mode.
-  for (auto& pair : window_state_map_) {
-    if (pair.second->GetType() == mojom::WindowStateType::LEFT_SNAPPED ||
-        pair.second->GetType() == mojom::WindowStateType::RIGHT_SNAPPED) {
+  // Maximize all snapped windows upon exiting split view mode. Note the snapped
+  // window might not be tracked in our |window_state_map_|.
+  MruWindowTracker::WindowList windows =
+      Shell::Get()->mru_window_tracker()->BuildWindowListIgnoreModal();
+  for (auto* window : windows) {
+    wm::WindowState* window_state = wm::GetWindowState(window);
+    if (window_state->IsSnapped()) {
       wm::WMEvent event(wm::WM_EVENT_MAXIMIZE);
-      wm::GetWindowState(pair.first)->OnWMEvent(&event);
+      window_state->OnWMEvent(&event);
     }
   }
 }
diff --git a/ash/wm/workspace/backdrop_delegate.h b/ash/wm/workspace/backdrop_delegate.h
index 6a7dca1..bbf3ddf 100644
--- a/ash/wm/workspace/backdrop_delegate.h
+++ b/ash/wm/workspace/backdrop_delegate.h
@@ -19,7 +19,7 @@
  public:
   virtual ~BackdropDelegate() {}
 
-  // A window got added to the layout.
+  // Returns true if |window| should have a backdrop.
   virtual bool HasBackdrop(aura::Window* window) = 0;
 };
 
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc
index 83213a0..8974ece 100644
--- a/ash/wm/workspace/workspace_layout_manager_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -1039,9 +1039,8 @@
   // Turn the top window back drop on / off.
   void ShowTopWindowBackdropForContainer(aura::Window* container, bool show) {
     std::unique_ptr<BackdropDelegate> backdrop;
-    if (show) {
+    if (show)
       backdrop = std::make_unique<TabletModeBackdropDelegateImpl>();
-    }
     GetWorkspaceLayoutManager(container)->SetBackdropDelegate(
         std::move(backdrop));
     // Closing and / or opening can be a delayed operation.
diff --git a/base/BUILD.gn b/base/BUILD.gn
index c466beb..c4f703b 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1277,6 +1277,8 @@
       "process/process_handle_posix.cc",
       "process/process_posix.cc",
       "rand_util_posix.cc",
+      "threading/platform_thread_internal_posix.cc",
+      "threading/platform_thread_internal_posix.h",
     ]
 
     sources += [
@@ -2790,6 +2792,9 @@
       "//third_party/junit",
       "//third_party/ub-uiautomator:ub_uiautomator_java",
     ]
+
+    deps += android_extra_test_deps
+
     java_files = [
       "test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java",
       "test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java",
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc
index b84db9b7..fde2db8 100644
--- a/base/allocator/partition_allocator/partition_alloc_unittest.cc
+++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -46,7 +46,7 @@
 #if !defined(ARCH_CPU_64_BITS) || !defined(OS_POSIX)
   // 32 bits => address space is limited already.
   return true;
-#elif defined(OS_POSIX) && !defined(OS_MACOSX)
+#elif defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
   // macOS will accept, but not enforce, |RLIMIT_AS| changes. See
   // https://crbug.com/435269 and rdar://17576114.
   //
@@ -69,7 +69,7 @@
 }
 
 bool ClearAddressSpaceLimit() {
-#if !defined(ARCH_CPU_64_BITS) || !defined(OS_POSIX)
+#if !defined(ARCH_CPU_64_BITS) || !defined(OS_POSIX) || defined(OS_FUCHSIA)
   return true;
 #elif defined(OS_POSIX)
   struct rlimit limit;
@@ -1348,7 +1348,7 @@
 
 // Disable this test on Android because, due to its allocation-heavy behavior,
 // it tends to get OOM-killed rather than pass.
-#if defined(OS_MACOSX) || defined(OS_ANDROID)
+#if defined(OS_MACOSX) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
 #define MAYBE_RepeatedReturnNullDirect DISABLED_RepeatedReturnNullDirect
 #else
 #define MAYBE_RepeatedReturnNullDirect RepeatedReturnNullDirect
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc
index 27cd58a9..ad28562 100644
--- a/base/files/file_util_posix.cc
+++ b/base/files/file_util_posix.cc
@@ -1001,8 +1001,14 @@
 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
 
 int GetMaximumPathComponentLength(const FilePath& path) {
+#if defined(OS_FUCHSIA)
+  // Return a value we do not expect anyone ever to reach, but which is small
+  // enough to guard against e.g. bugs causing multi-megabyte paths.
+  return 1024;
+#else
   AssertBlockingAllowed();
   return pathconf(path.value().c_str(), _PC_NAME_MAX);
+#endif
 }
 
 #if !defined(OS_ANDROID)
diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc
index 6f48da1..5069b852 100644
--- a/base/message_loop/message_pump_win.cc
+++ b/base/message_loop/message_pump_win.cc
@@ -313,7 +313,7 @@
 
     // Create a WM_TIMER event that will wake us up to check for any pending
     // timers (in case we are running within a nested, external sub-pump).
-    BOOL ret = SetTimer(message_window_.hwnd(), 0, delay_msec, nullptr);
+    UINT_PTR ret = SetTimer(message_window_.hwnd(), 0, delay_msec, nullptr);
     if (ret)
       return;
     // If we can't set timers, we are in big trouble... but cross our fingers
diff --git a/base/metrics/field_trial.h b/base/metrics/field_trial.h
index 10122ff..c8e479e 100644
--- a/base/metrics/field_trial.h
+++ b/base/metrics/field_trial.h
@@ -388,7 +388,8 @@
 //------------------------------------------------------------------------------
 // Class with a list of all active field trials.  A trial is active if it has
 // been registered, which includes evaluating its state based on its probaility.
-// Only one instance of this class exists.
+// Only one instance of this class exists and outside of testing, will live for
+// the entire life time of the process.
 class BASE_EXPORT FieldTrialList {
  public:
   typedef SharedPersistentMemoryAllocator FieldTrialAllocator;
diff --git a/base/process/process_metrics.h b/base/process/process_metrics.h
index 779daa7..fc2c46d 100644
--- a/base/process/process_metrics.h
+++ b/base/process/process_metrics.h
@@ -334,7 +334,7 @@
 // at once. If the number is unavailable, a conservative best guess is returned.
 BASE_EXPORT size_t GetMaxFds();
 
-#if defined(OS_POSIX)
+#if defined(OS_POSIX) && !defined(OS_FUCHSIA)
 // Sets the file descriptor soft limit to |max_descriptors| or the OS hard
 // limit, whichever is lower.
 BASE_EXPORT void SetFdLimit(unsigned int max_descriptors);
diff --git a/base/process/process_metrics_fuchsia.cc b/base/process/process_metrics_fuchsia.cc
index d07911d..5204383 100644
--- a/base/process/process_metrics_fuchsia.cc
+++ b/base/process/process_metrics_fuchsia.cc
@@ -4,8 +4,14 @@
 
 #include "base/process/process_metrics.h"
 
+#include <fdio/limits.h>
+
 namespace base {
 
+size_t GetMaxFds() {
+  return FDIO_MAX_FD;
+}
+
 size_t GetSystemCommitCharge() {
   // Not available, doesn't seem likely that it will be (for the whole system).
   NOTIMPLEMENTED();
diff --git a/base/process/process_metrics_posix.cc b/base/process/process_metrics_posix.cc
index 73a52d621..49487d1 100644
--- a/base/process/process_metrics_posix.cc
+++ b/base/process/process_metrics_posix.cc
@@ -31,6 +31,8 @@
 
 ProcessMetrics::~ProcessMetrics() = default;
 
+#if !defined(OS_FUCHSIA)
+
 #if defined(OS_LINUX)
 static const rlim_t kSystemDefaultMaxFds = 8192;
 #elif defined(OS_MACOSX)
@@ -39,8 +41,6 @@
 static const rlim_t kSystemDefaultMaxFds = 8192;
 #elif defined(OS_FREEBSD)
 static const rlim_t kSystemDefaultMaxFds = 8192;
-#elif defined(OS_FUCHSIA)
-static const rlim_t kSystemDefaultMaxFds = 8192;
 #elif defined(OS_NETBSD)
 static const rlim_t kSystemDefaultMaxFds = 1024;
 #elif defined(OS_OPENBSD)
@@ -85,6 +85,8 @@
   }
 }
 
+#endif  // !defined(OS_FUCHSIA)
+
 size_t GetPageSize() {
   return getpagesize();
 }
diff --git a/base/process/process_util_unittest.cc b/base/process/process_util_unittest.cc
index 4b91f43..1f2a8690 100644
--- a/base/process/process_util_unittest.cc
+++ b/base/process/process_util_unittest.cc
@@ -65,6 +65,7 @@
 #include "third_party/lss/linux_syscall_support.h"
 #endif
 #if defined(OS_FUCHSIA)
+#include <fdio/limits.h>
 #include <zircon/process.h>
 #include <zircon/processargs.h>
 #include <zircon/syscalls.h>
@@ -577,6 +578,9 @@
 // Returns the maximum number of files that a process can have open.
 // Returns 0 on error.
 int GetMaxFilesOpenInProcess() {
+#if defined(OS_FUCHSIA)
+  return FDIO_MAX_FD;
+#else
   struct rlimit rlim;
   if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
     return 0;
@@ -590,6 +594,7 @@
   }
 
   return rlim.rlim_cur;
+#endif  // !defined(OS_FUCHSIA)
 }
 
 const int kChildPipe = 20;  // FD # for write end of pipe in child process.
diff --git a/base/synchronization/condition_variable_unittest.cc b/base/synchronization/condition_variable_unittest.cc
index 1aa1a4a..705257a 100644
--- a/base/synchronization/condition_variable_unittest.cc
+++ b/base/synchronization/condition_variable_unittest.cc
@@ -194,7 +194,7 @@
   lock.Release();
 }
 
-#if defined(OS_POSIX)
+#if defined(OS_POSIX) && !defined(OS_FUCHSIA)
 const int kDiscontinuitySeconds = 2;
 
 void BackInTime(Lock* lock) {
diff --git a/base/synchronization/lock_impl_posix.cc b/base/synchronization/lock_impl_posix.cc
index 43c9d49..0895691 100644
--- a/base/synchronization/lock_impl_posix.cc
+++ b/base/synchronization/lock_impl_posix.cc
@@ -21,7 +21,7 @@
 // Lock::PriorityInheritanceAvailable still must be checked as the code may
 // compile but the underlying platform still may not correctly support priority
 // inheritance locks.
-#if defined(OS_NACL) || defined(OS_ANDROID)
+#if defined(OS_NACL) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
 #define PRIORITY_INHERITANCE_LOCKS_POSSIBLE() 0
 #else
 #define PRIORITY_INHERITANCE_LOCKS_POSSIBLE() 1
diff --git a/base/threading/platform_thread_fuchsia.cc b/base/threading/platform_thread_fuchsia.cc
index 66d8e09..1939f82 100644
--- a/base/threading/platform_thread_fuchsia.cc
+++ b/base/threading/platform_thread_fuchsia.cc
@@ -13,33 +13,6 @@
 
 namespace base {
 
-namespace internal {
-
-const ThreadPriorityToNiceValuePair kThreadPriorityToNiceValueMap[4] = {
-    {ThreadPriority::BACKGROUND, 10},
-    {ThreadPriority::NORMAL, 0},
-    {ThreadPriority::DISPLAY, -8},
-    {ThreadPriority::REALTIME_AUDIO, -10},
-};
-
-bool SetCurrentThreadPriorityForPlatform(ThreadPriority priority) {
-  sched_param prio = {0};
-  prio.sched_priority = ThreadPriorityToNiceValue(priority);
-  return pthread_setschedparam(pthread_self(), SCHED_OTHER, &prio) == 0;
-}
-
-bool GetCurrentThreadPriorityForPlatform(ThreadPriority* priority) {
-  sched_param prio = {0};
-  int policy;
-  if (pthread_getschedparam(pthread_self(), &policy, &prio) != 0) {
-    return false;
-  }
-  *priority = NiceValueToThreadPriority(prio.sched_priority);
-  return true;
-}
-
-}  // namespace internal
-
 void InitThreading() {}
 
 void TerminateOnThread() {}
@@ -58,4 +31,21 @@
                                               name);
 }
 
+// static
+bool PlatformThread::CanIncreaseCurrentThreadPriority() {
+  return false;
+}
+
+// static
+void PlatformThread::SetCurrentThreadPriority(ThreadPriority priority) {
+  if (priority != ThreadPriority::NORMAL) {
+    NOTIMPLEMENTED() << "setting ThreadPriority " << static_cast<int>(priority);
+  }
+}
+
+// static
+ThreadPriority PlatformThread::GetCurrentThreadPriority() {
+  return ThreadPriority::NORMAL;
+}
+
 }  // namespace base
diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc
index 7f0cf22e..da2d164 100644
--- a/base/threading/platform_thread_posix.cc
+++ b/base/threading/platform_thread_posix.cc
@@ -234,8 +234,9 @@
   CHECK_EQ(0, pthread_detach(thread_handle.platform_handle()));
 }
 
-// Mac has its own Set/GetCurrentThreadPriority() implementations.
-#if !defined(OS_MACOSX)
+// Mac and Fuchsia have their own Set/GetCurrentThreadPriority()
+// implementations.
+#if !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
 
 // static
 bool PlatformThread::CanIncreaseCurrentThreadPriority() {
@@ -298,6 +299,6 @@
 #endif  // !defined(OS_NACL)
 }
 
-#endif  // !defined(OS_MACOSX)
+#endif  // !defined(OS_MACOSX) && !defined(OS_FUCHSIA)
 
 }  // namespace base
diff --git a/base/threading/platform_thread_unittest.cc b/base/threading/platform_thread_unittest.cc
index 5025576..7eea22e 100644
--- a/base/threading/platform_thread_unittest.cc
+++ b/base/threading/platform_thread_unittest.cc
@@ -294,10 +294,10 @@
   }
 }
 
-// Test for a function defined in platform_thread_internal_posix.cc. On OSX and
-// iOS, platform_thread_internal_posix.cc is not compiled, so these platforms
-// are excluded here, too.
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS)
+// This tests internal PlatformThread APIs used under some POSIX platforms,
+// with the exception of Mac OS X, iOS and Fuchsia.
+#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS) && \
+    !defined(OS_FUCHSIA)
 TEST(PlatformThreadTest, GetNiceValueToThreadPriority) {
   using internal::NiceValueToThreadPriority;
   using internal::kThreadPriorityToNiceValueMap;
@@ -352,7 +352,8 @@
   EXPECT_EQ(ThreadPriority::REALTIME_AUDIO,
             NiceValueToThreadPriority(kLowestNiceValue));
 }
-#endif
+#endif  // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS) &&
+        // !defined(OS_FUCHSIA)
 
 TEST(PlatformThreadTest, SetHugeThreadName) {
   // Construct an excessively long thread name.
diff --git a/base/time/pr_time_unittest.cc b/base/time/pr_time_unittest.cc
index 3f1a348..5c3e3fca 100644
--- a/base/time/pr_time_unittest.cc
+++ b/base/time/pr_time_unittest.cc
@@ -75,9 +75,8 @@
   time_t current_time = 0;
   time(&current_time);
 
-  const int BUFFER_SIZE = 64;
-  struct tm local_time = {0};
-  char time_buf[BUFFER_SIZE] = {0};
+  struct tm local_time = {};
+  char time_buf[64] = {};
 #if defined(OS_WIN)
   localtime_s(&local_time, &current_time);
   asctime_s(time_buf, arraysize(time_buf), &local_time);
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc
index a78d11f..8f30071 100644
--- a/base/time/time_unittest.cc
+++ b/base/time/time_unittest.cc
@@ -306,9 +306,8 @@
   time_t current_time = 0;
   time(&current_time);
 
-  const int BUFFER_SIZE = 64;
-  struct tm local_time = {0};
-  char time_buf[BUFFER_SIZE] = {0};
+  struct tm local_time = {};
+  char time_buf[64] = {};
 #if defined(OS_WIN)
   localtime_s(&local_time, &current_time);
   asctime_s(time_buf, arraysize(time_buf), &local_time);
diff --git a/build/android/gyp/jinja_template.py b/build/android/gyp/jinja_template.py
index af361b8..459565b 100755
--- a/build/android/gyp/jinja_template.py
+++ b/build/android/gyp/jinja_template.py
@@ -60,6 +60,14 @@
 
 def _ProcessFile(processor, input_filename, output_filename):
   output = processor.Render(input_filename)
+
+  # If |output| is same with the file content, we skip update and
+  # ninja's restat will avoid rebuilding things that depend on it.
+  if os.path.isfile(output_filename):
+    with codecs.open(output_filename, 'r', 'utf-8') as f:
+      if f.read() == output:
+        return
+
   with codecs.open(output_filename, 'w', 'utf-8') as output_file:
     output_file.write(output)
 
diff --git a/build/check_gn_headers_whitelist.txt b/build/check_gn_headers_whitelist.txt
index c268ed1..e17b0a3 100644
--- a/build/check_gn_headers_whitelist.txt
+++ b/build/check_gn_headers_whitelist.txt
@@ -244,7 +244,6 @@
 skia/ext/skia_commit_hash.h
 skia/ext/texture_handle.h
 testing/gmock_mutant.h
-third_party/WebKit/common/feature_policy/feature_policy_feature.h
 third_party/WebKit/Source/bindings/modules/v8/serialization/WebCryptoSubTags.h
 third_party/WebKit/Source/core/animation/CSSInterpolationEnvironment.h
 third_party/WebKit/Source/core/animation/SVGInterpolationEnvironment.h
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index f02687c..1a90862 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -113,6 +113,11 @@
     webview_framework_jar = webview_public_framework_jar
   }
 
+  # TODO(crbug.com/807768): Remove this extra dependency.
+  if (!defined(android_extra_test_deps)) {
+    android_extra_test_deps = []
+  }
+
   assert(defined(default_android_sdk_root),
          "SDK release " + android_sdk_release + " not recognized.")
 
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index c558283..58cf167 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -613,6 +613,15 @@
     if (is_mac) {
       ldflags += [ "-Wl,-all_load" ]
     }
+
+    # This flag causes LTO to create an .ARM.attributes section with the correct
+    # architecture. This is necessary because LLD will refuse to link a program
+    # unless the architecture revision in .ARM.attributes is sufficiently new.
+    # TODO(pcc): The contents of .ARM.attributes should be based on the
+    # -march flag passed at compile time (see llvm.org/pr36291).
+    if (current_cpu == "arm") {
+      ldflags += [ "-march=$arm_arch" ]
+    }
   }
 
   # Pass the same C/C++ flags to the objective C/C++ compiler.
diff --git a/cc/ipc/cc_serialization_perftest.cc b/cc/ipc/cc_serialization_perftest.cc
index ad3ca99..d8741b8 100644
--- a/cc/ipc/cc_serialization_perftest.cc
+++ b/cc/ipc/cc_serialization_perftest.cc
@@ -9,6 +9,7 @@
 #include "cc/ipc/cc_param_traits.h"
 #include "components/viz/common/quads/compositor_frame.h"
 #include "components/viz/common/quads/picture_draw_quad.h"
+#include "components/viz/test/compositor_frame_helpers.h"
 #include "gpu/ipc/common/mailbox_holder_struct_traits.h"
 #include "gpu/ipc/common/mailbox_struct_traits.h"
 #include "gpu/ipc/common/sync_token_struct_traits.h"
@@ -392,12 +393,11 @@
                                      uint32_t num_quads,
                                      uint32_t num_passes,
                                      UseSingleSharedQuadState single_sqs) {
-    viz::CompositorFrame frame;
-    frame.metadata.begin_frame_ack = viz::BeginFrameAck(0, 1, true);
+    viz::CompositorFrame frame = viz::MakeEmptyCompositorFrame();
 
     for (uint32_t i = 0; i < num_passes; ++i) {
       std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create();
-      render_pass->SetNew(1, gfx::Rect(), gfx::Rect(), gfx::Transform());
+      render_pass->SetNew(1, gfx::Rect(20, 20), gfx::Rect(), gfx::Transform());
       for (uint32_t j = 0; j < num_quads; ++j) {
         if (j == 0 || single_sqs == UseSingleSharedQuadState::NO)
           render_pass->CreateAndAppendSharedQuadState();
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index 707c91d..3553d91d 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -9,6 +9,7 @@
 
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#include "base/numerics/checked_math.h"
 #include "base/trace_event/trace_event_argument.h"
 #include "cc/layers/layer_impl.h"
 #include "cc/trees/clip_node.h"
@@ -938,33 +939,74 @@
   DCHECK(effect_node->has_render_surface);
   DCHECK(effect_node->has_copy_request);
 
-  auto range = copy_requests_.equal_range(node_id);
-  for (auto it = range.first; it != range.second; ++it)
-    requests->push_back(std::move(it->second));
-  copy_requests_.erase(range.first, range.second);
-
-  for (auto& it : *requests) {
-    if (!it->has_area())
-      continue;
-
-    // The area needs to be transformed from the space of content that draws to
-    // the surface to the space of the surface itself.
-    int destination_id = effect_node->transform_id;
-    int source_id;
-    if (effect_node->parent_id != EffectTree::kInvalidNodeId) {
-      // For non-root surfaces, transform only by sub-layer scale.
-      source_id = destination_id;
-    } else {
-      // The root surface doesn't have the notion of sub-layer scale, but
-      // instead has a similar notion of transforming from the space of the root
-      // layer to the space of the screen.
-      DCHECK_EQ(kRootNodeId, destination_id);
-      source_id = TransformTree::kContentsRootNodeId;
-    }
-    gfx::Transform transform;
-    property_trees()->GetToTarget(source_id, node_id, &transform);
-    it->set_area(MathUtil::MapEnclosingClippedRect(transform, it->area()));
+  // The area needs to be transformed from the space of content that draws to
+  // the surface to the space of the surface itself.
+  int destination_id = effect_node->transform_id;
+  int source_id;
+  if (effect_node->parent_id != EffectTree::kInvalidNodeId) {
+    // For non-root surfaces, transform only by sub-layer scale.
+    source_id = destination_id;
+  } else {
+    // The root surface doesn't have the notion of sub-layer scale, but instead
+    // has a similar notion of transforming from the space of the root layer to
+    // the space of the screen.
+    DCHECK_EQ(kRootNodeId, destination_id);
+    source_id = TransformTree::kContentsRootNodeId;
   }
+  gfx::Transform transform;
+  property_trees()->GetToTarget(source_id, node_id, &transform);
+
+  // Move each CopyOutputRequest out of |copy_requests_| and into |requests|,
+  // adjusting the source area and scale ratio of each. If the transform is
+  // something other than a straightforward translate+scale, the copy requests
+  // will be dropped.
+  auto range = copy_requests_.equal_range(node_id);
+  if (transform.IsPositiveScaleOrTranslation()) {
+    // Transform a vector in content space to surface space to determine how the
+    // scale ratio of each CopyOutputRequest should be adjusted. Since the scale
+    // ratios are provided integer coordinates, the basis vector determines the
+    // precision w.r.t. the fractional part of the Transform's scale factors.
+    constexpr gfx::Vector2d kContentVector(1024, 1024);
+    gfx::RectF surface_rect(0, 0, kContentVector.x(), kContentVector.y());
+    transform.TransformRect(&surface_rect);
+
+    for (auto it = range.first; it != range.second; ++it) {
+      viz::CopyOutputRequest* const request = it->second.get();
+      if (request->has_area()) {
+        request->set_area(
+            MathUtil::MapEnclosingClippedRect(transform, request->area()));
+      }
+
+      // Only adjust the scale ratio if the request specifies one, or if it
+      // specifies a result selection. Otherwise, the requestor is expecting a
+      // copy of the exact source pixels. If the adjustment to the scale ratio
+      // would produce out-of-range values, drop the copy request.
+      if (request->is_scaled() || request->has_result_selection()) {
+        float scale_from_x = request->scale_from().x() * surface_rect.width();
+        float scale_from_y = request->scale_from().y() * surface_rect.height();
+        if (std::isnan(scale_from_x) ||
+            !base::IsValueInRangeForNumericType<int>(scale_from_x) ||
+            std::isnan(scale_from_y) ||
+            !base::IsValueInRangeForNumericType<int>(scale_from_y)) {
+          continue;
+        }
+        int scale_to_x = request->scale_to().x();
+        int scale_to_y = request->scale_to().y();
+        if (!base::CheckMul(scale_to_x, kContentVector.x())
+                 .AssignIfValid(&scale_to_x) ||
+            !base::CheckMul(scale_to_y, kContentVector.y())
+                 .AssignIfValid(&scale_to_y)) {
+          continue;
+        }
+        request->SetScaleRatio(gfx::Vector2d(gfx::ToRoundedInt(scale_from_x),
+                                             gfx::ToRoundedInt(scale_from_y)),
+                               gfx::Vector2d(scale_to_x, scale_to_y));
+      }
+
+      requests->push_back(std::move(it->second));
+    }
+  }
+  copy_requests_.erase(range.first, range.second);
 }
 
 bool EffectTree::HasCopyRequests() const {
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index aae04e65..adef923 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -568,6 +568,8 @@
     "//url/mojom:url_mojom_gurl_java",
   ]
 
+  deps += android_extra_test_deps
+
   data = [
     "//chrome/test/data/android/",
     "//chrome/test/data/banners/",
@@ -1175,6 +1177,9 @@
     "//chrome/browser/profiling_host:profiling_host_javatests",
     "//third_party/android_support_test_runner:runner_java",
   ]
+
+  deps += android_extra_test_deps
+
   additional_apks = [
     "//chrome/android/webapk/libs/runtime_library/javatests/apk_with_webapk_service:apk_with_webapk_service",
     "//chrome/android/webapk/shell_apk:webapk",
diff --git a/chrome/android/java/res/drawable/bookmark_big.xml b/chrome/android/java/res/drawable/bookmark_big.xml
index 87812f7..a00bdd2f 100644
--- a/chrome/android/java/res/drawable/bookmark_big.xml
+++ b/chrome/android/java/res/drawable/bookmark_big.xml
@@ -11,6 +11,6 @@
     android:viewportHeight="24.0"
     android:viewportWidth="24.0" >
     <path
-        android:fillColor="@color/google_grey_500"
+        android:fillColor="@color/black_alpha_38"
         android:pathData="M22,9.24l-7.19,-0.62L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27 18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z" />
 </vector>
diff --git a/chrome/android/java/res/drawable/downloads_big.xml b/chrome/android/java/res/drawable/downloads_big.xml
index aa111f0..2c69e2ce 100644
--- a/chrome/android/java/res/drawable/downloads_big.xml
+++ b/chrome/android/java/res/drawable/downloads_big.xml
@@ -12,5 +12,5 @@
         android:viewportHeight="24.0">
     <path
         android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z"
-        android:fillColor="@color/google_grey_500"/>
+        android:fillColor="@color/black_alpha_38"/>
 </vector>
diff --git a/chrome/android/java/res/drawable/history_big.xml b/chrome/android/java/res/drawable/history_big.xml
index 183a4eb..1706921 100644
--- a/chrome/android/java/res/drawable/history_big.xml
+++ b/chrome/android/java/res/drawable/history_big.xml
@@ -11,6 +11,6 @@
     android:viewportWidth="24.0"
     android:viewportHeight="24.0">
     <path
-        android:fillColor="@color/google_grey_500"
+        android:fillColor="@color/black_alpha_38"
         android:pathData="M11.991,3C16.968,3 21,7.032 21,12C21,16.968 16.968,21 11.991,21C7.023,21 3,16.968 3,12C3,7.032 7.023,3 11.991,3ZM12.45,7.5L11.1,7.5L11.1,12.9L15.825,15.735L16.5,14.628L12.45,12.225L12.45,7.5Z" />
 </vector>
diff --git a/chrome/android/java/res/drawable/search_toolbar_modern_bg.xml b/chrome/android/java/res/drawable/search_toolbar_modern_bg.xml
index 32518ee..0168995 100644
--- a/chrome/android/java/res/drawable/search_toolbar_modern_bg.xml
+++ b/chrome/android/java/res/drawable/search_toolbar_modern_bg.xml
@@ -6,7 +6,7 @@
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="@color/modern_toolbar_bg" />
+            <solid android:color="@color/modern_primary_color" />
         </shape>
     </item>
     <item
diff --git a/chrome/android/java/res/layout/bookmark_add_edit_folder_activity.xml b/chrome/android/java/res/layout/bookmark_add_edit_folder_activity.xml
index e6f2223..86daf6b 100644
--- a/chrome/android/java/res/layout/bookmark_add_edit_folder_activity.xml
+++ b/chrome/android/java/res/layout/bookmark_add_edit_folder_activity.xml
@@ -9,6 +9,7 @@
     android:minHeight="@dimen/bookmark_minimum_dialog_size_tablet" >
 
     <ScrollView
+        android:id="@+id/scroll_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:paddingTop="@dimen/toolbar_height_no_shadow"
@@ -61,8 +62,7 @@
         android:id="@+id/toolbar"
         android:layout_width="match_parent"
         android:layout_height="@dimen/toolbar_height_no_shadow"
-        style="@style/ModernToolbar"
-        android:background="@color/modern_toolbar_bg" />
+        style="@style/ModernToolbar" />
 
     <View
         android:id="@+id/shadow"
diff --git a/chrome/android/java/res/layout/bookmark_edit.xml b/chrome/android/java/res/layout/bookmark_edit.xml
index 27fd2b7..2cbd156 100644
--- a/chrome/android/java/res/layout/bookmark_edit.xml
+++ b/chrome/android/java/res/layout/bookmark_edit.xml
@@ -8,6 +8,7 @@
     xmlns:chrome="http://schemas.android.com/apk/res-auto" >
 
     <ScrollView
+        android:id="@+id/scroll_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:paddingTop="@dimen/toolbar_height_no_shadow"
@@ -77,8 +78,7 @@
         android:id="@+id/toolbar"
         android:layout_width="match_parent"
         android:layout_height="@dimen/toolbar_height_no_shadow"
-        style="@style/ModernToolbar"
-        android:background="@color/modern_toolbar_bg" />
+        style="@style/ModernToolbar" />
 
     <View
         android:id="@+id/shadow"
diff --git a/chrome/android/java/res/layout/bookmark_folder_select_activity.xml b/chrome/android/java/res/layout/bookmark_folder_select_activity.xml
index c72071d..75dfa95e 100644
--- a/chrome/android/java/res/layout/bookmark_folder_select_activity.xml
+++ b/chrome/android/java/res/layout/bookmark_folder_select_activity.xml
@@ -19,8 +19,7 @@
         android:id="@+id/toolbar"
         android:layout_width="match_parent"
         android:layout_height="@dimen/toolbar_height_no_shadow"
-        style="@style/ModernToolbar"
-        android:background="@color/modern_toolbar_bg" />
+        style="@style/ModernToolbar" />
 
     <View
         android:id="@+id/shadow"
diff --git a/chrome/android/java/res/layout/selectable_list_layout.xml b/chrome/android/java/res/layout/selectable_list_layout.xml
index 65f9b17..66bc974e 100644
--- a/chrome/android/java/res/layout/selectable_list_layout.xml
+++ b/chrome/android/java/res/layout/selectable_list_layout.xml
@@ -5,30 +5,6 @@
 
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <android.support.v7.widget.RecyclerView
-        android:id="@+id/recycler_view"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:paddingTop="@dimen/toolbar_height_no_shadow"
-        android:clipToPadding="false"
-        android:visibility="gone" />
-
-    <TextView
-        android:id="@+id/empty_view"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:drawablePadding="3dp"
-        android:textColor="@color/google_grey_500"
-        android:textSize="16sp"
-        android:visibility="gone" />
-
-    <org.chromium.chrome.browser.widget.LoadingView
-        android:id="@+id/loading_view"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center" />
-
     <ViewStub
         android:id="@+id/action_bar_stub"
         android:inflatedId="@+id/action_bar"
@@ -36,6 +12,35 @@
         android:layout_height="@dimen/toolbar_height_no_shadow"
         android:background="@color/default_primary_color" />
 
+    <FrameLayout
+        android:id="@+id/list_content"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginTop="@dimen/toolbar_height_no_shadow" >
+
+        <android.support.v7.widget.RecyclerView
+            android:id="@+id/recycler_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:clipToPadding="false"
+            android:visibility="gone" />
+
+        <TextView
+            android:id="@+id/empty_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:drawablePadding="3dp"
+            android:textAppearance="@style/BlackDisabledText1"
+            android:visibility="gone" />
+
+        <org.chromium.chrome.browser.widget.LoadingView
+            android:id="@+id/loading_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center" />
+    </FrameLayout>
+
     <org.chromium.chrome.browser.widget.FadingShadowView
         android:id="@+id/shadow"
         android:layout_width="match_parent"
diff --git a/chrome/android/java/res/layout/suggestions_bottom_sheet_content.xml b/chrome/android/java/res/layout/suggestions_bottom_sheet_content.xml
index 47cb54a..76969cd 100644
--- a/chrome/android/java/res/layout/suggestions_bottom_sheet_content.xml
+++ b/chrome/android/java/res/layout/suggestions_bottom_sheet_content.xml
@@ -19,7 +19,6 @@
         android:id="@+id/loading_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal"
-        android:paddingTop="@dimen/chrome_home_empty_view_top_padding" />
+        android:layout_gravity="center_horizontal" />
 
 </FrameLayout>
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml
index 75e991c..89d7299 100644
--- a/chrome/android/java/res/values-v17/styles.xml
+++ b/chrome/android/java/res/values-v17/styles.xml
@@ -576,6 +576,7 @@
     <style name="ModernToolbar" parent="Widget.AppCompat.Toolbar">
         <item name="titleTextAppearance">@style/BlackHeadline1</item>
         <item name="windowActionBarOverlay">true</item>
+        <item name="android:background">@color/modern_primary_color</item>
     </style>
     <style name="ToolbarButton">
         <item name="android:background">?attr/selectableItemBackground</item>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml
index 8575090..36ddc6d 100644
--- a/chrome/android/java/res/values/colors.xml
+++ b/chrome/android/java/res/values/colors.xml
@@ -206,7 +206,6 @@
     <!-- Other colors -->
     <color name="media_viewer_bg">#000000</color>
     <color name="image_viewer_bg">#0E0E0E</color>
-    <color name="modern_toolbar_bg">@color/white_alpha_90</color>
     <color name="google_blue_500_alpha_38_opaque">#B7D1FB</color>
     <color name="toolbar_shadow_color">@color/black_alpha_11</color>
     <color name="bottom_system_nav_color">@android:color/white</color>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index a5129edc..d4429db 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -496,7 +496,7 @@
     <dimen name="selectable_list_action_bar_end_padding">6dp</dimen>
     <dimen name="toolbar_wide_display_start_offset">13dp</dimen>
     <dimen name="toolbar_modern_search_view_start_offset">4dp</dimen>
-    <dimen name="search_toolbar_modern_bg_top_bottom_inset">10dp</dimen>
+    <dimen name="search_toolbar_modern_bg_top_bottom_inset">8dp</dimen>
     <dimen name="search_toolbar_modern_bg_lateral_inset">8dp</dimen>
     <dimen name="selectable_list_toolbar_nav_button_start_offset">4dp</dimen>
     <dimen name="selectable_list_search_icon_end_padding">4dp</dimen>
@@ -509,7 +509,6 @@
     <dimen name="bottom_nav_shadow_height">8dp</dimen>
 
     <!-- Chrome Home dimensions -->
-    <dimen name="chrome_home_empty_view_top_padding">72dp</dimen>
     <dimen name="chrome_home_min_full_half_distance">160dp</dimen>
     <dimen name="chrome_home_progress_bar_height">4dp</dimen>
     <dimen name="chrome_home_incognito_ntp_bottom_margin">32dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java
index d39d630..8922e23 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddEditFolderActivity.java
@@ -14,7 +14,6 @@
 import android.view.View.OnClickListener;
 import android.widget.TextView;
 
-import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.SynchronousInitializationActivity;
 import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
@@ -159,11 +158,15 @@
 
         mParentTextView.setText(mModel.getBookmarkTitle(mParentId));
 
+        View shadow = findViewById(R.id.shadow);
         if (!FeatureUtilities.isChromeModernDesignEnabled()) {
-            findViewById(R.id.shadow).setVisibility(View.VISIBLE);
+            shadow.setVisibility(View.VISIBLE);
             toolbar.setTitleTextAppearance(toolbar.getContext(), R.style.BlackHeadline2);
-            toolbar.setBackgroundColor(
-                    ApiCompatibilityUtils.getColor(getResources(), R.color.modern_primary_color));
+        } else {
+            View scrollView = findViewById(R.id.scroll_view);
+            scrollView.getViewTreeObserver().addOnScrollChangedListener(() -> {
+                shadow.setVisibility(scrollView.getScrollY() > 0 ? View.VISIBLE : View.GONE);
+            });
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
index 01ee1e16..ac271060 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkEditActivity.java
@@ -12,7 +12,6 @@
 import android.view.View;
 import android.widget.TextView;
 
-import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.Log;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.SynchronousInitializationActivity;
@@ -87,11 +86,15 @@
 
         updateViewContent(false);
 
+        View shadow = findViewById(R.id.shadow);
         if (!FeatureUtilities.isChromeModernDesignEnabled()) {
-            findViewById(R.id.shadow).setVisibility(View.VISIBLE);
+            shadow.setVisibility(View.VISIBLE);
             toolbar.setTitleTextAppearance(toolbar.getContext(), R.style.BlackHeadline2);
-            toolbar.setBackgroundColor(
-                    ApiCompatibilityUtils.getColor(getResources(), R.color.modern_primary_color));
+        } else {
+            View scrollView = findViewById(R.id.scroll_view);
+            scrollView.getViewTreeObserver().addOnScrollChangedListener(() -> {
+                shadow.setVisibility(scrollView.getScrollY() > 0 ? View.VISIBLE : View.GONE);
+            });
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderSelectActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderSelectActivity.java
index 4307f0b..0f44352 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderSelectActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderSelectActivity.java
@@ -167,11 +167,20 @@
 
         updateFolderList();
 
+        View shadow = findViewById(R.id.shadow);
         if (!FeatureUtilities.isChromeModernDesignEnabled()) {
-            findViewById(R.id.shadow).setVisibility(View.VISIBLE);
+            shadow.setVisibility(View.VISIBLE);
             toolbar.setTitleTextAppearance(toolbar.getContext(), R.style.BlackHeadline2);
-            toolbar.setBackgroundColor(
-                    ApiCompatibilityUtils.getColor(getResources(), R.color.modern_primary_color));
+        } else {
+            int listPaddingTop =
+                    getResources().getDimensionPixelSize(R.dimen.bookmark_list_view_padding_top);
+            mBookmarkIdsList.getViewTreeObserver().addOnScrollChangedListener(() -> {
+                if (mBookmarkIdsList.getChildCount() < 1) return;
+
+                shadow.setVisibility(mBookmarkIdsList.getChildAt(0).getTop() < listPaddingTop
+                                ? View.VISIBLE
+                                : View.GONE);
+            });
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
index d5e3670..2213b95 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
@@ -26,7 +26,6 @@
 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksReader;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.snackbar.SnackbarManager;
-import org.chromium.chrome.browser.util.FeatureUtilities;
 import org.chromium.chrome.browser.widget.selection.SelectableBottomSheetContent.SelectableBottomSheetContentManager;
 import org.chromium.chrome.browser.widget.selection.SelectableListLayout;
 import org.chromium.chrome.browser.widget.selection.SelectableListToolbar;
@@ -154,10 +153,7 @@
 
         mToolbar = (BookmarkActionBar) mSelectableListLayout.initializeToolbar(
                 R.layout.bookmark_action_bar, mSelectionDelegate, 0, null, R.id.normal_menu_group,
-                R.id.selection_mode_menu_group,
-                FeatureUtilities.isChromeModernDesignEnabled() ? R.color.modern_toolbar_bg
-                                                               : R.color.modern_primary_color,
-                null, true);
+                R.id.selection_mode_menu_group, R.color.modern_primary_color, null, true);
         mToolbar.initializeSearchView(
                 this, R.string.bookmark_action_bar_search, R.id.search_menu_id);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
index 24586ba..617b9fa 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
@@ -37,12 +37,18 @@
 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
 import org.chromium.chrome.browser.ntp.NewTabPage;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
+import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
+import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
+import org.chromium.chrome.browser.tabmodel.TabModelUtils;
 import org.chromium.chrome.browser.util.ColorUtils;
 import org.chromium.chrome.browser.util.FeatureUtilities;
+import org.chromium.ui.base.LocalizationUtils;
 import org.chromium.ui.base.SPenSupport;
 import org.chromium.ui.resources.ResourceManager;
 import org.chromium.ui.resources.dynamics.DynamicResourceLoader;
@@ -53,8 +59,9 @@
  * A class that is responsible for managing an active {@link Layout} to show to the screen.  This
  * includes lifecycle managment like showing/hiding this {@link Layout}.
  */
-public class LayoutManager
-        implements LayoutUpdateHost, LayoutProvider, OverlayPanelContentViewDelegate {
+public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
+                                      OverlayPanelContentViewDelegate,
+                                      TabModelSelector.CloseAllTabsDelegate {
     /** Sampling at 60 fps. */
     private static final long FRAME_DELTA_TIME_MS = 16;
 
@@ -76,7 +83,9 @@
 
     // External Dependencies
     private TabModelSelector mTabModelSelector;
-    @SuppressWarnings("unused")
+
+    private TabModelObserver mTabModelObserver;
+    private TabModelSelectorObserver mTabModelSelectorObserver;
     private TabModelSelectorTabObserver mTabModelSelectorTabObserver;
     private ViewGroup mContentContainer;
 
@@ -120,6 +129,80 @@
     private final CompositorAnimationHandler mAnimationHandler;
 
     /**
+     * Protected class to handle {@link TabModelObserver} related tasks. Extending classes will
+     * need to override any related calls to add new functionality */
+    protected class LayoutManagerTabModelObserver extends EmptyTabModelObserver {
+        @Override
+        public void didSelectTab(Tab tab, TabModel.TabSelectionType type, int lastId) {
+            if (tab.getId() != lastId) tabSelected(tab.getId(), lastId, tab.isIncognito());
+        }
+
+        @Override
+        public void willAddTab(Tab tab, TabModel.TabLaunchType type) {
+            // Open the new tab
+            if (type == TabModel.TabLaunchType.FROM_RESTORE) return;
+            if (type == TabModel.TabLaunchType.FROM_REPARENTING) return;
+            if (type == TabModel.TabLaunchType.FROM_EXTERNAL_APP) return;
+            if (type == TabModel.TabLaunchType.FROM_LAUNCHER_SHORTCUT) return;
+
+            tabCreating(getTabModelSelector().getCurrentTabId(), tab.getUrl(), tab.isIncognito());
+        }
+
+        @Override
+        public void didAddTab(Tab tab, TabModel.TabLaunchType launchType) {
+            int tabId = tab.getId();
+            if (launchType == TabModel.TabLaunchType.FROM_RESTORE) {
+                getActiveLayout().onTabRestored(time(), tabId);
+            } else {
+                boolean incognito = tab.isIncognito();
+                boolean willBeSelected =
+                        launchType != TabModel.TabLaunchType.FROM_LONGPRESS_BACKGROUND
+                        || (!getTabModelSelector().isIncognitoSelected() && incognito);
+                float lastTapX = LocalizationUtils.isLayoutRtl() ? mHost.getWidth() * mPxToDp : 0.f;
+                float lastTapY = 0.f;
+                if (launchType != TabModel.TabLaunchType.FROM_CHROME_UI) {
+                    float heightDelta = mHost.getHeightMinusBrowserControls() * mPxToDp;
+                    lastTapX = mPxToDp * mLastTapX;
+                    lastTapY = mPxToDp * mLastTapY - heightDelta;
+                }
+
+                tabCreated(tabId, getTabModelSelector().getCurrentTabId(), launchType, incognito,
+                        willBeSelected, lastTapX, lastTapY);
+            }
+        }
+
+        @Override
+        public void didCloseTab(int tabId, boolean incognito) {
+            tabClosed(tabId, incognito, false);
+        }
+
+        @Override
+        public void tabPendingClosure(Tab tab) {
+            tabClosed(tab.getId(), tab.isIncognito(), false);
+        }
+
+        @Override
+        public void tabClosureUndone(Tab tab) {
+            tabClosureCancelled(tab.getId(), tab.isIncognito());
+        }
+
+        @Override
+        public void tabClosureCommitted(Tab tab) {
+            LayoutManager.this.tabClosureCommitted(tab.getId(), tab.isIncognito());
+        }
+
+        @Override
+        public void didMoveTab(Tab tab, int newIndex, int curIndex) {
+            tabMoved(tab.getId(), curIndex, newIndex, tab.isIncognito());
+        }
+
+        @Override
+        public void tabRemoved(Tab tab) {
+            tabClosed(tab.getId(), tab.isIncognito(), true);
+        }
+    }
+
+    /**
      * Creates a {@link LayoutManager} instance.
      * @param host A {@link LayoutManagerHost} instance.
      */
@@ -315,6 +398,36 @@
             public void onDidChangeThemeColor(Tab tab, int color) {
                 initLayoutTabFromHost(tab.getId());
             }
+
+            @Override
+            public void onLoadStarted(Tab tab, boolean toDifferentDocument) {
+                tabLoadStarted(tab.getId(), tab.isIncognito());
+            }
+
+            @Override
+            public void onLoadStopped(Tab tab, boolean toDifferentDocument) {
+                tabLoadFinished(tab.getId(), tab.isIncognito());
+            }
+
+            @Override
+            public void onPageLoadStarted(Tab tab, String url) {
+                tabPageLoadStarted(tab.getId(), tab.isIncognito());
+            }
+
+            @Override
+            public void onPageLoadFinished(Tab tab) {
+                tabPageLoadFinished(tab.getId(), tab.isIncognito());
+            }
+
+            @Override
+            public void onPageLoadFailed(Tab tab, int errorCode) {
+                tabPageLoadFinished(tab.getId(), tab.isIncognito());
+            }
+
+            @Override
+            public void onCrash(Tab tab, boolean sadTabShown) {
+                tabPageLoadFinished(tab.getId(), tab.isIncognito());
+            }
         };
 
         mContentContainer = androidContentContainer;
@@ -322,6 +435,18 @@
         if (mNextActiveLayout != null) startShowing(mNextActiveLayout, true);
 
         updateLayoutForTabModelSelector();
+
+        mTabModelSelectorObserver = new EmptyTabModelSelectorObserver() {
+            @Override
+            public void onTabModelSelected(TabModel newModel, TabModel oldModel) {
+                tabModelSwitched(newModel.isIncognito());
+            }
+        };
+        selector.addObserver(mTabModelSelectorObserver);
+        selector.setCloseAllTabsDelegate(this);
+
+        mTabModelObserver = createTabModelObserver();
+        for (TabModel model : selector.getModels()) model.addObserver(mTabModelObserver);
     }
 
     /**
@@ -333,6 +458,14 @@
         if (mStaticLayout != null) mStaticLayout.destroy();
         if (mOverlayPanelManager != null) mOverlayPanelManager.destroy();
         if (mTabModelSelectorTabObserver != null) mTabModelSelectorTabObserver.destroy();
+        if (mTabModelSelectorObserver != null) {
+            getTabModelSelector().removeObserver(mTabModelSelectorObserver);
+        }
+        if (mTabModelObserver != null) {
+            for (TabModel model : getTabModelSelector().getModels()) {
+                model.removeObserver(mTabModelObserver);
+            }
+        }
     }
 
     /**
@@ -397,6 +530,123 @@
         return mStaticLayout;
     }
 
+    /**
+     * @return The {@link TabModelObserver} instance this class should be using.
+     */
+    protected LayoutManagerChrome.LayoutManagerTabModelObserver createTabModelObserver() {
+        return new LayoutManagerChrome.LayoutManagerTabModelObserver();
+    }
+
+    @VisibleForTesting
+    public void tabSelected(int tabId, int prevId, boolean incognito) {
+        // Update the model here so we properly set the right selected TabModel.
+        if (getActiveLayout() != null) {
+            getActiveLayout().onTabSelected(time(), tabId, prevId, incognito);
+        }
+    }
+
+    /**
+     * Should be called when a tab creating event is triggered (called before the tab is done being
+     * created).
+     * @param sourceId    The id of the creating tab if any.
+     * @param url         The url of the created tab.
+     * @param isIncognito Whether or not created tab will be incognito.
+     */
+    protected void tabCreating(int sourceId, String url, boolean isIncognito) {
+        if (getActiveLayout() != null) getActiveLayout().onTabCreating(sourceId);
+    }
+
+    /**
+     * Should be called when a tab created event is triggered.
+     * @param id             The id of the tab that was created.
+     * @param sourceId       The id of the creating tab if any.
+     * @param launchType     How the tab was launched.
+     * @param incognito      Whether or not the created tab is incognito.
+     * @param willBeSelected Whether or not the created tab will be selected.
+     * @param originX        The x coordinate of the action that created this tab in dp.
+     * @param originY        The y coordinate of the action that created this tab in dp.
+     */
+    protected void tabCreated(int id, int sourceId, TabModel.TabLaunchType launchType,
+            boolean incognito, boolean willBeSelected, float originX, float originY) {
+        int newIndex = TabModelUtils.getTabIndexById(getTabModelSelector().getModel(incognito), id);
+        getActiveLayout().onTabCreated(
+                time(), id, newIndex, sourceId, incognito, !willBeSelected, originX, originY);
+    }
+
+    /**
+     * Should be called when a tab closed event is triggered.
+     * @param id         The id of the closed tab.
+     * @param nextId     The id of the next tab that will be visible, if any.
+     * @param incognito  Whether or not the closed tab is incognito.
+     * @param tabRemoved Whether the tab was removed from the model (e.g. for reparenting), rather
+     *                   than closed and destroyed.
+     */
+    protected void tabClosed(int id, int nextId, boolean incognito, boolean tabRemoved) {
+        if (getActiveLayout() != null) getActiveLayout().onTabClosed(time(), id, nextId, incognito);
+    }
+
+    private void tabClosed(int tabId, boolean incognito, boolean tabRemoved) {
+        Tab currentTab =
+                getTabModelSelector() != null ? getTabModelSelector().getCurrentTab() : null;
+        int nextTabId = currentTab != null ? currentTab.getId() : Tab.INVALID_TAB_ID;
+        tabClosed(tabId, nextTabId, incognito, tabRemoved);
+    }
+
+    /**
+     * Called when a tab closure has been committed and all tab cleanup should happen.
+     * @param id        The id of the closed tab.
+     * @param incognito Whether or not the closed tab is incognito.
+     */
+    protected void tabClosureCommitted(int id, boolean incognito) {
+        if (getActiveLayout() != null) {
+            getActiveLayout().onTabClosureCommitted(time(), id, incognito);
+        }
+    }
+
+    /**
+     * Called when the selected tab model has switched.
+     * @param incognito Whether or not the new current tab model is incognito.
+     */
+    protected void tabModelSwitched(boolean incognito) {
+        if (getActiveLayout() != null) getActiveLayout().onTabModelSwitched(incognito);
+    }
+
+    private void tabMoved(int id, int oldIndex, int newIndex, boolean incognito) {
+        if (getActiveLayout() != null) {
+            getActiveLayout().onTabMoved(time(), id, oldIndex, newIndex, incognito);
+        }
+    }
+
+    private void tabPageLoadStarted(int id, boolean incognito) {
+        if (getActiveLayout() != null) getActiveLayout().onTabPageLoadStarted(id, incognito);
+    }
+
+    private void tabPageLoadFinished(int id, boolean incognito) {
+        if (getActiveLayout() != null) getActiveLayout().onTabPageLoadFinished(id, incognito);
+    }
+
+    private void tabLoadStarted(int id, boolean incognito) {
+        if (getActiveLayout() != null) getActiveLayout().onTabLoadStarted(id, incognito);
+    }
+
+    private void tabLoadFinished(int id, boolean incognito) {
+        if (getActiveLayout() != null) getActiveLayout().onTabLoadFinished(id, incognito);
+    }
+
+    private void tabClosureCancelled(int id, boolean incognito) {
+        if (getActiveLayout() != null) {
+            getActiveLayout().onTabClosureCancelled(time(), id, incognito);
+        }
+    }
+
+    @Override
+    public boolean closeAllTabsRequest(boolean incognito) {
+        if (!getActiveLayout().handlesCloseAll()) return false;
+
+        getActiveLayout().onTabsAllClosing(time(), incognito);
+        return true;
+    }
+
     @Override
     public void initLayoutTabFromHost(final int tabId) {
         if (getTabModelSelector() == null || getActiveLayout() == null) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
index 9efcf40..f287549 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -22,21 +22,12 @@
 import org.chromium.chrome.browser.device.DeviceClassManager;
 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
 import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
-import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
-import org.chromium.chrome.browser.tabmodel.TabModel;
 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
-import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType;
-import org.chromium.chrome.browser.tabmodel.TabModelObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
-import org.chromium.chrome.browser.tabmodel.TabModelSelector.CloseAllTabsDelegate;
-import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
-import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
 import org.chromium.chrome.browser.tabmodel.TabModelUtils;
 import org.chromium.chrome.browser.util.AccessibilityUtil;
 import org.chromium.chrome.browser.widget.OverviewListLayout;
-import org.chromium.ui.base.LocalizationUtils;
 import org.chromium.ui.resources.dynamics.DynamicResourceLoader;
 
 import java.util.List;
@@ -45,8 +36,7 @@
  * A {@link Layout} controller for the more complicated Chrome browser.  This is currently a
  * superset of {@link LayoutManager}.
  */
-public class LayoutManagerChrome
-        extends LayoutManager implements OverviewModeBehavior, CloseAllTabsDelegate {
+public class LayoutManagerChrome extends LayoutManager implements OverviewModeBehavior {
     // Layouts
     /** An {@link Layout} that should be used as the accessibility tab switcher. */
     protected OverviewListLayout mOverviewListLayout;
@@ -66,83 +56,6 @@
     private boolean mEnableAnimations = true;
     private boolean mCreatingNtp;
     private final ObserverList<OverviewModeObserver> mOverviewModeObservers;
-    private TabModelSelectorObserver mTabModelSelectorObserver;
-    private TabModelObserver mTabModelObserver;
-    private TabModelSelectorTabObserver mTabSelectorTabObserver;
-
-    /**
-     * Protected class to handle {@link TabModelObserver} related tasks. Extending classes will
-     * need to override any related calls to add new functionality */
-    protected class LayoutManagerTabModelObserver extends EmptyTabModelObserver {
-        @Override
-        public void didSelectTab(Tab tab, TabSelectionType type, int lastId) {
-            if (tab.getId() != lastId) tabSelected(tab.getId(), lastId, tab.isIncognito());
-        }
-
-        @Override
-        public void willAddTab(Tab tab, TabLaunchType type) {
-            // Open the new tab
-            if (type == TabLaunchType.FROM_RESTORE) return;
-            if (type == TabLaunchType.FROM_REPARENTING) return;
-            if (type == TabLaunchType.FROM_EXTERNAL_APP) return;
-            if (type == TabLaunchType.FROM_LAUNCHER_SHORTCUT) return;
-
-            tabCreating(getTabModelSelector().getCurrentTabId(), tab.getUrl(), tab.isIncognito());
-        }
-
-        @Override
-        public void didAddTab(Tab tab, TabLaunchType launchType) {
-            int tabId = tab.getId();
-            if (launchType == TabLaunchType.FROM_RESTORE) {
-                getActiveLayout().onTabRestored(time(), tabId);
-            } else {
-                boolean incognito = tab.isIncognito();
-                boolean willBeSelected = launchType != TabLaunchType.FROM_LONGPRESS_BACKGROUND
-                        || (!getTabModelSelector().isIncognitoSelected() && incognito);
-                float lastTapX = LocalizationUtils.isLayoutRtl()
-                        ? mHost.getWidth() * mPxToDp : 0.f;
-                float lastTapY = 0.f;
-                if (launchType != TabLaunchType.FROM_CHROME_UI) {
-                    float heightDelta = mHost.getHeightMinusBrowserControls() * mPxToDp;
-                    lastTapX = mPxToDp * mLastTapX;
-                    lastTapY = mPxToDp * mLastTapY - heightDelta;
-                }
-
-                tabCreated(tabId, getTabModelSelector().getCurrentTabId(), launchType, incognito,
-                        willBeSelected, lastTapX, lastTapY);
-            }
-        }
-
-        @Override
-        public void didCloseTab(int tabId, boolean incognito) {
-            tabClosed(tabId, incognito, false);
-        }
-
-        @Override
-        public void tabPendingClosure(Tab tab) {
-            tabClosed(tab.getId(), tab.isIncognito(), false);
-        }
-
-        @Override
-        public void tabClosureUndone(Tab tab) {
-            tabClosureCancelled(tab.getId(), tab.isIncognito());
-        }
-
-        @Override
-        public void tabClosureCommitted(Tab tab) {
-            LayoutManagerChrome.this.tabClosureCommitted(tab.getId(), tab.isIncognito());
-        }
-
-        @Override
-        public void didMoveTab(Tab tab, int newIndex, int curIndex) {
-            tabMoved(tab.getId(), curIndex, newIndex, tab.isIncognito());
-        }
-
-        @Override
-        public void tabRemoved(Tab tab) {
-            tabClosed(tab.getId(), tab.isIncognito(), true);
-        }
-    }
 
     /**
      * Creates the {@link LayoutManagerChrome} instance.
@@ -167,13 +80,6 @@
     }
 
     /**
-     * @return The {@link TabModelObserver} instance this class should be using.
-     */
-    protected LayoutManagerTabModelObserver createTabModelObserver() {
-        return new LayoutManagerTabModelObserver();
-    }
-
-    /**
      * @return A list of virtual views representing compositor rendered views.
      */
     @Override
@@ -206,64 +112,11 @@
 
         super.init(selector, creator, content, androidContentContainer, contextualSearchDelegate,
                 dynamicResourceLoader);
-
-        mTabModelSelectorObserver = new EmptyTabModelSelectorObserver() {
-            @Override
-            public void onTabModelSelected(TabModel newModel, TabModel oldModel) {
-                tabModelSwitched(newModel.isIncognito());
-            }
-        };
-        selector.addObserver(mTabModelSelectorObserver);
-        selector.setCloseAllTabsDelegate(this);
-
-        mTabModelObserver = createTabModelObserver();
-        for (TabModel model : selector.getModels()) model.addObserver(mTabModelObserver);
-
-        mTabSelectorTabObserver = new TabModelSelectorTabObserver(selector) {
-            @Override
-            public void onLoadStarted(Tab tab, boolean toDifferentDocument) {
-                tabLoadStarted(tab.getId(), tab.isIncognito());
-            }
-
-            @Override
-            public void onLoadStopped(Tab tab, boolean toDifferentDocument) {
-                tabLoadFinished(tab.getId(), tab.isIncognito());
-            }
-
-            @Override
-            public void onPageLoadStarted(Tab tab, String url) {
-                tabPageLoadStarted(tab.getId(), tab.isIncognito());
-            }
-
-            @Override
-            public void onPageLoadFinished(Tab tab) {
-                tabPageLoadFinished(tab.getId(), tab.isIncognito());
-            }
-
-            @Override
-            public void onPageLoadFailed(Tab tab, int errorCode) {
-                tabPageLoadFinished(tab.getId(), tab.isIncognito());
-            }
-
-            @Override
-            public void onCrash(Tab tab, boolean sadTabShown) {
-                tabPageLoadFinished(tab.getId(), tab.isIncognito());
-            }
-        };
     }
 
     @Override
     public void destroy() {
         super.destroy();
-        if (mTabModelSelectorObserver != null) {
-            getTabModelSelector().removeObserver(mTabModelSelectorObserver);
-        }
-        if (mTabModelObserver != null) {
-            for (TabModel model : getTabModelSelector().getModels()) {
-                model.removeObserver(mTabModelObserver);
-            }
-        }
-        if (mTabSelectorTabObserver != null) mTabSelectorTabObserver.destroy();
         mOverviewModeObservers.clear();
 
         if (mOverviewLayout != null) {
@@ -397,118 +250,19 @@
         }
     }
 
-    @VisibleForTesting
-    public void tabSelected(int tabId, int prevId, boolean incognito) {
-        // Update the model here so we properly set the right selected TabModel.
-        if (getActiveLayout() != null) {
-            getActiveLayout().onTabSelected(time(), tabId, prevId, incognito);
-        }
-    }
-
-    /**
-     * Should be called when a tab created event is triggered.
-     * @param id             The id of the tab that was created.
-     * @param sourceId       The id of the creating tab if any.
-     * @param launchType     How the tab was launched.
-     * @param incognito      Whether or not the created tab is incognito.
-     * @param willBeSelected Whether or not the created tab will be selected.
-     * @param originX        The x coordinate of the action that created this tab in dp.
-     * @param originY        The y coordinate of the action that created this tab in dp.
-     */
+    @Override
     protected void tabCreated(int id, int sourceId, TabLaunchType launchType, boolean incognito,
             boolean willBeSelected, float originX, float originY) {
         Tab newTab = TabModelUtils.getTabById(getTabModelSelector().getModel(incognito), id);
         mCreatingNtp = newTab != null && newTab.isNativePage();
-
-        int newIndex = TabModelUtils.getTabIndexById(getTabModelSelector().getModel(incognito), id);
-        getActiveLayout().onTabCreated(
-                time(), id, newIndex, sourceId, incognito, !willBeSelected, originX, originY);
-    }
-
-    /**
-     * Should be called when a tab creating event is triggered (called before the tab is done being
-     * created).
-     * @param sourceId    The id of the creating tab if any.
-     * @param url         The url of the created tab.
-     * @param isIncognito Whether or not created tab will be incognito.
-     */
-    protected void tabCreating(int sourceId, String url, boolean isIncognito) {
-        if (getActiveLayout() != null) getActiveLayout().onTabCreating(sourceId);
-    }
-
-    /**
-     * Should be called when a tab closed event is triggered.
-     * @param id         The id of the closed tab.
-     * @param nextId     The id of the next tab that will be visible, if any.
-     * @param incognito  Whether or not the closed tab is incognito.
-     * @param tabRemoved Whether the tab was removed from the model (e.g. for reparenting), rather
-     *                   than closed and destroyed.
-     */
-    protected void tabClosed(int id, int nextId, boolean incognito, boolean tabRemoved) {
-        if (getActiveLayout() != null) getActiveLayout().onTabClosed(time(), id, nextId, incognito);
-    }
-
-    private void tabClosed(int tabId, boolean incognito, boolean tabRemoved) {
-        Tab currentTab =
-                getTabModelSelector() != null ? getTabModelSelector().getCurrentTab() : null;
-        int nextTabId = currentTab != null ? currentTab.getId() : Tab.INVALID_TAB_ID;
-        tabClosed(tabId, nextTabId, incognito, tabRemoved);
-    }
-
-    /**
-     * Called when a tab closure has been committed and all tab cleanup should happen.
-     * @param id        The id of the closed tab.
-     * @param incognito Whether or not the closed tab is incognito.
-     */
-    protected void tabClosureCommitted(int id, boolean incognito) {
-        if (getActiveLayout() != null) {
-            getActiveLayout().onTabClosureCommitted(time(), id, incognito);
-        }
+        super.tabCreated(id, sourceId, launchType, incognito, willBeSelected, originX, originY);
     }
 
     @Override
     public boolean closeAllTabsRequest(boolean incognito) {
-        if (!isOverviewLayout(getActiveLayout()) || !getActiveLayout().handlesCloseAll()) {
-            return false;
-        }
-        getActiveLayout().onTabsAllClosing(time(), incognito);
-        return true;
-    }
+        if (!isOverviewLayout(getActiveLayout())) return false;
 
-    /**
-     * Called when the selected tab model has switched.
-     * @param incognito Whether or not the new current tab model is incognito.
-     */
-    protected void tabModelSwitched(boolean incognito) {
-        if (getActiveLayout() != null) getActiveLayout().onTabModelSwitched(incognito);
-    }
-
-    private void tabMoved(int id, int oldIndex, int newIndex, boolean incognito) {
-        if (getActiveLayout() != null) {
-            getActiveLayout().onTabMoved(time(), id, oldIndex, newIndex, incognito);
-        }
-    }
-
-    private void tabPageLoadStarted(int id, boolean incognito) {
-        if (getActiveLayout() != null) getActiveLayout().onTabPageLoadStarted(id, incognito);
-    }
-
-    private void tabPageLoadFinished(int id, boolean incognito) {
-        if (getActiveLayout() != null) getActiveLayout().onTabPageLoadFinished(id, incognito);
-    }
-
-    private void tabLoadStarted(int id, boolean incognito) {
-        if (getActiveLayout() != null) getActiveLayout().onTabLoadStarted(id, incognito);
-    }
-
-    private void tabLoadFinished(int id, boolean incognito) {
-        if (getActiveLayout() != null) getActiveLayout().onTabLoadFinished(id, incognito);
-    }
-
-    private void tabClosureCancelled(int id, boolean incognito) {
-        if (getActiveLayout() != null) {
-            getActiveLayout().onTabClosureCancelled(time(), id, incognito);
-        }
+        return super.closeAllTabsRequest(incognito);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
index 1f0a07a..9c0e191 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromeTablet.java
@@ -89,9 +89,7 @@
             // internal tab to show and not start hiding until we're done calling finalizeShowing().
             // This prevents a flicker because we properly build and set the internal
             // {@link LayoutTab} before actually showing the {@link TabView}.
-            if (getActiveLayout() != null) {
-                getActiveLayout().onTabSelected(time(), tabId, prevId, incognito);
-            }
+            super.tabSelected(tabId, prevId, incognito);
             if (getActiveLayout() != null) getActiveLayout().onTabSelecting(time(), tabId);
         }
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
index 7f194ea2..d1ec012a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -432,7 +432,7 @@
                     (params == null ? null : params.getFinalizeCallback()));
         }
 
-        LayoutManager layoutDriver = new CustomTabLayoutManager(getCompositorViewHolder());
+        LayoutManager layoutDriver = new LayoutManager(getCompositorViewHolder());
         initializeCompositorContent(layoutDriver, findViewById(R.id.url_bar),
                 (ViewGroup) findViewById(android.R.id.content),
                 (ToolbarControlContainer) findViewById(R.id.control_container));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabLayoutManager.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabLayoutManager.java
deleted file mode 100644
index bf534e32..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabLayoutManager.java
+++ /dev/null
@@ -1,60 +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.customtabs;
-
-import android.view.ViewGroup;
-
-import org.chromium.chrome.browser.compositor.layouts.LayoutManager;
-import org.chromium.chrome.browser.compositor.layouts.LayoutManagerHost;
-import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
-import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDelegate;
-import org.chromium.chrome.browser.tab.Tab;
-import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
-import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
-import org.chromium.chrome.browser.tabmodel.TabModel;
-import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
-import org.chromium.chrome.browser.tabmodel.TabModelObserver;
-import org.chromium.chrome.browser.tabmodel.TabModelSelector;
-import org.chromium.chrome.browser.tabmodel.TabModelUtils;
-import org.chromium.ui.resources.dynamics.DynamicResourceLoader;
-
-/**
- * A simple LayoutManager that shows multiple tabs without animation.
- */
-public class CustomTabLayoutManager extends LayoutManager {
-    TabModelObserver mTabModelObserver = new EmptyTabModelObserver() {
-        @Override
-        public void didAddTab(Tab tab, TabLaunchType type) {
-            if (type == TabLaunchType.FROM_RESTORE) {
-                getActiveLayout().onTabRestored(time(), tab.getId());
-            } else {
-                int newIndex = TabModelUtils.getTabIndexById(getTabModelSelector().getModel(false),
-                        tab.getId());
-                getActiveLayout().onTabCreated(time(), tab.getId(), newIndex,
-                        getTabModelSelector().getCurrentTabId(), false, false, 0f, 0f);
-            }
-        }
-
-        @Override
-        public void didCloseTab(int tabId, boolean incognito) {
-            getActiveLayout().onTabSelected(time(), getTabModelSelector().getCurrentTabId(),
-                    tabId, false);
-        }
-    };
-
-    public CustomTabLayoutManager(LayoutManagerHost host) {
-        super(host);
-    }
-
-    @Override
-    public void init(TabModelSelector selector, TabCreatorManager creator,
-            TabContentManager content, ViewGroup androidContentContainer,
-            ContextualSearchManagementDelegate contextualSearchDelegate,
-            DynamicResourceLoader dynamicResourceLoader) {
-        super.init(selector, creator, content, androidContentContainer, contextualSearchDelegate,
-                dynamicResourceLoader);
-        for (TabModel model : selector.getModels()) model.addObserver(mTabModelObserver);
-    }
-}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java
index 1c5d5c5..967365f6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java
@@ -36,7 +36,6 @@
 import org.chromium.chrome.browser.snackbar.Snackbar;
 import org.chromium.chrome.browser.snackbar.SnackbarManager;
 import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController;
-import org.chromium.chrome.browser.util.FeatureUtilities;
 import org.chromium.chrome.browser.widget.ThumbnailProvider;
 import org.chromium.chrome.browser.widget.ThumbnailProviderImpl;
 import org.chromium.chrome.browser.widget.selection.SelectableBottomSheetContent.SelectableBottomSheetContentManager;
@@ -251,9 +250,7 @@
         mToolbar = (DownloadManagerToolbar) mSelectableListLayout.initializeToolbar(
                 R.layout.download_manager_toolbar, mBackendProvider.getSelectionDelegate(), 0, null,
                 R.id.normal_menu_group, R.id.selection_mode_menu_group,
-                FeatureUtilities.isChromeModernDesignEnabled() ? R.color.modern_toolbar_bg
-                                                               : R.color.modern_primary_color,
-                this, true);
+                R.color.modern_primary_color, this, true);
         mToolbar.setManager(this);
         mToolbar.initializeFilterSpinner(mFilterAdapter);
         mToolbar.initializeSearchView(this, R.string.download_manager_search, R.id.search_menu_id);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
index 0fbe865..1f255fd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
@@ -39,7 +39,6 @@
 import org.chromium.chrome.browser.snackbar.Snackbar;
 import org.chromium.chrome.browser.snackbar.SnackbarManager;
 import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController;
-import org.chromium.chrome.browser.util.FeatureUtilities;
 import org.chromium.chrome.browser.util.IntentUtils;
 import org.chromium.chrome.browser.widget.selection.SelectableBottomSheetContent.SelectableBottomSheetContentManager;
 import org.chromium.chrome.browser.widget.selection.SelectableListLayout;
@@ -118,9 +117,7 @@
         mToolbar = (HistoryManagerToolbar) mSelectableListLayout.initializeToolbar(
                 R.layout.history_toolbar, mSelectionDelegate, R.string.menu_history, null,
                 R.id.normal_menu_group, R.id.selection_mode_menu_group,
-                FeatureUtilities.isChromeModernDesignEnabled() ? R.color.modern_toolbar_bg
-                                                               : R.color.modern_primary_color,
-                this, true);
+                R.color.modern_primary_color, this, true);
         mToolbar.setManager(this);
         mToolbar.initializeSearchView(this, R.string.history_manager_search, R.id.search_menu_id);
         mToolbar.setInfoMenuItem(R.id.info_menu_id);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
index be8a9a9a..a4772470 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -113,7 +113,13 @@
     private static final String VR_CORE_MARKET_URI =
             "market://details?id=" + VrCoreVersionChecker.VR_CORE_PACKAGE_ID;
 
-    private static final int WINDOW_FADE_ANIMATION_DURATION_MS = 150;
+    // This value is intentionally probably overkill. This is the time we need to wait from when
+    // Chrome is resumed, to when Chrome actually renders a black frame, so that we can cancel the
+    // stay_hidden animation and not see a white monoscopic frame in-headset. 150ms is definitely
+    // too short, 250ms is sometimes too short for debug builds. 500ms should hopefully be safe even
+    // under fairly exceptional conditions, and won't delay entering VR a noticeable amount given
+    // how slow it already is.
+    private static final int WINDOW_FADE_ANIMATION_DURATION_MS = 500;
 
     private static VrShellDelegate sInstance;
     private static VrBroadcastReceiver sVrBroadcastReceiver;
@@ -217,8 +223,13 @@
             sInstance.mExpectPauseOrDonSucceeded.removeCallbacksAndMessages(null);
             sInstance.mVrClassesWrapper.setVrModeEnabled(sInstance.mActivity, true);
             if (DEBUG_LOGS) Log.i(TAG, "VrBroadcastReceiver onReceive");
-            sInstance.setWindowModeForVr();
+
             if (sInstance.mPaused) {
+                // Note that even though we are definitely entering VR here, we don't want to set
+                // the window mode yet, as setting the window mode while we're in the background can
+                // racily lead to that window mode change essentially being ignored, with future
+                // attempts to set the same window mode also being ignored.
+
                 if (sInstance.mInVrAtChromeLaunch == null) sInstance.mInVrAtChromeLaunch = false;
                 // We add a black overlay view so that we can show black while the VR UI is loading.
                 // Note that this alone isn't sufficient to prevent 2D UI from showing while
@@ -1336,6 +1347,7 @@
     }
 
     private void handleDonFlowSuccess() {
+        setWindowModeForVr();
         if (mInVr) {
             maybeSetPresentResult(true, mDonSucceeded);
             mDonSucceeded = false;
@@ -1402,6 +1414,7 @@
 
     private void onStart() {
         mStopped = false;
+        if (mDonSucceeded) setWindowModeForVr();
     }
 
     private void onStop() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
index a57ac10..1930e4a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -47,7 +47,6 @@
 import org.chromium.chrome.browser.browserservices.OriginVerifier.OriginVerificationListener;
 import org.chromium.chrome.browser.compositor.layouts.LayoutManager;
 import org.chromium.chrome.browser.customtabs.CustomTabAppMenuPropertiesDelegate;
-import org.chromium.chrome.browser.customtabs.CustomTabLayoutManager;
 import org.chromium.chrome.browser.customtabs.CustomTabsConnection;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.document.DocumentUtils;
@@ -333,7 +332,7 @@
         }
 
         initializeUI(getSavedInstanceState());
-        LayoutManager layoutDriver = new CustomTabLayoutManager(getCompositorViewHolder());
+        LayoutManager layoutDriver = new LayoutManager(getCompositorViewHolder());
         initializeCompositorContent(layoutDriver, findViewById(R.id.url_bar),
                 (ViewGroup) findViewById(android.R.id.content),
                 (ToolbarControlContainer) findViewById(R.id.control_container));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
index ad791e8..5610832 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
@@ -18,7 +18,6 @@
 import android.support.v7.widget.RecyclerView.OnScrollListener;
 import android.support.v7.widget.Toolbar.OnMenuItemClickListener;
 import android.util.AttributeSet;
-import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewStub;
@@ -67,7 +66,6 @@
 
     private int mEmptyStringResId;
     private int mSearchEmptyStringResId;
-    private int mChromeHomeEmptyAndLoadingViewTopPadding;
 
     private UiConfig mUiConfig;
 
@@ -112,15 +110,8 @@
 
         LayoutInflater.from(getContext()).inflate(R.layout.selectable_list_layout, this);
 
-        // TODO(twellington): Remove this fork in the code after UX decides on final design
-        // for empty and loading views.
-        mChromeHomeEmptyAndLoadingViewTopPadding =
-                getResources().getDimensionPixelSize(R.dimen.chrome_home_empty_view_top_padding);
-
         mEmptyView = (TextView) findViewById(R.id.empty_view);
-        setEmptyOrLoadingViewStyle(mEmptyView);
         mLoadingView = (LoadingView) findViewById(R.id.loading_view);
-        setEmptyOrLoadingViewStyle(mLoadingView);
         mLoadingView.showLoadingUI();
 
         mToolbarStub = (ViewStub) findViewById(R.id.action_bar_stub);
@@ -204,7 +195,6 @@
         mToolbarShadow.init(
                 ApiCompatibilityUtils.getColor(getResources(), R.color.toolbar_shadow_color),
                 FadingShadow.POSITION_TOP);
-        if (FeatureUtilities.isChromeModernDesignEnabled()) mToolbarShadow.setAlpha(0);
 
         mShowShadowOnSelection = showShadowOnSelection;
         delegate.addObserver(this);
@@ -327,7 +317,8 @@
     private void setToolbarShadowVisibility() {
         if (mToolbar == null || mRecyclerView == null) return;
 
-        boolean showShadow = mRecyclerView.canScrollVertically(-1) || mToolbar.isSearching()
+        boolean showShadow = mRecyclerView.canScrollVertically(-1)
+                || (mToolbar.isSearching() && !FeatureUtilities.isChromeModernDesignEnabled())
                 || (mToolbar.getSelectionDelegate().isSelectionEnabled() && mShowShadowOnSelection);
         mToolbarShadow.setVisibility(showShadow ? View.VISIBLE : View.GONE);
     }
@@ -344,13 +335,4 @@
     public View getToolbarShadowForTests() {
         return mToolbarShadow;
     }
-
-    private void setEmptyOrLoadingViewStyle(View view) {
-        if (!FeatureUtilities.isChromeModernDesignEnabled()) return;
-
-        ((FrameLayout.LayoutParams) view.getLayoutParams()).gravity = Gravity.CENTER_HORIZONTAL;
-        ApiCompatibilityUtils.setPaddingRelative(view, ApiCompatibilityUtils.getPaddingStart(view),
-                view.getPaddingTop() + mChromeHomeEmptyAndLoadingViewTopPadding,
-                ApiCompatibilityUtils.getPaddingEnd(view), view.getPaddingBottom());
-    }
 }
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java
index 4058811..4868b40 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListToolbar.java
@@ -198,7 +198,8 @@
 
         normalBackgroundColorResId = normalBackgroundColorResId != null
                 ? normalBackgroundColorResId
-                : R.color.default_primary_color;
+                : FeatureUtilities.isChromeModernDesignEnabled() ? R.color.modern_primary_color
+                                                                 : R.color.default_primary_color;
         mNormalBackgroundColor =
                 ApiCompatibilityUtils.getColor(getResources(), normalBackgroundColorResId);
         setBackgroundColor(mNormalBackgroundColor);
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 9a478cd..2ebf50b9 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -303,7 +303,6 @@
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java",
-  "java/src/org/chromium/chrome/browser/customtabs/CustomTabLayoutManager.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionService.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowTestHelper.java b/chrome/android/javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowTestHelper.java
index 1af7876..36cc2ca 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowTestHelper.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowTestHelper.java
@@ -9,7 +9,9 @@
 import android.app.ActivityManager;
 import android.content.Context;
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Build;
+import android.support.annotation.Nullable;
 
 import org.junit.Assert;
 
@@ -22,6 +24,7 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.content_public.browser.LoadUrlParams;
 
 import java.lang.ref.WeakReference;
 import java.util.Locale;
@@ -33,12 +36,25 @@
  */
 public class MultiWindowTestHelper {
     /**
-     * Creates a new {@link ChromeTabbedActivity2}.
+     * Creates a new {@link ChromeTabbedActivity2} with no {@link LoadUrlParams}.
      * @param activity A current running activity that will handle the intent to start another
-     *        activity.
+     *                 activity.
      * @return The new {@link ChromeTabbedActivity2}.
      */
     public static ChromeTabbedActivity2 createSecondChromeTabbedActivity(Activity activity) {
+        return createSecondChromeTabbedActivity(activity, null);
+    }
+
+    /**
+     * Creates a new {@link ChromeTabbedActivity2}.
+     * @param activity A current running activity that will handle the intent to start another
+     *                 activity.
+     * @param params {@link LoadUrlParams} used to create the launch intent. May be null if no
+     *               params should be used when creating the activity.
+     * @return The new {@link ChromeTabbedActivity2}.
+     */
+    public static ChromeTabbedActivity2 createSecondChromeTabbedActivity(
+            Activity activity, @Nullable LoadUrlParams params) {
         // TODO(twellington): after there is test support for putting an activity into multi-window
         // mode, this should be changed to use the menu item for opening a new window.
 
@@ -54,7 +70,13 @@
                 ChromeTabbedActivity2.class, secondActivityClass);
 
         // Create an intent and start the second ChromeTabbedActivity.
-        Intent intent = new Intent();
+        Intent intent;
+        if (params != null) {
+            intent = new Intent(Intent.ACTION_VIEW, Uri.parse(params.getUrl()));
+        } else {
+            intent = new Intent();
+        }
+
         MultiWindowUtils.setOpenInOtherWindowIntentExtras(intent, activity, secondActivityClass);
         MultiWindowUtils.onMultiInstanceModeStarted();
         activity.startActivity(intent);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelMergingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelMergingTest.java
index 3aa0a5f2..b2ce456f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelMergingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelMergingTest.java
@@ -51,7 +51,7 @@
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-@MinAndroidSdkLevel(24)
+@MinAndroidSdkLevel(Build.VERSION_CODES.N)
 public class TabModelMergingTest {
     @Rule
     public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
@@ -63,6 +63,7 @@
     private static final String TEST_URL_4 = UrlUtils.encodeHtmlDataUri("<html>test_url_4.</html>");
     private static final String TEST_URL_5 = UrlUtils.encodeHtmlDataUri("<html>test_url_5.</html>");
     private static final String TEST_URL_6 = UrlUtils.encodeHtmlDataUri("<html>test_url_6.</html>");
+    private static final String TEST_URL_7 = UrlUtils.encodeHtmlDataUri("<html>test_url_7.</html>");
 
     private ChromeTabbedActivity mActivity1;
     private ChromeTabbedActivity mActivity2;
@@ -90,8 +91,9 @@
         // Start multi-instance mode so that ChromeTabbedActivity's check for whether the activity
         // is started up correctly doesn't fail.
         ChromeTabbedActivity.onMultiInstanceModeStarted();
-        mActivity2 = MultiWindowTestHelper.createSecondChromeTabbedActivity(mActivity1);
-        CriteriaHelper.pollUiThread(new Criteria() {
+        mActivity2 = MultiWindowTestHelper.createSecondChromeTabbedActivity(
+                mActivity1, new LoadUrlParams(TEST_URL_7));
+        CriteriaHelper.pollUiThread(new Criteria("CTA2 tab state failed to initialize.") {
             @Override
             public boolean isSatisfied() {
                 return mActivity2.areTabModelsInitialized()
@@ -125,10 +127,6 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                // Load a URL in ChromeTabbedActivity2 so that its first tab isn't chrome://newtab.
-                // chrome://newtab may be skipped when reading tab state during cold start.
-                mActivity2.getActivityTab().loadUrl(new LoadUrlParams(TEST_URL_5));
-
                 // Create normal tabs.
                 mActivity1.getTabCreator(false).createNewTab(new LoadUrlParams(TEST_URL_0),
                         TabLaunchType.FROM_CHROME_UI, null);
@@ -198,7 +196,7 @@
         });
 
         // Wait for all tabs to be merged into the activity.
-        CriteriaHelper.pollUiThread(new Criteria() {
+        CriteriaHelper.pollUiThread(new Criteria("Total tab count incorrect.") {
             @Override
             public boolean isSatisfied() {
                 return activity.getTabModelSelector().getTotalTabCount() == expectedNumberOfTabs;
@@ -233,7 +231,7 @@
                         .startActivitySync(intent);
 
         // Wait for the tab state to be initialized.
-        CriteriaHelper.pollUiThread(new Criteria() {
+        CriteriaHelper.pollUiThread(new Criteria("Tab state failed to initialize.") {
             @Override
             public boolean isSatisfied() {
                 return newActivity.areTabModelsInitialized()
@@ -298,16 +296,24 @@
         });
 
         // Destroy both activities.
-        mActivity1.finishAndRemoveTask();
         mActivity2.finishAndRemoveTask();
-        CriteriaHelper.pollUiThread(new Criteria() {
+        CriteriaHelper.pollUiThread(new Criteria(
+                "CTA2 should be destroyed, current state: " + mActivity2State) {
             @Override
             public boolean isSatisfied() {
-                return mActivity1State == ActivityState.DESTROYED
-                        && mActivity2State == ActivityState.DESTROYED;
+                return mActivity2State == ActivityState.DESTROYED;
             }
         });
 
+        mActivity1.finishAndRemoveTask();
+        CriteriaHelper.pollUiThread(
+                new Criteria("CTA should be destroyed, current state: " + mActivity1State) {
+                    @Override
+                    public boolean isSatisfied() {
+                        return mActivity1State == ActivityState.DESTROYED;
+                    }
+                });
+
         // Start the new ChromeTabbedActivity.
         final ChromeTabbedActivity newActivity = startNewChromeTabbedActivityAndAssert(
                 intent, expectedSelectedUrl, mMergeIntoActivity1ExpectedTabs);
@@ -339,7 +345,8 @@
         // Destroy ChromeTabbedActivity2. ChromeTabbedActivity should have been destroyed during the
         // merge.
         mActivity2.finishAndRemoveTask();
-        CriteriaHelper.pollUiThread(new Criteria() {
+        CriteriaHelper.pollUiThread(new Criteria("Both activitie should be destroyed."
+                + "CTA state: " + mActivity1State + " - CTA2State: " + mActivity2State) {
             @Override
             public boolean isSatisfied() {
                 return mActivity1State == ActivityState.DESTROYED
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index d4e058ab..feeeb9c7 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -183,6 +183,20 @@
           Chromium - <ph name="PAGE_TITLE">$1<ex>Google</ex></ph>
         </message>
       </if>
+      <!-- Accessible window title format - includes the channel, and the same
+           on all browser platforms rather than different on Chrome OS. -->
+      <message name="IDS_ACCESSIBLE_BROWSER_WINDOW_TITLE_FORMAT" desc="The format for the accessible name of a tabbed browser window">
+        <ph name="PAGE_TITLE">$1<ex>Google</ex></ph> - Chromium
+      </message>
+      <message name="IDS_ACCESSIBLE_BETA_BROWSER_WINDOW_TITLE_FORMAT" desc="The format for the accessible name of a tabbed browser window for the beta channel version of the browser">
+        <ph name="PAGE_TITLE">$1<ex>Google</ex></ph> - Chromium Beta
+      </message>
+      <message name="IDS_ACCESSIBLE_DEV_BROWSER_WINDOW_TITLE_FORMAT" desc="The format for the accessible name of a tabbed browser window for the developer (dev) channel version of the browser">
+        <ph name="PAGE_TITLE">$1<ex>Google</ex></ph> - Chromium Dev
+      </message>
+      <message name="IDS_ACCESSIBLE_CANARY_BROWSER_WINDOW_TITLE_FORMAT" desc="The format for the accessible name of a tabbed browser window for the canary (nightly build) channel version of the browser">
+        <ph name="PAGE_TITLE">$1<ex>Google</ex></ph> - Chromium Canary
+      </message>
       <if expr="not chromeos">
         <message name="IDS_GET_HELP_USING_CHROME" desc="Text of the button which takes the user to the Chrome help page.">
           Get help with using Chromium
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index ad52bed..9003dc1 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5329,6 +5329,9 @@
       <message name="IDS_ACCESSIBLE_INCOGNITO_WINDOW_TITLE_FORMAT" desc="The format for the accessible title of an incognito window">
         <ph name="WINDOW_TITLE">$1</ph> (Incognito)
       </message>
+      <message name="IDS_ACCESSIBLE_WINDOW_TITLE_WITH_PROFILE_FORMAT" desc="The format for describing the accessible window title when the window is associated with a particular profile.">
+        <ph name="PROFILE_NAME">$1<ex>John Smith</ex></ph>: <ph name="WINDOW_TITLE">$2<ex>Facebook</ex></ph>
+      </message>
       <message name="IDS_ACCNAME_APP_UPGRADE_RECOMMENDED" desc="The accessible name for the app menu when software update is available.">
         <ph name="ACCNAME_APP">$1<ex>Chrome</ex></ph> (Update is available)
       </message>
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index 1c473589..487ddf8 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -188,6 +188,20 @@
           Chrome - <ph name="PAGE_TITLE">$1<ex>Google</ex></ph>
         </message>
       </if>
+      <!-- Accessible window title format - includes the channel, and the same
+           on all browser platforms rather than different on Chrome OS. -->
+      <message name="IDS_ACCESSIBLE_BROWSER_WINDOW_TITLE_FORMAT" desc="The format for the accessible name of a tabbed browser window">
+        <ph name="PAGE_TITLE">$1<ex>Google</ex></ph> - Google Chrome
+      </message>
+      <message name="IDS_ACCESSIBLE_BETA_BROWSER_WINDOW_TITLE_FORMAT" desc="The format for the accessible name of a tabbed browser window for the beta channel version of the browser">
+        <ph name="PAGE_TITLE">$1<ex>Google</ex></ph> - Google Chrome Beta
+      </message>
+      <message name="IDS_ACCESSIBLE_DEV_BROWSER_WINDOW_TITLE_FORMAT" desc="The format for the accessible name of a tabbed browser window for the developer (dev) channel version of the browser">
+        <ph name="PAGE_TITLE">$1<ex>Google</ex></ph> - Google Chrome Dev
+      </message>
+      <message name="IDS_ACCESSIBLE_CANARY_BROWSER_WINDOW_TITLE_FORMAT" desc="The format for the accessible name of a tabbed browser window for the canary (nightly build) channel version of the browser">
+        <ph name="PAGE_TITLE">$1<ex>Google</ex></ph> - Google Chrome Canary
+      </message>
       <if expr="not chromeos">
         <message name="IDS_GET_HELP_USING_CHROME" desc="Text of the button which takes the user to the Chrome help page.">
           Get help with using Chrome
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index a46fe308..83bfba7e 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -132,7 +132,6 @@
   # No inclusion of WebKit from the browser, other than strictly enum/POD,
   # header-only types, and some selected common code.
   "-third_party/WebKit",
-  "+third_party/WebKit/common/feature_policy/feature_policy_feature.h",
   "+third_party/WebKit/public/platform/WebCache.h",
   "+third_party/WebKit/public/platform/WebDisplayMode.h",
   "+third_party/WebKit/public/platform/WebLoadingBehaviorFlag.h",
diff --git a/chrome/browser/accessibility/accessibility_permission_context.cc b/chrome/browser/accessibility/accessibility_permission_context.cc
index 58419b3..11b5193 100644
--- a/chrome/browser/accessibility/accessibility_permission_context.cc
+++ b/chrome/browser/accessibility/accessibility_permission_context.cc
@@ -5,10 +5,10 @@
 #include "chrome/browser/accessibility/accessibility_permission_context.h"
 
 AccessibilityPermissionContext::AccessibilityPermissionContext(Profile* profile)
-    : PermissionContextBase(profile,
-                            CONTENT_SETTINGS_TYPE_ACCESSIBILITY_EVENTS,
-                            blink::FeaturePolicyFeature::kAccessibilityEvents) {
-}
+    : PermissionContextBase(
+          profile,
+          CONTENT_SETTINGS_TYPE_ACCESSIBILITY_EVENTS,
+          blink::mojom::FeaturePolicyFeature::kAccessibilityEvents) {}
 
 AccessibilityPermissionContext::~AccessibilityPermissionContext() = default;
 
diff --git a/chrome/browser/apps/guest_view/extension_view/extension_view_browsertest.cc b/chrome/browser/apps/guest_view/extension_view/extension_view_browsertest.cc
index a7059a3..e7ad859 100644
--- a/chrome/browser/apps/guest_view/extension_view/extension_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/extension_view/extension_view_browsertest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "base/strings/stringprintf.h"
-#include "base/test/scoped_feature_list.h"
 #include "chrome/browser/apps/app_browsertest_util.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/guest_view/browser/guest_view_manager.h"
@@ -22,10 +21,11 @@
 using guest_view::TestGuestViewManager;
 using guest_view::TestGuestViewManagerFactory;
 
-class ExtensionViewTest : public extensions::PlatformAppBrowserTest,
-                          public testing::WithParamInterface<bool> {
+class ExtensionViewTest : public extensions::PlatformAppBrowserTest {
  public:
   ExtensionViewTest() {
+    CHECK(
+        base::FeatureList::IsEnabled(::features::kGuestViewCrossProcessFrames));
     GuestViewManager::set_factory_for_testing(&factory_);
   }
 
@@ -74,27 +74,11 @@
   }
 
  private:
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line);
-
-    bool use_cross_process_frames_for_guests = GetParam();
-    if (use_cross_process_frames_for_guests) {
-      scoped_feature_list_.InitAndEnableFeature(
-          features::kGuestViewCrossProcessFrames);
-    } else {
-      scoped_feature_list_.InitAndDisableFeature(
-          features::kGuestViewCrossProcessFrames);
-    }
-  }
-
   TestGuestViewManagerFactory factory_;
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
-INSTANTIATE_TEST_CASE_P(ExtensionViewTests, ExtensionViewTest, testing::Bool());
-
 // Tests that <extensionview> can be created and added to the DOM.
-IN_PROC_BROWSER_TEST_P(ExtensionViewTest,
+IN_PROC_BROWSER_TEST_F(ExtensionViewTest,
                        TestExtensionViewCreationShouldSucceed) {
   TestHelper("testExtensionViewCreationShouldSucceed",
              "extension_view/creation", "", "");
@@ -102,7 +86,7 @@
 
 // Tests that verify that <extensionview> does not change extension ID if
 // someone tries to change it in JavaScript.
-IN_PROC_BROWSER_TEST_P(ExtensionViewTest, ShimExtensionAttribute) {
+IN_PROC_BROWSER_TEST_F(ExtensionViewTest, ShimExtensionAttribute) {
   const extensions::Extension* skeleton_app =
       InstallPlatformApp("extension_view/skeleton");
   TestHelper("testExtensionAttribute", "extension_view/extension_attribute",
@@ -111,7 +95,7 @@
 
 // Tests that verify that <extensionview> does not change src if
 // someone tries to change it in JavaScript.
-IN_PROC_BROWSER_TEST_P(ExtensionViewTest, ShimSrcAttribute) {
+IN_PROC_BROWSER_TEST_F(ExtensionViewTest, ShimSrcAttribute) {
   const extensions::Extension* skeleton_app =
       InstallPlatformApp("extension_view/skeleton");
   TestHelper("testSrcAttribute", "extension_view/src_attribute",
@@ -130,45 +114,39 @@
   }
 };
 
-INSTANTIATE_TEST_CASE_P(ExtensionViewTests,
-                        ExtensionViewLoadApiTest,
-                        testing::Bool());
-
-IN_PROC_BROWSER_TEST_P(ExtensionViewLoadApiTest, LoadAPIFunction) {
+IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPIFunction) {
   TestLoadApiHelper("testLoadAPIFunction");
 }
 
-IN_PROC_BROWSER_TEST_P(ExtensionViewLoadApiTest, LoadAPISameIdAndSrc) {
+IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPISameIdAndSrc) {
   TestLoadApiHelper("testLoadAPISameIdAndSrc");
 }
 
-IN_PROC_BROWSER_TEST_P(ExtensionViewLoadApiTest, LoadAPISameIdDifferentSrc) {
+IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPISameIdDifferentSrc) {
   TestLoadApiHelper("testLoadAPISameIdDifferentSrc");
 }
 
-// Flaky, see crbug.com/810007
-IN_PROC_BROWSER_TEST_P(ExtensionViewLoadApiTest,
-                       DISABLED_LoadAPILoadOtherExtension) {
+IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPILoadOtherExtension) {
   TestLoadApiHelper("testLoadAPILoadOtherExtension");
 }
 
-IN_PROC_BROWSER_TEST_P(ExtensionViewLoadApiTest, LoadAPIInvalidExtension) {
+IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPIInvalidExtension) {
   TestLoadApiHelper("testLoadAPIInvalidExtension");
 }
 
-IN_PROC_BROWSER_TEST_P(ExtensionViewLoadApiTest, LoadAPIAfterInvalidCall) {
+IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPIAfterInvalidCall) {
   TestLoadApiHelper("testLoadAPIAfterInvalidCall");
 }
 
-IN_PROC_BROWSER_TEST_P(ExtensionViewLoadApiTest, LoadAPINullExtension) {
+IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, LoadAPINullExtension) {
   TestLoadApiHelper("testLoadAPINullExtension");
 }
 
-IN_PROC_BROWSER_TEST_P(ExtensionViewLoadApiTest, QueuedLoadAPIFunction) {
+IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest, QueuedLoadAPIFunction) {
   TestLoadApiHelper("testQueuedLoadAPIFunction");
 }
 
-IN_PROC_BROWSER_TEST_P(ExtensionViewLoadApiTest,
+IN_PROC_BROWSER_TEST_F(ExtensionViewLoadApiTest,
                        QueuedLoadAPILoadOtherExtension) {
   TestLoadApiHelper("testQueuedLoadAPILoadOtherExtension");
 }
diff --git a/chrome/browser/background_sync/background_sync_permission_context.cc b/chrome/browser/background_sync/background_sync_permission_context.cc
index 8946017ce..180f006 100644
--- a/chrome/browser/background_sync/background_sync_permission_context.cc
+++ b/chrome/browser/background_sync/background_sync_permission_context.cc
@@ -11,7 +11,7 @@
     Profile* profile)
     : PermissionContextBase(profile,
                             CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC,
-                            blink::FeaturePolicyFeature::kNotFound) {}
+                            blink::mojom::FeaturePolicyFeature::kNotFound) {}
 
 void BackgroundSyncPermissionContext::DecidePermission(
     content::WebContents* web_contents,
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 3402af9e..b3c5edc 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -19,6 +19,7 @@
 #include "base/command_line.h"
 #include "base/debug/crash_logging.h"
 #include "base/debug/debugger.h"
+#include "base/debug/leak_annotations.h"
 #include "base/deferred_sequenced_task_runner.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
@@ -922,11 +923,13 @@
 }
 
 void ChromeBrowserMainParts::SetupFieldTrials() {
-  // Initialize FieldTrialList to support FieldTrials that use one-time
-  // randomization.
-  DCHECK(!field_trial_list_);
-  field_trial_list_ = std::make_unique<base::FieldTrialList>(
+  // Initialize FieldTrialList to support FieldTrials. This is intentionally
+  // leaked since it needs to live for the duration of the browser process and
+  // there's no benefit in cleaning it up at exit.
+  base::FieldTrialList* leaked_field_trial_list = new base::FieldTrialList(
       browser_process_->GetMetricsServicesManager()->CreateEntropyProvider());
+  ANNOTATE_LEAKING_OBJECT_PTR(leaked_field_trial_list);
+  ignore_result(leaked_field_trial_list);
 
   auto feature_list = std::make_unique<base::FeatureList>();
 
@@ -1212,9 +1215,10 @@
 
   SetupOriginTrialsCommandLine(browser_process_->local_state());
 
-  // Now that the command line has been mutated based on about:flags, we can
-  // initialize field trials. The field trials are needed by IOThread's
-  // initialization which happens in BrowserProcess:PreCreateThreads. Metrics
+  // Initialize field trials now that the Local State file has been read. This
+  // is done as soon as possible (here), so that code using the base::Feature
+  // API can be used from this point on. Field trials are also needed by
+  // IOThread's initialization in BrowserProcess:PreCreateThreads. Metrics
   // initialization is handled in PreMainMessageLoopRunImpl since it posts
   // tasks.
   SetupFieldTrials();
diff --git a/chrome/browser/chrome_browser_main.h b/chrome/browser/chrome_browser_main.h
index 1d39768..5c19e51 100644
--- a/chrome/browser/chrome_browser_main.h
+++ b/chrome/browser/chrome_browser_main.h
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "base/metrics/field_trial.h"
 #include "base/profiler/stack_sampling_profiler.h"
 #include "build/build_config.h"
 #include "chrome/browser/chrome_browser_field_trials.h"
@@ -157,10 +156,6 @@
   // it is destroyed last.
   std::unique_ptr<ShutdownWatcherHelper> shutdown_watcher_;
 
-  // Statistical testing infrastructure for the entire browser. nullptr until
-  // |SetupFieldTrials()| is called.
-  std::unique_ptr<base::FieldTrialList> field_trial_list_;
-
   ChromeBrowserFieldTrials browser_field_trials_;
 
 #if !defined(OS_ANDROID)
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
index 9d9317fd..8891aa1 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc
+++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -15,15 +15,12 @@
 #include "ash/public/cpp/ash_pref_names.h"
 #include "ash/public/interfaces/constants.mojom.h"
 #include "ash/root_window_controller.h"
-#include "ash/shelf/shelf.h"
-#include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shell.h"
 #include "ash/sticky_keys/sticky_keys_controller.h"
 #include "ash/system/tray/system_tray_notifier.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
-#include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/singleton.h"
 #include "base/metrics/histogram_macros.h"
@@ -31,7 +28,6 @@
 #include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
-#include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/accessibility/accessibility_extension_api.h"
 #include "chrome/browser/browser_process.h"
@@ -73,9 +69,7 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/service_manager_connection.h"
-#include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_registry.h"
-#include "extensions/browser/extension_system.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_messages.h"
 #include "extensions/common/extension_resource.h"
@@ -85,7 +79,6 @@
 #include "media/base/media_switches.h"
 #include "services/service_manager/public/cpp/connector.h"
 #include "ui/base/ime/chromeos/extension_ime_util.h"
-#include "ui/base/ime/chromeos/input_method_manager.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/keyboard/keyboard_controller.h"
 #include "ui/views/widget/widget.h"
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.h b/chrome/browser/chromeos/accessibility/accessibility_manager.h
index d9edf32..4c61e20 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_manager.h
+++ b/chrome/browser/chromeos/accessibility/accessibility_manager.h
@@ -82,8 +82,8 @@
   // The sound is always played.
   ALWAYS = 0,
 
-  // The sound is played only if spoken feedback is enabled, or
-  // --ash-enable-system-sounds flag is used.
+  // The sound is played only if spoken feedback is enabled, and
+  // --ash-disable-system-sounds is not set.
   ONLY_IF_SPOKEN_FEEDBACK_ENABLED,
 };
 
diff --git a/chrome/browser/chromeos/accessibility/magnification_manager.cc b/chrome/browser/chromeos/accessibility/magnification_manager.cc
index a0044af..9f98aff 100644
--- a/chrome/browser/chromeos/accessibility/magnification_manager.cc
+++ b/chrome/browser/chromeos/accessibility/magnification_manager.cc
@@ -49,6 +49,7 @@
             ash::prefs::kAccessibilityScreenMagnifierScale),
         enabled_(false),
         keep_focus_centered_(false),
+        scale_(0.0),
         observing_focus_change_in_page_(false) {
     registrar_.Add(this, chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
                    content::NotificationService::AllSources());
@@ -109,12 +110,19 @@
       pref_change_registrar_->Init(profile->GetPrefs());
       pref_change_registrar_->Add(
           ash::prefs::kAccessibilityScreenMagnifierEnabled,
-          base::Bind(&MagnificationManagerImpl::UpdateMagnifierFromPrefs,
-                     base::Unretained(this)));
+          base::BindRepeating(
+              &MagnificationManagerImpl::UpdateMagnifierFromPrefs,
+              base::Unretained(this)));
       pref_change_registrar_->Add(
           ash::prefs::kAccessibilityScreenMagnifierCenterFocus,
-          base::Bind(&MagnificationManagerImpl::UpdateMagnifierFromPrefs,
-                     base::Unretained(this)));
+          base::BindRepeating(
+              &MagnificationManagerImpl::UpdateMagnifierFromPrefs,
+              base::Unretained(this)));
+      pref_change_registrar_->Add(
+          ash::prefs::kAccessibilityScreenMagnifierScale,
+          base::BindRepeating(
+              &MagnificationManagerImpl::UpdateMagnifierFromPrefs,
+              base::Unretained(this)));
     }
 
     magnifier_enabled_pref_handler_.HandleProfileChanged(profile_, profile);
@@ -139,7 +147,7 @@
     MonitorFocusInPageChange();
   }
 
-  virtual void SetMagniferKeepFocusCenteredInternal(bool keep_focus_centered) {
+  virtual void SetMagnifierKeepFocusCenteredInternal(bool keep_focus_centered) {
     if (keep_focus_centered_ == keep_focus_centered)
       return;
 
@@ -149,6 +157,16 @@
         keep_focus_centered_);
   }
 
+  virtual void SetMagnifierScaleInternal(double scale) {
+    if (scale_ == scale)
+      return;
+
+    scale_ = scale;
+
+    ash::Shell::Get()->magnification_controller()->SetScale(
+        scale_, false /* animate */);
+  }
+
   void UpdateMagnifierFromPrefs() {
     if (!profile_)
       return;
@@ -158,12 +176,16 @@
         prefs->GetBoolean(ash::prefs::kAccessibilityScreenMagnifierEnabled);
     const bool keep_focus_centered =
         prefs->GetBoolean(ash::prefs::kAccessibilityScreenMagnifierCenterFocus);
+    const double scale =
+        prefs->GetDouble(ash::prefs::kAccessibilityScreenMagnifierScale);
 
     if (!enabled) {
       SetMagnifierEnabledInternal(enabled);
-      SetMagniferKeepFocusCenteredInternal(keep_focus_centered);
+      SetMagnifierKeepFocusCenteredInternal(keep_focus_centered);
+      SetMagnifierScaleInternal(scale);
     } else {
-      SetMagniferKeepFocusCenteredInternal(keep_focus_centered);
+      SetMagnifierScaleInternal(scale);
+      SetMagnifierKeepFocusCenteredInternal(keep_focus_centered);
       SetMagnifierEnabledInternal(enabled);
     }
 
@@ -236,6 +258,7 @@
 
   bool enabled_;
   bool keep_focus_centered_;
+  double scale_;
   bool observing_focus_change_in_page_;
 
   content::NotificationRegistrar registrar_;
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_creation_browsertest.cc b/chrome/browser/chromeos/login/supervised/supervised_user_creation_browsertest.cc
index 5489720..f86ba11 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_creation_browsertest.cc
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_creation_browsertest.cc
@@ -29,7 +29,6 @@
 #include "chrome/common/chrome_features.h"
 #include "chromeos/cryptohome/mock_async_method_caller.h"
 #include "chromeos/cryptohome/mock_homedir_methods.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_change.h"
 #include "components/sync/model/sync_error_factory_mock.h"
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_password_browsertest.cc b/chrome/browser/chromeos/login/supervised/supervised_user_password_browsertest.cc
index ec69eca..9ec9519 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_password_browsertest.cc
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_password_browsertest.cc
@@ -24,7 +24,6 @@
 #include "chrome/common/chrome_features.h"
 #include "chromeos/cryptohome/mock_async_method_caller.h"
 #include "chromeos/cryptohome/mock_homedir_methods.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_change.h"
 #include "components/sync/model/sync_error_factory_mock.h"
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_test_base.cc b/chrome/browser/chromeos/login/supervised/supervised_user_test_base.cc
index a954d4d..db24fb5 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_test_base.cc
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_test_base.cc
@@ -44,7 +44,6 @@
 #include "chromeos/login/auth/user_context.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_change.h"
 #include "components/sync/model/sync_error_factory_mock.h"
@@ -157,8 +156,7 @@
   specifics.mutable_managed_user()->CopyFrom(proto);
 
   syncer::SyncData change_data = syncer::SyncData::CreateRemoteData(
-      ++next_sync_data_id_, specifics, base::Time(), syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create());
+      ++next_sync_data_id_, specifics, base::Time());
   syncer::SyncChange change(FROM_HERE,
                             update ? syncer::SyncChange::ACTION_UPDATE
                                    : syncer::SyncChange::ACTION_ADD,
@@ -203,8 +201,7 @@
   specifics.mutable_managed_user_shared_setting()->CopyFrom(proto);
 
   syncer::SyncData change_data = syncer::SyncData::CreateRemoteData(
-      ++next_sync_data_id_, specifics, base::Time(), syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create());
+      ++next_sync_data_id_, specifics, base::Time());
   syncer::SyncChange change(FROM_HERE,
                             update ? syncer::SyncChange::ACTION_UPDATE
                                    : syncer::SyncChange::ACTION_ADD,
diff --git a/chrome/browser/chromeos/login/ui/gaia_dialog_delegate.h b/chrome/browser/chromeos/login/ui/gaia_dialog_delegate.h
index 02cc150..601200e 100644
--- a/chrome/browser/chromeos/login/ui/gaia_dialog_delegate.h
+++ b/chrome/browser/chromeos/login/ui/gaia_dialog_delegate.h
@@ -27,12 +27,12 @@
 class OobeUI;
 
 // This class manages the behavior of the gaia signin dialog.
-// And its lifecyle is managed by the widget created in Show().
+// And its lifecycle is managed by the widget created in Show().
 //   WebDialogView<----delegate_----GaiaDialogDelegate
 //         |
 //         |
 //         V
-//   clientView---->Widget's view hierachy
+//   clientView---->Widget's view hierarchy
 class GaiaDialogDelegate : public ui::WebDialogDelegate {
  public:
   explicit GaiaDialogDelegate(base::WeakPtr<LoginDisplayHostViews> controller);
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_common.cc b/chrome/browser/chromeos/login/ui/login_display_host_common.cc
index fc06356..e5be17a 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_common.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_common.cc
@@ -30,6 +30,16 @@
 // network requests are made while the system is idle waiting for user input.
 constexpr int64_t kPolicyServiceInitializationDelayMilliseconds = 100;
 
+void ScheduleCompletionCallbacks(std::vector<base::OnceClosure>&& callbacks) {
+  for (auto& callback : callbacks) {
+    if (callback.is_null())
+      continue;
+
+    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                  std::move(callback));
+  }
+}
+
 }  // namespace
 
 LoginDisplayHostCommon::LoginDisplayHostCommon() : weak_factory_(this) {
@@ -56,16 +66,29 @@
                  content::NotificationService::AllSources());
 }
 
-LoginDisplayHostCommon::~LoginDisplayHostCommon() {}
+LoginDisplayHostCommon::~LoginDisplayHostCommon() {
+  ScheduleCompletionCallbacks(std::move(completion_callbacks_));
+}
 
 void LoginDisplayHostCommon::BeforeSessionStart() {
   session_starting_ = true;
 }
 
+void LoginDisplayHostCommon::Finalize(base::OnceClosure completion_callback) {
+  completion_callbacks_.push_back(std::move(completion_callback));
+  OnFinalize();
+}
+
 AppLaunchController* LoginDisplayHostCommon::GetAppLaunchController() {
   return app_launch_controller_.get();
 }
 
+void LoginDisplayHostCommon::StartUserAdding(
+    base::OnceClosure completion_callback) {
+  completion_callbacks_.push_back(std::move(completion_callback));
+  OnStartUserAdding();
+}
+
 void LoginDisplayHostCommon::StartSignInScreen(
     const LoginScreenContext& context) {
   PrewarmAuthentication();
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_common.h b/chrome/browser/chromeos/login/ui/login_display_host_common.h
index 57dd92a..ba25697 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_common.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_common.h
@@ -35,7 +35,9 @@
 
   // LoginDisplayHost:
   void BeforeSessionStart() final;
+  void Finalize(base::OnceClosure completion_callback) final;
   AppLaunchController* GetAppLaunchController() final;
+  void StartUserAdding(base::OnceClosure completion_callback) final;
   void StartSignInScreen(const LoginScreenContext& context) final;
   void PrewarmAuthentication() final;
   void StartAppLaunch(const std::string& app_id,
@@ -62,6 +64,8 @@
   virtual void OnStartAppLaunch() = 0;
   virtual void OnStartArcKiosk() = 0;
   virtual void OnBrowserCreated() = 0;
+  virtual void OnStartUserAdding() = 0;
+  virtual void OnFinalize() = 0;
 
   // Deletes |auth_prewarmer_|.
   void OnAuthPrewarmDone();
@@ -99,6 +103,9 @@
   // during a login session and restored afterwards.
   std::unique_ptr<wm::ScopedDragDropDisabler> scoped_drag_drop_disabler_;
 
+  // Called after host deletion.
+  std::vector<base::OnceClosure> completion_callbacks_;
+
   base::WeakPtrFactory<LoginDisplayHostCommon> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(LoginDisplayHostCommon);
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_views.cc b/chrome/browser/chromeos/login/ui/login_display_host_views.cc
index deeaa4d..4c1935e 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_views.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_views.cc
@@ -20,24 +20,10 @@
 
 namespace chromeos {
 
-namespace {
-
-void ScheduleCompletionCallbacks(std::vector<base::OnceClosure>&& callbacks) {
-  for (auto& callback : callbacks) {
-    if (callback.is_null())
-      continue;
-    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-                                                  std::move(callback));
-  }
-}
-
-}  // namespace
-
 LoginDisplayHostViews::LoginDisplayHostViews() : weak_factory_(this) {}
 
 LoginDisplayHostViews::~LoginDisplayHostViews() {
   LoginScreenClient::Get()->SetDelegate(nullptr);
-  ScheduleCompletionCallbacks(std::move(completion_callbacks_));
 }
 
 LoginDisplay* LoginDisplayHostViews::CreateLoginDisplay(
@@ -61,11 +47,10 @@
   return nullptr;
 }
 
-void LoginDisplayHostViews::Finalize(base::OnceClosure completion_callback) {
+void LoginDisplayHostViews::OnFinalize() {
   if (dialog_)
     dialog_->Close();
 
-  completion_callbacks_.push_back(std::move(completion_callback));
   base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
 }
 
@@ -86,9 +71,8 @@
   return nullptr;
 }
 
-void LoginDisplayHostViews::StartUserAdding(
-    base::OnceClosure completion_callback) {
-  completion_callbacks_.push_back(std::move(completion_callback));
+void LoginDisplayHostViews::OnStartUserAdding() {
+  NOTIMPLEMENTED();
 }
 
 void LoginDisplayHostViews::CancelUserAdding() {
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_views.h b/chrome/browser/chromeos/login/ui/login_display_host_views.h
index d29eb87..89ee683 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_views.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_views.h
@@ -34,11 +34,11 @@
   gfx::NativeWindow GetNativeWindow() const override;
   OobeUI* GetOobeUI() const override;
   WebUILoginView* GetWebUILoginView() const override;
-  void Finalize(base::OnceClosure completion_callback) override;
+  void OnFinalize() override;
   void SetStatusAreaVisible(bool visible) override;
   void StartWizard(OobeScreen first_screen) override;
   WizardController* GetWizardController() override;
-  void StartUserAdding(base::OnceClosure completion_callback) override;
+  void OnStartUserAdding() override;
   void CancelUserAdding() override;
   void OnStartSignInScreen(const LoginScreenContext& context) override;
   void OnPreferencesChanged() override;
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
index 46f99d8..6d80317 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
@@ -298,16 +298,6 @@
       keyboard::KEYBOARD_OVERSCROLL_OVERRIDE_NONE);
 }
 
-void ScheduleCompletionCallbacks(std::vector<base::OnceClosure>&& callbacks) {
-  for (auto& callback : callbacks) {
-    if (callback.is_null())
-      continue;
-
-    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-                                                  std::move(callback));
-  }
-}
-
 class CloseAfterCommit : public ui::CompositorObserver,
                          public views::WidgetObserver {
  public:
@@ -516,8 +506,6 @@
   views::FocusManager::set_arrow_key_traversal_enabled(false);
   ResetLoginWindowAndView();
 
-  ScheduleCompletionCallbacks(std::move(completion_callbacks_));
-
   // TODO(tengs): This should be refactored. See crbug.com/314934.
   if (user_manager::UserManager::Get()->IsCurrentUserNew()) {
     // DriveOptInController will delete itself when finished.
@@ -543,11 +531,9 @@
   return login_view_;
 }
 
-void LoginDisplayHostWebUI::Finalize(base::OnceClosure completion_callback) {
+void LoginDisplayHostWebUI::OnFinalize() {
   DVLOG(1) << "Finalizing LoginDisplayHost. User session starting";
 
-  completion_callbacks_.push_back(std::move(completion_callback));
-
   switch (finalize_animation_type_) {
     case ANIMATION_NONE:
       ShutdownDisplayHost();
@@ -619,12 +605,10 @@
   return wizard_controller_.get();
 }
 
-void LoginDisplayHostWebUI::StartUserAdding(
-    base::OnceClosure completion_callback) {
+void LoginDisplayHostWebUI::OnStartUserAdding() {
   DisableKeyboardOverscroll();
 
   restore_path_ = RESTORE_ADD_USER_INTO_SESSION;
-  completion_callbacks_.push_back(std::move(completion_callback));
   // Animation is not supported in Mash
   if (!ash_util::IsRunningInMash())
     finalize_animation_type_ = ANIMATION_ADD_USER;
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.h b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
index 5b529687..afb0310 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_webui.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
@@ -58,11 +58,11 @@
   gfx::NativeWindow GetNativeWindow() const override;
   OobeUI* GetOobeUI() const override;
   WebUILoginView* GetWebUILoginView() const override;
-  void Finalize(base::OnceClosure completion_callback) override;
+  void OnFinalize() override;
   void SetStatusAreaVisible(bool visible) override;
   void StartWizard(OobeScreen first_screen) override;
   WizardController* GetWizardController() override;
-  void StartUserAdding(base::OnceClosure completion_callback) override;
+  void OnStartUserAdding() override;
   void CancelUserAdding() override;
   void OnStartSignInScreen(const LoginScreenContext& context) override;
   void OnPreferencesChanged() override;
@@ -230,9 +230,6 @@
   // Stored parameters for StartWizard, required to restore in case of crash.
   OobeScreen first_screen_;
 
-  // Called after host deletion.
-  std::vector<base::OnceClosure> completion_callbacks_;
-
   // A focus ring controller to draw focus ring around view for keyboard
   // driven oobe.
   std::unique_ptr<ash::FocusRingController> focus_ring_controller_;
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
index 2ab98b71..636fcb6 100644
--- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
+++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.cc
@@ -516,6 +516,10 @@
   return false;
 }
 
+bool FakeChromeUserManager::IsCurrentUserCryptohomeDataEphemeral() const {
+  return current_user_ephemeral_;
+}
+
 bool FakeChromeUserManager::CanCurrentUserLock() const {
   return false;
 }
@@ -568,7 +572,7 @@
 
 bool FakeChromeUserManager::IsUserNonCryptohomeDataEphemeral(
     const AccountId& account_id) const {
-  return false;
+  return current_user_ephemeral_;
 }
 
 bool FakeChromeUserManager::AreSupervisedUsersAllowed() const {
diff --git a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h
index f198db0..1d892c1 100644
--- a/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h
+++ b/chrome/browser/chromeos/login/users/fake_chrome_user_manager.h
@@ -92,6 +92,7 @@
                              const UserAccountData& account_data) override;
   bool IsCurrentUserOwner() const override;
   bool IsCurrentUserNew() const override;
+  bool IsCurrentUserCryptohomeDataEphemeral() const override;
   bool IsCurrentUserNonCryptohomeDataEphemeral() const override;
   bool CanCurrentUserLock() const override;
   bool IsUserLoggedIn() const override;
@@ -184,6 +185,9 @@
   }
 
   void set_current_user_new(bool new_user) { current_user_new_ = new_user; }
+  void set_current_user_ephemeral(bool user_ephemeral) {
+    current_user_ephemeral_ = user_ephemeral;
+  }
 
   void set_is_enterprise_managed(bool is_enterprise_managed) {
     is_enterprise_managed_ = is_enterprise_managed;
@@ -200,6 +204,7 @@
   AccountId owner_account_id_ = EmptyAccountId();
   bool fake_ephemeral_users_enabled_ = false;
   bool current_user_new_ = false;
+  bool current_user_ephemeral_ = false;
 
   MultiProfileUserController* multi_profile_user_controller_ = nullptr;
 
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
index f8247d964..86c25a7 100644
--- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
+++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
@@ -376,8 +376,8 @@
     client_->Register(
         em::DeviceRegisterRequest::DEVICE,
         EnrollmentModeToRegistrationFlavor(enrollment_config_.mode),
-        license_type_, auth_token_, client_id_, requisition_,
-        current_state_key_);
+        em::DeviceRegisterRequest::LIFETIME_INDEFINITE, license_type_,
+        auth_token_, client_id_, requisition_, current_state_key_);
   }
 }
 
@@ -395,15 +395,16 @@
 void EnrollmentHandlerChromeOS::HandleRegistrationCertificateResult(
     chromeos::attestation::AttestationStatus status,
     const std::string& pem_certificate_chain) {
-  if (status == chromeos::attestation::ATTESTATION_SUCCESS)
+  if (status == chromeos::attestation::ATTESTATION_SUCCESS) {
     client_->RegisterWithCertificate(
         em::DeviceRegisterRequest::DEVICE,
         EnrollmentModeToRegistrationFlavor(enrollment_config_.mode),
-        license_type_, pem_certificate_chain, client_id_, requisition_,
-        current_state_key_);
-  else
+        em::DeviceRegisterRequest::LIFETIME_INDEFINITE, license_type_,
+        pem_certificate_chain, client_id_, requisition_, current_state_key_);
+  } else {
     ReportResult(EnrollmentStatus::ForStatus(
         EnrollmentStatus::REGISTRATION_CERT_FETCH_FAILED));
+  }
 }
 
 void EnrollmentHandlerChromeOS::HandlePolicyValidationResult(
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
index 81dac49..e3b2f41 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
@@ -484,10 +484,14 @@
   if (error.state() == GoogleServiceAuthError::NONE) {
     // Start client registration. Either OnRegistrationStateChanged() or
     // OnClientError() will be called back.
+    const auto lifetime =
+        user_manager::UserManager::Get()->IsCurrentUserCryptohomeDataEphemeral()
+            ? em::DeviceRegisterRequest::LIFETIME_EPHEMERAL_USER
+            : em::DeviceRegisterRequest::LIFETIME_INDEFINITE;
     client()->Register(em::DeviceRegisterRequest::USER,
                        em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
-                       em::LicenseType::UNDEFINED, policy_token, std::string(),
-                       std::string(), std::string());
+                       lifetime, em::LicenseType::UNDEFINED, policy_token,
+                       std::string(), std::string(), std::string());
   } else {
     UMA_HISTOGRAM_ENUMERATION(kUMAInitialFetchOAuth2Error,
                               error.state(),
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
index 86d4f69f..26e5e29 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
@@ -64,7 +64,9 @@
 
 using testing::AnyNumber;
 using testing::AtLeast;
+using testing::AtMost;
 using testing::Mock;
+using testing::SaveArg;
 using testing::_;
 
 namespace {
@@ -739,4 +741,51 @@
   EXPECT_TRUE(manager_->policies().Equals(expected_bundle_));
 }
 
+TEST_F(UserCloudPolicyManagerChromeOSTest, TestLifetimeReportingRegular) {
+  ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(
+      base::TimeDelta::FromSeconds(1000), PolicyEnforcement::kPolicyRequired));
+
+  store_->NotifyStoreLoaded();
+
+  em::DeviceManagementRequest register_request;
+
+  EXPECT_CALL(device_management_service_,
+              StartJob(dm_protocol::kValueRequestRegister, _, _, _, _, _))
+      .Times(AtMost(1))
+      .WillOnce(SaveArg<5>(&register_request));
+
+  MockDeviceManagementJob* register_job = IssueOAuthToken(false);
+  ASSERT_TRUE(register_job);
+  Mock::VerifyAndClearExpectations(&device_management_service_);
+  ASSERT_TRUE(register_request.has_register_request());
+  ASSERT_TRUE(register_request.register_request().has_lifetime());
+  ASSERT_EQ(em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
+            register_request.register_request().lifetime());
+}
+
+TEST_F(UserCloudPolicyManagerChromeOSTest, TestLifetimeReportingEphemeralUser) {
+  user_manager_->set_current_user_ephemeral(true);
+
+  ASSERT_NO_FATAL_FAILURE(MakeManagerWithEmptyStore(
+      base::TimeDelta::FromSeconds(1000), PolicyEnforcement::kPolicyRequired));
+
+  store_->NotifyStoreLoaded();
+
+  em::DeviceManagementRequest register_request;
+
+  EXPECT_CALL(device_management_service_,
+              StartJob(dm_protocol::kValueRequestRegister, _, _, _, _, _))
+      .Times(AtMost(1))
+      .WillOnce(SaveArg<5>(&register_request));
+
+  MockDeviceManagementJob* register_job = IssueOAuthToken(false);
+  ASSERT_TRUE(register_job);
+
+  Mock::VerifyAndClearExpectations(&device_management_service_);
+  ASSERT_TRUE(register_request.has_register_request());
+  ASSERT_TRUE(register_request.register_request().has_lifetime());
+  ASSERT_EQ(em::DeviceRegisterRequest::LIFETIME_EPHEMERAL_USER,
+            register_request.register_request().lifetime());
+}
+
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/user_policy_test_helper.cc b/chrome/browser/chromeos/policy/user_policy_test_helper.cc
index 32ff0cf0..630c3de 100644
--- a/chrome/browser/chromeos/policy/user_policy_test_helper.cc
+++ b/chrome/browser/chromeos/policy/user_policy_test_helper.cc
@@ -104,6 +104,7 @@
   policy_manager->core()->client()->Register(
       registration_type,
       enterprise_management::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
+      enterprise_management::DeviceRegisterRequest::LIFETIME_INDEFINITE,
       enterprise_management::LicenseType::UNDEFINED, "bogus", std::string(),
       std::string(), std::string());
 
diff --git a/chrome/browser/chromeos/preferences_unittest.cc b/chrome/browser/chromeos/preferences_unittest.cc
index 5ea6717..5139b60 100644
--- a/chrome/browser/chromeos/preferences_unittest.cc
+++ b/chrome/browser/chromeos/preferences_unittest.cc
@@ -21,8 +21,6 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/prefs/pref_member.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_change.h"
 #include "components/sync/model/sync_data.h"
@@ -62,12 +60,7 @@
   sync_pb::PreferenceSpecifics* pref = specifics.mutable_preference();
   pref->set_name(name);
   pref->set_value(serialized);
-  return syncer::SyncData::CreateRemoteData(
-      1,
-      specifics,
-      base::Time(),
-      syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create());
+  return syncer::SyncData::CreateRemoteData(1, specifics, base::Time());
 }
 
 }  // anonymous namespace
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc
index 4380d3f5..13f15a0 100644
--- a/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc
+++ b/chrome/browser/chromeos/printing/cups_print_job_manager_impl.cc
@@ -12,6 +12,7 @@
 #include <vector>
 
 #include "base/bind.h"
+#include "base/compiler_specific.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/sequenced_task_runner.h"
 #include "base/stl_util.h"
@@ -223,7 +224,7 @@
     case ::printing::CupsJob::ABORTED:
     case ::printing::CupsJob::CANCELED:
       print_job->set_error_code(ErrorCodeFromReasons(printer_status));
-    // fall through
+      FALLTHROUGH;
     default:
       print_job->set_state(ConvertState(job.state));
       break;
diff --git a/chrome/browser/clipboard/clipboard_read_permission_context.cc b/chrome/browser/clipboard/clipboard_read_permission_context.cc
index 7034c14..a0efc75 100644
--- a/chrome/browser/clipboard/clipboard_read_permission_context.cc
+++ b/chrome/browser/clipboard/clipboard_read_permission_context.cc
@@ -8,12 +8,12 @@
 #include "chrome/browser/permissions/permission_request_id.h"
 #include "chrome/common/chrome_features.h"
 #include "components/content_settings/core/common/content_settings_types.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 
 ClipboardReadPermissionContext::ClipboardReadPermissionContext(Profile* profile)
     : PermissionContextBase(profile,
                             CONTENT_SETTINGS_TYPE_CLIPBOARD_READ,
-                            blink::FeaturePolicyFeature::kNotFound) {}
+                            blink::mojom::FeaturePolicyFeature::kNotFound) {}
 
 ClipboardReadPermissionContext::~ClipboardReadPermissionContext() {}
 
diff --git a/chrome/browser/clipboard/clipboard_write_permission_context.cc b/chrome/browser/clipboard/clipboard_write_permission_context.cc
index 9285b59..23f1915 100644
--- a/chrome/browser/clipboard/clipboard_write_permission_context.cc
+++ b/chrome/browser/clipboard/clipboard_write_permission_context.cc
@@ -6,14 +6,14 @@
 
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_types.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 #include "url/gurl.h"
 
 ClipboardWritePermissionContext::ClipboardWritePermissionContext(
     Profile* profile)
     : PermissionContextBase(profile,
                             CONTENT_SETTINGS_TYPE_CLIPBOARD_WRITE,
-                            blink::FeaturePolicyFeature::kNotFound) {}
+                            blink::mojom::FeaturePolicyFeature::kNotFound) {}
 
 ClipboardWritePermissionContext::~ClipboardWritePermissionContext() {}
 
diff --git a/chrome/browser/custom_handlers/OWNERS b/chrome/browser/custom_handlers/OWNERS
index 9fd573ab..f4a612f 100644
--- a/chrome/browser/custom_handlers/OWNERS
+++ b/chrome/browser/custom_handlers/OWNERS
@@ -1 +1,2 @@
 benwells@chromium.org
+mgiuca@chromium.org
diff --git a/chrome/browser/download/notification/download_notification_browsertest.cc b/chrome/browser/download/notification/download_notification_browsertest.cc
index 4a4196f..a53caf6 100644
--- a/chrome/browser/download/notification/download_notification_browsertest.cc
+++ b/chrome/browser/download/notification/download_notification_browsertest.cc
@@ -357,7 +357,13 @@
   EXPECT_FALSE(GetNotification(notification_id()));
 }
 
-IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, DownloadDangerousFile) {
+// Flaky on ChromeOS.  http://crbug.com/810302
+#if defined(OS_CHROMEOS)
+#define MAYBE_DownloadDangerousFile DISABLED_DownloadDangerousFile
+#else
+#define MAYBE_DownloadDangerousFile DownloadDangerousFile
+#endif
+IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, MAYBE_DownloadDangerousFile) {
   GURL download_url(embedded_test_server()->GetURL(
       "/downloads/dangerous/dangerous.swf"));
 
@@ -399,7 +405,13 @@
   EXPECT_TRUE(base::PathExists(GetDownloadPath().Append(filename.BaseName())));
 }
 
-IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, DiscardDangerousFile) {
+// Flaky on ChromeOS.  http://crbug.com/810302
+#if defined(OS_CHROMEOS)
+#define MAYBE_DiscardDangerousFile DISABLED_DiscardDangerousFile
+#else
+#define MAYBE_DiscardDangerousFile DiscardDangerousFile
+#endif
+IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, MAYBE_DiscardDangerousFile) {
   GURL download_url(embedded_test_server()->GetURL(
       "/downloads/dangerous/dangerous.swf"));
 
diff --git a/chrome/browser/extensions/api/sessions/sessions_apitest.cc b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
index 6f68a4cd..54a7bfd 100644
--- a/chrome/browser/extensions/api/sessions/sessions_apitest.cc
+++ b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
@@ -30,8 +30,6 @@
 #include "components/browser_sync/profile_sync_service_mock.h"
 #include "components/sync/device_info/local_device_info_provider_mock.h"
 #include "components/sync/driver/sync_api_component_factory_mock.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_error_factory_mock.h"
 #include "components/sync_sessions/sessions_sync_manager.h"
@@ -266,16 +264,14 @@
     sync_pb::EntitySpecifics entity;
     entity.mutable_session()->CopyFrom(meta);
     initial_data.push_back(syncer::SyncData::CreateRemoteData(
-        1, entity, base::Time(), syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create(),
+        1, entity, base::Time(),
         sync_sessions::SessionsSyncManager::TagHashFromSpecifics(
             entity.session())));
     for (size_t i = 0; i < tabs.size(); i++) {
       sync_pb::EntitySpecifics entity;
       entity.mutable_session()->CopyFrom(tabs[i]);
       initial_data.push_back(syncer::SyncData::CreateRemoteData(
-          i + 2, entity, base::Time(), syncer::AttachmentIdList(),
-          syncer::AttachmentServiceProxyForTest::Create(),
+          i + 2, entity, base::Time(),
           sync_sessions::SessionsSyncManager::TagHashFromSpecifics(
               entity.session())));
     }
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc
index 1218883..e1408ca 100644
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -284,6 +284,8 @@
       settings_api::PrefType::PREF_TYPE_NUMBER;
   (*s_whitelist)[ash::prefs::kAccessibilityScreenMagnifierEnabled] =
       settings_api::PrefType::PREF_TYPE_BOOLEAN;
+  (*s_whitelist)[ash::prefs::kAccessibilityScreenMagnifierScale] =
+      settings_api::PrefType::PREF_TYPE_NUMBER;
   (*s_whitelist)[ash::prefs::kAccessibilitySelectToSpeakEnabled] =
       settings_api::PrefType::PREF_TYPE_BOOLEAN;
   (*s_whitelist)[ash::prefs::kAccessibilityStickyKeysEnabled] =
diff --git a/chrome/browser/extensions/extension_disabled_ui_browsertest.cc b/chrome/browser/extensions/extension_disabled_ui_browsertest.cc
index c2baada..b12f1da 100644
--- a/chrome/browser/extensions/extension_disabled_ui_browsertest.cc
+++ b/chrome/browser/extensions/extension_disabled_ui_browsertest.cc
@@ -293,11 +293,7 @@
       "http://localhost/autoupdate/updates.xml");
   specifics.mutable_extension()->set_version("2");
   syncer::SyncData sync_data =
-      syncer::SyncData::CreateRemoteData(1234567,
-                                         specifics,
-                                         base::Time::Now(),
-                                         syncer::AttachmentIdList(),
-                                         syncer::AttachmentServiceProxy());
+      syncer::SyncData::CreateRemoteData(1234567, specifics, base::Time::Now());
 
   ExtensionSyncService* sync_service = ExtensionSyncService::Get(profile());
   sync_service->MergeDataAndStartSyncing(
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc
index c69cf2e..a276669 100644
--- a/chrome/browser/extensions/service_worker_apitest.cc
+++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -10,6 +10,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/extensions/lazy_background_page_test_util.h"
@@ -697,7 +698,13 @@
       "service_worker/web_accessible_resources/fetch/", "page.html"));
 }
 
-IN_PROC_BROWSER_TEST_P(ServiceWorkerTest, TabsCreate) {
+// Flaky on Linux: http://crbug/810397.
+#if defined(OS_LINUX)
+#define MAYBE_TabsCreate DISABLED_TabsCreate
+#else
+#define MAYBE_TabsCreate TabsCreate
+#endif
+IN_PROC_BROWSER_TEST_P(ServiceWorkerTest, MAYBE_TabsCreate) {
   // Extensions APIs from SW are only enabled on trunk.
   ScopedCurrentChannel current_channel_override(version_info::Channel::UNKNOWN);
   const Extension* extension = LoadExtensionWithFlags(
diff --git a/chrome/browser/generic_sensor/sensor_permission_context.cc b/chrome/browser/generic_sensor/sensor_permission_context.cc
index 0fba82a..08f4c3d3 100644
--- a/chrome/browser/generic_sensor/sensor_permission_context.cc
+++ b/chrome/browser/generic_sensor/sensor_permission_context.cc
@@ -6,13 +6,13 @@
 
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_types.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 #include "url/gurl.h"
 
 SensorPermissionContext::SensorPermissionContext(Profile* profile)
     : PermissionContextBase(profile,
                             CONTENT_SETTINGS_TYPE_SENSORS,
-                            blink::FeaturePolicyFeature::kNotFound) {}
+                            blink::mojom::FeaturePolicyFeature::kNotFound) {}
 
 SensorPermissionContext::~SensorPermissionContext() {}
 
diff --git a/chrome/browser/geolocation/geolocation_permission_context.cc b/chrome/browser/geolocation/geolocation_permission_context.cc
index ba2c791..3c17db3 100644
--- a/chrome/browser/geolocation/geolocation_permission_context.cc
+++ b/chrome/browser/geolocation/geolocation_permission_context.cc
@@ -19,7 +19,7 @@
 GeolocationPermissionContext::GeolocationPermissionContext(Profile* profile)
     : PermissionContextBase(profile,
                             CONTENT_SETTINGS_TYPE_GEOLOCATION,
-                            blink::FeaturePolicyFeature::kGeolocation),
+                            blink::mojom::FeaturePolicyFeature::kGeolocation),
       extensions_context_(profile) {}
 
 GeolocationPermissionContext::~GeolocationPermissionContext() {
diff --git a/chrome/browser/lifetime/application_lifetime.cc b/chrome/browser/lifetime/application_lifetime.cc
index eba3fee..3e90b65 100644
--- a/chrome/browser/lifetime/application_lifetime.cc
+++ b/chrome/browser/lifetime/application_lifetime.cc
@@ -367,7 +367,7 @@
   // termination as soon as it hides or destroys its windows. Since any
   // execution past that point will be non-deterministically cut short, we
   // might as well put ourselves out of that misery deterministically.
-  base::Process::Current().Terminate(0, false);
+  base::Process::TerminateCurrentProcessImmediately(0);
 }
 
 void ShutdownIfNeeded() {
diff --git a/chrome/browser/media/midi_permission_context.cc b/chrome/browser/media/midi_permission_context.cc
index 0c2ceba..e7205ee 100644
--- a/chrome/browser/media/midi_permission_context.cc
+++ b/chrome/browser/media/midi_permission_context.cc
@@ -7,7 +7,7 @@
 MidiPermissionContext::MidiPermissionContext(Profile* profile)
     : PermissionContextBase(profile,
                             CONTENT_SETTINGS_TYPE_MIDI,
-                            blink::FeaturePolicyFeature::kMidiFeature) {}
+                            blink::mojom::FeaturePolicyFeature::kMidiFeature) {}
 
 MidiPermissionContext::~MidiPermissionContext() {
 }
diff --git a/chrome/browser/media/midi_sysex_permission_context.cc b/chrome/browser/media/midi_sysex_permission_context.cc
index 7f48d35..64b3b83c 100644
--- a/chrome/browser/media/midi_sysex_permission_context.cc
+++ b/chrome/browser/media/midi_sysex_permission_context.cc
@@ -12,7 +12,7 @@
 MidiSysexPermissionContext::MidiSysexPermissionContext(Profile* profile)
     : PermissionContextBase(profile,
                             CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
-                            blink::FeaturePolicyFeature::kMidiFeature) {}
+                            blink::mojom::FeaturePolicyFeature::kMidiFeature) {}
 
 MidiSysexPermissionContext::~MidiSysexPermissionContext() {}
 
diff --git a/chrome/browser/media/protected_media_identifier_permission_context.cc b/chrome/browser/media/protected_media_identifier_permission_context.cc
index 2733865..eebfa98 100644
--- a/chrome/browser/media/protected_media_identifier_permission_context.cc
+++ b/chrome/browser/media/protected_media_identifier_permission_context.cc
@@ -42,7 +42,7 @@
     ProtectedMediaIdentifierPermissionContext(Profile* profile)
     : PermissionContextBase(profile,
                             CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
-                            blink::FeaturePolicyFeature::kEncryptedMedia)
+                            blink::mojom::FeaturePolicyFeature::kEncryptedMedia)
 #if defined(OS_CHROMEOS)
       ,
       weak_factory_(this)
diff --git a/chrome/browser/media/webrtc/media_stream_device_permission_context.cc b/chrome/browser/media/webrtc/media_stream_device_permission_context.cc
index 211f02be..eee1469 100644
--- a/chrome/browser/media/webrtc/media_stream_device_permission_context.cc
+++ b/chrome/browser/media/webrtc/media_stream_device_permission_context.cc
@@ -14,12 +14,13 @@
 
 namespace {
 
-blink::FeaturePolicyFeature GetFeaturePolicyFeature(ContentSettingsType type) {
+blink::mojom::FeaturePolicyFeature GetFeaturePolicyFeature(
+    ContentSettingsType type) {
   if (type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)
-    return blink::FeaturePolicyFeature::kMicrophone;
+    return blink::mojom::FeaturePolicyFeature::kMicrophone;
 
   DCHECK_EQ(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, type);
-  return blink::FeaturePolicyFeature::kCamera;
+  return blink::mojom::FeaturePolicyFeature::kCamera;
 }
 
 }  // namespace
diff --git a/chrome/browser/media/webrtc/media_stream_devices_controller.cc b/chrome/browser/media/webrtc/media_stream_devices_controller.cc
index 5d4de0e..ee0b7fe 100644
--- a/chrome/browser/media/webrtc/media_stream_devices_controller.cc
+++ b/chrome/browser/media/webrtc/media_stream_devices_controller.cc
@@ -37,7 +37,7 @@
 #include "content/public/common/media_stream_request.h"
 #include "content/public/common/origin_util.h"
 #include "extensions/common/constants.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 
 #if defined(OS_ANDROID)
 #include <vector>
@@ -317,8 +317,9 @@
     DCHECK_NE(CONTENT_SETTING_DEFAULT, video_setting_);
     content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
         request.render_process_id, request.render_frame_id);
-    if (!rfh->IsFeatureEnabled(blink::FeaturePolicyFeature::kMicrophone) ||
-        !rfh->IsFeatureEnabled(blink::FeaturePolicyFeature::kCamera)) {
+    if (!rfh->IsFeatureEnabled(
+            blink::mojom::FeaturePolicyFeature::kMicrophone) ||
+        !rfh->IsFeatureEnabled(blink::mojom::FeaturePolicyFeature::kCamera)) {
       rfh->AddMessageToConsole(content::CONSOLE_MESSAGE_LEVEL_WARNING,
                                kPepperMediaFeaturePolicyDeprecationMessage);
     }
diff --git a/chrome/browser/net/dns_probe_browsertest.cc b/chrome/browser/net/dns_probe_browsertest.cc
index 7f4f773..c9efad45 100644
--- a/chrome/browser/net/dns_probe_browsertest.cc
+++ b/chrome/browser/net/dns_probe_browsertest.cc
@@ -39,6 +39,7 @@
 #include "net/url_request/url_request_filter.h"
 #include "net/url_request/url_request_interceptor.h"
 #include "net/url_request/url_request_job.h"
+#include "net/url_request/url_request_test_job.h"
 #include "services/network/public/cpp/features.h"
 
 using base::Bind;
@@ -434,6 +435,9 @@
   void TearDownOnMainThread() override;
 
  protected:
+  bool InterceptURLLoaderRequest(
+      content::URLLoaderInterceptor::RequestParams* params);
+
   // Sets the browser object that other methods apply to, and that has the
   // DnsProbeStatus messages of its currently active tab monitored.
   void SetActiveBrowser(Browser* browser);
@@ -479,6 +483,7 @@
   NetErrorTabHelper* monitored_tab_helper_;
 
   bool awaiting_dns_probe_status_;
+  bool corrections_service_working_;
   // Queue of statuses received but not yet consumed by WaitForSentStatus().
   std::list<DnsProbeStatus> dns_probe_status_queue_;
 
@@ -491,8 +496,8 @@
     : helper_(new DnsProbeBrowserTestIOThreadHelper()),
       active_browser_(NULL),
       monitored_tab_helper_(NULL),
-      awaiting_dns_probe_status_(false) {
-}
+      awaiting_dns_probe_status_(false),
+      corrections_service_working_(true) {}
 
 DnsProbeBrowserTest::~DnsProbeBrowserTest() {
   // No tests should have any unconsumed probe statuses.
@@ -511,14 +516,15 @@
       BindOnce(&DnsProbeBrowserTestIOThreadHelper::SetUpOnIOThread,
                Unretained(helper_), g_browser_process->io_thread()));
 
+  ASSERT_TRUE(embedded_test_server()->Start());
+
   if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
-    // Just instantiating this helper is enough to respond to
-    // http(s)://mock.failed.request requests.
-    url_loader_interceptor_ =
-        std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
-            [](content::URLLoaderInterceptor::RequestParams* params) {
-              return false;
-            }));
+    // NOTE: Need to intercept requests for subresources to catch the Link
+    // Doctor requests.
+    url_loader_interceptor_ = std::make_unique<content::URLLoaderInterceptor>(
+        base::BindRepeating(&DnsProbeBrowserTest::InterceptURLLoaderRequest,
+                            base::Unretained(this)),
+        true, true);
   }
 
   SetActiveBrowser(browser());
@@ -537,6 +543,20 @@
       NetErrorTabHelper::TESTING_DEFAULT);
 }
 
+bool DnsProbeBrowserTest::InterceptURLLoaderRequest(
+    content::URLLoaderInterceptor::RequestParams* params) {
+  if (params->url_request.url.spec() == LinkDoctorBaseURL().spec() &&
+      corrections_service_working_) {
+    return chrome_browser_net::WriteFileToURLLoader(
+        embedded_test_server(), params, "mock-link-doctor.json");
+  }
+
+  // Just returning false is enough to respond to http(s)://mock.failed.request
+  // requests, which are the only requests that come in besides the LinkDoctor
+  // requests.
+  return false;
+}
+
 void DnsProbeBrowserTest::SetActiveBrowser(Browser* browser) {
   // If currently watching a NetErrorTabHelper, stop doing so before start
   // watching another.
@@ -553,6 +573,7 @@
 
 void DnsProbeBrowserTest::SetCorrectionServiceBroken(bool broken) {
   int net_error = broken ? net::ERR_NAME_NOT_RESOLVED : net::OK;
+  corrections_service_working_ = (net_error == net::OK);
 
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
@@ -666,7 +687,15 @@
 
 void DnsProbeBrowserTest::ExpectDisplayingCorrections(
     const std::string& status_text) {
-  EXPECT_TRUE(PageContains("http://mock.http/title2.html"));
+  // NOTE: In the case of the Network Service, the expected URL has a port
+  // inserted.
+  GURL url;
+  if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+    url = embedded_test_server()->GetURL("mock.http", "/title2.html");
+  } else {
+    url = GURL("http://mock.http/title2.html");
+  }
+  EXPECT_TRUE(PageContains(url.spec()));
   EXPECT_TRUE(PageContains(status_text));
 }
 
@@ -906,8 +935,6 @@
 IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, NoProbeInSubframe) {
   SetCorrectionServiceBroken(false);
 
-  ASSERT_TRUE(embedded_test_server()->Start());
-
   NavigateToURL(browser(),
                 embedded_test_server()->GetURL("/iframe_dns_error.html"));
 
diff --git a/chrome/browser/net/errorpage_browsertest.cc b/chrome/browser/net/errorpage_browsertest.cc
index ca4b943..615867b 100644
--- a/chrome/browser/net/errorpage_browsertest.cc
+++ b/chrome/browser/net/errorpage_browsertest.cc
@@ -471,15 +471,17 @@
                     BrowserThread::UI, FROM_HERE,
                     base::BindOnce(&DNSErrorPageTest::RequestCreated,
                                    base::Unretained(owner)));
-                return WriteFileToURLLoader(owner, params,
-                                            "mock-link-doctor.json");
+                return chrome_browser_net::WriteFileToURLLoader(
+                    owner->embedded_test_server(), params,
+                    "mock-link-doctor.json");
               }
 
               // Add an interceptor for the search engine the error page will
               // use.
               if (params->url_request.url.host() ==
                   owner->search_term_url_.host()) {
-                return WriteFileToURLLoader(owner, params, "title3.html");
+                return chrome_browser_net::WriteFileToURLLoader(
+                    owner->embedded_test_server(), params, "title3.html");
               }
 
               return false;
@@ -521,40 +523,6 @@
 
   void TearDownOnMainThread() override { url_loader_interceptor_.reset(); }
 
-  static bool WriteFileToURLLoader(
-      DNSErrorPageTest* owner,
-      content::URLLoaderInterceptor::RequestParams* params,
-      std::string path) {
-    base::ScopedAllowBlockingForTesting allow_blocking;
-
-    if (path[0] == '/')
-      path.erase(0, 1);
-
-    if (path == "favicon.ico")
-      return false;
-
-    base::FilePath file_path;
-    PathService::Get(chrome::DIR_TEST_DATA, &file_path);
-    file_path = file_path.AppendASCII(path);
-
-    std::string contents;
-    const bool result = base::ReadFileToString(file_path, &contents);
-    EXPECT_TRUE(result);
-
-    if (path == "mock-link-doctor.json") {
-      GURL url =
-          owner->embedded_test_server()->GetURL("mock.http", "/title2.html");
-
-      std::string placeholder = "http://mock.http/title2.html";
-      contents.replace(contents.find(placeholder), placeholder.length(),
-                       url.spec());
-    }
-
-    content::URLLoaderInterceptor::WriteResponse(
-        net::URLRequestTestJob::test_headers(), contents, params->client.get());
-    return true;
-  }
-
   void SetUpOnMainThread() override {
     // All mock.http requests get served by the embedded test server.
     host_resolver()->AddRule("mock.http", "127.0.0.1");
diff --git a/chrome/browser/net/url_request_mock_util.cc b/chrome/browser/net/url_request_mock_util.cc
index c8252d0..78824398 100644
--- a/chrome/browser/net/url_request_mock_util.cc
+++ b/chrome/browser/net/url_request_mock_util.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/files/file_util.h"
 #include "base/path_service.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/common/chrome_paths.h"
@@ -14,6 +15,8 @@
 #include "net/test/url_request/url_request_mock_http_job.h"
 #include "net/test/url_request/url_request_slow_download_job.h"
 #include "net/url_request/url_request_filter.h"
+#include "net/url_request/url_request_test_job.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 using content::BrowserThread;
 
@@ -44,4 +47,36 @@
   }
 }
 
+bool WriteFileToURLLoader(net::EmbeddedTestServer* test_server,
+                          content::URLLoaderInterceptor::RequestParams* params,
+                          std::string path) {
+  base::ScopedAllowBlockingForTesting allow_blocking;
+
+  if (path[0] == '/')
+    path.erase(0, 1);
+
+  if (path == "favicon.ico")
+    return false;
+
+  base::FilePath file_path;
+  PathService::Get(chrome::DIR_TEST_DATA, &file_path);
+  file_path = file_path.AppendASCII(path);
+
+  std::string contents;
+  const bool result = base::ReadFileToString(file_path, &contents);
+  EXPECT_TRUE(result);
+
+  if (path == "mock-link-doctor.json") {
+    GURL url = test_server->GetURL("mock.http", "/title2.html");
+
+    std::string placeholder = "http://mock.http/title2.html";
+    contents.replace(contents.find(placeholder), placeholder.length(),
+                     url.spec());
+  }
+
+  content::URLLoaderInterceptor::WriteResponse(
+      net::URLRequestTestJob::test_headers(), contents, params->client.get());
+  return true;
+}
+
 }  // namespace chrome_browser_net
diff --git a/chrome/browser/net/url_request_mock_util.h b/chrome/browser/net/url_request_mock_util.h
index b3a81bb..5c2f1c1 100644
--- a/chrome/browser/net/url_request_mock_util.h
+++ b/chrome/browser/net/url_request_mock_util.h
@@ -5,6 +5,9 @@
 #ifndef CHROME_BROWSER_NET_URL_REQUEST_MOCK_UTIL_H_
 #define CHROME_BROWSER_NET_URL_REQUEST_MOCK_UTIL_H_
 
+#include "content/public/test/url_loader_interceptor.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
 // You should use routines in this file only for test code!
 
 namespace chrome_browser_net {
@@ -12,6 +15,15 @@
 // Enables or disables url request filters for mocked url requests.
 void SetUrlRequestMocksEnabled(bool enabled);
 
+// Writes the contents of |path| as a response to a request intercepted
+// by the URLLoaderInterceptor associated with |params->client()|. Notes:
+// - |path| is assumed to be relative to chrome::DIR_TEST_DATA.
+// - If |path| is |mock_link_doctor.json|, rewrites the that
+//   file's|urlCorrection| URL as it is mapped by |test_server|.
+bool WriteFileToURLLoader(net::EmbeddedTestServer* test_server,
+                          content::URLLoaderInterceptor::RequestParams* params,
+                          std::string path);
+
 }  // namespace chrome_browser_net
 
 #endif  // CHROME_BROWSER_NET_URL_REQUEST_MOCK_UTIL_H_
diff --git a/chrome/browser/notifications/notification_permission_context.cc b/chrome/browser/notifications/notification_permission_context.cc
index a3b31bb..64faf0d 100644
--- a/chrome/browser/notifications/notification_permission_context.cc
+++ b/chrome/browser/notifications/notification_permission_context.cc
@@ -160,7 +160,7 @@
 NotificationPermissionContext::NotificationPermissionContext(Profile* profile)
     : PermissionContextBase(profile,
                             CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
-                            blink::FeaturePolicyFeature::kNotFound),
+                            blink::mojom::FeaturePolicyFeature::kNotFound),
       weak_factory_ui_thread_(this) {}
 
 NotificationPermissionContext::~NotificationPermissionContext() {}
diff --git a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
index 33fb994..5c80eb6 100644
--- a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
+++ b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
@@ -201,19 +201,6 @@
 // notification_interactive_uitest.cc to this file.
 
 IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
-                       DisplayPersistentNotificationWithoutPermission) {
-  RequestAndDenyPermission();
-
-  std::string script_result;
-  ASSERT_TRUE(RunScript("DisplayPersistentNotification()", &script_result));
-  EXPECT_EQ(
-      "TypeError: No notification permission has been granted for this origin.",
-      script_result);
-
-  ASSERT_EQ(0u, GetDisplayedNotifications(true /* is_persistent */).size());
-}
-
-IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest,
                        DisplayPersistentNotificationWithPermission) {
   RequestAndAcceptPermission();
 
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h
index c0967d6..9a24531 100644
--- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h
@@ -85,18 +85,33 @@
   FIRST_MEANINGFUL_PAINT_LAST_ENTRY
 };
 
+// Different events can prevent us from recording a successful time to
+// interactive value, and sometimes several of these failure events can happen
+// simultaneously. In the case of multiple invalidating events, we record the
+// failure reason in decreasing order of priority of the following:
+//
+// 1. Did not reach First Meaningful Paint
+// 2. Did not reach quiescence
+// 3. Page was not in foreground until TTI was detected.
+// 4. There was a non-mouse-move user input before interactive time.
+//
+// Table of conditions and the TTI Status recorded for each case:
+// FMP Reached | Quiesence Reached | Always Foreground | No User Input | Status
+// True        | True              | True              | True          | 0
+// True        | True              | True              | False         | 2
+// True        | True              | False             | *             | 1
+// True        | False             | *                 | *             | 3
+// False       | *                 | *                 | *             | 4
 enum TimeToInteractiveStatus {
   // Time to Interactive recorded successfully.
   TIME_TO_INTERACTIVE_RECORDED = 0,
 
-  // Reasons for not recording Time to Interactive:
   // Main thread and network quiescence reached, but the user backgrounded the
   // page at least once before reaching quiescence.
   TIME_TO_INTERACTIVE_BACKGROUNDED = 1,
 
   // Main thread and network quiescence reached, but there was a non-mouse-move
   // user input that hit the renderer main thread between navigation start and
-  // the
   // interactive time, so the detected interactive time is inaccurate. Note that
   // Time to Interactive is not invalidated if the user input is after
   // interactive time, but before quiescence windows are detected. User input
@@ -111,7 +126,9 @@
   TIME_TO_INTERACTIVE_DID_NOT_REACH_QUIESCENCE = 3,
 
   // User left page before First Meaningful Paint happened, but after First
-  // Paint.
+  // Paint. This status will also be recorded if the first meaningful paint was
+  // reached on the renderer, but invalidated there due to user input. Input
+  // invalided First Meaningful Paint values do not reach the browser.
   TIME_TO_INTERACTIVE_DID_NOT_REACH_FIRST_MEANINGFUL_PAINT = 4,
 
   TIME_TO_INTERACTIVE_LAST_ENTRY
diff --git a/chrome/browser/permissions/permission_context_base.cc b/chrome/browser/permissions/permission_context_base.cc
index 6cee43a..11e24c2f 100644
--- a/chrome/browser/permissions/permission_context_base.cc
+++ b/chrome/browser/permissions/permission_context_base.cc
@@ -84,7 +84,7 @@
 PermissionContextBase::PermissionContextBase(
     Profile* profile,
     ContentSettingsType content_settings_type,
-    blink::FeaturePolicyFeature feature_policy_feature)
+    blink::mojom::FeaturePolicyFeature feature_policy_feature)
     : profile_(profile),
       content_settings_type_(content_settings_type),
       feature_policy_feature_(feature_policy_feature),
@@ -410,7 +410,7 @@
   }
 
   // Some features don't have an associated feature policy yet. Allow those.
-  if (feature_policy_feature_ == blink::FeaturePolicyFeature::kNotFound)
+  if (feature_policy_feature_ == blink::mojom::FeaturePolicyFeature::kNotFound)
     return true;
 
   return rfh->IsFeatureEnabled(feature_policy_feature_);
diff --git a/chrome/browser/permissions/permission_context_base.h b/chrome/browser/permissions/permission_context_base.h
index 0145c2a..ad0b279 100644
--- a/chrome/browser/permissions/permission_context_base.h
+++ b/chrome/browser/permissions/permission_context_base.h
@@ -16,7 +16,7 @@
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "components/keyed_service/core/keyed_service.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 
 class GURL;
 class PermissionRequestID;
@@ -53,9 +53,10 @@
 
 class PermissionContextBase : public KeyedService {
  public:
-  PermissionContextBase(Profile* profile,
-                        ContentSettingsType content_settings_type,
-                        blink::FeaturePolicyFeature feature_policy_feature);
+  PermissionContextBase(
+      Profile* profile,
+      ContentSettingsType content_settings_type,
+      blink::mojom::FeaturePolicyFeature feature_policy_feature);
   ~PermissionContextBase() override;
 
   // A field trial used to enable the global permissions kill switch.
@@ -187,7 +188,7 @@
 
   Profile* profile_;
   const ContentSettingsType content_settings_type_;
-  const blink::FeaturePolicyFeature feature_policy_feature_;
+  const blink::mojom::FeaturePolicyFeature feature_policy_feature_;
   std::unordered_map<std::string, std::unique_ptr<PermissionRequest>>
       pending_requests_;
 
diff --git a/chrome/browser/permissions/permission_context_base_feature_policy_unittest.cc b/chrome/browser/permissions/permission_context_base_feature_policy_unittest.cc
index f682467..eab8119 100644
--- a/chrome/browser/permissions/permission_context_base_feature_policy_unittest.cc
+++ b/chrome/browser/permissions/permission_context_base_feature_policy_unittest.cc
@@ -17,7 +17,7 @@
 #include "content/public/common/content_features.h"
 #include "content/public/test/navigation_simulator.h"
 #include "content/public/test/test_renderer_host.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -63,7 +63,7 @@
   // The header policy should only be set once on page load, so we refresh the
   // page to simulate that.
   void RefreshPageAndSetHeaderPolicy(content::RenderFrameHost** rfh,
-                                     blink::FeaturePolicyFeature feature,
+                                     blink::mojom::FeaturePolicyFeature feature,
                                      const std::vector<std::string>& origins) {
     content::RenderFrameHost* current = *rfh;
     SimulateNavigation(&current, current->GetLastCommittedURL());
@@ -124,15 +124,15 @@
 
   content::RenderFrameHost* parent = GetMainRFH(kOrigin1);
 
-  RefreshPageAndSetHeaderPolicy(&parent,
-                                blink::FeaturePolicyFeature::kMidiFeature,
-                                std::vector<std::string>());
+  RefreshPageAndSetHeaderPolicy(
+      &parent, blink::mojom::FeaturePolicyFeature::kMidiFeature,
+      std::vector<std::string>());
   MidiPermissionContext midi(profile());
   EXPECT_EQ(CONTENT_SETTING_ALLOW, GetPermissionForFrame(&midi, parent));
 
-  RefreshPageAndSetHeaderPolicy(&parent,
-                                blink::FeaturePolicyFeature::kGeolocation,
-                                std::vector<std::string>());
+  RefreshPageAndSetHeaderPolicy(
+      &parent, blink::mojom::FeaturePolicyFeature::kGeolocation,
+      std::vector<std::string>());
   GeolocationPermissionContext geolocation(profile());
   EXPECT_EQ(CONTENT_SETTING_ASK, GetPermissionForFrame(&geolocation, parent));
 }
@@ -162,18 +162,18 @@
   content::RenderFrameHost* parent = GetMainRFH(kOrigin1);
 
   // Disable midi in the top level frame.
-  RefreshPageAndSetHeaderPolicy(&parent,
-                                blink::FeaturePolicyFeature::kMidiFeature,
-                                std::vector<std::string>());
+  RefreshPageAndSetHeaderPolicy(
+      &parent, blink::mojom::FeaturePolicyFeature::kMidiFeature,
+      std::vector<std::string>());
   content::RenderFrameHost* child = AddChildRFH(parent, kOrigin2);
   MidiPermissionContext midi(profile());
   EXPECT_EQ(CONTENT_SETTING_BLOCK, GetPermissionForFrame(&midi, parent));
   EXPECT_EQ(CONTENT_SETTING_BLOCK, GetPermissionForFrame(&midi, child));
 
   // Disable geolocation in the top level frame.
-  RefreshPageAndSetHeaderPolicy(&parent,
-                                blink::FeaturePolicyFeature::kGeolocation,
-                                std::vector<std::string>());
+  RefreshPageAndSetHeaderPolicy(
+      &parent, blink::mojom::FeaturePolicyFeature::kGeolocation,
+      std::vector<std::string>());
   child = AddChildRFH(parent, kOrigin2);
   GeolocationPermissionContext geolocation(profile());
   EXPECT_EQ(CONTENT_SETTING_BLOCK, GetPermissionForFrame(&geolocation, parent));
@@ -185,7 +185,8 @@
 
   // Enable midi for the child frame.
   RefreshPageAndSetHeaderPolicy(
-      &parent, blink::FeaturePolicyFeature::kMidiFeature, {kOrigin1, kOrigin2});
+      &parent, blink::mojom::FeaturePolicyFeature::kMidiFeature,
+      {kOrigin1, kOrigin2});
   content::RenderFrameHost* child = AddChildRFH(parent, kOrigin2);
   MidiPermissionContext midi(profile());
   EXPECT_EQ(CONTENT_SETTING_ALLOW, GetPermissionForFrame(&midi, parent));
@@ -193,7 +194,8 @@
 
   // Enable geolocation for the child frame.
   RefreshPageAndSetHeaderPolicy(
-      &parent, blink::FeaturePolicyFeature::kGeolocation, {kOrigin1, kOrigin2});
+      &parent, blink::mojom::FeaturePolicyFeature::kGeolocation,
+      {kOrigin1, kOrigin2});
   child = AddChildRFH(parent, kOrigin2);
   GeolocationPermissionContext geolocation(profile());
   EXPECT_EQ(CONTENT_SETTING_ASK, GetPermissionForFrame(&geolocation, parent));
@@ -213,9 +215,9 @@
             RequestPermissionForFrame(&geolocation, parent));
 
   // Disable geolocation in the top level frame.
-  RefreshPageAndSetHeaderPolicy(&parent,
-                                blink::FeaturePolicyFeature::kGeolocation,
-                                std::vector<std::string>());
+  RefreshPageAndSetHeaderPolicy(
+      &parent, blink::mojom::FeaturePolicyFeature::kGeolocation,
+      std::vector<std::string>());
 
   // Request should fail.
   EXPECT_EQ(CONTENT_SETTING_BLOCK,
diff --git a/chrome/browser/permissions/permission_context_base_unittest.cc b/chrome/browser/permissions/permission_context_base_unittest.cc
index 72a91e06..49ecaad 100644
--- a/chrome/browser/permissions/permission_context_base_unittest.cc
+++ b/chrome/browser/permissions/permission_context_base_unittest.cc
@@ -102,7 +102,7 @@
                         const ContentSettingsType content_settings_type)
       : PermissionContextBase(profile,
                               content_settings_type,
-                              blink::FeaturePolicyFeature::kNotFound),
+                              blink::mojom::FeaturePolicyFeature::kNotFound),
         tab_context_updated_(false) {}
 
   ~TestPermissionContext() override {}
diff --git a/chrome/browser/plugins/flash_permission_context.cc b/chrome/browser/plugins/flash_permission_context.cc
index 1fd98ab7..3352b9f 100644
--- a/chrome/browser/plugins/flash_permission_context.cc
+++ b/chrome/browser/plugins/flash_permission_context.cc
@@ -34,7 +34,7 @@
 FlashPermissionContext::FlashPermissionContext(Profile* profile)
     : PermissionContextBase(profile,
                             CONTENT_SETTINGS_TYPE_PLUGINS,
-                            blink::FeaturePolicyFeature::kNotFound) {}
+                            blink::mojom::FeaturePolicyFeature::kNotFound) {}
 
 FlashPermissionContext::~FlashPermissionContext() {}
 
diff --git a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
index cd765aeb..51f9a29 100644
--- a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
@@ -248,6 +248,7 @@
 #endif
     policy_manager->core()->client()->Register(
         registration_type, em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
+        em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
         em::LicenseType::UNDEFINED, "bogus", std::string(), std::string(),
         std::string());
     run_loop.Run();
diff --git a/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc
index c1da569..c8aca52 100644
--- a/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_manager_browsertest.cc
@@ -135,6 +135,7 @@
 #endif
     policy_manager()->core()->client()->Register(
         registration_type, em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
+        em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
         em::LicenseType::UNDEFINED, "bogus", std::string(), std::string(),
         std::string());
     run_loop.Run();
diff --git a/chrome/browser/prefs/synced_pref_change_registrar_browsertest.cc b/chrome/browser/prefs/synced_pref_change_registrar_browsertest.cc
index 6980c56d..8940f27 100644
--- a/chrome/browser/prefs/synced_pref_change_registrar_browsertest.cc
+++ b/chrome/browser/prefs/synced_pref_change_registrar_browsertest.cc
@@ -21,8 +21,6 @@
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/core/common/policy_types.h"
 #include "components/policy/policy_constants.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_change.h"
 #include "components/sync/model/sync_error_factory.h"
@@ -62,11 +60,7 @@
     pref_specifics->set_value(serialized_value);
 
     syncer::SyncData change_data = syncer::SyncData::CreateRemoteData(
-        ++next_sync_data_id_,
-        specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create());
+        ++next_sync_data_id_, specifics, base::Time());
     syncer::SyncChange change(
         FROM_HERE, syncer::SyncChange::ACTION_UPDATE, change_data);
 
diff --git a/chrome/browser/resources/settings/site_settings/constants.js b/chrome/browser/resources/settings/site_settings/constants.js
index a855a17..f878c56 100644
--- a/chrome/browser/resources/settings/site_settings/constants.js
+++ b/chrome/browser/resources/settings/site_settings/constants.js
@@ -30,7 +30,7 @@
   MIDI_DEVICES: 'midi-sysex',
   USB_DEVICES: 'usb-chooser-data',
   ZOOM_LEVELS: 'zoom-levels',
-  PROTECTED_CONTENT: 'protectedContent',
+  PROTECTED_CONTENT: 'protected-content',
   ADS: 'ads',
   CLIPBOARD: 'clipboard',
   SENSORS: 'sensors',
diff --git a/chrome/browser/safe_browsing/threat_details_unittest.cc b/chrome/browser/safe_browsing/threat_details_unittest.cc
index 0ff90ce0f..ce46aa2 100644
--- a/chrome/browser/safe_browsing/threat_details_unittest.cc
+++ b/chrome/browser/safe_browsing/threat_details_unittest.cc
@@ -904,7 +904,7 @@
 // This test uses the following structure.
 // kDOMParentURL
 //  \- <div id=outer>  # Trimmed
-//  \- <script id=outer-sibling src=kReferrerURL>  # Trimmed
+//  \- <script id=outer-sibling src=kReferrerURL>  # Reported (parent of ad ID)
 //   \- <script id=sibling src=kFirstRedirectURL>  # Reported (sibling of ad ID)
 //   \- <div data-google-query-id=ad-tag>  # Reported (ad ID)
 //     \- <iframe src=kDOMChildURL foo=bar>  # Reported (child of ad ID)
@@ -1037,9 +1037,12 @@
   res_dom_child->add_child_ids(2);
   res_dom_child->set_tag_name("iframe");
 
-  // Note that resource |top_script| with URL kReferrerURL would normally appear
-  // as resource #4, but it was trimmed from the report. Hence resource ID 4 is
-  // skipped.
+  ClientSafeBrowsingReportRequest::Resource* res_ad_parent =
+      expected.add_resources();
+  res_ad_parent->set_id(4);
+  res_ad_parent->set_url(kReferrerURL);
+  res_ad_parent->set_parent_id(5);
+  res_ad_parent->set_tag_name("script");
 
   ClientSafeBrowsingReportRequest::Resource* res_sibling =
       expected.add_resources();
@@ -1056,6 +1059,17 @@
   res_dom_parent->add_child_ids(4);
   res_dom_parent->add_child_ids(6);
 
+  HTMLElement* elem_dom_parent_script = expected.add_dom();
+  elem_dom_parent_script->set_id(3);
+  elem_dom_parent_script->set_tag("SCRIPT");
+  elem_dom_parent_script->set_resource_id(res_ad_parent->id());
+  elem_dom_parent_script->add_attribute()->set_name("src");
+  elem_dom_parent_script->mutable_attribute(0)->set_value(kReferrerURL);
+  elem_dom_parent_script->add_attribute()->set_name("id");
+  elem_dom_parent_script->mutable_attribute(1)->set_value("outer-sibling");
+  elem_dom_parent_script->add_child_ids(4);
+  elem_dom_parent_script->add_child_ids(5);
+
   HTMLElement* elem_dom_sibling_script = expected.add_dom();
   elem_dom_sibling_script->set_id(4);
   elem_dom_sibling_script->set_tag("SCRIPT");
diff --git a/chrome/browser/storage/durable_storage_permission_context.cc b/chrome/browser/storage/durable_storage_permission_context.cc
index 0fc1d35..8d4ca4e 100644
--- a/chrome/browser/storage/durable_storage_permission_context.cc
+++ b/chrome/browser/storage/durable_storage_permission_context.cc
@@ -30,7 +30,7 @@
     Profile* profile)
     : PermissionContextBase(profile,
                             CONTENT_SETTINGS_TYPE_DURABLE_STORAGE,
-                            blink::FeaturePolicyFeature::kNotFound) {}
+                            blink::mojom::FeaturePolicyFeature::kNotFound) {}
 
 void DurableStoragePermissionContext::DecidePermission(
     content::WebContents* web_contents,
diff --git a/chrome/browser/supervised_user/legacy/supervised_user_registration_utility_unittest.cc b/chrome/browser/supervised_user/legacy/supervised_user_registration_utility_unittest.cc
index 775bcb3..c97699d7 100644
--- a/chrome/browser/supervised_user/legacy/supervised_user_registration_utility_unittest.cc
+++ b/chrome/browser/supervised_user/legacy/supervised_user_registration_utility_unittest.cc
@@ -20,8 +20,6 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/prefs/scoped_user_pref_update.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/sync_change.h"
 #include "components/sync/model/sync_error_factory_mock.h"
 #include "components/sync/protocol/sync.pb.h"
@@ -220,15 +218,9 @@
         sync_change.sync_data().GetSpecifics();
     EXPECT_FALSE(specifics.managed_user().acknowledged());
     specifics.mutable_managed_user()->set_acknowledged(true);
-    new_changes.push_back(
-        SyncChange(FROM_HERE,
-                   SyncChange::ACTION_UPDATE,
-                   SyncData::CreateRemoteData(
-                       ++sync_data_id_,
-                       specifics,
-                       base::Time(),
-                       syncer::AttachmentIdList(),
-                       syncer::AttachmentServiceProxyForTest::Create())));
+    new_changes.push_back(SyncChange(
+        FROM_HERE, SyncChange::ACTION_UPDATE,
+        SyncData::CreateRemoteData(++sync_data_id_, specifics, base::Time())));
   }
   service()->ProcessSyncChanges(FROM_HERE, new_changes);
 
diff --git a/chrome/browser/supervised_user/legacy/supervised_user_sync_service_unittest.cc b/chrome/browser/supervised_user/legacy/supervised_user_sync_service_unittest.cc
index 706e8c09e..9c24388 100644
--- a/chrome/browser/supervised_user/legacy/supervised_user_sync_service_unittest.cc
+++ b/chrome/browser/supervised_user/legacy/supervised_user_sync_service_unittest.cc
@@ -18,8 +18,6 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/prefs/scoped_user_pref_update.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/sync_change.h"
 #include "components/sync/model/sync_error_factory_mock.h"
 #include "components/sync/protocol/sync.pb.h"
@@ -145,12 +143,7 @@
   if (!chrome_avatar.empty())
     specifics.mutable_managed_user()->set_chrome_avatar(chrome_avatar);
 
-  return SyncData::CreateRemoteData(
-      ++sync_data_id_,
-      specifics,
-      base::Time(),
-      syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create());
+  return SyncData::CreateRemoteData(++sync_data_id_, specifics, base::Time());
 }
 
 TEST_F(SupervisedUserSyncServiceTest, MergeEmpty) {
diff --git a/chrome/browser/themes/theme_syncable_service_unittest.cc b/chrome/browser/themes/theme_syncable_service_unittest.cc
index 0133719..6cf0709 100644
--- a/chrome/browser/themes/theme_syncable_service_unittest.cc
+++ b/chrome/browser/themes/theme_syncable_service_unittest.cc
@@ -21,8 +21,6 @@
 #include "chrome/browser/themes/theme_service_factory.h"
 #include "chrome/common/extensions/extension_test_util.h"
 #include "chrome/test/base/testing_profile.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_change_processor_wrapper_for_test.h"
 #include "components/sync/model/sync_error.h"
@@ -456,15 +454,9 @@
   sync_pb::EntitySpecifics entity_specifics;
   entity_specifics.mutable_theme()->CopyFrom(theme_specifics);
   syncer::SyncChangeList change_list;
-  change_list.push_back(
-      syncer::SyncChange(FROM_HERE,
-                         syncer::SyncChange::ACTION_UPDATE,
-                         syncer::SyncData::CreateRemoteData(
-                             1,
-                             entity_specifics,
-                             base::Time(),
-                             syncer::AttachmentIdList(),
-                             syncer::AttachmentServiceProxyForTest::Create())));
+  change_list.push_back(syncer::SyncChange(
+      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+      syncer::SyncData::CreateRemoteData(1, entity_specifics, base::Time())));
   error = theme_sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
   EXPECT_FALSE(error.IsSet()) << error.message();
   EXPECT_EQ(fake_theme_service_->theme_extension(), theme_extension_.get());
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 30fe53c3..2c30fd0 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -2485,8 +2485,6 @@
         "cocoa/extensions/extension_installed_bubble_controller.h",
         "cocoa/extensions/extension_installed_bubble_controller.mm",
         "cocoa/extensions/extension_uninstall_dialog_cocoa.mm",
-        "cocoa/extensions/media_galleries_dialog_cocoa.h",
-        "cocoa/extensions/media_galleries_dialog_cocoa.mm",
         "cocoa/global_error_bubble_controller.h",
         "cocoa/global_error_bubble_controller.mm",
         "cocoa/login_handler_cocoa.h",
@@ -2500,8 +2498,6 @@
         "cocoa/passwords/password_prompt_view_bridge.h",
         "cocoa/passwords/password_prompt_view_bridge.mm",
         "cocoa/permission_bubble/chooser_bubble_ui_views_mac.mm",
-        "cocoa/profiles/user_manager_mac.h",
-        "cocoa/profiles/user_manager_mac.mm",
         "cocoa/session_crashed_bubble.mm",
         "cocoa/simple_message_box_bridge_views.mm",
         "cocoa/simple_message_box_cocoa.h",
@@ -3300,6 +3296,13 @@
         ]
       }
     }
+
+    if (!is_chromeos) {
+      sources += [
+        "views/relaunch_notification/relaunch_notification_controller.cc",
+        "views/relaunch_notification/relaunch_notification_controller.h",
+      ]
+    }
   }
 
   if (use_aura) {
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
index 242b9e2..2817f49 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
@@ -13,7 +13,6 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/crx_file/id_util.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_error_factory.h"
 #include "components/sync/model/sync_error_factory_mock.h"
@@ -106,10 +105,8 @@
   if (item_pin_ordinal != kUnset)
     app_list->set_item_pin_ordinal(item_pin_ordinal);
 
-  return syncer::SyncData::CreateRemoteData(
-      std::hash<std::string>{}(id), specifics, base::Time(),
-      syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create());
+  return syncer::SyncData::CreateRemoteData(std::hash<std::string>{}(id),
+                                            specifics, base::Time());
 }
 
 syncer::SyncDataList CreateBadAppRemoteData(const std::string& id) {
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
index 41c1bf2..e7b09d4 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -91,7 +91,6 @@
 #include "components/keep_alive_registry/scoped_keep_alive.h"
 #include "components/prefs/pref_notifier_impl.h"
 #include "components/signin/core/account_id/account_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_error_factory_mock.h"
 #include "components/sync/protocol/sync.pb.h"
@@ -635,9 +634,8 @@
     sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference();
     pref_one->set_name(prefs::kPinnedLauncherApps);
     pref_one->set_value(serialized);
-    init_sync_list.push_back(syncer::SyncData::CreateRemoteData(
-        1, one, base::Time(), syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    init_sync_list.push_back(
+        syncer::SyncData::CreateRemoteData(1, one, base::Time()));
     StartPrefSyncService(init_sync_list);
   }
 
diff --git a/chrome/browser/ui/sad_tab.h b/chrome/browser/ui/sad_tab.h
index 58cbd1f..0a95dc62 100644
--- a/chrome/browser/ui/sad_tab.h
+++ b/chrome/browser/ui/sad_tab.h
@@ -37,6 +37,11 @@
 
   virtual ~SadTab() {}
 
+  // Called when the sad tab needs to be reinstalled in its window,
+  // for example because an inactive tab was activated, or because a tab was
+  // dragged to a new browser window.
+  virtual void ReinstallInWebView() {}
+
   // These functions return resource string IDs for UI text. They may be
   // different for each sad tab. (Right now, the first sad tab in a session
   // suggests reloading and subsequent ones suggest sending feedback.)
@@ -60,6 +65,8 @@
  protected:
   SadTab(content::WebContents* web_contents, SadTabKind kind);
 
+  content::WebContents* web_contents() const { return web_contents_; }
+
  private:
   content::WebContents* web_contents_;
   SadTabKind kind_;
diff --git a/chrome/browser/ui/sad_tab_helper.cc b/chrome/browser/ui/sad_tab_helper.cc
index ed0041b..2fdb9f8a 100644
--- a/chrome/browser/ui/sad_tab_helper.cc
+++ b/chrome/browser/ui/sad_tab_helper.cc
@@ -39,6 +39,11 @@
     : content::WebContentsObserver(web_contents) {
 }
 
+void SadTabHelper::ReinstallInWebView() {
+  if (sad_tab_)
+    sad_tab_->ReinstallInWebView();
+}
+
 void SadTabHelper::RenderViewReady() {
   sad_tab_.reset();
 }
diff --git a/chrome/browser/ui/sad_tab_helper.h b/chrome/browser/ui/sad_tab_helper.h
index a3461d9..5f11a82 100644
--- a/chrome/browser/ui/sad_tab_helper.h
+++ b/chrome/browser/ui/sad_tab_helper.h
@@ -22,6 +22,11 @@
 
   SadTab* sad_tab() { return sad_tab_.get(); }
 
+  // Called when the sad tab needs to be reinstalled in the WebView,
+  // for example because a tab was activated, or because a tab was
+  // dragged to a new browser window.
+  void ReinstallInWebView();
+
  private:
   friend class content::WebContentsUserData<SadTabHelper>;
 
diff --git a/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.cc b/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.cc
index 55617a9..93f336a5 100644
--- a/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.cc
+++ b/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.cc
@@ -10,8 +10,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/protocol/session_specifics.pb.h"
 #include "components/sync_sessions/open_tabs_ui_delegate.h"
 #include "components/sync_sessions/sessions_sync_manager.h"
@@ -198,25 +196,15 @@
         sync_pb::SessionSpecifics* tab_base = entity.mutable_session();
         BuildTabSpecifics(s, w, t, tab_base);
         changes.push_back(syncer::SyncChange(
-            FROM_HERE,
-            syncer::SyncChange::ACTION_ADD,
-            syncer::SyncData::CreateRemoteData(
-                tab_base->tab_node_id(),
-                entity,
-                GetTabTimestamp(s, w, t),
-                syncer::AttachmentIdList(),
-                syncer::AttachmentServiceProxyForTest::Create())));
+            FROM_HERE, syncer::SyncChange::ACTION_ADD,
+            syncer::SyncData::CreateRemoteData(tab_base->tab_node_id(), entity,
+                                               GetTabTimestamp(s, w, t))));
       }
     }
-    changes.push_back(syncer::SyncChange(
-        FROM_HERE,
-        syncer::SyncChange::ACTION_ADD,
-        syncer::SyncData::CreateRemoteData(
-            1,
-            session_entity,
-            GetSessionTimestamp(s),
-            syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create())));
+    changes.push_back(
+        syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD,
+                           syncer::SyncData::CreateRemoteData(
+                               1, session_entity, GetSessionTimestamp(s))));
   }
   manager->ProcessSyncChanges(FROM_HERE, changes);
   VerifyExport(manager);
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
index 87aaa4b..e823f5b8 100644
--- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
+++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
@@ -51,7 +51,9 @@
 #include "content/public/common/content_switches.h"
 #include "mash/common/config.h"                                   // nogncheck
 #include "mash/quick_launch/public/interfaces/constants.mojom.h"  // nogncheck
-#endif
+#else  // defined(OS_CHROMEOS)
+#include "chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.h"
+#endif  // defined(OS_CHROMEOS)
 
 namespace {
 
@@ -203,3 +205,20 @@
       create_wm_state);
 #endif  // defined(USE_AURA)
 }
+
+void ChromeBrowserMainExtraPartsViews::PostBrowserStart() {
+#if !defined(OS_CHROMEOS)
+  relaunch_notification_controller_ =
+      std::make_unique<RelaunchNotificationController>(
+          UpgradeDetector::GetInstance());
+#endif
+}
+
+void ChromeBrowserMainExtraPartsViews::PostMainMessageLoopRun() {
+#if !defined(OS_CHROMEOS)
+  // The relaunch notification controller acts on timer-based events. Tear it
+  // down explicitly here to avoid a case where such an event arrives during
+  // shutdown.
+  relaunch_notification_controller_.reset();
+#endif
+}
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h
index 36947de..11078848 100644
--- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h
+++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h
@@ -31,6 +31,10 @@
 }
 #endif
 
+#if !defined(OS_CHROMEOS)
+class RelaunchNotificationController;
+#endif
+
 class ChromeBrowserMainExtraPartsViews : public ChromeBrowserMainExtraParts {
  public:
   ChromeBrowserMainExtraPartsViews();
@@ -42,6 +46,8 @@
   void PreProfileInit() override;
   void ServiceManagerConnectionStarted(
       content::ServiceManagerConnection* connection) override;
+  void PostBrowserStart() override;
+  void PostMainMessageLoopRun() override;
 
  private:
   std::unique_ptr<views::ViewsDelegate> views_delegate_;
@@ -61,6 +67,12 @@
   std::unique_ptr<ui::InputDeviceClient> input_device_client_;
 #endif
 
+#if !defined(OS_CHROMEOS)
+  // Manages the relaunch notification prompts.
+  std::unique_ptr<RelaunchNotificationController>
+      relaunch_notification_controller_;
+#endif
+
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserMainExtraPartsViews);
 };
 
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index e6ad4b4..2f87fe4f 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -54,6 +54,7 @@
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window_state.h"
 #include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
+#include "chrome/browser/ui/sad_tab_helper.h"
 #include "chrome/browser/ui/sync/bubble_sync_promo_delegate.h"
 #include "chrome/browser/ui/tabs/tab_menu_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -94,10 +95,12 @@
 #include "chrome/browser/ui/views/translate/translate_bubble_view.h"
 #include "chrome/browser/ui/views/update_recommended_message_box.h"
 #include "chrome/browser/ui/window_sizer/window_sizer.h"
+#include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/command.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
+#include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/theme_resources.h"
 #include "components/app_modal/app_modal_dialog_queue.h"
@@ -110,6 +113,7 @@
 #include "components/sessions/core/tab_restore_service.h"
 #include "components/signin/core/browser/profile_management_switches.h"
 #include "components/translate/core/browser/language_state.h"
+#include "components/version_info/channel.h"
 #include "content/public/browser/download_manager.h"
 #include "content/public/browser/keyboard_event_processing_result.h"
 #include "content/public/browser/notification_service.h"
@@ -784,6 +788,10 @@
   if (change_tab_contents) {
     web_contents_close_handler_->ActiveTabChanged();
     contents_web_view_->SetWebContents(new_contents);
+    SadTabHelper* sad_tab_helper = SadTabHelper::FromWebContents(new_contents);
+    if (sad_tab_helper)
+      sad_tab_helper->ReinstallInWebView();
+
     // The second layout update should be no-op. It will just set the
     // DevTools WebContents.
     UpdateDevToolsForContents(new_contents, true);
@@ -829,7 +837,7 @@
 
 gfx::Size BrowserView::GetContentsSize() const {
   DCHECK(initialized_);
-  return GetTabContentsContainerView()->size();
+  return contents_web_view_->size();
 }
 
 bool BrowserView::IsMaximized() const {
@@ -1429,10 +1437,6 @@
   return toolbar_ ? toolbar_->location_bar() : nullptr;
 }
 
-views::View* BrowserView::GetTabContentsContainerView() const {
-  return contents_web_view_;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // BrowserView, TabStripModelObserver implementation:
 
@@ -1548,22 +1552,64 @@
 }
 
 base::string16 BrowserView::GetAccessibleWindowTitle() const {
+  return GetAccessibleWindowTitleForChannelAndProfile(chrome::GetChannel(),
+                                                      browser_->profile());
+}
+
+base::string16 BrowserView::GetAccessibleWindowTitleForChannelAndProfile(
+    version_info::Channel channel,
+    Profile* profile) const {
+  // Start with the tab title, which includes properties of the tab
+  // like playing audio or network error.
   const bool include_app_name = false;
   int active_index = browser_->tab_strip_model()->active_index();
-  if (active_index > -1) {
-    if (IsIncognito()) {
-      return l10n_util::GetStringFUTF16(
-          IDS_ACCESSIBLE_INCOGNITO_WINDOW_TITLE_FORMAT,
-          GetAccessibleTabLabel(include_app_name, active_index));
+  base::string16 title;
+  if (active_index > -1)
+    title = GetAccessibleTabLabel(include_app_name, active_index);
+  else
+    title = browser_->GetWindowTitleForCurrentTab(include_app_name);
+
+  // Add the name of the browser, unless this is an app window.
+  if (!browser()->is_app()) {
+    int message_id;
+    switch (channel) {
+      case version_info::Channel::CANARY:
+        message_id = IDS_ACCESSIBLE_CANARY_BROWSER_WINDOW_TITLE_FORMAT;
+        break;
+      case version_info::Channel::DEV:
+        message_id = IDS_ACCESSIBLE_DEV_BROWSER_WINDOW_TITLE_FORMAT;
+        break;
+      case version_info::Channel::BETA:
+        message_id = IDS_ACCESSIBLE_BETA_BROWSER_WINDOW_TITLE_FORMAT;
+        break;
+      default:
+        // Stable or unknown.
+        message_id = IDS_ACCESSIBLE_BROWSER_WINDOW_TITLE_FORMAT;
+        break;
     }
-    return GetAccessibleTabLabel(include_app_name, active_index);
+    title = l10n_util::GetStringFUTF16(message_id, title);
   }
-  if (IsIncognito()) {
-    return l10n_util::GetStringFUTF16(
-        IDS_ACCESSIBLE_INCOGNITO_WINDOW_TITLE_FORMAT,
-        browser_->GetWindowTitleForCurrentTab(include_app_name));
+
+  // Finally annotate with the user - add Incognito if it's an incognito
+  // window, otherwise use the avatar name.
+  if (profile->IsOffTheRecord()) {
+    title = l10n_util::GetStringFUTF16(
+        IDS_ACCESSIBLE_INCOGNITO_WINDOW_TITLE_FORMAT, title);
+  } else if (profile->GetProfileType() == Profile::REGULAR_PROFILE) {
+    base::string16 profile_name =
+        profiles::GetAvatarNameForProfile(profile->GetPath());
+
+    // GetAvatarNameForProfile will return the empty string if there's only one
+    // user account, so the profile name is only appended if someone is
+    // using multiple user accounts. That keeps it concise for most users
+    // who only use one account.
+    if (!profile_name.empty()) {
+      title = l10n_util::GetStringFUTF16(
+          IDS_ACCESSIBLE_WINDOW_TITLE_WITH_PROFILE_FORMAT, profile_name, title);
+    }
   }
-  return browser_->GetWindowTitleForCurrentTab(include_app_name);
+
+  return title;
 }
 
 base::string16 BrowserView::GetAccessibleTabLabel(bool include_app_name,
@@ -1850,7 +1896,7 @@
     panes->push_back(infobar_container_);
   if (download_shelf_.get())
     panes->push_back(download_shelf_.get());
-  panes->push_back(GetTabContentsContainerView());
+  panes->push_back(contents_web_view_);
   if (devtools_web_view_->visible())
     panes->push_back(devtools_web_view_);
 }
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index b977395..ddcf79b 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -73,6 +73,10 @@
 class Extension;
 }
 
+namespace version_info {
+enum class Channel;
+}
+
 namespace views {
 class AccessiblePaneView;
 class ExternalFocusTracker;
@@ -194,6 +198,9 @@
     return exclusive_access_bubble_.get();
   }
 
+  // Accessor for the contents WebView.
+  views::WebView* contents_web_view() { return contents_web_view_; }
+
   // Returns true if various window components are visible.
   bool IsTabStripVisible() const;
 
@@ -378,7 +385,6 @@
 
   BookmarkBarView* GetBookmarkBarView() const;
   LocationBarView* GetLocationBarView() const;
-  views::View* GetTabContentsContainerView() const;
 
   // Overridden from TabStripModelObserver:
   void TabInsertedAt(TabStripModel* tab_strip_model,
@@ -482,7 +488,6 @@
 
   // Testing interface:
   views::View* GetContentsContainerForTest() { return contents_container_; }
-  views::WebView* GetContentsWebViewForTest() { return contents_web_view_; }
   views::WebView* GetDevToolsWebViewForTest() { return devtools_web_view_; }
 
   // Called by BrowserFrame during theme changes.
@@ -497,6 +502,7 @@
   // interface to keep these two classes decoupled and testable.
   friend class BrowserViewLayoutDelegateImpl;
   FRIEND_TEST_ALL_PREFIXES(BrowserViewTest, BrowserView);
+  FRIEND_TEST_ALL_PREFIXES(BrowserViewTest, AccessibleWindowTitle);
 
   // If the browser is in immersive full screen mode, it will reveal the
   // tabstrip for a short duration. This is useful for shortcuts that perform
@@ -607,6 +613,11 @@
   bool FindCommandIdForAccelerator(const ui::Accelerator& accelerator,
                                    int* command_id) const;
 
+  // Called by GetAccessibleWindowTitle, split out to make it testable.
+  base::string16 GetAccessibleWindowTitleForChannelAndProfile(
+      version_info::Channel,
+      Profile* profile) const;
+
   // The BrowserFrame that hosts this view.
   BrowserFrame* frame_ = nullptr;
 
diff --git a/chrome/browser/ui/views/frame/browser_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_view_browsertest.cc
index 3ca1592..1253eb7 100644
--- a/chrome/browser/ui/views/frame/browser_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_browsertest.cc
@@ -38,7 +38,7 @@
   }
 
   views::WebView* contents_web_view() {
-    return browser_view()->GetContentsWebViewForTest();
+    return browser_view()->contents_web_view();
   }
 
   void OpenDevToolsWindow(bool docked) {
diff --git a/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc b/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc
index afb9a71d..ae7bc9d 100644
--- a/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc
@@ -72,7 +72,7 @@
   ASSERT_TRUE(widget2);
   const views::FocusManager* focus_manager2 = widget2->GetFocusManager();
   ASSERT_TRUE(focus_manager2);
-  EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
+  EXPECT_EQ(browser_view2->contents_web_view(),
             focus_manager2->GetFocusedView());
 
   // Switch to the 1st browser window, focus should still be on the location
@@ -86,7 +86,7 @@
   views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
   ASSERT_TRUE(widget);
   EXPECT_EQ(nullptr, widget->GetFocusManager()->GetFocusedView());
-  EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
+  EXPECT_EQ(browser_view2->contents_web_view(),
             focus_manager2->GetFocusedView());
 
   // Close the 2nd browser to avoid a DCHECK().
diff --git a/chrome/browser/ui/views/frame/browser_view_unittest.cc b/chrome/browser/ui/views/frame/browser_view_unittest.cc
index c7f8bf1..de56294 100644
--- a/chrome/browser/ui/views/frame/browser_view_unittest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_unittest.cc
@@ -17,7 +17,11 @@
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/common/url_constants.h"
+#include "chrome/grit/chromium_strings.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "components/version_info/channel.h"
 #include "ui/base/accelerators/accelerator.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/views/controls/webview/webview.h"
 
 namespace {
@@ -39,6 +43,14 @@
   return tabstrip_origin;
 }
 
+// Helper function to take a printf-style format string and substitute the
+// browser name (like "Chromium" or "Google Chrome") for %s, and return the
+// result as a base::string16.
+base::string16 SubBrowserName(const char* fmt) {
+  return base::UTF8ToUTF16(base::StringPrintf(
+      fmt, l10n_util::GetStringUTF8(IDS_PRODUCT_NAME).c_str()));
+}
+
 }  // namespace
 
 typedef TestWithBrowserView BrowserViewTest;
@@ -71,8 +83,7 @@
   ToolbarView* toolbar = browser_view()->toolbar();
   views::View* contents_container =
       browser_view()->GetContentsContainerForTest();
-  views::WebView* contents_web_view =
-      browser_view()->GetContentsWebViewForTest();
+  views::WebView* contents_web_view = browser_view()->contents_web_view();
   views::WebView* devtools_web_view =
       browser_view()->GetDevToolsWebViewForTest();
 
@@ -205,6 +216,52 @@
   BookmarkBarView::DisableAnimationsForTesting(false);
 }
 
+TEST_F(BrowserViewTest, AccessibleWindowTitle) {
+  EXPECT_EQ(SubBrowserName("Untitled - %s"),
+            browser_view()->GetAccessibleWindowTitleForChannelAndProfile(
+                version_info::Channel::STABLE, browser()->profile()));
+  EXPECT_EQ(SubBrowserName("Untitled - %s Beta"),
+            browser_view()->GetAccessibleWindowTitleForChannelAndProfile(
+                version_info::Channel::BETA, browser()->profile()));
+  EXPECT_EQ(SubBrowserName("Untitled - %s Dev"),
+            browser_view()->GetAccessibleWindowTitleForChannelAndProfile(
+                version_info::Channel::DEV, browser()->profile()));
+  EXPECT_EQ(SubBrowserName("Untitled - %s Canary"),
+            browser_view()->GetAccessibleWindowTitleForChannelAndProfile(
+                version_info::Channel::CANARY, browser()->profile()));
+
+  AddTab(browser(), GURL("about:blank"));
+  EXPECT_EQ(SubBrowserName("about:blank - %s"),
+            browser_view()->GetAccessibleWindowTitleForChannelAndProfile(
+                version_info::Channel::STABLE, browser()->profile()));
+
+  Tab* tab = browser_view()->tabstrip()->tab_at(0);
+  TabRendererData start_media;
+  start_media.alert_state = TabAlertState::AUDIO_PLAYING;
+  tab->SetData(std::move(start_media));
+  EXPECT_EQ(SubBrowserName("about:blank - Audio playing - %s"),
+            browser_view()->GetAccessibleWindowTitleForChannelAndProfile(
+                version_info::Channel::STABLE, browser()->profile()));
+
+  TabRendererData network_error;
+  network_error.network_state = TabNetworkState::kError;
+  tab->SetData(std::move(network_error));
+  EXPECT_EQ(SubBrowserName("about:blank - Network error - %s Beta"),
+            browser_view()->GetAccessibleWindowTitleForChannelAndProfile(
+                version_info::Channel::BETA, browser()->profile()));
+
+  TestingProfile* profile = profile_manager()->CreateTestingProfile("Sadia");
+  EXPECT_EQ(SubBrowserName("Sadia: about:blank - Network error - %s Dev"),
+            browser_view()->GetAccessibleWindowTitleForChannelAndProfile(
+                version_info::Channel::DEV, profile));
+
+  EXPECT_EQ(
+      SubBrowserName("about:blank - Network error - %s Canary (Incognito)"),
+      browser_view()->GetAccessibleWindowTitleForChannelAndProfile(
+          version_info::Channel::CANARY,
+          TestingProfile::Builder().BuildIncognito(profile)));
+}
+
 class BrowserViewHostedAppTest : public TestWithBrowserView {
  public:
   BrowserViewHostedAppTest() : TestWithBrowserView(Browser::TYPE_POPUP, true) {}
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
index 420a7a0..b1f1765 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_browsertest.cc
@@ -89,8 +89,7 @@
 IN_PROC_BROWSER_TEST_F(ImmersiveModeControllerAshHostedAppBrowserTest, Layout) {
   TabStrip* tabstrip = browser_view()->tabstrip();
   ToolbarView* toolbar = browser_view()->toolbar();
-  views::WebView* contents_web_view =
-      browser_view()->GetContentsWebViewForTest();
+  views::WebView* contents_web_view = browser_view()->contents_web_view();
   views::View* top_container = browser_view()->top_container();
 
   // Immersive fullscreen starts out disabled.
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
index 3d68da1..5880a552 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
@@ -72,7 +72,7 @@
   // Set whether the browser is in tab fullscreen.
   void SetTabFullscreen(bool tab_fullscreen) {
     content::WebContents* web_contents =
-        browser_view()->GetContentsWebViewForTest()->GetWebContents();
+        browser_view()->contents_web_view()->GetWebContents();
     std::unique_ptr<FullscreenNotificationObserver> waiter(
         new FullscreenNotificationObserver());
     if (tab_fullscreen) {
@@ -120,8 +120,7 @@
 
   TabStrip* tabstrip = browser_view()->tabstrip();
   ToolbarView* toolbar = browser_view()->toolbar();
-  views::WebView* contents_web_view =
-      browser_view()->GetContentsWebViewForTest();
+  views::WebView* contents_web_view = browser_view()->contents_web_view();
 
   // Immersive fullscreen starts out disabled.
   ASSERT_FALSE(browser_view()->GetWidget()->IsFullscreen());
diff --git a/chrome/browser/ui/views/relaunch_notification/OWNERS b/chrome/browser/ui/views/relaunch_notification/OWNERS
new file mode 100644
index 0000000..481f194
--- /dev/null
+++ b/chrome/browser/ui/views/relaunch_notification/OWNERS
@@ -0,0 +1 @@
+grt@chromium.org

diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.cc b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.cc
new file mode 100644
index 0000000..006e3965
--- /dev/null
+++ b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.cc
@@ -0,0 +1,192 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/common/pref_names.h"
+#include "components/prefs/pref_service.h"
+
+namespace {
+
+// A type represending the possible RelaunchNotification policy setting values.
+enum class RelaunchNotificationSetting {
+  // Indications are via the Chrome menu only -- no work for the controller.
+  kChromeMenuOnly,
+
+  // Present the relaunch recommended bubble in the last active browser window.
+  kRecommendedBubble,
+
+  // Present the relaunch required dialog in the last active browser window.
+  kRequiredDialog,
+};
+
+// Returns the policy setting, mapping out-of-range values to kChromeMenuOnly.
+RelaunchNotificationSetting ReadPreference() {
+  switch (g_browser_process->local_state()->GetInteger(
+      prefs::kRelaunchNotification)) {
+    case 1:
+      return RelaunchNotificationSetting::kRecommendedBubble;
+    case 2:
+      return RelaunchNotificationSetting::kRequiredDialog;
+  }
+  return RelaunchNotificationSetting::kChromeMenuOnly;
+}
+
+}  // namespace
+
+RelaunchNotificationController::RelaunchNotificationController(
+    UpgradeDetector* upgrade_detector)
+    : upgrade_detector_(upgrade_detector),
+      last_notification_style_(NotificationStyle::kNone),
+      last_level_(UpgradeDetector::UPGRADE_ANNOYANCE_NONE) {
+  PrefService* local_state = g_browser_process->local_state();
+  if (local_state) {
+    pref_change_registrar_.Init(local_state);
+    // base::Unretained is safe here because |this| outlives the registrar.
+    pref_change_registrar_.Add(
+        prefs::kRelaunchNotification,
+        base::BindRepeating(&RelaunchNotificationController::HandleCurrentStyle,
+                            base::Unretained(this)));
+    // Synchronize the instance with the current state of the preference.
+    HandleCurrentStyle();
+  }
+}
+
+RelaunchNotificationController::~RelaunchNotificationController() {
+  if (last_notification_style_ != NotificationStyle::kNone)
+    StopObservingUpgrades();
+}
+
+void RelaunchNotificationController::OnUpgradeRecommended() {
+  DCHECK_NE(last_notification_style_, NotificationStyle::kNone);
+  UpgradeDetector::UpgradeNotificationAnnoyanceLevel current_level =
+      upgrade_detector_->upgrade_notification_stage();
+
+  // Nothing to do if there has been no change in the level. If appropriate, a
+  // notification for this level has already been shown.
+  if (current_level == last_level_)
+    return;
+
+  // Handle the new level.
+  switch (current_level) {
+    case UpgradeDetector::UPGRADE_ANNOYANCE_NONE:
+      // While it's unexpected that the level could move back down to none, it's
+      // not a challenge to do the right thing.
+      CloseRelaunchNotification();
+      break;
+    case UpgradeDetector::UPGRADE_ANNOYANCE_LOW:
+    case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED:
+    case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH:
+    case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE:
+      ShowRelaunchNotification();
+      break;
+    case UpgradeDetector::UPGRADE_ANNOYANCE_CRITICAL:
+      // Critical notifications are handled by ToolbarView.
+      // TODO(grt): Reconsider this when implementing the relaunch required
+      // dialog. Obeying the administrator's wish to force a relaunch when
+      // the annoyance level reaches HIGH is more important than showing the
+      // critical update dialog. Perhaps handling of "critical" events should
+      // be decoupled from the "relaunch to update" events.
+      CloseRelaunchNotification();
+      break;
+  }
+
+  last_level_ = current_level;
+}
+
+void RelaunchNotificationController::HandleCurrentStyle() {
+  NotificationStyle notification_style = NotificationStyle::kNone;
+
+  switch (ReadPreference()) {
+    case RelaunchNotificationSetting::kChromeMenuOnly:
+      DCHECK_EQ(notification_style, NotificationStyle::kNone);
+      break;
+    case RelaunchNotificationSetting::kRecommendedBubble:
+      notification_style = NotificationStyle::kRecommended;
+      break;
+    case RelaunchNotificationSetting::kRequiredDialog:
+      notification_style = NotificationStyle::kRequired;
+      break;
+  }
+
+  // Nothing to do if there has been no change in the preference.
+  if (notification_style == last_notification_style_)
+    return;
+
+  // Close the bubble or dialog if either is open.
+  if (last_notification_style_ != NotificationStyle::kNone)
+    CloseRelaunchNotification();
+
+  // Reset state so that a notifications is shown anew in a new style if needed.
+  last_level_ = UpgradeDetector::UPGRADE_ANNOYANCE_NONE;
+
+  if (notification_style == NotificationStyle::kNone) {
+    // Transition away from monitoring for upgrade events back to being dormant:
+    // there is no need since AppMenuIconController takes care of updating the
+    // Chrome menu as needed.
+    StopObservingUpgrades();
+    last_notification_style_ = notification_style;
+    return;
+  }
+
+  // Transitioning away from being dormant: observe the UpgradeDetector.
+  if (last_notification_style_ == NotificationStyle::kNone)
+    StartObservingUpgrades();
+
+  last_notification_style_ = notification_style;
+
+  // Synchronize the instance with the current state of detection.
+  OnUpgradeRecommended();
+}
+
+void RelaunchNotificationController::StartObservingUpgrades() {
+  upgrade_detector_->AddObserver(this);
+}
+
+void RelaunchNotificationController::StopObservingUpgrades() {
+  upgrade_detector_->RemoveObserver(this);
+}
+
+void RelaunchNotificationController::ShowRelaunchNotification() {
+  DCHECK_NE(last_notification_style_, NotificationStyle::kNone);
+
+  if (last_notification_style_ == NotificationStyle::kRecommended)
+    ShowRelaunchRecommendedBubble();
+  else
+    ShowRelaunchRequiredDialog();
+}
+
+void RelaunchNotificationController::CloseRelaunchNotification() {
+  DCHECK_NE(last_notification_style_, NotificationStyle::kNone);
+
+  // Nothing needs to be closed if the annoyance level is none or critical.
+  if (last_level_ == UpgradeDetector::UPGRADE_ANNOYANCE_NONE ||
+      last_level_ == UpgradeDetector::UPGRADE_ANNOYANCE_CRITICAL) {
+    return;
+  }
+
+  if (last_notification_style_ == NotificationStyle::kRecommended)
+    CloseRelaunchRecommendedBubble();
+  else
+    CloseRelaunchRequiredDialog();
+}
+
+void RelaunchNotificationController::ShowRelaunchRecommendedBubble() {
+  // TODO(grt): implement.
+}
+
+void RelaunchNotificationController::CloseRelaunchRecommendedBubble() {
+  // TODO(grt): implement.
+}
+
+void RelaunchNotificationController::ShowRelaunchRequiredDialog() {
+  // TODO(grt): implement.
+}
+
+void RelaunchNotificationController::CloseRelaunchRequiredDialog() {
+  // TODO(grt): implement.
+}
diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.h b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.h
new file mode 100644
index 0000000..8189261
--- /dev/null
+++ b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.h
@@ -0,0 +1,90 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_RELAUNCH_NOTIFICATION_RELAUNCH_NOTIFICATION_CONTROLLER_H_
+#define CHROME_BROWSER_UI_VIEWS_RELAUNCH_NOTIFICATION_RELAUNCH_NOTIFICATION_CONTROLLER_H_
+
+#include "base/macros.h"
+#include "chrome/browser/upgrade_detector.h"
+#include "chrome/browser/upgrade_observer.h"
+#include "components/prefs/pref_change_registrar.h"
+
+// A class that observes changes to the browser.relaunch_notification preference
+// (which is backed by the RelaunchNotification policy setting) and annoyance
+// levels from the UpgradeDetector. An appropriate notification is shown to the
+// user based on the policy setting and current upgrade annoyance level.
+class RelaunchNotificationController : public UpgradeObserver {
+ public:
+  // |upgrade_detector| is expected to be the process-wide detector, and must
+  // outlive the controller.
+  explicit RelaunchNotificationController(UpgradeDetector* upgrade_detector);
+  ~RelaunchNotificationController() override;
+
+ protected:
+  // UpgradeObserver:
+  void OnUpgradeRecommended() override;
+
+ private:
+  enum class NotificationStyle {
+    kNone,         // No notifications are shown.
+    kRecommended,  // Relaunches are recommended.
+    kRequired,     // Relaunches are required.
+  };
+
+  // Adjusts to the current notification style as indicated by the
+  // browser.relaunch_notification Local State preference.
+  void HandleCurrentStyle();
+
+  // Bring the instance out of or back to dormant mode.
+  void StartObservingUpgrades();
+  void StopObservingUpgrades();
+
+  // Shows the proper notification based on the preference setting. Invoked as a
+  // result of a detected change in the UpgradeDetector's annoyance level.
+  void ShowRelaunchNotification();
+
+  // Closes any previously-shown notifications. This is safe to call if no
+  // notifications have been shown. Notifications may be closed by other means
+  // (e.g., by the user), so there is no expectation that a previously-shown
+  // notification is still open when this is invoked.
+  void CloseRelaunchNotification();
+
+  // The following methods, which are invoked by the controller to show or close
+  // notifications, are virtual for the sake of testing.
+
+  // Shows the relaunch recommended bubble if it is not already open.
+  virtual void ShowRelaunchRecommendedBubble();
+
+  // Closes the relaunch recommended bubble if it is still open.
+  virtual void CloseRelaunchRecommendedBubble();
+
+  // Shows the relaunch required dialog if it is not already open.
+  virtual void ShowRelaunchRequiredDialog();
+
+  // Closes the relaunch required dialog if it is still open.
+  virtual void CloseRelaunchRequiredDialog();
+
+  // The process-wide upgrade detector.
+  UpgradeDetector* const upgrade_detector_;
+
+  // Observes changes to the browser.relaunch_notification Local State pref.
+  PrefChangeRegistrar pref_change_registrar_;
+
+  // The last observed notification style. When kNone, the controller is
+  // said to be "dormant" as there is no work for it to do aside from watch for
+  // changes to browser.relaunch_notification. When any other value, the
+  // controller is observing the UpgradeDetector to detect when to show a
+  // notification.
+  NotificationStyle last_notification_style_;
+
+  // The last observed annoyance level for which a notification was shown. This
+  // member is unconditionally UPGRADE_ANNOYANCE_NONE when the controller is
+  // dormant (browser.relaunch_notification is 0). It is any other value only
+  // when a notification has been shown.
+  UpgradeDetector::UpgradeNotificationAnnoyanceLevel last_level_;
+
+  DISALLOW_COPY_AND_ASSIGN(RelaunchNotificationController);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_RELAUNCH_NOTIFICATION_RELAUNCH_NOTIFICATION_CONTROLLER_H_
diff --git a/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_unittest.cc b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_unittest.cc
new file mode 100644
index 0000000..b12a993
--- /dev/null
+++ b/chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller_unittest.cc
@@ -0,0 +1,316 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/relaunch_notification/relaunch_notification_controller.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/values.h"
+#include "chrome/browser/upgrade_detector.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/scoped_testing_local_state.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+// A delegate interface for handling the actions taken by the controller.
+class ControllerDelegate {
+ public:
+  virtual ~ControllerDelegate() = default;
+  virtual void ShowRelaunchRecommendedBubble() = 0;
+  virtual void CloseRelaunchRecommendedBubble() = 0;
+  virtual void ShowRelaunchRequiredDialog() = 0;
+  virtual void CloseRelaunchRequiredDialog() = 0;
+
+ protected:
+  ControllerDelegate() = default;
+};
+
+// A fake controller that asks a delegate to do work.
+class FakeRelaunchNotificationController
+    : public RelaunchNotificationController {
+ public:
+  FakeRelaunchNotificationController(UpgradeDetector* upgrade_detector,
+                                     ControllerDelegate* delegate)
+      : RelaunchNotificationController(upgrade_detector), delegate_(delegate) {}
+
+ private:
+  void ShowRelaunchRecommendedBubble() override {
+    delegate_->ShowRelaunchRecommendedBubble();
+  }
+
+  void CloseRelaunchRecommendedBubble() override {
+    delegate_->CloseRelaunchRecommendedBubble();
+  }
+
+  void ShowRelaunchRequiredDialog() override {
+    delegate_->ShowRelaunchRequiredDialog();
+  }
+
+  void CloseRelaunchRequiredDialog() override {
+    delegate_->CloseRelaunchRequiredDialog();
+  }
+
+  ControllerDelegate* delegate_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeRelaunchNotificationController);
+};
+
+// A mock delegate for testing.
+class MockControllerDelegate : public ControllerDelegate {
+ public:
+  MOCK_METHOD0(ShowRelaunchRecommendedBubble, void());
+  MOCK_METHOD0(CloseRelaunchRecommendedBubble, void());
+  MOCK_METHOD0(ShowRelaunchRequiredDialog, void());
+  MOCK_METHOD0(CloseRelaunchRequiredDialog, void());
+};
+
+// A fake UpgradeDetector.
+class FakeUpgradeDetector : public UpgradeDetector {
+ public:
+  FakeUpgradeDetector() = default;
+
+  // Sets the annoyance level to |level| and broadcasts the change to all
+  // observers.
+  void BroadcastLevelChange(UpgradeNotificationAnnoyanceLevel level) {
+    set_upgrade_notification_stage(level);
+    NotifyUpgrade();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(FakeUpgradeDetector);
+};
+
+}  // namespace
+
+// A test harness that provides facilities for manipulating the relaunch
+// notification policy setting and for broadcasting upgrade notifications.
+class RelaunchNotificationControllerTest : public ::testing::Test {
+ protected:
+  RelaunchNotificationControllerTest()
+      : scoped_local_state_(TestingBrowserProcess::GetGlobal()) {}
+  UpgradeDetector* upgrade_detector() { return &upgrade_detector_; }
+  FakeUpgradeDetector& fake_upgrade_detector() { return upgrade_detector_; }
+
+  // Sets the browser.relaunch_notification preference in Local State to
+  // |value|.
+  void SetNotificationPref(int value) {
+    scoped_local_state_.Get()->SetManagedPref(
+        prefs::kRelaunchNotification, std::make_unique<base::Value>(value));
+  }
+
+ private:
+  ScopedTestingLocalState scoped_local_state_;
+  FakeUpgradeDetector upgrade_detector_;
+
+  DISALLOW_COPY_AND_ASSIGN(RelaunchNotificationControllerTest);
+};
+
+TEST_F(RelaunchNotificationControllerTest, CreateDestroy) {
+  ::testing::StrictMock<MockControllerDelegate> mock_controller_delegate;
+
+  FakeRelaunchNotificationController controller(upgrade_detector(),
+                                                &mock_controller_delegate);
+}
+
+// Without the browser.relaunch_notification preference set, the controller
+// should not be observing the UpgradeDetector, and should therefore never
+// attempt to show any notifications.
+TEST_F(RelaunchNotificationControllerTest, PolicyUnset) {
+  ::testing::StrictMock<MockControllerDelegate> mock_controller_delegate;
+
+  FakeRelaunchNotificationController controller(upgrade_detector(),
+                                                &mock_controller_delegate);
+
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_LOW);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_HIGH);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_NONE);
+}
+
+// With the browser.relaunch_notification preference set to 1, the controller
+// should be observing the UpgradeDetector and should show "Requested"
+// notifications on each level change.
+TEST_F(RelaunchNotificationControllerTest, RecommendedByPolicy) {
+  SetNotificationPref(1);
+  ::testing::StrictMock<MockControllerDelegate> mock_controller_delegate;
+
+  FakeRelaunchNotificationController controller(upgrade_detector(),
+                                                &mock_controller_delegate);
+
+  // Nothing shown if the level is broadcast at NONE.
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_NONE);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  // Show for each level change, but not for repeat notifications.
+  EXPECT_CALL(mock_controller_delegate, ShowRelaunchRecommendedBubble());
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_LOW);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_LOW);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  EXPECT_CALL(mock_controller_delegate, ShowRelaunchRecommendedBubble());
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  EXPECT_CALL(mock_controller_delegate, ShowRelaunchRecommendedBubble());
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_HIGH);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_HIGH);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  EXPECT_CALL(mock_controller_delegate, ShowRelaunchRecommendedBubble());
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  EXPECT_CALL(mock_controller_delegate, ShowRelaunchRecommendedBubble());
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_HIGH);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_HIGH);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  // And closed if the level drops back to none.
+  EXPECT_CALL(mock_controller_delegate, CloseRelaunchRecommendedBubble());
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_NONE);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_NONE);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+}
+
+// With the browser.relaunch_notification preference set to 2, the controller
+// should be observing the UpgradeDetector and should show "Required"
+// notifications on each level change.
+TEST_F(RelaunchNotificationControllerTest, RequiredByPolicy) {
+  SetNotificationPref(2);
+  ::testing::StrictMock<MockControllerDelegate> mock_controller_delegate;
+
+  FakeRelaunchNotificationController controller(upgrade_detector(),
+                                                &mock_controller_delegate);
+
+  // Nothing shown if the level is broadcast at NONE.
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_NONE);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  // Show for each level change, but not for repeat notifications.
+  EXPECT_CALL(mock_controller_delegate, ShowRelaunchRequiredDialog());
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_LOW);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_LOW);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  EXPECT_CALL(mock_controller_delegate, ShowRelaunchRequiredDialog());
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  EXPECT_CALL(mock_controller_delegate, ShowRelaunchRequiredDialog());
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_HIGH);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_HIGH);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  EXPECT_CALL(mock_controller_delegate, ShowRelaunchRequiredDialog());
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  EXPECT_CALL(mock_controller_delegate, ShowRelaunchRequiredDialog());
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_HIGH);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_HIGH);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  // And closed if the level drops back to none.
+  EXPECT_CALL(mock_controller_delegate, CloseRelaunchRequiredDialog());
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_NONE);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_NONE);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+}
+
+// Flipping the policy should have no effect when at level NONE
+TEST_F(RelaunchNotificationControllerTest, PolicyChangesNoUpgrade) {
+  ::testing::StrictMock<MockControllerDelegate> mock_controller_delegate;
+
+  FakeRelaunchNotificationController controller(upgrade_detector(),
+                                                &mock_controller_delegate);
+
+  SetNotificationPref(1);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  SetNotificationPref(2);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  SetNotificationPref(3);  // Bogus value!
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  SetNotificationPref(0);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+}
+
+// Policy changes at an elevated level should show the appropriate notification.
+TEST_F(RelaunchNotificationControllerTest, PolicyChangesWithUpgrade) {
+  ::testing::StrictMock<MockControllerDelegate> mock_controller_delegate;
+
+  FakeRelaunchNotificationController controller(upgrade_detector(),
+                                                &mock_controller_delegate);
+
+  fake_upgrade_detector().BroadcastLevelChange(
+      UpgradeDetector::UPGRADE_ANNOYANCE_LOW);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  EXPECT_CALL(mock_controller_delegate, ShowRelaunchRecommendedBubble());
+  SetNotificationPref(1);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  EXPECT_CALL(mock_controller_delegate, CloseRelaunchRecommendedBubble());
+  EXPECT_CALL(mock_controller_delegate, ShowRelaunchRequiredDialog());
+  SetNotificationPref(2);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+
+  EXPECT_CALL(mock_controller_delegate, CloseRelaunchRequiredDialog());
+  SetNotificationPref(0);
+  ::testing::Mock::VerifyAndClear(&mock_controller_delegate);
+}
diff --git a/chrome/browser/ui/views/sad_tab_view.cc b/chrome/browser/ui/views/sad_tab_view.cc
index ccfb5436..9b9ebcf 100644
--- a/chrome/browser/ui/views/sad_tab_view.cc
+++ b/chrome/browser/ui/views/sad_tab_view.cc
@@ -10,22 +10,27 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/app/vector_icons/vector_icons.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/harmony/bulleted_label_list_view.h"
 #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/harmony/chrome_typography.h"
 #include "chrome/browser/ui/views_mode_controller.h"
 #include "content/public/browser/web_contents.h"
+#include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/native_theme/common_theme.h"
 #include "ui/native_theme/native_theme.h"
+#include "ui/views/accessibility/view_accessibility.h"
 #include "ui/views/background.h"
 #include "ui/views/controls/button/md_text_button.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/link.h"
+#include "ui/views/controls/webview/webview.h"
 #include "ui/views/layout/grid_layout.h"
 #include "ui/views/widget/widget.h"
 
@@ -48,8 +53,16 @@
 
 }  // namespace
 
+// static
+const char SadTabView::kViewClassName[] = "SadTabView";
+
 SadTabView::SadTabView(content::WebContents* web_contents, SadTabKind kind)
     : SadTab(web_contents, kind) {
+  // This view gets inserted as a child of a WebView, but we don't want the
+  // WebView to delete us if the WebView gets deleted before the SadTabHelper
+  // does.
+  set_owned_by_client();
+
   SetBackground(views::CreateThemedSolidBackground(
       this, ui::NativeTheme::kColorId_DialogBackground));
 
@@ -120,29 +133,46 @@
   layout->AddPaddingRow(2, provider->GetDistanceMetric(
                                views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
 
-  views::Widget::InitParams sad_tab_params(
-      views::Widget::InitParams::TYPE_CONTROL);
+  AttachToWebView();
 
-  // It is not possible to create a native_widget_win that has no parent in
-  // and later re-parent it.
-  // TODO(avi): This is a cheat. Can this be made cleaner?
-  sad_tab_params.parent = web_contents->GetNativeView();
-
-  set_owned_by_client();
-
-  views::Widget* sad_tab = new views::Widget;
-  sad_tab->Init(sad_tab_params);
-  sad_tab->SetContentsView(this);
-
-  views::Widget::ReparentNativeView(sad_tab->GetNativeView(),
-                                    web_contents->GetNativeView());
-  gfx::Rect bounds = web_contents->GetContainerBounds();
-  sad_tab->SetBounds(gfx::Rect(bounds.size()));
+  // Make the accessibility role of this view an alert dialog, and
+  // put focus on the action button. This causes screen readers to
+  // immediately announce the text of this view.
+  GetViewAccessibility().OverrideRole(ax::mojom::Role::kDialog);
+  action_button_->RequestFocus();
 }
 
 SadTabView::~SadTabView() {
-  if (GetWidget())
-    GetWidget()->Close();
+  if (owner_)
+    owner_->SetCrashedOverlayView(nullptr);
+}
+
+void SadTabView::ReinstallInWebView() {
+  if (owner_) {
+    owner_->SetCrashedOverlayView(nullptr);
+    owner_ = nullptr;
+  }
+  AttachToWebView();
+}
+
+void SadTabView::AttachToWebView() {
+  Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
+  // This can be null during prefetch.
+  if (!browser)
+    return;
+
+  // In unit tests, browser->window() might not be a real BrowserView.
+  if (!browser->window()->GetNativeWindow())
+    return;
+
+  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
+  DCHECK(browser_view);
+
+  views::WebView* web_view = browser_view->contents_web_view();
+  if (web_view->GetWebContents() == web_contents()) {
+    owner_ = web_view;
+    owner_->SetCrashedOverlayView(this);
+  }
 }
 
 void SadTabView::LinkClicked(views::Link* source, int event_flags) {
@@ -167,6 +197,10 @@
   View::Layout();
 }
 
+const char* SadTabView::GetClassName() const {
+  return kViewClassName;
+}
+
 void SadTabView::OnPaint(gfx::Canvas* canvas) {
   if (!painted_) {
     RecordFirstPaint();
@@ -175,6 +209,10 @@
   View::OnPaint(canvas);
 }
 
+void SadTabView::RemovedFromWidget() {
+  owner_ = nullptr;
+}
+
 SadTab* SadTab::Create(content::WebContents* web_contents,
                        SadTabKind kind) {
 #if defined(OS_MACOSX)
diff --git a/chrome/browser/ui/views/sad_tab_view.h b/chrome/browser/ui/views/sad_tab_view.h
index 7a398eb..54c2794e 100644
--- a/chrome/browser/ui/views/sad_tab_view.h
+++ b/chrome/browser/ui/views/sad_tab_view.h
@@ -19,6 +19,11 @@
 namespace views {
 class Label;
 class LabelButton;
+class WebView;
+}  // namespace views
+
+namespace test {
+class SadTabViewTestApi;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -34,11 +39,17 @@
                    public views::LinkListener,
                    public views::ButtonListener {
  public:
+  static const char kViewClassName[];
+
   SadTabView(content::WebContents* web_contents, SadTabKind kind);
   ~SadTabView() override;
 
+  // Overridden from SadTab:
+  void ReinstallInWebView() override;
+
   // Overridden from views::View:
   void Layout() override;
+  const char* GetClassName() const override;
 
   // Overridden from views::LinkListener:
   void LinkClicked(views::Link* source, int event_flags) override;
@@ -49,14 +60,22 @@
  protected:
   // Overridden from views::View:
   void OnPaint(gfx::Canvas* canvas) override;
+  void RemovedFromWidget() override;
 
  private:
+  friend class test::SadTabViewTestApi;
+
+  // Set this View as the crashed overlay view for the WebView associated
+  // with this object's WebContents.
+  void AttachToWebView();
+
   bool painted_ = false;
   views::Label* message_;
   std::vector<views::Label*> bullet_labels_;
   views::Link* help_link_;
   views::LabelButton* action_button_;
   views::Label* title_;
+  views::WebView* owner_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(SadTabView);
 };
diff --git a/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc b/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc
new file mode 100644
index 0000000..71e9a1b
--- /dev/null
+++ b/chrome/browser/ui/views/sad_tab_view_interactive_uitest.cc
@@ -0,0 +1,204 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/sad_tab_view.h"
+
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/sad_tab.h"
+#include "chrome/browser/ui/sad_tab_helper.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/interactive_test_utils.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/common/result_codes.h"
+#include "content/public/test/browser_test_utils.h"
+#include "ui/views/controls/button/blue_button.h"
+#include "ui/views/controls/button/label_button.h"
+#include "ui/views/widget/widget.h"
+
+namespace test {
+
+// A friend of SadTabView that's able to call RecordFirstPaint.
+class SadTabViewTestApi {
+ public:
+  static void RecordFirstPaintForTesting(SadTabView* sad_tab_view) {
+    if (!sad_tab_view->painted_) {
+      sad_tab_view->RecordFirstPaint();
+      sad_tab_view->painted_ = true;
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SadTabViewTestApi);
+};
+
+}  // namespace test
+
+class SadTabViewInteractiveUITest : public InProcessBrowserTest {
+ public:
+  SadTabViewInteractiveUITest() {}
+
+ protected:
+  void KillRendererForActiveWebContentsSync() {
+    content::WebContents* web_contents =
+        browser()->tab_strip_model()->GetActiveWebContents();
+    content::RenderProcessHost* process =
+        web_contents->GetMainFrame()->GetProcess();
+    content::RenderProcessHostWatcher crash_observer(
+        process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+    process->Shutdown(content::RESULT_CODE_KILLED, false);
+    crash_observer.Wait();
+  }
+
+  void PressTab() {
+    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_TAB, false,
+                                                false, false, false));
+  }
+
+  void PressShiftTab() {
+    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_TAB, false,
+                                                true, false, false));
+  }
+
+  void PressSpacebar() {
+    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_SPACE,
+                                                false, false, false, false));
+  }
+
+  views::FocusManager* GetFocusManager() {
+    BrowserView* browser_view =
+        BrowserView::GetBrowserViewForBrowser(browser());
+    return browser_view->GetWidget()->GetFocusManager();
+  }
+
+  views::View* GetFocusedView() { return GetFocusManager()->GetFocusedView(); }
+
+  const char* ActionButtonClassName() {
+#if defined(OS_CHROMEOS)
+    return views::BlueButton::kViewClassName;
+#else
+    return views::LabelButton::kViewClassName;
+#endif
+  }
+
+  bool IsFocusedViewInsideViewClass(const char* view_class) {
+    views::View* view = GetFocusedView();
+    while (view) {
+      if (view->GetClassName() == view_class)
+        return true;
+      view = view->parent();
+    }
+    return false;
+  }
+
+  bool IsFocusedViewInsideSadTab() {
+    return IsFocusedViewInsideViewClass(SadTabView::kViewClassName);
+  }
+
+  bool IsFocusedViewInsideBrowserToolbar() {
+    return IsFocusedViewInsideViewClass(ToolbarView::kViewClassName);
+  }
+
+  bool IsFocusedViewOnActionButtonInSadTab() {
+    return IsFocusedViewInsideViewClass(SadTabView::kViewClassName) &&
+           IsFocusedViewInsideViewClass(ActionButtonClassName());
+  }
+
+  void ClickOnActionButtonInSadTab() {
+    TabStripModel* tab_strip_model = browser()->tab_strip_model();
+    content::WebContents* web_contents =
+        tab_strip_model->GetActiveWebContents();
+    while (!IsFocusedViewOnActionButtonInSadTab())
+      PressTab();
+
+    // SadTab has a DCHECK that it's been painted at least once
+    // before the action button can be pressed, bypass that.
+    SadTabHelper* sad_tab_helper = SadTabHelper::FromWebContents(web_contents);
+    SadTabView* sad_tab_view =
+        static_cast<SadTabView*>(sad_tab_helper->sad_tab());
+    test::SadTabViewTestApi::RecordFirstPaintForTesting(sad_tab_view);
+    PressSpacebar();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SadTabViewInteractiveUITest);
+};
+
+IN_PROC_BROWSER_TEST_F(SadTabViewInteractiveUITest,
+                       SadTabKeyboardAccessibility) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL url(embedded_test_server()->GetURL("/links.html"));
+  ui_test_utils::NavigateToURL(browser(), url);
+
+  // Start with focus in the location bar.
+  chrome::FocusLocationBar(browser());
+  ASSERT_FALSE(IsFocusedViewInsideSadTab());
+  ASSERT_TRUE(IsFocusedViewInsideBrowserToolbar());
+
+  // Kill the renderer process, resulting in a sad tab.
+  KillRendererForActiveWebContentsSync();
+
+  // Focus should now be on a label button inside the sad tab.
+  ASSERT_STREQ(GetFocusedView()->GetClassName(), ActionButtonClassName());
+  ASSERT_TRUE(IsFocusedViewInsideSadTab());
+  ASSERT_FALSE(IsFocusedViewInsideBrowserToolbar());
+
+  // Pressing the Tab key should cycle focus back to the toolbar.
+  PressTab();
+  ASSERT_FALSE(IsFocusedViewInsideSadTab());
+  ASSERT_TRUE(IsFocusedViewInsideBrowserToolbar());
+
+  // Keep pressing the Tab key and make sure we make it back to the sad tab.
+  while (!IsFocusedViewInsideSadTab())
+    PressTab();
+  ASSERT_FALSE(IsFocusedViewInsideBrowserToolbar());
+
+  // Press Shift-Tab and ensure we end up back in the toolbar.
+  PressShiftTab();
+  ASSERT_FALSE(IsFocusedViewInsideSadTab());
+  ASSERT_TRUE(IsFocusedViewInsideBrowserToolbar());
+}
+
+IN_PROC_BROWSER_TEST_F(SadTabViewInteractiveUITest, ReloadMultipleSadTabs) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL url(embedded_test_server()->GetURL("/links.html"));
+  ui_test_utils::NavigateToURL(browser(), url);
+
+  // Kill the renderer process, resulting in a sad tab.
+  KillRendererForActiveWebContentsSync();
+
+  // Create a second tab, navigate to a second url.
+  chrome::NewTab(browser());
+  GURL url2(embedded_test_server()->GetURL("/simple.html"));
+  ui_test_utils::NavigateToURL(browser(), url2);
+
+  // Kill that one too.
+  KillRendererForActiveWebContentsSync();
+
+  // Switch back to the first tab.
+  TabStripModel* tab_strip_model = browser()->tab_strip_model();
+  EXPECT_EQ(1, tab_strip_model->active_index());
+  tab_strip_model->ActivateTabAt(0, true);
+  EXPECT_EQ(0, tab_strip_model->active_index());
+  content::WebContents* web_contents = tab_strip_model->GetActiveWebContents();
+  EXPECT_TRUE(web_contents->IsCrashed());
+
+  ClickOnActionButtonInSadTab();
+
+  // Ensure the first WebContents reloads.
+  content::WaitForLoadStop(web_contents);
+  EXPECT_FALSE(web_contents->IsCrashed());
+
+  // Switch to the second tab, reload it too.
+  tab_strip_model->ActivateTabAt(1, true);
+  web_contents = tab_strip_model->GetActiveWebContents();
+  EXPECT_TRUE(web_contents->IsCrashed());
+  ClickOnActionButtonInSadTab();
+  content::WaitForLoadStop(web_contents);
+  EXPECT_FALSE(web_contents->IsCrashed());
+}
diff --git a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
index 914b32e3..3ee3094 100644
--- a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
+++ b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
@@ -97,15 +97,6 @@
                 params));
 }
 
-void ChromeWebContentsViewDelegateViews::SizeChanged(const gfx::Size& size) {
-  SadTabHelper* sad_tab_helper = SadTabHelper::FromWebContents(web_contents_);
-  if (!sad_tab_helper)
-    return;
-  SadTabView* sad_tab = static_cast<SadTabView*>(sad_tab_helper->sad_tab());
-  if (sad_tab)
-    sad_tab->GetWidget()->SetBounds(gfx::Rect(size));
-}
-
 content::WebContentsViewDelegate* CreateWebContentsViewDelegate(
     content::WebContents* web_contents) {
   return new ChromeWebContentsViewDelegateViews(web_contents);
diff --git a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h
index 1a9e68f..684850c 100644
--- a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h
+++ b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.h
@@ -41,7 +41,6 @@
   bool TakeFocus(bool reverse) override;
   void ShowContextMenu(content::RenderFrameHost* render_frame_host,
                        const content::ContextMenuParams& params) override;
-  void SizeChanged(const gfx::Size& size) override;
 
   // Overridden from ContextMenuDelegate.
   std::unique_ptr<RenderViewContextMenuBase> BuildMenu(
diff --git a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.mm b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.mm
index 78ef61b..b8b3e22 100644
--- a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.mm
+++ b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_mac.mm
@@ -41,15 +41,6 @@
   return focus_helper_->TakeFocus(reverse);
 }
 
-void ChromeWebContentsViewDelegateViewsMac::SizeChanged(const gfx::Size& size) {
-  SadTabHelper* sad_tab_helper = SadTabHelper::FromWebContents(web_contents());
-  if (!sad_tab_helper)
-    return;
-  SadTabView* sad_tab = static_cast<SadTabView*>(sad_tab_helper->sad_tab());
-  if (sad_tab)
-    sad_tab->GetWidget()->SetBounds(gfx::Rect(size));
-}
-
 #if BUILDFLAG(MAC_VIEWS_BROWSER)
 
 content::WebContentsViewDelegate* CreateWebContentsViewDelegate(
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
index e3ce7c2..2d0c9af 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/sad_tab_helper.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
@@ -915,6 +916,12 @@
         add_types |= TabStripModel::ADD_PINNED;
       GetModel(attached_tabstrip_)->InsertWebContentsAt(
           index + i, drag_data_[i].contents, add_types);
+
+      // If a sad tab is showing, the SadTabView needs to be updated.
+      SadTabHelper* sad_tab_helper =
+          SadTabHelper::FromWebContents(drag_data_[i].contents);
+      if (sad_tab_helper)
+        sad_tab_helper->ReinstallInWebView();
     }
 
     tabs = GetTabsMatchingDraggedContents(attached_tabstrip_);
@@ -973,7 +980,6 @@
     // Hide the tab so that the user doesn't see it animate closed.
     drag_data_[i].attached_tab->SetVisible(false);
     drag_data_[i].attached_tab->set_detached();
-
     attached_model->DetachWebContentsAt(index);
 
     // Detaching may end up deleting the tab, drop references to it.
diff --git a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc
index 3b6e2b9..a5cf856 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.cc
@@ -95,6 +95,10 @@
   return delegate_->GetHeadingText();
 }
 
+bool ToolbarActionsBarBubbleViews::ShouldShowCloseButton() const {
+  return true;
+}
+
 bool ToolbarActionsBarBubbleViews::Cancel() {
   DCHECK(!delegate_notified_of_close_);
   delegate_notified_of_close_ = true;
@@ -131,8 +135,9 @@
   views::Label* content_label =
       new views::Label(delegate_->GetBodyText(anchored_to_action_));
   content_label->SetMultiLine(true);
-  int width = views::Widget::GetLocalizedContentsWidth(
-        IDS_EXTENSION_TOOLBAR_REDESIGN_NOTIFICATION_BUBBLE_WIDTH_CHARS);
+  int width = provider->GetDistanceMetric(
+                  ChromeDistanceMetric::DISTANCE_BUBBLE_PREFERRED_WIDTH) -
+              margins().width();
   content_label->SizeToFit(width);
   content_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   AddChildView(content_label);
diff --git a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.h b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.h
index 48cf753..409fcd3 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.h
+++ b/chrome/browser/ui/views/toolbar/toolbar_actions_bar_bubble_views.h
@@ -42,6 +42,7 @@
 
   // views::BubbleDialogDelegateView:
   base::string16 GetWindowTitle() const override;
+  bool ShouldShowCloseButton() const override;
   views::View* CreateExtraView() override;
   bool Cancel() override;
   bool Accept() override;
diff --git a/chrome/browser/ui/webui/signin/signin_create_profile_handler_unittest.cc b/chrome/browser/ui/webui/signin/signin_create_profile_handler_unittest.cc
index f9337a1..aa23be5 100644
--- a/chrome/browser/ui/webui/signin/signin_create_profile_handler_unittest.cc
+++ b/chrome/browser/ui/webui/signin/signin_create_profile_handler_unittest.cc
@@ -22,7 +22,6 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/signin/core/browser/fake_auth_status_provider.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_data.h"
 #include "components/sync/model/sync_error_factory_mock.h"
@@ -73,12 +72,7 @@
   specifics.mutable_managed_user()->set_acknowledged(true);
   specifics.mutable_managed_user()->set_chrome_avatar(chrome_avatar);
 
-  return syncer::SyncData::CreateRemoteData(
-      1,
-      specifics,
-      base::Time(),
-      syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create());
+  return syncer::SyncData::CreateRemoteData(1, specifics, base::Time());
 }
 #endif
 
diff --git a/chrome/browser/ui/webui/signin/signin_supervised_user_import_handler_unittest.cc b/chrome/browser/ui/webui/signin/signin_supervised_user_import_handler_unittest.cc
index 13bd890f..cc615490d 100644
--- a/chrome/browser/ui/webui/signin/signin_supervised_user_import_handler_unittest.cc
+++ b/chrome/browser/ui/webui/signin/signin_supervised_user_import_handler_unittest.cc
@@ -17,8 +17,6 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/signin/core/browser/fake_auth_status_provider.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_error_factory_mock.h"
 #include "components/sync/protocol/sync.pb.h"
@@ -48,12 +46,7 @@
   specifics.mutable_managed_user()->set_acknowledged(true);
   specifics.mutable_managed_user()->set_chrome_avatar(chrome_avatar);
 
-  return syncer::SyncData::CreateRemoteData(
-      1,
-      specifics,
-      base::Time(),
-      syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create());
+  return syncer::SyncData::CreateRemoteData(1, specifics, base::Time());
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/webui/site_settings_helper.cc b/chrome/browser/ui/webui/site_settings_helper.cc
index 6c210595..36b5ef2 100644
--- a/chrome/browser/ui/webui/site_settings_helper.cc
+++ b/chrome/browser/ui/webui/site_settings_helper.cc
@@ -69,7 +69,7 @@
     {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, "ppapi-broker"},
     {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, "multiple-automatic-downloads"},
     {CONTENT_SETTINGS_TYPE_MIDI_SYSEX, "midi-sysex"},
-    {CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, "protectedContent"},
+    {CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, "protected-content"},
     {CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC, "background-sync"},
     {CONTENT_SETTINGS_TYPE_ADS, "ads"},
     {CONTENT_SETTINGS_TYPE_SOUND, "sound"},
diff --git a/chrome/browser/unload_browsertest.cc b/chrome/browser/unload_browsertest.cc
index 5181622..7bdb11db0 100644
--- a/chrome/browser/unload_browsertest.cc
+++ b/chrome/browser/unload_browsertest.cc
@@ -887,7 +887,8 @@
 }
 
 // Times out on Windows and Linux.
-#if defined(OS_WIN) || defined(OS_LINUX)
+// Crashes on Mac (http://crbug/810294).
+#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX)
 #define MAYBE_WindowCloseAfterBeforeUnloadCrash \
     DISABLED_WindowCloseAfterBeforeUnloadCrash
 #else
diff --git a/chrome/browser/upgrade_detector_impl.h b/chrome/browser/upgrade_detector_impl.h
index af6f7b6..08abc02 100644
--- a/chrome/browser/upgrade_detector_impl.h
+++ b/chrome/browser/upgrade_detector_impl.h
@@ -21,6 +21,7 @@
 class TaskRunner;
 }
 
+// This class contains the non-CrOS desktop implementation of the detector.
 class UpgradeDetectorImpl : public UpgradeDetector,
                             public variations::VariationsService::Observer {
  public:
diff --git a/chrome/browser/usb/usb_tab_helper.cc b/chrome/browser/usb/usb_tab_helper.cc
index 577d44f7..ff0216e 100644
--- a/chrome/browser/usb/usb_tab_helper.cc
+++ b/chrome/browser/usb/usb_tab_helper.cc
@@ -14,7 +14,7 @@
 #include "content/public/common/content_features.h"
 #include "device/usb/mojo/device_manager_impl.h"
 #include "mojo/public/cpp/bindings/message.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 
 #if defined(OS_ANDROID)
 #include "chrome/browser/android/usb/web_usb_chooser_service_android.h"
@@ -170,7 +170,7 @@
   DCHECK(WebContents::FromRenderFrameHost(render_frame_host) == web_contents());
   if (base::FeatureList::IsEnabled(features::kFeaturePolicy)) {
     return render_frame_host->IsFeatureEnabled(
-        blink::FeaturePolicyFeature::kUsb);
+        blink::mojom::FeaturePolicyFeature::kUsb);
   }
   return web_contents()->GetMainFrame() == render_frame_host;
 }
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index e2c9556..1638872 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -706,6 +706,22 @@
       "63ED55E43214C211F82122ED56407FF1A807F2A3",  // Media Router Dev
       "226CF815E39A363090A1E547D53063472B8279FA"   // Media Router Release
     ]
+  },
+  {
+    "channel": "stable",
+    "extension_types": ["platform_app"],
+    "platforms": ["chromeos"],
+    "session_types": ["kiosk"],
+    "whitelist": [
+      "E703483CEF33DEC18B4B6DD84B5C776FB9182BDB",  // https://crbug.com/803362
+      "A3BC37E2148AC4E99BE4B16AF9D42DD1E592BBBE",  // https://crbug.com/803362
+      "1C93BD3CF875F4A73C0B2A163BB8FBDA8B8B3D80",  // https://crbug.com/803362
+      "307E96539209F95A1A8740C713E6998A73657D96",  // https://crbug.com/803362
+      "4F25792AF1AA7483936DE29C07806F203C7170A0",  // https://crbug.com/803362
+      "BD8781D757D830FC2E85470A1B6E8A718B7EE0D9",  // https://crbug.com/803362
+      "4AC2B6C63C6480D150DFDA13E4A5956EB1D0DDBB",  // https://crbug.com/803362
+      "81986D4F846CEDDDB962643FA501D1780DD441BB"   // https://crbug.com/803362
+    ]
   }],
   "signedInDevices": {
     "channel": "dev",
diff --git a/chrome/common/extensions/docs/static/images/packaging/download_crx_blur.png b/chrome/common/extensions/docs/static/images/packaging/download_crx_blur.png
new file mode 100644
index 0000000..58d35be
--- /dev/null
+++ b/chrome/common/extensions/docs/static/images/packaging/download_crx_blur.png
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/packaging/packaging_devmode.png b/chrome/common/extensions/docs/static/images/packaging/packaging_devmode.png
new file mode 100644
index 0000000..85c53a3
--- /dev/null
+++ b/chrome/common/extensions/docs/static/images/packaging/packaging_devmode.png
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/packaging/packaging_files.png b/chrome/common/extensions/docs/static/images/packaging/packaging_files.png
new file mode 100644
index 0000000..a13f3cd
--- /dev/null
+++ b/chrome/common/extensions/docs/static/images/packaging/packaging_files.png
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/packaging/packaging_root.png b/chrome/common/extensions/docs/static/images/packaging/packaging_root.png
new file mode 100644
index 0000000..837b565e
--- /dev/null
+++ b/chrome/common/extensions/docs/static/images/packaging/packaging_root.png
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/packaging/packaging_update_now.png b/chrome/common/extensions/docs/static/images/packaging/packaging_update_now.png
new file mode 100644
index 0000000..df8d7024
--- /dev/null
+++ b/chrome/common/extensions/docs/static/images/packaging/packaging_update_now.png
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/packaging/packaging_updated.png b/chrome/common/extensions/docs/static/images/packaging/packaging_updated.png
new file mode 100644
index 0000000..6e04153
--- /dev/null
+++ b/chrome/common/extensions/docs/static/images/packaging/packaging_updated.png
Binary files differ
diff --git a/chrome/common/extensions/docs/static/images/packaging/packaging_updating.png b/chrome/common/extensions/docs/static/images/packaging/packaging_updating.png
new file mode 100644
index 0000000..96b00723
--- /dev/null
+++ b/chrome/common/extensions/docs/static/images/packaging/packaging_updating.png
Binary files differ
diff --git a/chrome/common/extensions/docs/templates/articles/hosting.html b/chrome/common/extensions/docs/templates/articles/hosting.html
index 800560e..b210732 100644
--- a/chrome/common/extensions/docs/templates/articles/hosting.html
+++ b/chrome/common/extensions/docs/templates/articles/hosting.html
@@ -1,19 +1,27 @@
-<h1>Hosting and Updating</h1>
-
-<h2 id="hosting">Hosting</h2>
-
+<h1>Webstore Hosting and Updating</h1>
 <p>
-  Extensions must be uploaded through the
-  <a href="https://chrome.google.com/webstore/developer/dashboard">
-  Developer Dashboard</a>
-  and are
-  <a href="/webstore">distributed</a> in the
+  Most extensions are hosted in the
   <a href="https://chrome.google.com/webstore/category/extensions">
-  Chrome Web Store</a> to
+  Chrome Web Store</a>
+  to best
   <a href="http://blog.chromium.org/2015/05/continuing-to-protect-chrome-users-from.html">
   protect users from malicious extensions</a>.
-  Allow users to add an extension through the web store
-  from a designated website by enabling
+</p>
+<h2 id="hosting">Hosting</h2>
+<p>
+  All extensions are distributed to users as a special ZIP file
+  with a <code>.crx</code> suffix.
+  Extensions hosted in the <a href="/webstore">Chrome Web Store</a>
+  are uploaded through the
+  <a href="/webstore/developer/dashboard">Developer Dashboard</a>
+  as <code>.zip</code> files.
+  The <a href="/webstore/publish">publishing</a> process
+  automatically converts the <code>.zip</code> into a
+  <code>.crx</code> file.
+</p>
+<p>
+  Extensions hosted by the Chrome Web Store can additionaly be installed from a
+  designated website by enabling
   <a href="/webstore/inline_installation">inline installation</a>.
 </p>
 
@@ -25,7 +33,7 @@
         enterprise policy</a>.</li>
     <li>Unpacked extension directories from a local machine while in
       <a href="getstarted#unpacked">developer mode</a>.</li>
-    <li><a href="/linux_hosting">Hosting for Linux</a> installations.</li>
+    <li><a href="/linux_hosting">Linux installation</a>.</li>
   </ol>
 </p>
 
@@ -35,13 +43,13 @@
 <h2 id="updating">Updating</h2>
 
 <p>
-  Extensions are automatically updated without user intervention,
-  just like the Chrome Browser.
+  The Chrome Browser periodically checks for new versions of
+  installed extensions and updates them without user intervention.
 </p>
 
 <p>
-  To update an extension,
-  the version number will need to increase in the manifest:
+  To release an update to an extension,
+   increase the number in the <code>“version”</code> field of the manifest.
 </p>
 
 <pre data-filename="manifest.json">
@@ -61,11 +69,12 @@
 </pre>
 
 <p>
-  Re-<a href="/packaging">package</a> the updated extension and locate it in the
+  Convert the updated extension directory into a ZIP file
+  and locate the old version in the
   <a href="https://chrome.google.com/webstore/developer/dashboard">
   Developer Dashboard</a>.
   Select <strong>Edit</strong>, upload the new package,
   and hit <strong>Publish</strong>.
-  The extension will automatically update for users
+  The browser will will automatically update the extension for users
   after the new version is published.
 </p>
diff --git a/chrome/common/extensions/docs/templates/articles/linux_hosting.html b/chrome/common/extensions/docs/templates/articles/linux_hosting.html
index dae19b70..935dcbf 100644
--- a/chrome/common/extensions/docs/templates/articles/linux_hosting.html
+++ b/chrome/common/extensions/docs/templates/articles/linux_hosting.html
@@ -1,33 +1,147 @@
-<h1>Hosting for Linux</h1>
+<h1>Linux Installation</h1>
 
 <p>
-  Extensions hosted on a server outside of the
+  Extensions hosted outside of the
   <a href="http://chrome.google.com/webstore">Chrome Web Store</a>
   can only be installed by Linux users.
-  This page describes how to serve <code>.crx</code> files
-  from a personal server.
+  This article describes how to package, host, and update
+  <code>.crx</code> files from a personal server.
   If distributing an extension or theme solely through the
   <a href="http://chrome.google.com/webstore">Chrome Web Store</a>,
-  consult the <a href="/webstore">store developer documentation</a>.
+  consult <a href="/extensions/hosting">Webstore Hosting and Updating</a>.
 </p>
-
+<h2 id="packaging">Packaging</h2>
 <p>
   Extensions and themes are served as <code>.crx</code> files.
   When uploading through the
-  <a href="https://chrome.google.com/webstore/developer/dashboard">Chrome Developer Dashboard</a>,
+  <a href="https://chrome.google.com/webstore/developer/dashboard">
+    Chrome Developer Dashboard
+  </a>,
   the dashboard creates the <code>.crx</code> file automatically.
   If published on a personal server,
-  the <code>.crx</code> file will need to be created locally,
-  as described in <a href="packaging">Packaging</a>.
-  <a href="autoupdate">Autoupdate</a> information can be included
-  to ensure users always have the latest copy.
+  the <code>.crx</code> file will need to be created locally
+  or downloaded from the Chrome Web Store.
 </p>
+<h3 id="create">Download .crx from the Chrome Web Store</h3>
+<p>
+  If an extension is hosted on the Chrome Web Store,
+  the <code>.crx</code> file can be downloaded from the Developer Dashboard.
+  Locate the extension under "Your Listings" and click on "More info".
+  In the popup window,
+  click the blue <code>main.crx</code> link to download it.
+</p>
+<img src="{{static}}/images/packaging/download_crx_blur.png"
+ height="250"
+ alt="Download .crx from the Developer Dashboard">
+<p>
+  The downloaded file can be hosted on a personal server.
+  This is the most secure way to host an extension locally
+  as the contents of the extension will be signed by the Chrome Web Store.
+  This helps detect potential attacks and tampering.
+</p>
+<h3 id="create">Create .crx locally</h3>
+<p>
+  Extension directories are converted to <code>.crx</code>
+  files at the <span id="extension_management">Extensions Management Page.
+  Navigate to <code>chrome://extensions/</code> in the ominibox,
+  or click on the Chrome menu,
+  hover over "More Tools" then select "Extensions"</span>.
+</p>
+<p>
+  On the Extensions Management Page, enable "Developer mode"
+  by checking the box in the top right-hand corner and
+  select the <strong>Pack extension...</strong> button.
+</p>
+
+<img src="{{static}}/images/packaging/packaging_devmode.png"
+ height="100"
+ alt="Developer Mode is Checked then Click Pack Extension">
+
+<p>
+  Specify the path to the extension’s folder
+  in the Extension root directory field then click the
+  <strong>Pack Extension</strong> button.
+  Ignore the <strong>Private key</strong> field for a first-time package.
+</p>
+
+<img src="{{static}}/images/packaging/packaging_root.png"
+ height="200"
+ alt="Specify Extension Path then Click Pack Extension">
+
+<p>
+  Chrome will create two files,
+  a <code>.crx</code> file and a <code>.pem</code> file,
+  which contains the extension’s private key.
+</p>
+<img src="{{static}}/images/packaging/packaging_files.png"
+ height="200"
+ alt="Packaged Extension Files">
+
+ <p>
+   <b>Do not lose the private key!</b>
+   Keep the <code>.pem</code> file in a secret and secure place;
+   it will be needed to <a href="#update">update</a> the extension.
+ </p>
+<h3 id="update">Update a .crx package</h2>
+
+<p>
+  Update an extension's <code>.crx</code> file
+  by increasing the version number in <code>manifest.json</code>.
+</p>
+<pre data-filename="manifest.json">
+  {
+    ...
+    <b>"version": "1.5",</b>
+    ...
+    }
+  }</pre>
+  <pre data-filename="manifest.json">
+  {
+    ...
+    <b>"version": "1.6",</b>
+    ...
+    }
+  }
+</pre>
+<p>
+  Return to the
+  <a href="/packaging#extension_management">Extensions Management Page</a>
+  and click the <b>Pack extension...</b> button.
+  Specify the path to the extensions directory and the location of private key.
+</p>
+
+<img src="{{static}}/images/packaging/packaging_updating.png"
+ height="200"
+ alt="Updating Extension Files">
+<p>
+  The page will provide the path for the updated packaged extension.
+</p>
+ <img src="{{static}}/images/packaging/packaging_updated.png"
+  height="150"
+  alt="Updating Extension Files">
+
+<h3 id="packaging">Package through Command Line</h3>
+
+<p>
+  Package extensions in the command line by invoking
+  <a href="https://www.chromium.org/developers/how-tos/run-chromium-with-flags">
+    <code>chrome.exe</code></a>.
+  Use the <code>--pack-extension</code> flag
+  to specify the location of the extension's folder and
+  the <code>--pack-extension-key</code> flag
+  to specify the location of the extension's private key file.
+</p>
+
+<pre>
+  chrome.exe --pack-extension=C:\myext --pack-extension-key=C:\myext.pem
+</pre>
+
+<h2 id="hosting">Hosting</h1>
 
 <p>
   A server that hosts <code>.crx</code> files
-  must use appropriate HTTP headers,
-  so that users can install the file
-  by clicking a link to it.
+  must use appropriate HTTP headers
+  to allow users to install the extension by clicking a link.
 </p>
 
 <p>
@@ -75,3 +189,251 @@
   either change the configuration of the server
   or try hosting the <code>.crx</code> file at another server.
 </p>
+<h2 id="update">Updating</h2>
+<p>
+  Every few hours,
+  the browser checks installed extensions for an update URL.
+  For each one,
+  it makes a request to that URL looking for an update manifest XML file.
+</p>
+<ul>
+  <li>
+    The content returned by an update check is an <em>update manifest</em>
+    XML document listing the latest version of an extension.
+  </li>
+</ul>
+<p>
+  If the update manifest mentions a version
+  that is more recent than what is installed,
+  the browser downloads and installs the new version.
+  As with manual updates, the new <code>.crx</code> file must be signed
+  with the same private key as the currently installed version.
+</p>
+
+<p class="note">
+  <b>Note:</b>
+  In order to maintain user privacy,
+  Google Chrome does not send any Cookie headers
+  with autoupdate manifest requests,
+  and ignores any Set-Cookie headers in the responses to those requests.
+</p>
+
+<h3 id="update_url">Update URL</h3>
+<p>
+  Extensions hosted on servers outside of the Chrome Webstore
+  must include the <code>update_url</code> field in their
+  <a href="manifest"><code>manifest.json</code></a> file.
+</p>
+
+<pre data-filename="manifest.json">
+{
+  "name": "My extension",
+  ...
+  <b>"update_url": "https://myhost.com/mytestextension/updates.xml"</b>,
+  ...
+}
+</pre>
+
+<h3 id="update_manifest">Update manifest</h3>
+<p>
+  The update manifest returned by the server should be an XML document.
+</p>
+
+<pre data-filename="updates.xml">
+&lt;?xml version='1.0' encoding='UTF-8'?&gt;
+&lt;gupdate xmlns='https://www.google.com/update2/response' protocol='2.0'&gt;
+  &lt;app appid='<b>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</b>'&gt;
+   &nbsp;&lt;updatecheck&nbsp;codebase='<b>https://myhost.com/mytestextension/mte_v2.crx</b>'&nbsp;version='<b>2.0</b>' /&gt;
+  &lt;/app&gt;
+&lt;/gupdate&gt;
+</pre>
+
+<p>
+  This XML format is borrowed from that used by
+  <a href="https://github.com/google/omaha">Omaha</a>,
+  Google's update infrastructure.
+  The extensions system uses the following attributes
+  for the <code>&lt;app></code>
+  and <code>&lt;updatecheck></code> elements of the update manifest:
+</p>
+<table>
+  <tr>
+    <td>appid</td>
+    <td>The extension ID is generated based on a hash of the public key,
+      as described in <a href="/linux_hosting#packaging">packaging</a>.
+      An extension's ID is displayed on the
+      <a href="/linux_hosting#extension_management">
+        Extensions Managment Page</a></td>
+  </tr>
+  <tr>
+    <td>codebase</td>
+    <td>An HTTPS URL to the <code>.crx</code> file.</td>
+  </tr>
+  <tr>
+    <td>version</td>
+    <td>Used by the client to determine whether it should download the
+      <code>.crx</code> file specified by <code>codebase</code>.
+      It should match the value of "version" in the <code>.crx</code> file's
+      <code>manifest.json</code> file.</td>
+  </tr>
+</table>
+{{?is_apps}}
+
+<p>
+  Hosted apps, however, are not listed on the Extensions page.
+  You can find the ID of any
+  app using the following steps:
+</p>
+
+<ul>
+  <li>
+    Open the app. You can do this by clicking its icon on the New Tab page.
+  </li>
+  <li>
+    Open the JavaScript console.  You can do this by clicking the wrench icon
+       and choosing <b>Tools &gt; JavaScript Console</b>.
+  </li>
+  <li>
+    Enter the following expression into the JavaScript console:
+    <code>chrome.app.getDetails().id</code>
+    <br>
+    The console shows the app's ID as a quoted string.
+  </li>
+</ul>
+{{/is_apps}}
+
+<p>
+  The update manifest XML file may contain information about multiple extensions
+  by including multiple &lt;app&gt; elements.
+</p>
+
+
+<h3 id="testing">Testing</h3>
+<p>
+  The default update check frequency is several hours,
+  but an update can be forced using the <b>Update extensions now</b> button
+  on the Extensions Management Page.
+</p>
+<img src="{{static}}/images/packaging/packaging_update_now.png"
+ height="100"
+ alt="Update Extensions Now">
+<p>
+  Another option is to use the --extensions-update-frequency command-line flag
+  to set a more frequent interval in seconds.
+  The follwoing command will make Google Chrome run checks every 45 seconds.
+</p>
+
+<pre>
+  chrome.exe <b>--extensions-update-frequency=45</b>
+</pre>
+
+<p>
+  This will start checks for all installed extensions.
+</p>
+
+
+<h3 id="request_parameters">Advanced usage: request parameters</h3>
+<p>
+  The basic autoupdate mechanism is designed to make the server-side work as
+  easy as just dropping a static XML file onto any plain web server,
+  such as Apache,
+  and updating that XML file as new extension versions are released.
+</p>
+<p>
+  Developers hosting multiple extensions may check request parameters,
+  which indicate the extension ID and version in the update request.
+  Including these paramaters allow extensions to update from
+  the same URL running dynamic server-side code instead of a static XML file.
+</p>
+<p>
+  The format of the request parameters is:
+</p>
+<p>
+  <code>&nbsp;&nbsp;?x=<em>&lt;extension_data&gt;</em></code>
+</p>
+<p>
+  Where <code><em>&lt;extension_data&gt;</em></code>
+  is a URL-encoded string of the format:
+</p>
+<p>
+  <code>&nbsp;&nbsp;<em>id=&lt;id&gt;</em>&amp;v=<em>&lt;version&gt;</em></code>
+</p>
+
+<p>
+  For example, two extensions point to the same update URL
+  (<code>https://test.com/extension_updates.php</code>):
+</p>
+<ul>
+  <li>
+    Extension 1
+    <ul>
+      <li> ID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" </li>
+      <li> Version: "1.1"</li>
+    </ul>
+  </li>
+  <li>
+    Extension 2
+    <ul>
+      <li> ID: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" </li>
+      <li> Version: "0.4"</li>
+    </ul>
+  </li>
+</ul>
+
+
+<p>
+  The request to update each individual extension would be,
+</p>
+<pre>
+  https://test.com/extension_updates.php?x=id%3Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%26v%3D1.1
+</pre>
+<p>
+  and
+</p>
+<pre>
+  https://test.com/extension_updates.php?x=id%3Dbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb%26v%3D0.4
+</pre>
+
+
+<p>
+  Multiple extensions can be listed in a single request for each unique update URL.
+  For the above example, if a user has both of the extensions installed,
+  then the two requests are merged into a single request:
+</p>
+<pre>
+  https://test.com/extension_updates.php?x=id%3Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%26v%3D1.1&amp;x=id%3Dbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb%26v%3D0.4
+</pre>
+
+<p>
+  If the number of installed extensions using the same update URL is large
+  enough that a GET request URL is too long (over 2000 characters or so),
+  the update check issues additional GET requests as necessary.
+</p>
+
+<h3 id="minimum_browser_version">Advanced usage: minimum browser version</h3>
+<p>
+  As more APIs are added to the extensions system,
+  an updated version of an extension
+  that will work only with newer versions of the browser may be released.
+  While Google Chrome itself is autoupdated,
+  it can take a few days before the majority of the user base
+  has updated to any given new release.
+  To ensure that a given update will apply only to Google Chrome versions at
+  or higher than a specific version,
+  add the "prodversionmin" attribute to the
+  &lt;app&gt; element in the update response.
+</p>
+
+<pre data-filename="updates.xml">
+  &lt;?xml version='1.0' encoding='UTF-8'?&gt;
+  &lt;gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'&gt;
+  &nbsp;&nbsp;&lt;app appid='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'&gt;
+  &nbsp;&nbsp; &nbsp;&lt;updatecheck&nbsp;codebase='http://myhost.com/mytestextension/mte_v2.crx'&nbsp;version='2.0' <b>prodversionmin='3.0.193.0'</b>/&gt;
+  &nbsp;&nbsp;&lt;/app&gt;
+  &lt;/gupdate&gt;
+</pre>
+
+<p>
+  This would ensure that users would autoupdate to version 2
+  only if they are running Google Chrome 3.0.193.0 or greater.
+</p>
diff --git a/chrome/common/extensions/docs/templates/json/chrome_sidenav.json b/chrome/common/extensions/docs/templates/json/chrome_sidenav.json
index 5d152652..691e0aab2 100644
--- a/chrome/common/extensions/docs/templates/json/chrome_sidenav.json
+++ b/chrome/common/extensions/docs/templates/json/chrome_sidenav.json
@@ -620,18 +620,18 @@
             "href": "/extensions/hosting",
             "items": [
               {
-                "title": "Hosting and Updating",
+                "title": "Webstore Hosting and Updating",
                 "href": "/extensions/hosting"
               },
               {
+                "title": "Linux Installation",
+                "href": "/extensions/linux_hosting"
+              },
+              {
                 "title": "Hosting Policy Changes",
                 "href": "/extensions/hosting_changes"
               },
               {
-                "title": "Packaging",
-                "href": "/extensions/packaging"
-              },
-              {
                 "title": "One-Time Payments",
                 "href": "/webstore/one_time_payments"
               },
diff --git a/chrome/common/extensions/docs/templates/public/extensions/redirects.json b/chrome/common/extensions/docs/templates/public/extensions/redirects.json
index a4ecb32..f051685 100644
--- a/chrome/common/extensions/docs/templates/public/extensions/redirects.json
+++ b/chrome/common/extensions/docs/templates/public/extensions/redirects.json
@@ -13,5 +13,7 @@
   "pushMessaging": "https://developers.google.com/cloud-messaging/chrome/client",
   "gcm_tos": "https://developers.google.com/terms/",
   "gcm_server": "https://developers.google.com/cloud-messaging/server",
-  "autoupdate": "hosting"
+  "autoupdate": "hosting",
+  "packaging": "hosting",
+  "crx": "hosting"
 }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 43ab561..fa143f5 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -4141,6 +4141,8 @@
     ]
     if (is_chromeos) {
       sources += [ "../browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc" ]
+    } else {
+      sources += [ "../browser/ui/views/relaunch_notification/relaunch_notification_controller_unittest.cc" ]
     }
     if (!is_chromeos && (!is_mac || mac_views_browser)) {
       sources += [
@@ -4683,6 +4685,7 @@
           "../browser/ui/views/location_bar/star_view_browsertest.cc",
           "../browser/ui/views/omnibox/omnibox_view_views_browsertest.cc",
           "../browser/ui/views/passwords/manage_passwords_icon_view_interactive_uitest.cc",
+          "../browser/ui/views/sad_tab_view_interactive_uitest.cc",
           "../browser/ui/views/ssl_client_certificate_selector_browsertest.cc",
           "../browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc",
           "../browser/ui/views/tabs/tab_drag_controller_interactive_uitest.h",
diff --git a/chrome/test/data/webui/settings/all_sites_tests.js b/chrome/test/data/webui/settings/all_sites_tests.js
index 9b134be..237a2b10 100644
--- a/chrome/test/data/webui/settings/all_sites_tests.js
+++ b/chrome/test/data/webui/settings/all_sites_tests.js
@@ -7,137 +7,20 @@
  * different providers.
  * @type {SiteSettingsPref}
  */
-const prefsMixedProvider = {
-  exceptions: {
-    geolocation: [
-      {
-        embeddingOrigin: '',
-        origin: 'https://[*.]foo.com',
-        setting: 'block',
-        source: 'policy',
-      },
-      {
-        embeddingOrigin: '',
-        origin: 'https://bar.foo.com',
-        setting: 'block',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: '',
-        origin: 'https://[*.]foo.com',
-        setting: 'block',
-        source: 'preference',
-      },
-    ],
-    images: [],
-  }
-};
+let prefsMixedProvider;
 
 /**
  * An example pref with mixed origin and pattern.
  * @type {SiteSettingsPref}
  */
-const prefsMixedOriginAndPattern = {
-  exceptions: {
-    ads: [],
-    auto_downloads: [],
-    background_sync: [],
-    camera: [],
-    cookies: [],
-    geolocation: [
-      {
-        embeddingOrigin: '',
-        origin: 'https://foo.com',
-        setting: 'allow',
-        source: 'preference',
-      },
-    ],
-    images: [],
-    javascript: [
-      {
-        embeddingOrigin: '',
-        origin: 'https://[*.]foo.com',
-        setting: 'allow',
-        source: 'preference',
-      },
-    ],
-    mic: [],
-    notifications: [],
-    plugins: [],
-    midi_devices: [],
-    protectedContent: [],
-    popups: [],
-    sound: [],
-    unsandboxed_plugins: [],
-    clipboard: [],
-    sensors: [],
-  }
-};
+let prefsMixedOriginAndPattern;
 
 /**
  * An example pref with multiple categories and multiple allow/block
  * state.
  * @type {SiteSettingsPref}
  */
-const prefsVarious = {
-  exceptions: {
-    ads: [],
-    auto_downloads: [],
-    background_sync: [],
-    camera: [],
-    cookies: [],
-    geolocation: [
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'https://foo.com',
-        setting: 'allow',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'https://bar.com',
-        setting: 'block',
-        source: 'preference',
-      },
-    ],
-    images: [],
-    javascript: [],
-    mic: [],
-    midi_devices: [],
-    notifications: [
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'https://google.com',
-        setting: 'block',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'https://bar.com',
-        setting: 'block',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'https://foo.com',
-        setting: 'block',
-        source: 'preference',
-      },
-    ],
-    plugins: [],
-    protectedContent: [],
-    popups: [],
-    sound: [],
-    unsandboxed_plugins: [],
-    clipboard: [],
-    sensors: [],
-  }
-};
+let prefsVarious;
 
 suite('AllSites', function() {
   /**
@@ -162,6 +45,52 @@
 
   // Initialize a site-list before each test.
   setup(function() {
+    prefsMixedProvider = test_util.createSiteSettingsPrefs(
+        [], [test_util.createContentSettingTypeToValuePair(
+                settings.ContentSettingsTypes.GEOLOCATION, [
+                  test_util.createRawSiteException('https://[*.]foo.com', {
+                    setting: settings.ContentSetting.BLOCK,
+                    source: settings.SiteSettingSource.POLICY,
+                  }),
+                  test_util.createRawSiteException('https://bar.foo.com', {
+                    setting: settings.ContentSetting.BLOCK,
+                  }),
+                  test_util.createRawSiteException('https://[*.]foo.com', {
+                    setting: settings.ContentSetting.BLOCK,
+                  }),
+                ])]);
+
+    prefsMixedOriginAndPattern = test_util.createSiteSettingsPrefs(
+        [], [test_util.createContentSettingTypeToValuePair(
+                settings.ContentSettingsTypes.GEOLOCATION, [
+                  test_util.createRawSiteException('https://foo.com'),
+                  test_util.createRawSiteException('https://[*.]foo.com'),
+                ])]);
+
+    prefsVarious = test_util.createSiteSettingsPrefs([], [
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.GEOLOCATION,
+          [
+            test_util.createRawSiteException('https://foo.com'),
+            test_util.createRawSiteException('https://bar.com', {
+              setting: settings.ContentSetting.BLOCK,
+            })
+          ]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.NOTIFICATIONS,
+          [
+            test_util.createRawSiteException('https://google.com', {
+              setting: settings.ContentSetting.BLOCK,
+            }),
+            test_util.createRawSiteException('https://bar.com', {
+              setting: settings.ContentSetting.BLOCK,
+            }),
+            test_util.createRawSiteException('https://foo.com', {
+              setting: settings.ContentSetting.BLOCK,
+            }),
+          ])
+    ]);
+
     browserProxy = new TestSiteSettingsPrefsBrowserProxy();
     settings.SiteSettingsPrefsBrowserProxyImpl.instance_ = browserProxy;
     PolymerTest.clearBody();
@@ -230,13 +159,19 @@
                 'If this fails with 5 instead of the expected 3, then ' +
                     'the de-duping of sites is not working for site_list');
             assertEquals(
-                prefsVarious.exceptions.geolocation[1].origin,
+                prefsVarious
+                    .exceptions[settings.ContentSettingsTypes.GEOLOCATION][1]
+                    .origin,
                 testElement.sites[0].origin);
             assertEquals(
-                prefsVarious.exceptions.geolocation[0].origin,
+                prefsVarious
+                    .exceptions[settings.ContentSettingsTypes.GEOLOCATION][0]
+                    .origin,
                 testElement.sites[1].origin);
             assertEquals(
-                prefsVarious.exceptions.notifications[0].origin,
+                prefsVarious
+                    .exceptions[settings.ContentSettingsTypes.NOTIFICATIONS][0]
+                    .origin,
                 testElement.sites[2].origin);
             assertEquals(undefined, testElement.selectedOrigin);
 
@@ -246,7 +181,9 @@
             assertNotEquals(undefined, clickable);
             MockInteractions.tap(clickable);
             assertEquals(
-                prefsVarious.exceptions.geolocation[0].origin,
+                prefsVarious
+                    .exceptions[settings.ContentSettingsTypes.GEOLOCATION][0]
+                    .origin,
                 settings.getQueryParameters().get('site'));
           });
         });
@@ -280,7 +217,9 @@
                     'the de-duping of sites has been enabled for site_list.');
             if (testElement.sites.length == 1) {
               assertEquals(
-                  prefsMixedOriginAndPattern.exceptions.geolocation[0].origin,
+                  prefsMixedOriginAndPattern
+                      .exceptions[settings.ContentSettingsTypes.GEOLOCATION][0]
+                      .origin,
                   testElement.sites[0].displayName);
             }
 
@@ -292,7 +231,9 @@
             MockInteractions.tap(clickable);
             if (testElement.sites.length == 1) {
               assertEquals(
-                  prefsMixedOriginAndPattern.exceptions.geolocation[0].origin,
+                  prefsMixedOriginAndPattern
+                      .exceptions[settings.ContentSettingsTypes.GEOLOCATION][0]
+                      .origin,
                   testElement.sites[0].displayName);
             }
           });
diff --git a/chrome/test/data/webui/settings/category_default_setting_tests.js b/chrome/test/data/webui/settings/category_default_setting_tests.js
index e877269f..baee8b4 100644
--- a/chrome/test/data/webui/settings/category_default_setting_tests.js
+++ b/chrome/test/data/webui/settings/category_default_setting_tests.js
@@ -39,10 +39,10 @@
   function testCategoryEnabled(
       testElement, category, prefs, expectedEnabled,
       expectedEnabledContentSetting) {
+    testElement.category = category;
     browserProxy.reset();
     browserProxy.setPrefs(prefs);
 
-    testElement.category = category;
     return browserProxy.whenCalled('getDefaultValueForContentType')
         .then(function(contentType) {
           assertEquals(category, contentType);
@@ -66,13 +66,15 @@
      * An example pref where the location category is enabled.
      * @type {SiteSettingsPref}
      */
-    const prefsLocationEnabled = {
-      defaults: {
-        geolocation: {
-          setting: 'allow',
-        },
-      },
-    };
+    const prefsLocationEnabled = test_util.createSiteSettingsPrefs(
+        [
+          test_util.createContentSettingTypeToValuePair(
+              settings.ContentSettingsTypes.GEOLOCATION,
+              test_util.createDefaultContentSetting({
+                setting: settings.ContentSetting.ALLOW,
+              })),
+        ],
+        []);
 
     return testCategoryEnabled(
         testElement, settings.ContentSettingsTypes.GEOLOCATION,
@@ -84,13 +86,13 @@
      * An example pref where the location category is disabled.
      * @type {SiteSettingsPref}
      */
-    const prefsLocationDisabled = {
-      defaults: {
-        geolocation: {
-          setting: 'block',
-        },
-      },
-    };
+    const prefsLocationDisabled = test_util.createSiteSettingsPrefs(
+        [test_util.createContentSettingTypeToValuePair(
+            settings.ContentSettingsTypes.GEOLOCATION,
+            test_util.createDefaultContentSetting({
+              setting: settings.ContentSetting.BLOCK,
+            }))],
+        []);
 
     return testCategoryEnabled(
         testElement, settings.ContentSettingsTypes.GEOLOCATION,
@@ -98,13 +100,13 @@
   });
 
   test('test Flash content setting in DETECT/ASK setting', function() {
-    const prefsFlash = {
-      defaults: {
-        plugins: {
-          setting: 'detect_important_content',
-        },
-      },
-    };
+    const prefsFlash = test_util.createSiteSettingsPrefs(
+        [test_util.createContentSettingTypeToValuePair(
+            settings.ContentSettingsTypes.PLUGINS,
+            test_util.createDefaultContentSetting({
+              setting: settings.ContentSetting.IMPORTANT_CONTENT,
+            }))],
+        []);
 
     return testCategoryEnabled(
         testElement, settings.ContentSettingsTypes.PLUGINS, prefsFlash, true,
@@ -112,13 +114,13 @@
   });
 
   test('test Flash content setting in legacy ALLOW setting', function() {
-    const prefsFlash = {
-      defaults: {
-        plugins: {
-          setting: 'allow',
-        },
-      },
-    };
+    const prefsFlash = test_util.createSiteSettingsPrefs(
+        [test_util.createContentSettingTypeToValuePair(
+            settings.ContentSettingsTypes.PLUGINS,
+            test_util.createDefaultContentSetting({
+              setting: settings.ContentSetting.ALLOW,
+            }))],
+        []);
 
     return testCategoryEnabled(
         testElement, settings.ContentSettingsTypes.PLUGINS, prefsFlash, true,
@@ -126,13 +128,13 @@
   });
 
   test('test Flash content setting in BLOCK setting', function() {
-    const prefsFlash = {
-      defaults: {
-        plugins: {
-          setting: 'block',
-        },
-      },
-    };
+    const prefsFlash = test_util.createSiteSettingsPrefs(
+        [test_util.createContentSettingTypeToValuePair(
+            settings.ContentSettingsTypes.PLUGINS,
+            test_util.createDefaultContentSetting({
+              setting: settings.ContentSetting.BLOCK,
+            }))],
+        []);
 
     return testCategoryEnabled(
         testElement, settings.ContentSettingsTypes.PLUGINS, prefsFlash, false,
@@ -140,32 +142,42 @@
   });
 
   test('test content setting from extension', function() {
-    const prefs = {
-      defaults: {
-        mic: {
-          setting: 'block',
-          source: ContentSettingProvider.EXTENSION,
-        },
-      },
-    };
-    browserProxy.reset();
-    browserProxy.setPrefs(prefs);
     testElement.category = settings.ContentSettingsTypes.MIC;
+    return browserProxy.getDefaultValueForContentType(testElement.category)
+        .then((defaultValue) => {
+          // Sanity check - make sure the default content setting is not the
+          // value the extension is about to set.
+          assertEquals(settings.ContentSetting.ASK, defaultValue.setting);
+          browserProxy.resetResolver('getDefaultValueForContentType');
 
-    // Test that extension-enforced content settings don't override user-set
-    // content settings.
-    browserProxy.whenCalled('setDefaultValueForContentType')
-        .then(() => assertNotReached());
-    return browserProxy.whenCalled('getDefaultValueForContentType').then(() => {
-      assertEquals(false, testElement.categoryEnabled);
-    });
+          const prefs = test_util.createSiteSettingsPrefs(
+              [test_util.createContentSettingTypeToValuePair(
+                  settings.ContentSettingsTypes.MIC,
+                  test_util.createDefaultContentSetting({
+                    setting: settings.ContentSetting.BLOCK,
+                    source: ContentSettingProvider.EXTENSION,
+                  }))],
+              []);
+          browserProxy.reset();
+          browserProxy.setPrefs(prefs);
+
+          // Test that extension-enforced content settings don't override
+          // user-set content settings.
+          browserProxy.whenCalled('setDefaultValueForContentType').then(() => {
+            assertNotReached();
+          });
+          return browserProxy.whenCalled('getDefaultValueForContentType');
+        })
+        .then(() => {
+          assertEquals(false, testElement.categoryEnabled);
+        });
   });
 
   function testTristateCategory(
       prefs, category, thirdState, secondaryToggleId) {
+    testElement.category = category;
     browserProxy.setPrefs(prefs);
 
-    testElement.category = category;
     let secondaryToggle = null;
 
     return browserProxy.whenCalled('getDefaultValueForContentType')
@@ -270,13 +282,13 @@
      * An example pref where the Cookies category is set to delete when
      * session ends.
      */
-    const prefsCookiesSessionOnly = {
-      defaults: {
-        cookies: {
-          setting: 'session_only',
-        },
-      },
-    };
+    const prefsCookiesSessionOnly = test_util.createSiteSettingsPrefs(
+        [test_util.createContentSettingTypeToValuePair(
+            settings.ContentSettingsTypes.COOKIES,
+            test_util.createDefaultContentSetting({
+              setting: settings.ContentSetting.SESSION_ONLY,
+            }))],
+        []);
 
     return testTristateCategory(
         prefsCookiesSessionOnly, settings.ContentSettingsTypes.COOKIES,
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js
index 1d6378ee..b31a508 100644
--- a/chrome/test/data/webui/settings/cr_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -813,6 +813,7 @@
   /** @override */
   extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([
     '../test_browser_proxy.js',
+    'test_util.js',
     'test_site_settings_prefs_browser_proxy.js',
     'category_default_setting_tests.js',
   ]),
@@ -837,6 +838,7 @@
   /** @override */
   extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([
     '../test_browser_proxy.js',
+    'test_util.js',
     'test_site_settings_prefs_browser_proxy.js',
     'category_setting_exceptions_tests.js',
   ]),
@@ -866,6 +868,7 @@
   /** @override */
   extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([
     '../test_browser_proxy.js',
+    'test_util.js',
     'test_site_settings_prefs_browser_proxy.js',
     'all_sites_tests.js',
   ]),
@@ -890,6 +893,7 @@
   /** @override */
   extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([
     '../test_browser_proxy.js',
+    'test_util.js',
     'test_site_settings_prefs_browser_proxy.js',
     'site_details_tests.js',
   ]),
@@ -914,6 +918,7 @@
   /** @override */
   extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([
     '../test_browser_proxy.js',
+    'test_util.js',
     'test_site_settings_prefs_browser_proxy.js',
     'site_details_permission_tests.js',
   ]),
@@ -943,6 +948,7 @@
   /** @override */
   extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([
     '../test_browser_proxy.js',
+    'test_util.js',
     'test_site_settings_prefs_browser_proxy.js',
     'site_list_tests.js',
   ]),
@@ -975,6 +981,7 @@
   /** @override */
   extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([
     '../test_browser_proxy.js',
+    'test_util.js',
     'test_site_settings_prefs_browser_proxy.js',
     'zoom_levels_tests.js',
   ]),
@@ -999,6 +1006,7 @@
   /** @override */
   extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([
     '../test_browser_proxy.js',
+    'test_util.js',
     'test_site_settings_prefs_browser_proxy.js',
     'usb_devices_tests.js',
   ]),
@@ -1023,6 +1031,7 @@
   /** @override */
   extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([
     '../test_browser_proxy.js',
+    'test_util.js',
     'test_site_settings_prefs_browser_proxy.js',
     'protocol_handlers_tests.js',
   ]),
diff --git a/chrome/test/data/webui/settings/site_details_permission_tests.js b/chrome/test/data/webui/settings/site_details_permission_tests.js
index 43fd4eb5..f4ff0e8 100644
--- a/chrome/test/data/webui/settings/site_details_permission_tests.js
+++ b/chrome/test/data/webui/settings/site_details_permission_tests.js
@@ -18,23 +18,15 @@
 
   // Initialize a site-details-permission before each test.
   setup(function() {
-    prefs = {
-      defaults: {
-        camera: {
-          setting: settings.ContentSetting.ALLOW,
-        }
-      },
-      exceptions: {
-        camera: [
-          {
-            embeddingOrigin: '',
-            origin: 'https://www.example.com',
-            setting: settings.ContentSetting.ALLOW,
-            source: settings.SiteSettingSource.PREFERENCE,
-          },
-        ]
-      }
-    };
+    prefs = test_util.createSiteSettingsPrefs(
+        [test_util.createContentSettingTypeToValuePair(
+            settings.ContentSettingsTypes.CAMERA,
+            test_util.createDefaultContentSetting({
+              setting: settings.ContentSetting.ALLOW,
+            }))],
+        [test_util.createContentSettingTypeToValuePair(
+            settings.ContentSettingsTypes.CAMERA,
+            [test_util.createRawSiteException('https://www.example.com')])]);
 
     browserProxy = new TestSiteSettingsPrefsBrowserProxy();
     settings.SiteSettingsPrefsBrowserProxyImpl.instance_ = browserProxy;
@@ -118,12 +110,13 @@
               'Allow (default)', testElement.$.permission.options[0].text,
               'Default setting string should match prefs');
           browserProxy.resetResolver('getDefaultValueForContentType');
-          const defaultPrefs = {
-            camera: {
-              setting: settings.ContentSetting.BLOCK,
-            }
-          };
-          browserProxy.setDefaultPrefs(defaultPrefs);
+          const defaultPrefs = test_util.createSiteSettingsPrefs(
+              [test_util.createContentSettingTypeToValuePair(
+                  settings.ContentSettingsTypes.CAMERA,
+                  test_util.createDefaultContentSetting(
+                      {setting: settings.ContentSetting.BLOCK}))],
+              []);
+          browserProxy.setPrefs(defaultPrefs);
           return browserProxy.whenCalled('getDefaultValueForContentType');
         })
         .then((args) => {
@@ -132,12 +125,12 @@
               'Block (default)', testElement.$.permission.options[0].text,
               'Default setting string should match prefs');
           browserProxy.resetResolver('getDefaultValueForContentType');
-          const defaultPrefs = {
-            camera: {
-              setting: settings.ContentSetting.ASK,
-            }
-          };
-          browserProxy.setDefaultPrefs(defaultPrefs);
+          const defaultPrefs = test_util.createSiteSettingsPrefs(
+              [test_util.createContentSettingTypeToValuePair(
+                  settings.ContentSettingsTypes.CAMERA,
+                  test_util.createDefaultContentSetting())],
+              []);
+          browserProxy.setPrefs(defaultPrefs);
           return browserProxy.whenCalled('getDefaultValueForContentType');
         })
         .then((args) => {
diff --git a/chrome/test/data/webui/settings/site_details_tests.js b/chrome/test/data/webui/settings/site_details_tests.js
index 0a1ec4e..e3616e94 100644
--- a/chrome/test/data/webui/settings/site_details_tests.js
+++ b/chrome/test/data/webui/settings/site_details_tests.js
@@ -16,104 +16,74 @@
    */
   let prefs;
 
-  // Helper to create a mock permission preference.
-  function createExceptionForTest(override) {
-    return Object.assign(
-        {
-          embeddingOrigin: 'https://foo.com:443',
-          origin: 'https://foo.com:443',
-          setting: settings.ContentSetting.ALLOW,
-          source: settings.SiteSettingSource.PREFERENCE,
-        },
-        override);
-  }
-
   // Initialize a site-details before each test.
   setup(function() {
-    prefs = {
-      defaults: {
-        ads: {
-          setting: settings.ContentSetting.BLOCK,
-        },
-        auto_downloads: {
-          setting: settings.ContentSetting.ASK,
-        },
-        background_sync: {
-          setting: settings.ContentSetting.ALLOW,
-        },
-        camera: {
-          setting: settings.ContentSetting.ASK,
-        },
-        geolocation: {
-          setting: settings.ContentSetting.ASK,
-        },
-        images: {
-          setting: settings.ContentSetting.ALLOW,
-        },
-        javascript: {
-          setting: settings.ContentSetting.ALLOW,
-        },
-        mic: {
-          setting: settings.ContentSetting.ASK,
-        },
-        midi_devices: {
-          setting: settings.ContentSetting.ASK,
-        },
-        notifications: {
-          setting: settings.ContentSetting.ASK,
-        },
-        plugins: {
-          setting: settings.ContentSetting.ASK,
-        },
-        popups: {
-          setting: settings.ContentSetting.BLOCK,
-        },
-        sound: {
-          setting: settings.ContentSetting.ALLOW,
-        },
-        unsandboxed_plugins: {
-          setting: settings.ContentSetting.ASK,
-        },
-        protectedContent: {
-          setting: settings.ContentSetting.ALLOW,
-        },
-        clipboard: {
-          setting: settings.ContentSetting.ALLOW,
-        },
-        sensors: {
-          setting: settings.ContentSetting.ALLOW,
-        },
-      },
-      exceptions: {
-        ads: [createExceptionForTest()],
-        auto_downloads: [createExceptionForTest()],
-        background_sync: [createExceptionForTest()],
-        camera: [createExceptionForTest()],
-        geolocation: [createExceptionForTest()],
-        images: [createExceptionForTest({
-          source: settings.SiteSettingSource.DEFAULT,
-        })],
-        javascript: [createExceptionForTest()],
-        mic: [createExceptionForTest()],
-        midi_devices: [createExceptionForTest()],
-        notifications: [createExceptionForTest({
-          setting: settings.ContentSetting.ASK,
-          source: settings.SiteSettingSource.POLICY,
-        })],
-        plugins: [createExceptionForTest({
-          source: settings.SiteSettingSource.EXTENSION,
-        })],
-        popups: [createExceptionForTest({
-          setting: settings.ContentSetting.BLOCK,
-          source: settings.SiteSettingSource.DEFAULT,
-        })],
-        sound: [createExceptionForTest()],
-        unsandboxed_plugins: [createExceptionForTest()],
-        protectedContent: [createExceptionForTest()],
-        clipboard: [createExceptionForTest()],
-        sensors: [createExceptionForTest()],
-      }
-    };
+    prefs = test_util.createSiteSettingsPrefs([], [
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.COOKIES,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.IMAGES,
+          [test_util.createRawSiteException('https://foo.com:443', {
+            source: settings.SiteSettingSource.DEFAULT,
+          })]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.JAVASCRIPT,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.SOUND,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.PLUGINS,
+          [test_util.createRawSiteException('https://foo.com:443', {
+            source: settings.SiteSettingSource.EXTENSION,
+          })]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.POPUPS,
+          [test_util.createRawSiteException('https://foo.com:443', {
+            setting: settings.ContentSetting.BLOCK,
+            source: settings.SiteSettingSource.DEFAULT,
+          })]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.GEOLOCATION,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.NOTIFICATIONS,
+          [test_util.createRawSiteException('https://foo.com:443', {
+            setting: settings.ContentSetting.ASK,
+            source: settings.SiteSettingSource.POLICY,
+          })]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.MIC,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.CAMERA,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.UNSANDBOXED_PLUGINS,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.AUTOMATIC_DOWNLOADS,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.BACKGROUND_SYNC,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.MIDI_DEVICES,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.PROTECTED_CONTENT,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.ADS,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.CLIPBOARD,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+      test_util.createContentSettingTypeToValuePair(
+          settings.ContentSettingsTypes.SENSORS,
+          [test_util.createRawSiteException('https://foo.com:443')]),
+    ]);
 
     browserProxy = new TestSiteSettingsPrefsBrowserProxy();
     settings.SiteSettingsPrefsBrowserProxyImpl.instance_ = browserProxy;
@@ -381,49 +351,4 @@
         });
   });
 
-  test('resetting permissions will set ads back to default', function() {
-    browserProxy.setPrefs(prefs);
-    loadTimeData.overrideValues({enableSafeBrowsingSubresourceFilter: true});
-    testElement = createSiteDetails('https://foo.com:443');
-
-    const siteDetailsPermission = testElement.root.querySelector('#ads');
-
-    return browserProxy.whenCalled('isOriginValid')
-        .then(() => {
-          return browserProxy.whenCalled('getOriginPermissions');
-        })
-        .then(() => {
-          browserProxy.resetResolver('getOriginPermissions');
-          // Sanity check prefs are correct and that Ads was set to 'Allow'.
-          assertEquals(
-              settings.ContentSetting.ALLOW,
-              siteDetailsPermission.$.permission.value);
-
-          // Since the ads permission will only show 'Allow' and 'Block',
-          // check the user can still clear this setting by resetting all
-          // permissions.
-          MockInteractions.tap(testElement.$.clearAndReset);
-          assertTrue(testElement.$.confirmDeleteDialog.open);
-          const actionButtonList =
-              testElement.$.confirmDeleteDialog.getElementsByClassName(
-                  'action-button');
-          assertEquals(1, actionButtonList.length);
-          MockInteractions.tap(actionButtonList[0]);
-
-          return browserProxy.whenCalled('setOriginPermissions');
-        })
-        .then(() => {
-          return browserProxy.whenCalled('clearFlashPref');
-        })
-        .then(() => {
-          return browserProxy.whenCalled('getOriginPermissions');
-        })
-        .then((args) => {
-          assertTrue(args[1].includes(settings.ContentSettingsTypes.ADS));
-          // Check the ads permission is set to default.
-          assertEquals(
-              settings.ContentSetting.DEFAULT,
-              siteDetailsPermission.$.permission.value);
-        });
-  });
 });
diff --git a/chrome/test/data/webui/settings/site_list_tests.js b/chrome/test/data/webui/settings/site_list_tests.js
index ae91172..d1e9940 100644
--- a/chrome/test/data/webui/settings/site_list_tests.js
+++ b/chrome/test/data/webui/settings/site_list_tests.js
@@ -10,332 +10,238 @@
  * all types, even though some might be blank.
  * @type {SiteSettingsPref}
  */
-const prefsGeolocation = {
-  exceptions: {
-    ads: [],
-    auto_downloads: [],
-    background_sync: [],
-    camera: [],
-    cookies: [],
-    geolocation: [
-      {
-        embeddingOrigin: 'https://bar-allow.com:443',
-        origin: 'https://bar-allow.com:443',
-        setting: 'allow',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: 'https://foo-allow.com:443',
-        origin: 'https://foo-allow.com:443',
-        setting: 'allow',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: 'https://bar-block.com:443',
-        origin: 'https://bar-block.com:443',
-        setting: 'block',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: 'https://foo-block.com:443',
-        origin: 'https://foo-block.com:443',
-        setting: 'block',
-        source: 'preference',
-      },
-    ],
-    images: [],
-    javascript: [],
-    mic: [],
-    midi_devices: [],
-    notifications: [],
-    plugins: [],
-    protectedContent: [],
-    popups: [],
-    sound: [],
-    unsandboxed_plugins: [],
-    clipboard: [],
-    sensors: [],
-  }
-};
+let prefsGeolocation;
 
 /**
  * An example of prefs controlledBy policy.
  * @type {SiteSettingsPref}
  */
-const prefsControlled = {
-  exceptions: {
-    plugins: [
-      {
-        embeddingOrigin: '',
-        origin: 'http://foo-block.com',
-        setting: 'block',
-        source: 'policy',
-      },
-    ]
-  }
-};
+let prefsControlled;
 
 /**
  * An example pref with mixed schemes (present and absent).
  * @type {SiteSettingsPref}
  */
-const prefsMixedSchemes = {
-  exceptions: {
-    geolocation: [
-      {
-        embeddingOrigin: 'https://foo-allow.com',
-        origin: 'https://foo-allow.com',
-        setting: 'allow',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: 'bar-allow.com',
-        origin: 'bar-allow.com',
-        setting: 'allow',
-        source: 'preference',
-      },
-    ]
-  }
-};
-
+let prefsMixedSchemes;
 
 /**
  * An example pref with exceptions with origins and patterns from
  * different providers.
  * @type {SiteSettingsPref}
  */
-const prefsMixedProvider = {
-  exceptions: {
-    geolocation: [
-      {
-        embeddingOrigin: 'https://[*.]foo.com',
-        origin: 'https://[*.]foo.com',
-        setting: 'block',
-        source: 'policy',
-      },
-      {
-        embeddingOrigin: 'https://bar.foo.com',
-        origin: 'https://bar.foo.com',
-        setting: 'block',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: 'https://[*.]foo.com',
-        origin: 'https://[*.]foo.com',
-        setting: 'block',
-        source: 'preference',
-      },
-    ]
-  }
-};
+let prefsMixedProvider;
 
 /**
  * An example pref with with and without embeddingOrigin.
  * @type {SiteSettingsPref}
  */
-const prefsMixedEmbeddingOrigin = {
-  exceptions: {
-    images: [
-      {
-        origin: 'https://foo.com',
-        embeddingOrigin: 'https://example.com',
-        setting: 'allow',
-        source: 'preference',
-      },
-      {
-        origin: 'https://bar.com',
-        embeddingOrigin: '',
-        setting: 'allow',
-        source: 'preference',
-      },
-    ],
-  }
-};
+let prefsMixedEmbeddingOrigin;
 
 /**
  * An example pref with multiple categories and multiple allow/block
  * state.
  * @type {SiteSettingsPref}
  */
-const prefsVarious = {
-  exceptions: {
-    ads: [],
-    auto_downloads: [],
-    background_sync: [],
-    camera: [],
-    cookies: [],
-    geolocation: [
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'https://foo.com',
-        setting: 'allow',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'https://bar.com',
-        setting: 'block',
-        source: 'preference',
-      },
-    ],
-    images: [],
-    javascript: [],
-    mic: [],
-    midi_devices: [],
-    notifications: [
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'https://google.com',
-        setting: 'block',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'https://bar.com',
-        setting: 'block',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'https://foo.com',
-        setting: 'block',
-        source: 'preference',
-      },
-    ],
-    plugins: [],
-    protectedContent: [],
-    popups: [],
-    unsandboxed_plugins: [],
-  }
-};
+let prefsVarious;
 
 /**
  * An example pref with 1 allowed location item.
  * @type {SiteSettingsPref}
  */
-const prefsOneEnabled = {
-  exceptions: {
-    geolocation: [
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'https://foo-allow.com:443',
-        setting: 'allow',
-        source: 'preference',
-      },
-    ]
-  }
-};
+let prefsOneEnabled;
 
 /**
  * An example pref with 1 blocked location item.
  * @type {SiteSettingsPref}
  */
-const prefsOneDisabled = {
-  exceptions: {
-    geolocation: [
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'https://foo-block.com:443',
-        setting: 'block',
-        source: 'preference',
-      },
-    ]
-  }
-};
+let prefsOneDisabled;
 
 /**
  * An example Cookies pref with 1 in each of the three categories.
  * @type {SiteSettingsPref}
  */
-const prefsSessionOnly = {
-  exceptions: {
-    cookies: [
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'http://foo-block.com',
-        setting: 'block',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'http://foo-allow.com',
-        setting: 'allow',
-        source: 'preference',
-      },
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'http://foo-session.com',
-        setting: 'session_only',
-        source: 'preference',
-      },
-    ]
-  }
-};
+let prefsSessionOnly;
 
 /**
  * An example Cookies pref with mixed incognito and regular settings.
  * @type {SiteSettingsPref}
  */
-const prefsIncognito = {
-  exceptions: {
-    cookies: [
-      // foo.com is blocked for regular sessions.
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'http://foo.com',
-        setting: 'block',
-        source: 'preference',
-      },
-      // bar.com is an allowed incognito item.
-      {
-        embeddingOrigin: '',
-        incognito: true,
-        origin: 'http://bar.com',
-        setting: 'allow',
-        source: 'preference',
-      },
-      // foo.com is allowed in incognito (overridden).
-      {
-        embeddingOrigin: '',
-        incognito: true,
-        origin: 'http://foo.com',
-        setting: 'allow',
-        source: 'preference',
-      },
-
-    ]
-  }
-};
+let prefsIncognito;
 
 /**
  * An example Javascript pref with a chrome-extension:// scheme.
  * @type {SiteSettingsPref}
  */
-const prefsChromeExtension = {
-  exceptions: {
-    javascript: [
-      {
-        embeddingOrigin: '',
-        incognito: false,
-        origin: 'chrome-extension://cfhgfbfpcbnnbibfphagcjmgjfjmojfa/',
-        setting: 'block',
-        source: 'preference',
-      },
-    ]
-  }
-};
+let prefsChromeExtension;
 
+/**
+ * Creates all the test |SiteSettingsPref|s that are needed for the tests in
+ * this file. They are populated after test setup in order to access the
+ * |settings| constants required.
+ */
+function populateTestExceptions() {
+  prefsGeolocation = test_util.createSiteSettingsPrefs([], [
+    test_util.createContentSettingTypeToValuePair(
+        settings.ContentSettingsTypes.GEOLOCATION,
+        [
+          test_util.createRawSiteException('https://bar-allow.com:443'),
+          test_util.createRawSiteException('https://foo-allow.com:443'),
+          test_util.createRawSiteException('https://bar-block.com:443', {
+            setting: settings.ContentSetting.BLOCK,
+          }),
+          test_util.createRawSiteException('https://foo-block.com:443', {
+            setting: settings.ContentSetting.BLOCK,
+          })
+        ]),
+  ]);
+
+  prefsControlled = test_util.createSiteSettingsPrefs(
+      [], [test_util.createContentSettingTypeToValuePair(
+              settings.ContentSettingsTypes.PLUGINS,
+              [test_util.createRawSiteException('http://foo-block.com', {
+                embeddingOrigin: '',
+                setting: settings.ContentSetting.BLOCK,
+                source: settings.SiteSettingSource.POLICY,
+              })])]);
+
+  prefsMixedSchemes = test_util.createSiteSettingsPrefs([], [
+    test_util.createContentSettingTypeToValuePair(
+        settings.ContentSettingsTypes.GEOLOCATION,
+        [
+          test_util.createRawSiteException('https://foo-allow.com', {
+            source: settings.SiteSettingSource.POLICY,
+          }),
+          test_util.createRawSiteException('bar-allow.com'),
+        ]),
+  ]);
+
+  prefsMixedProvider = test_util.createSiteSettingsPrefs([], [
+    test_util.createContentSettingTypeToValuePair(
+        settings.ContentSettingsTypes.GEOLOCATION,
+        [
+          test_util.createRawSiteException('https://[*.]foo.com', {
+            setting: settings.ContentSetting.BLOCK,
+            source: settings.SiteSettingSource.POLICY,
+          }),
+          test_util.createRawSiteException('https://bar.foo.com', {
+            setting: settings.ContentSetting.BLOCK,
+            source: settings.SiteSettingSource.POLICY,
+          }),
+          test_util.createRawSiteException('https://[*.]foo.com', {
+            setting: settings.ContentSetting.BLOCK,
+            source: settings.SiteSettingSource.POLICY,
+          })
+        ]),
+  ]);
+
+  prefsMixedEmbeddingOrigin = test_util.createSiteSettingsPrefs([], [
+    test_util.createContentSettingTypeToValuePair(
+        settings.ContentSettingsTypes.IMAGES,
+        [
+          test_util.createRawSiteException('https://foo.com', {
+            embeddingOrigin: 'https://example.com',
+          }),
+          test_util.createRawSiteException('https://bar.com', {
+            embeddingOrigin: '',
+          })
+        ]),
+  ]);
+
+  prefsVarious = test_util.createSiteSettingsPrefs([], [
+    test_util.createContentSettingTypeToValuePair(
+        settings.ContentSettingsTypes.GEOLOCATION,
+        [
+          test_util.createRawSiteException('https://foo.com', {
+            embeddingOrigin: '',
+          }),
+          test_util.createRawSiteException('https://bar.com', {
+            embeddingOrigin: '',
+          })
+        ]),
+    test_util.createContentSettingTypeToValuePair(
+        settings.ContentSettingsTypes.NOTIFICATIONS,
+        [
+          test_util.createRawSiteException('https://google.com', {
+            embeddingOrigin: '',
+          }),
+          test_util.createRawSiteException('https://bar.com', {
+            embeddingOrigin: '',
+          }),
+          test_util.createRawSiteException('https://foo.com', {
+            embeddingOrigin: '',
+          })
+        ]),
+  ]);
+
+  prefsOneEnabled = test_util.createSiteSettingsPrefs([], [
+    test_util.createContentSettingTypeToValuePair(
+        settings.ContentSettingsTypes.GEOLOCATION,
+        [test_util.createRawSiteException('https://foo-allow.com:443', {
+          embeddingOrigin: '',
+        })]),
+  ]);
+
+  prefsOneDisabled = test_util.createSiteSettingsPrefs([], [
+    test_util.createContentSettingTypeToValuePair(
+        settings.ContentSettingsTypes.GEOLOCATION,
+        [test_util.createRawSiteException('https://foo-block.com:443', {
+          embeddingOrigin: '',
+          setting: settings.ContentSetting.BLOCK,
+        })]),
+  ]);
+
+  prefsSessionOnly = test_util.createSiteSettingsPrefs([], [
+    test_util.createContentSettingTypeToValuePair(
+        settings.ContentSettingsTypes.COOKIES,
+        [
+          test_util.createRawSiteException('http://foo-block.com', {
+            embeddingOrigin: '',
+            setting: settings.ContentSetting.BLOCK,
+          }),
+          test_util.createRawSiteException('http://foo-allow.com', {
+            embeddingOrigin: '',
+          }),
+          test_util.createRawSiteException('http://foo-session.com', {
+            embeddingOrigin: '',
+            setting: settings.ContentSetting.SESSION_ONLY,
+          })
+        ]),
+  ]);
+
+  prefsIncognito = test_util.createSiteSettingsPrefs([], [
+    test_util.createContentSettingTypeToValuePair(
+        settings.ContentSettingsTypes.COOKIES,
+        [
+          // foo.com is blocked for regular sessions.
+          test_util.createRawSiteException('http://foo.com', {
+            embeddingOrigin: '',
+            setting: settings.ContentSetting.BLOCK,
+          }),
+          // bar.com is an allowed incognito item.
+          test_util.createRawSiteException('http://bar.com', {
+            embeddingOrigin: '',
+            incognito: true,
+          }),
+          // foo.com is allowed in incognito (overridden).
+          test_util.createRawSiteException('http://foo.com', {
+            embeddingOrigin: '',
+            incognito: true,
+          })
+        ]),
+  ]);
+
+  prefsChromeExtension = test_util.createSiteSettingsPrefs([], [
+    test_util.createContentSettingTypeToValuePair(
+        settings.ContentSettingsTypes.JAVASCRIPT,
+        [test_util.createRawSiteException(
+            'chrome-extension://cfhgfbfpcbnnbibfphagcjmgjfjmojfa/', {
+              embeddingOrigin: '',
+              setting: settings.ContentSetting.BLOCK,
+            })]),
+  ]);
+
+  prefsGeolocationEmpty = test_util.createSiteSettingsPrefs([], []);
+}
 
 suite('SiteList', function() {
   /**
@@ -361,6 +267,8 @@
 
   // Initialize a site-list before each test.
   setup(function() {
+    populateTestExceptions();
+
     browserProxy = new TestSiteSettingsPrefsBrowserProxy();
     settings.SiteSettingsPrefsBrowserProxyImpl.instance_ = browserProxy;
     PolymerTest.clearBody();
@@ -461,7 +369,7 @@
   test('getExceptionList API used', function() {
     setUpCategory(
         settings.ContentSettingsTypes.GEOLOCATION,
-        settings.ContentSetting.ALLOW, prefsEmpty);
+        settings.ContentSetting.ALLOW, prefsGeolocationEmpty);
     return browserProxy.whenCalled('getExceptionList')
         .then(function(contentType) {
           assertEquals(settings.ContentSettingsTypes.GEOLOCATION, contentType);
@@ -471,7 +379,7 @@
   test('Empty list', function() {
     setUpCategory(
         settings.ContentSettingsTypes.GEOLOCATION,
-        settings.ContentSetting.ALLOW, prefsEmpty);
+        settings.ContentSetting.ALLOW, prefsGeolocationEmpty);
     return browserProxy.whenCalled('getExceptionList')
         .then(function(contentType) {
           assertEquals(settings.ContentSettingsTypes.GEOLOCATION, contentType);
@@ -495,10 +403,10 @@
 
           assertEquals(2, testElement.sites.length);
           assertEquals(
-              prefsGeolocation.exceptions.geolocation[0].origin,
+              prefsGeolocation.exceptions[contentType][0].origin,
               testElement.sites[0].origin);
           assertEquals(
-              prefsGeolocation.exceptions.geolocation[1].origin,
+              prefsGeolocation.exceptions[contentType][1].origin,
               testElement.sites[1].origin);
           assertEquals(
               settings.ContentSetting.ALLOW, testElement.categorySubtype);
@@ -544,10 +452,11 @@
           assertEquals(3, testElement.sites.length);
           for (let i = 0; i < testElement.sites.length; ++i) {
             assertEquals(
-                prefsMixedProvider.exceptions.geolocation[i].origin,
+                prefsMixedProvider.exceptions[contentType][i].origin,
                 testElement.sites[i].origin);
             assertEquals(
-                kControlledByLookup[prefsMixedProvider.exceptions.geolocation[i]
+                kControlledByLookup[prefsMixedProvider
+                                        .exceptions[contentType][i]
                                         .source] ||
                     chrome.settingsPrivate.ControlledBy.PRIMARY_USER,
                 testElement.sites[i].controlledBy);
@@ -566,10 +475,10 @@
 
           assertEquals(2, testElement.sites.length);
           assertEquals(
-              prefsGeolocation.exceptions.geolocation[2].origin,
+              prefsGeolocation.exceptions[contentType][2].origin,
               testElement.sites[0].origin);
           assertEquals(
-              prefsGeolocation.exceptions.geolocation[3].origin,
+              prefsGeolocation.exceptions[contentType][3].origin,
               testElement.sites[1].origin);
           Polymer.dom.flush();  // Populates action menu.
           openActionMenu(0);
@@ -590,7 +499,7 @@
 
           assertEquals(1, testElement.sites.length);
           assertEquals(
-              prefsSessionOnly.exceptions.cookies[2].origin,
+              prefsSessionOnly.exceptions[contentType][2].origin,
               testElement.sites[0].origin);
 
           Polymer.dom.flush();  // Populates action menu.
@@ -649,7 +558,7 @@
 
           assertEquals(1, testElement.sites.length);
           assertEquals(
-              prefsIncognito.exceptions.cookies[0].origin,
+              prefsIncognito.exceptions[contentType][0].origin,
               testElement.sites[0].origin);
 
           Polymer.dom.flush();  // Populates action menu.
@@ -682,10 +591,10 @@
 
           assertEquals(2, testElement.sites.length);
           assertEquals(
-              prefsIncognito.exceptions.cookies[1].origin,
+              prefsIncognito.exceptions[contentType][1].origin,
               testElement.sites[0].origin);
           assertEquals(
-              prefsIncognito.exceptions.cookies[2].origin,
+              prefsIncognito.exceptions[contentType][2].origin,
               testElement.sites[1].origin);
 
           Polymer.dom.flush();  // Populates action menu.
@@ -723,7 +632,7 @@
 
           assertEquals(1, testElement.sites.length);
           assertEquals(
-              prefsOneEnabled.exceptions.geolocation[0].origin,
+              prefsOneEnabled.exceptions[contentType][0].origin,
               testElement.sites[0].origin);
 
           Polymer.dom.flush();
@@ -785,10 +694,10 @@
           // Validate that the sites gets populated from pre-canned prefs.
           assertEquals(2, testElement.sites.length);
           assertEquals(
-              prefsGeolocation.exceptions.geolocation[0].origin,
+              prefsGeolocation.exceptions[contentType][0].origin,
               testElement.sites[0].origin);
           assertEquals(
-              prefsGeolocation.exceptions.geolocation[1].origin,
+              prefsGeolocation.exceptions[contentType][1].origin,
               testElement.sites[1].origin);
           assertFalse(!!testElement.selectedOrigin);
 
@@ -798,7 +707,7 @@
           assertTrue(!!clickable);
           MockInteractions.tap(clickable);
           assertEquals(
-              prefsGeolocation.exceptions.geolocation[0].origin,
+              prefsGeolocation.exceptions[contentType][0].origin,
               settings.getQueryParameters().get('site'));
         });
   });
@@ -945,7 +854,7 @@
               'chrome-extension://cfhgfbfpcbnnbibfphagcjmgjfjmojfa/', args[0]);
           assertEquals('', args[1]);
           assertEquals(settings.ContentSettingsTypes.JAVASCRIPT, args[2]);
-          assertEquals('allow', args[3]);
+          assertEquals(settings.ContentSetting.ALLOW, args[3]);
         });
   });
 });
@@ -955,20 +864,21 @@
 
   /**
    * The dialog tests don't call |getExceptionList| so the exception needs to
-   * be processes as a |SiteSettingsPref|.
-   * @type {SiteSettingsPref}
+   * be processed as a |SiteException|.
+   * @type {SiteException}
    */
-  const cookieException = {
-    category: 'cookies',
-    embeddingOrigin: 'http://foo.com',
-    incognito: false,
-    origin: 'http://foo.com',
-    setting: 'block',
-    enforcement: '',
-    controlledBy: 'USER_POLICY',
-  };
+  let cookieException;
 
   setup(function() {
+    cookieException = {
+      category: settings.ContentSettingsTypes.COOKIES,
+      embeddingOrigin: 'http://foo.com',
+      incognito: false,
+      setting: settings.ContentSetting.BLOCK,
+      enforcement: '',
+      controlledBy: 'USER_POLICY',
+    };
+
     browserProxy = new TestSiteSettingsPrefsBrowserProxy();
     settings.SiteSettingsPrefsBrowserProxyImpl.instance_ = browserProxy;
     PolymerTest.clearBody();
@@ -1047,6 +957,8 @@
   /** @type {AddSiteDialogElement} */ let dialog;
 
   setup(function() {
+    populateTestExceptions();
+
     browserProxy = new TestSiteSettingsPrefsBrowserProxy();
     settings.SiteSettingsPrefsBrowserProxyImpl.instance_ = browserProxy;
     PolymerTest.clearBody();
diff --git a/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.js b/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.js
index 23a27b6..107545c2 100644
--- a/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.js
+++ b/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.js
@@ -5,62 +5,14 @@
 /**
  * In the real (non-test) code, this data comes from the C++ handler.
  * Only used for tests.
- * @typedef {{defaults: Map<string, !DefaultContentSetting>,
- *            exceptions: !Map<string, !Array<!RawSiteException>>}}
+ * @typedef {{defaults: !Object<settings.ContentSettingsTypes,
+ *                             !DefaultContentSetting>,
+ *            exceptions: !Object<settings.ContentSettingsTypes,
+ *                                !Array<!RawSiteException>>}}
  */
 let SiteSettingsPref;
 
 /**
- * An example empty pref.
- * TODO(https://crbug.com/742706): Use the values from
- * settings.ContentSettingsTypes (see site_settings/constants.js) as the keys
- * for these instead.
- * @type {SiteSettingsPref}
- */
-const prefsEmpty = {
-  defaults: {
-    ads: {},
-    auto_downloads: {},
-    background_sync: {},
-    camera: {},
-    cookies: {},
-    geolocation: {},
-    javascript: {},
-    mic: {},
-    midi_devices: {},
-    notifications: {},
-    plugins: {},
-    images: {},
-    popups: {},
-    protectedContent: {},
-    sound: {},
-    unsandboxed_plugins: {},
-    clipboard: {},
-    sensors: {},
-  },
-  exceptions: {
-    ads: [],
-    auto_downloads: [],
-    background_sync: [],
-    camera: [],
-    cookies: [],
-    geolocation: [],
-    javascript: [],
-    mic: [],
-    midi_devices: [],
-    notifications: [],
-    plugins: [],
-    images: [],
-    popups: [],
-    protectedContent: [],
-    sound: [],
-    unsandboxed_plugins: [],
-    clipboard: [],
-    sensors: [],
-  },
-};
-
-/**
  * A test version of SiteSettingsPrefsBrowserProxy. Provides helper methods
  * for allowing tests to know when a method was called, as well as
  * specifying mock responses.
@@ -95,7 +47,7 @@
     this.hasIncognito_ = false;
 
     /** @private {!SiteSettingsPref} */
-    this.prefs_ = prefsEmpty;
+    this.prefs_ = test_util.createSiteSettingsPrefs([], []);
 
     /** @private {!Array<ZoomLevelEntry>} */
     this.zoomList_ = [];
@@ -130,6 +82,9 @@
     this.prefs_ = prefs;
 
     // Notify all listeners that their data may be out of date.
+    for (const type in prefs.defaults) {
+      cr.webUIListenerCallback('contentSettingCategoryChanged', type);
+    }
     for (const type in this.prefs_.exceptions) {
       let exceptionList = this.prefs_.exceptions[type];
       for (let i = 0; i < exceptionList.length; ++i) {
@@ -141,25 +96,6 @@
   }
 
   /**
-   * Sets the default prefs only. Use this only when there is a need to
-   * distinguish between the callback for permissions changing and the callback
-   * for default permissions changing.
-   * TODO(https://crbug.com/742706): This function is a hack and should be
-   * removed.
-   * @param {!Map<string, !DefaultContentSetting>} defaultPrefs The new
-   *     default prefs to set.
-   */
-  setDefaultPrefs(defaultPrefs) {
-    this.prefs_.defaults = defaultPrefs;
-
-    // Notify all listeners that their data may be out of date.
-    for (const type in settings.ContentSettingsTypes) {
-      cr.webUIListenerCallback(
-          'contentSettingCategoryChanged', settings.ContentSettingsTypes[type]);
-    }
-  }
-
-  /**
    * Sets one exception for a given category, replacing any existing exceptions
    * for the same origin. Note this ignores embedding origins.
    * @param {!settings.ContentSettingsTypes} category The category the new
@@ -214,15 +150,16 @@
 
   /** @override */
   setOriginPermissions(origin, contentTypes, blanketSetting) {
-    for (const type in this.prefs_.exceptions) {
+    for (let i = 0; i < contentTypes.length; ++i) {
+      let type = contentTypes[i];
       let exceptionList = this.prefs_.exceptions[type];
-      for (let i = 0; i < exceptionList.length; ++i) {
+      for (let j = 0; j < exceptionList.length; ++j) {
         let effectiveSetting = blanketSetting;
         if (blanketSetting == settings.ContentSetting.DEFAULT) {
           effectiveSetting = this.prefs_.defaults[type].setting;
-          exceptionList[i].source = settings.SiteSettingSource.DEFAULT;
+          exceptionList[j].source = settings.SiteSettingSource.DEFAULT;
         }
-        exceptionList[i].setting = effectiveSetting;
+        exceptionList[j].setting = effectiveSetting;
       }
     }
 
@@ -239,52 +176,7 @@
   /** @override */
   getDefaultValueForContentType(contentType) {
     this.methodCalled('getDefaultValueForContentType', contentType);
-
-    let pref = undefined;
-    if (contentType == settings.ContentSettingsTypes.ADS) {
-      pref = this.prefs_.defaults.ads;
-    } else if (
-        contentType == settings.ContentSettingsTypes.AUTOMATIC_DOWNLOADS) {
-      pref = this.prefs_.defaults.auto_downloads;
-    } else if (contentType == settings.ContentSettingsTypes.BACKGROUND_SYNC) {
-      pref = this.prefs_.defaults.background_sync;
-    } else if (contentType == settings.ContentSettingsTypes.CAMERA) {
-      pref = this.prefs_.defaults.camera;
-    } else if (contentType == settings.ContentSettingsTypes.COOKIES) {
-      pref = this.prefs_.defaults.cookies;
-    } else if (contentType == settings.ContentSettingsTypes.GEOLOCATION) {
-      pref = this.prefs_.defaults.geolocation;
-    } else if (contentType == settings.ContentSettingsTypes.IMAGES) {
-      pref = this.prefs_.defaults.images;
-    } else if (contentType == settings.ContentSettingsTypes.JAVASCRIPT) {
-      pref = this.prefs_.defaults.javascript;
-    } else if (contentType == settings.ContentSettingsTypes.MIC) {
-      pref = this.prefs_.defaults.mic;
-    } else if (contentType == settings.ContentSettingsTypes.MIDI_DEVICES) {
-      pref = this.prefs_.defaults.midi_devices;
-    } else if (contentType == settings.ContentSettingsTypes.NOTIFICATIONS) {
-      pref = this.prefs_.defaults.notifications;
-    } else if (contentType == settings.ContentSettingsTypes.PDF_DOCUMENTS) {
-      pref = this.prefs_.defaults.pdf_documents;
-    } else if (contentType == settings.ContentSettingsTypes.POPUPS) {
-      pref = this.prefs_.defaults.popups;
-    } else if (contentType == settings.ContentSettingsTypes.PLUGINS) {
-      pref = this.prefs_.defaults.plugins;
-    } else if (contentType == settings.ContentSettingsTypes.SOUND) {
-      pref = this.prefs_.defaults.sound;
-    } else if (
-        contentType == settings.ContentSettingsTypes.UNSANDBOXED_PLUGINS) {
-      pref = this.prefs_.defaults.unsandboxed_plugins;
-    } else if (contentType == settings.ContentSettingsTypes.PROTECTED_CONTENT) {
-      pref = this.prefs_.defaults.protectedContent;
-    } else if (contentType == settings.ContentSettingsTypes.CLIPBOARD) {
-      pref = this.prefs_.defaults.clipboard;
-    } else if (contentType == settings.ContentSettingsTypes.SENSORS) {
-      pref = this.prefs_.defaults.sensors;
-    } else {
-      console.log('getDefault received unknown category: ' + contentType);
-    }
-
+    let pref = this.prefs_.defaults[contentType];
     assert(pref != undefined, 'Pref is missing for ' + contentType);
     return Promise.resolve(pref);
   }
@@ -292,55 +184,16 @@
   /** @override */
   getExceptionList(contentType) {
     this.methodCalled('getExceptionList', contentType);
-
-    let pref = undefined;
-    if (contentType == settings.ContentSettingsTypes.ADS)
-      pref = this.prefs_.exceptions.ads;
-    else if (contentType == settings.ContentSettingsTypes.AUTOMATIC_DOWNLOADS)
-      pref = this.prefs_.exceptions.auto_downloads;
-    else if (contentType == settings.ContentSettingsTypes.BACKGROUND_SYNC)
-      pref = this.prefs_.exceptions.background_sync;
-    else if (contentType == settings.ContentSettingsTypes.CAMERA)
-      pref = this.prefs_.exceptions.camera;
-    else if (contentType == settings.ContentSettingsTypes.COOKIES)
-      pref = this.prefs_.exceptions.cookies;
-    else if (contentType == settings.ContentSettingsTypes.GEOLOCATION)
-      pref = this.prefs_.exceptions.geolocation;
-    else if (contentType == settings.ContentSettingsTypes.IMAGES)
-      pref = this.prefs_.exceptions.images;
-    else if (contentType == settings.ContentSettingsTypes.JAVASCRIPT)
-      pref = this.prefs_.exceptions.javascript;
-    else if (contentType == settings.ContentSettingsTypes.MIC)
-      pref = this.prefs_.exceptions.mic;
-    else if (contentType == settings.ContentSettingsTypes.MIDI_DEVICES)
-      pref = this.prefs_.exceptions.midi_devices;
-    else if (contentType == settings.ContentSettingsTypes.NOTIFICATIONS)
-      pref = this.prefs_.exceptions.notifications;
-    else if (contentType == settings.ContentSettingsTypes.PDF_DOCUMENTS)
-      pref = this.prefs_.exceptions.pdf_documents;
-    else if (contentType == settings.ContentSettingsTypes.PLUGINS)
-      pref = this.prefs_.exceptions.plugins;
-    else if (contentType == settings.ContentSettingsTypes.PROTECTED_CONTENT)
-      pref = this.prefs_.exceptions.protectedContent;
-    else if (contentType == settings.ContentSettingsTypes.POPUPS)
-      pref = this.prefs_.exceptions.popups;
-    else if (contentType == settings.ContentSettingsTypes.SOUND)
-      pref = this.prefs_.exceptions.sound;
-    else if (contentType == settings.ContentSettingsTypes.UNSANDBOXED_PLUGINS)
-      pref = this.prefs_.exceptions.unsandboxed_plugins;
-    else if (contentType == settings.ContentSettingsTypes.CLIPBOARD)
-      pref = this.prefs_.exceptions.clipboard;
-    else if (contentType == settings.ContentSettingsTypes.SENSORS)
-      pref = this.prefs_.exceptions.sensors;
-    else
-      console.log('getExceptionList received unknown category: ' + contentType);
-
+    let pref = this.prefs_.exceptions[contentType];
     assert(pref != undefined, 'Pref is missing for ' + contentType);
 
     if (this.hasIncognito_) {
       const incognitoElements = [];
-      for (let i = 0; i < pref.length; ++i)
-        incognitoElements.push(Object.assign({incognito: true}, pref[i]));
+      for (let i = 0; i < pref.length; ++i) {
+        // Copy |pref[i]| to avoid changing the original |pref[i]|.
+        const incognitoPref = Object.assign({}, pref[i]);
+        incognitoElements.push(Object.assign(incognitoPref, {incognito: true}));
+      }
       pref = pref.concat(incognitoElements);
     }
 
@@ -388,25 +241,6 @@
 
     const exceptionList = [];
     contentTypes.forEach(function(contentType) {
-      // Convert |contentType| to its corresponding pref name, if different.
-      if (contentType == settings.ContentSettingsTypes.GEOLOCATION) {
-        contentType = 'geolocation';
-      } else if (contentType == settings.ContentSettingsTypes.CAMERA) {
-        contentType = 'camera';
-      } else if (contentType == settings.ContentSettingsTypes.MIC) {
-        contentType = 'mic';
-      } else if (contentType == settings.ContentSettingsTypes.MIDI_DEVICES) {
-        contentType = 'midi_devices';
-      } else if (contentType == settings.ContentSettingsTypes.BACKGROUND_SYNC) {
-        contentType = 'background_sync';
-      } else if (
-          contentType == settings.ContentSettingsTypes.AUTOMATIC_DOWNLOADS) {
-        contentType = 'auto_downloads';
-      } else if (
-          contentType == settings.ContentSettingsTypes.UNSANDBOXED_PLUGINS) {
-        contentType = 'unsandboxed_plugins';
-      }
-
       let setting;
       let source;
       this.prefs_.exceptions[contentType].some((originPrefs) => {
diff --git a/chrome/test/data/webui/settings/test_util.js b/chrome/test/data/webui/settings/test_util.js
index 0fac3a3..386b69507 100644
--- a/chrome/test/data/webui/settings/test_util.js
+++ b/chrome/test/data/webui/settings/test_util.js
@@ -26,8 +26,11 @@
             return;
           }
         }
-      }).observe(
-          target, {attributes: true, childList: false, characterData: false});
+      }).observe(target, {
+        attributes: true,
+        childList: false,
+        characterData: false
+      });
     });
   }
 
@@ -66,9 +69,126 @@
     el2.addEventListener(property + '-changed', forwardChange.bind(null, el1));
   }
 
+  /**
+   * Helper to create an object containing a ContentSettingsType key to array or
+   * object value. This is a convenience function that can eventually be
+   * replaced with ES6 computed properties.
+   * @param {settings.ContentSettingsTypes} contentType The ContentSettingsType
+   *     to use as the key.
+   * @param {Object} value The value to map to |contentType|.
+   * @return {Object<setting: settings.ContentSettingsTypes, value: Object>}
+   */
+  function createContentSettingTypeToValuePair(contentType, value) {
+    return {setting: contentType, value: value};
+  }
+
+  /**
+   * Helper to create a mock DefaultContentSetting.
+   * @param {!Object=} override An object with a subset of the properties of
+   *     DefaultContentSetting. Properties defined in |override| will
+   * overwrite the defaults in this function's return value.
+   * @return {DefaultContentSetting}
+   */
+  function createDefaultContentSetting(override) {
+    if (override === undefined)
+      override = {};
+    return Object.assign(
+        {
+          setting: settings.ContentSetting.ASK,
+          source: settings.SiteSettingSource.PREFERENCE,
+        },
+        override);
+  }
+
+  /**
+   * Helper to create a mock RawSiteException.
+   * @param {!string} origin The origin to use for this RawSiteException.
+   * @param {!Object=} override An object with a subset of the properties of
+   *     RawSiteException. Properties defined in |override| will overwrite the
+   *     defaults in this function's return value.
+   * @return {RawSiteException}
+   */
+  function createRawSiteException(origin, override) {
+    if (override === undefined)
+      override = {};
+    return Object.assign(
+        {
+          embeddingOrigin: origin,
+          incognito: false,
+          origin: origin,
+          displayName: '',
+          setting: settings.ContentSetting.ALLOW,
+          source: settings.SiteSettingSource.PREFERENCE,
+        },
+        override);
+  }
+
+  /**
+   * Helper to create a mock SiteSettingsPref.
+   * @param {!Array<{setting: settings.ContentSettingsTypes,
+   *                 value: DefaultContentSetting}>} defaultsList A list of
+   *     DefaultContentSettings and the content settings they apply to, which
+   *     will overwrite the defaults in the SiteSettingsPref returned by this
+   *     function.
+   * @param {!Array<{setting: settings.ContentSettingsTypes,
+   *                 value: !Array<RawSiteException>}>} exceptionsList A list of
+   *     RawSiteExceptions and the content settings they apply to, which will
+   *     overwrite the exceptions in the SiteSettingsPref returned by this
+   *     function.
+   * @return {SiteSettingsPref}
+   */
+  function createSiteSettingsPrefs(defaultsList, exceptionsList) {
+    // These test defaults reflect the actual defaults assigned to each
+    // ContentSettingType, but keeping these in sync shouldn't matter for tests.
+    const defaults = {};
+    for (let type in settings.ContentSettingsTypes) {
+      defaults[settings.ContentSettingsTypes[type]] =
+          createDefaultContentSetting({});
+    }
+    defaults[settings.ContentSettingsTypes.COOKIES].setting =
+        settings.ContentSetting.ALLOW;
+    defaults[settings.ContentSettingsTypes.IMAGES].setting =
+        settings.ContentSetting.ALLOW;
+    defaults[settings.ContentSettingsTypes.JAVASCRIPT].setting =
+        settings.ContentSetting.ALLOW;
+    defaults[settings.ContentSettingsTypes.SOUND].setting =
+        settings.ContentSetting.ALLOW;
+    defaults[settings.ContentSettingsTypes.POPUPS].setting =
+        settings.ContentSetting.BLOCK;
+    defaults[settings.ContentSettingsTypes.PROTOCOL_HANDLERS].setting =
+        settings.ContentSetting.ALLOW;
+    defaults[settings.ContentSettingsTypes.BACKGROUND_SYNC].setting =
+        settings.ContentSetting.ALLOW;
+    defaults[settings.ContentSettingsTypes.ADS].setting =
+        settings.ContentSetting.BLOCK;
+    defaults[settings.ContentSettingsTypes.SENSORS].setting =
+        settings.ContentSetting.ALLOW;
+    defaultsList.forEach((override) => {
+      defaults[override.setting] = override.value;
+    });
+
+    const exceptions = {};
+    for (let type in settings.ContentSettingsTypes) {
+      exceptions[settings.ContentSettingsTypes[type]] = [];
+    }
+    exceptionsList.forEach((override) => {
+      exceptions[override.setting] = override.value;
+    });
+
+    return {
+      defaults: defaults,
+      exceptions: exceptions,
+    };
+  }
+
   return {
     eventToPromise: eventToPromise,
     fakeDataBind: fakeDataBind,
     whenAttributeIs: whenAttributeIs,
+    createContentSettingTypeToValuePair: createContentSettingTypeToValuePair,
+    createDefaultContentSetting: createDefaultContentSetting,
+    createRawSiteException: createRawSiteException,
+    createSiteSettingsPrefs: createSiteSettingsPrefs,
   };
+
 });
diff --git a/components/browser_sync/profile_sync_components_factory_impl.cc b/components/browser_sync/profile_sync_components_factory_impl.cc
index 9c4a83a..b54f9384 100644
--- a/components/browser_sync/profile_sync_components_factory_impl.cc
+++ b/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -37,10 +37,7 @@
 #include "components/sync/driver/proxy_data_type_controller.h"
 #include "components/sync/driver/sync_client.h"
 #include "components/sync/driver/sync_driver_switches.h"
-#include "components/sync/engine/attachments/attachment_downloader.h"
-#include "components/sync/engine/attachments/attachment_uploader.h"
 #include "components/sync/engine/sync_engine.h"
-#include "components/sync/model/attachments/attachment_service.h"
 #include "components/sync_bookmarks/bookmark_change_processor.h"
 #include "components/sync_bookmarks/bookmark_data_type_controller.h"
 #include "components/sync_bookmarks/bookmark_model_associator.h"
@@ -382,54 +379,6 @@
   return token_service_;
 }
 
-std::unique_ptr<syncer::AttachmentService>
-ProfileSyncComponentsFactoryImpl::CreateAttachmentService(
-    std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store,
-    const syncer::UserShare& user_share,
-    const std::string& store_birthday,
-    syncer::ModelType model_type,
-    syncer::AttachmentService::Delegate* delegate) {
-  std::unique_ptr<syncer::AttachmentUploader> attachment_uploader;
-  std::unique_ptr<syncer::AttachmentDownloader> attachment_downloader;
-  // Only construct an AttachmentUploader and AttachmentDownload if we have sync
-  // credentials. We may not have sync credentials because there may not be a
-  // signed in sync user.
-  if (!user_share.sync_credentials.account_id.empty() &&
-      !user_share.sync_credentials.scope_set.empty()) {
-    scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>
-        token_service_provider(
-            new TokenServiceProvider(ui_thread_, token_service_));
-    // TODO(maniscalco): Use shared (one per profile) thread-safe instances of
-    // AttachmentUploader and AttachmentDownloader instead of creating a new one
-    // per AttachmentService (bug 369536).
-    attachment_uploader = syncer::AttachmentUploader::Create(
-        sync_service_url_, url_request_context_getter_,
-        user_share.sync_credentials.account_id,
-        user_share.sync_credentials.scope_set, token_service_provider,
-        store_birthday, model_type);
-
-    token_service_provider =
-        new TokenServiceProvider(ui_thread_, token_service_);
-    attachment_downloader = syncer::AttachmentDownloader::Create(
-        sync_service_url_, url_request_context_getter_,
-        user_share.sync_credentials.account_id,
-        user_share.sync_credentials.scope_set, token_service_provider,
-        store_birthday, model_type);
-  }
-
-  // It is important that the initial backoff delay is relatively large.  For
-  // whatever reason, the server may fail all requests for a short period of
-  // time.  When this happens we don't want to overwhelm the server with
-  // requests so we use a large initial backoff.
-  const base::TimeDelta initial_backoff_delay =
-      base::TimeDelta::FromMinutes(30);
-  const base::TimeDelta max_backoff_delay = base::TimeDelta::FromHours(4);
-  return syncer::AttachmentService::Create(
-      std::move(attachment_store), std::move(attachment_uploader),
-      std::move(attachment_downloader), delegate, initial_backoff_delay,
-      max_backoff_delay);
-}
-
 syncer::SyncApiComponentFactory::SyncComponents
 ProfileSyncComponentsFactoryImpl::CreateBookmarkSyncComponents(
     syncer::SyncService* sync_service,
diff --git a/components/browser_sync/profile_sync_components_factory_impl.h b/components/browser_sync/profile_sync_components_factory_impl.h
index 351e688..fa0259a 100644
--- a/components/browser_sync/profile_sync_components_factory_impl.h
+++ b/components/browser_sync/profile_sync_components_factory_impl.h
@@ -79,12 +79,6 @@
       const base::FilePath& sync_data_folder) override;
   std::unique_ptr<syncer::LocalDeviceInfoProvider>
   CreateLocalDeviceInfoProvider() override;
-  std::unique_ptr<syncer::AttachmentService> CreateAttachmentService(
-      std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store,
-      const syncer::UserShare& user_share,
-      const std::string& store_birthday,
-      syncer::ModelType model_type,
-      syncer::AttachmentService::Delegate* delegate) override;
   syncer::SyncApiComponentFactory::SyncComponents CreateBookmarkSyncComponents(
       syncer::SyncService* sync_service,
       std::unique_ptr<syncer::DataTypeErrorHandler> error_handler) override;
diff --git a/components/cronet/tools/generators/cronet_bindings_generator.py b/components/cronet/tools/generators/cronet_bindings_generator.py
index 65696da..66706d20 100755
--- a/components/cronet/tools/generators/cronet_bindings_generator.py
+++ b/components/cronet/tools/generators/cronet_bindings_generator.py
@@ -212,8 +212,7 @@
             export_attribute=args.export_attribute,
             export_header=args.export_header,
             generate_non_variant_code=args.generate_non_variant_code,
-            support_lazy_serialization=args.support_lazy_serialization,
-            allow_native_structs=args.allow_native_structs)
+            support_lazy_serialization=args.support_lazy_serialization)
         filtered_args = []
         if hasattr(generator_module, 'GENERATOR_PREFIX'):
           prefix = '--' + generator_module.GENERATOR_PREFIX + '_'
@@ -369,11 +368,6 @@
       "--support_lazy_serialization",
       help="If set, generated bindings will serialize lazily when possible.",
       action="store_true")
-  generate_parser.add_argument(
-      "--allow_native_structs",
-      help="Allows the [Native] attribute to be specified on structs within "
-      "the mojom file. Must not be specified on internal bindings mojom or "
-      "other dependencies thereof.", action="store_true")
   generate_parser.set_defaults(func=_Generate)
 
   precompile_parser = subparsers.add_parser("precompile",
diff --git a/components/cronet/tools/generators/cronet_c_generator.py b/components/cronet/tools/generators/cronet_c_generator.py
index 0d954b70..f880359 100644
--- a/components/cronet/tools/generators/cronet_c_generator.py
+++ b/components/cronet/tools/generators/cronet_c_generator.py
@@ -292,7 +292,6 @@
 
     return {
       "all_enums": all_enums,
-      "allow_native_structs": self.allow_native_structs,
       "enums": self.module.enums,
       "export_attribute": self.export_attribute,
       "export_header": self.export_header,
diff --git a/components/dom_distiller/core/dom_distiller_store_unittest.cc b/components/dom_distiller/core/dom_distiller_store_unittest.cc
index f5ac32bd..09cb30e 100644
--- a/components/dom_distiller/core/dom_distiller_store_unittest.cc
+++ b/components/dom_distiller/core/dom_distiller_store_unittest.cc
@@ -19,8 +19,6 @@
 #include "components/dom_distiller/core/article_entry.h"
 #include "components/dom_distiller/core/dom_distiller_test_util.h"
 #include "components/leveldb_proto/testing/fake_db.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/protocol/sync.pb.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -163,10 +161,8 @@
  protected:
   SyncData CreateSyncData(const ArticleEntry& entry) {
     EntitySpecifics specifics = SpecificsFromEntry(entry);
-    return SyncData::CreateRemoteData(
-        next_sync_id_++, specifics, Time::UnixEpoch(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create());
+    return SyncData::CreateRemoteData(next_sync_id_++, specifics,
+                                      Time::UnixEpoch());
   }
 
   SyncDataList SyncDataFromEntryMap(const EntryMap& model) {
diff --git a/components/exo/client_controlled_shell_surface.cc b/components/exo/client_controlled_shell_surface.cc
index e1224848..877fcf14 100644
--- a/components/exo/client_controlled_shell_surface.cc
+++ b/components/exo/client_controlled_shell_surface.cc
@@ -84,6 +84,7 @@
                                              next_state);
   }
   void HandleBoundsRequest(ash::wm::WindowState* window_state,
+                           ash::mojom::WindowStateType requested_state,
                            const gfx::Rect& bounds) override {
     bool is_resize = window_state->window()->bounds().size() != bounds.size();
 
@@ -95,7 +96,8 @@
                              .id();
 
     shell_surface_->OnBoundsChangeEvent(
-        window_state->GetStateType(), display_id, bounds_in_screen, is_resize,
+        window_state->GetStateType(), requested_state, display_id,
+        bounds_in_screen, is_resize,
         window_state->drag_details()
             ? window_state->drag_details()->bounds_change
             : 0);
@@ -243,24 +245,34 @@
 
 void ClientControlledShellSurface::SetMaximized() {
   TRACE_EVENT0("exo", "ClientControlledShellSurface::SetMaximized");
-  pending_show_state_ = ui::SHOW_STATE_MAXIMIZED;
+  pending_window_state_ = ash::mojom::WindowStateType::MAXIMIZED;
 }
 
 void ClientControlledShellSurface::SetMinimized() {
   TRACE_EVENT0("exo", "ClientControlledShellSurface::SetMinimized");
-  pending_show_state_ = ui::SHOW_STATE_MINIMIZED;
+  pending_window_state_ = ash::mojom::WindowStateType::MINIMIZED;
 }
 
 void ClientControlledShellSurface::SetRestored() {
   TRACE_EVENT0("exo", "ClientControlledShellSurface::SetRestored");
-  pending_show_state_ = ui::SHOW_STATE_NORMAL;
+  pending_window_state_ = ash::mojom::WindowStateType::NORMAL;
 }
 
 void ClientControlledShellSurface::SetFullscreen(bool fullscreen) {
   TRACE_EVENT1("exo", "ClientControlledShellSurface::SetFullscreen",
                "fullscreen", fullscreen);
-  pending_show_state_ =
-      fullscreen ? ui::SHOW_STATE_FULLSCREEN : ui::SHOW_STATE_NORMAL;
+  pending_window_state_ = fullscreen ? ash::mojom::WindowStateType::FULLSCREEN
+                                     : ash::mojom::WindowStateType::NORMAL;
+}
+
+void ClientControlledShellSurface::SetSnappedToLeft() {
+  TRACE_EVENT0("exo", "ClientControlledShellSurface::SetSnappedToLeft");
+  pending_window_state_ = ash::mojom::WindowStateType::LEFT_SNAPPED;
+}
+
+void ClientControlledShellSurface::SetSnappedToRight() {
+  TRACE_EVENT0("exo", "ClientControlledShellSurface::SetSnappedToRight");
+  pending_window_state_ = ash::mojom::WindowStateType::RIGHT_SNAPPED;
 }
 
 void ClientControlledShellSurface::SetPinned(ash::mojom::WindowPinType type) {
@@ -384,13 +396,14 @@
 
 void ClientControlledShellSurface::OnBoundsChangeEvent(
     ash::mojom::WindowStateType current_state,
+    ash::mojom::WindowStateType requested_state,
     int64_t display_id,
     const gfx::Rect& bounds,
     bool is_resize,
     int bounds_change) {
   if (!bounds.IsEmpty() && !bounds_changed_callback_.is_null()) {
-    bounds_changed_callback_.Run(current_state, display_id, bounds, is_resize,
-                                 bounds_change);
+    bounds_changed_callback_.Run(current_state, requested_state, display_id,
+                                 bounds, is_resize, bounds_change);
   }
 }
 
@@ -409,38 +422,33 @@
 
 void ClientControlledShellSurface::OnSurfaceCommit() {
   if (!widget_)
-    CreateShellSurfaceWidget(pending_show_state_);
+    CreateShellSurfaceWidget(ash::ToWindowShowState(pending_window_state_));
 
-  if (widget_->GetNativeWindow()->GetProperty(aura::client::kShowStateKey) !=
-      pending_show_state_) {
-    ash::wm::WindowState* window_state = GetWindowState();
+  ash::wm::WindowState* window_state = GetWindowState();
+  if (window_state->GetStateType() != pending_window_state_) {
     if (!IsPinned(window_state)) {
-      ash::mojom::WindowStateType next_window_state =
-          ash::mojom::WindowStateType::NORMAL;
       ash::wm::ClientControlledState::BoundsChangeAnimationType animation_type =
           ash::wm::ClientControlledState::kAnimationNone;
-      switch (pending_show_state_) {
-        case ui::SHOW_STATE_NORMAL:
-          if (widget_->IsMaximized() || widget_->IsFullscreen())
+      switch (pending_window_state_) {
+        case ash::mojom::WindowStateType::NORMAL:
+          if (widget_->IsMaximized() || widget_->IsFullscreen()) {
             animation_type =
                 ash::wm::ClientControlledState::kAnimationCrossFade;
+          }
           break;
-        case ui::SHOW_STATE_MINIMIZED:
-          next_window_state = ash::mojom::WindowStateType::MINIMIZED;
-          break;
-        case ui::SHOW_STATE_MAXIMIZED:
+
+        case ash::mojom::WindowStateType::MAXIMIZED:
+        case ash::mojom::WindowStateType::FULLSCREEN:
+        case ash::mojom::WindowStateType::LEFT_SNAPPED:
+        case ash::mojom::WindowStateType::RIGHT_SNAPPED:
           animation_type = ash::wm::ClientControlledState::kAnimationCrossFade;
-          next_window_state = ash::mojom::WindowStateType::MAXIMIZED;
           break;
-        case ui::SHOW_STATE_FULLSCREEN:
-          animation_type = ash::wm::ClientControlledState::kAnimationCrossFade;
-          next_window_state = ash::mojom::WindowStateType::FULLSCREEN;
-          break;
+
         default:
           break;
       }
-      client_controlled_state_->EnterNextState(window_state, next_window_state,
-                                               animation_type);
+      client_controlled_state_->EnterNextState(
+          window_state, pending_window_state_, animation_type);
     } else {
       VLOG(1) << "State change was requested while it is pinned";
     }
diff --git a/components/exo/client_controlled_shell_surface.h b/components/exo/client_controlled_shell_surface.h
index 7c9349db0..c0dc612 100644
--- a/components/exo/client_controlled_shell_surface.h
+++ b/components/exo/client_controlled_shell_surface.h
@@ -63,9 +63,15 @@
   // Called when the client was restored.
   void SetRestored();
 
-  // Called when the client chagned the fullscreen state.
+  // Called when the client changed the fullscreen state.
   void SetFullscreen(bool fullscreen);
 
+  // Called when the client was snapped to left.
+  void SetSnappedToLeft();
+
+  // Called when the client was snapped to right.
+  void SetSnappedToRight();
+
   // Set the callback to run when the surface state changed.
   using StateChangedCallback =
       base::RepeatingCallback<void(ash::mojom::WindowStateType old_state_type,
@@ -77,7 +83,8 @@
 
   // Set the callback to run when the surface bounds changed.
   using BoundsChangedCallback = base::RepeatingCallback<void(
-      ash::mojom::WindowStateType current_state_type,
+      ash::mojom::WindowStateType current_state,
+      ash::mojom::WindowStateType requested_state,
       int64_t display_id,
       const gfx::Rect& bounds,
       bool is_resize,
@@ -130,12 +137,15 @@
   // Sends the window bounds change event to client. |display_id| specifies in
   // which display the surface should live in. |drag_bounds_change| is
   // a masked value of ash::WindowResizer::kBoundsChange_Xxx, and specifies
-  // how the bounds was changed.
+  // how the bounds was changed. The bounds change event may also come from a
+  // snapped window state change |requested_state|.
   void OnBoundsChangeEvent(ash::mojom::WindowStateType current_state,
+                           ash::mojom::WindowStateType requested_state,
                            int64_t display_id,
                            const gfx::Rect& bounds,
                            bool is_resize,
                            int drag_bounds_change);
+
   // Sends the window drag events to client.
   void OnDragStarted(int component);
   void OnDragFinished(bool cancel, const gfx::Point& location);
@@ -238,7 +248,8 @@
 
   ash::wm::ClientControlledState* client_controlled_state_ = nullptr;
 
-  ui::WindowShowState pending_show_state_ = ui::SHOW_STATE_NORMAL;
+  ash::mojom::WindowStateType pending_window_state_ =
+      ash::mojom::WindowStateType::NORMAL;
 
   bool can_maximize_ = true;
 
diff --git a/components/exo/client_controlled_shell_surface_unittest.cc b/components/exo/client_controlled_shell_surface_unittest.cc
index 4decd526..6a1be07 100644
--- a/components/exo/client_controlled_shell_surface_unittest.cc
+++ b/components/exo/client_controlled_shell_surface_unittest.cc
@@ -9,6 +9,7 @@
 #include "ash/shell.h"
 #include "ash/shell_test_api.h"
 #include "ash/system/tray/system_tray.h"
+#include "ash/wm/splitview/split_view_controller.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "ash/wm/window_positioning_utils.h"
 #include "ash/wm/window_state.h"
@@ -801,4 +802,59 @@
   EXPECT_FALSE(window->Contains(found));
 }
 
+// Test the snap functionalities in splitscreen in tablet mode.
+TEST_F(ClientControlledShellSurfaceTest, SnapWindowInSplitViewModeTest) {
+  UpdateDisplay("807x607");
+  ash::Shell* shell = ash::Shell::Get();
+  shell->tablet_mode_controller()->EnableTabletModeWindowManager(true);
+
+  const gfx::Size buffer_size(800, 600);
+  std::unique_ptr<Buffer> buffer1(
+      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+  std::unique_ptr<Surface> surface1(new Surface);
+  auto shell_surface1 =
+      exo_test_helper()->CreateClientControlledShellSurface(surface1.get());
+  // Start in maximized.
+  shell_surface1->SetMaximized();
+  surface1->Attach(buffer1.get());
+  surface1->Commit();
+
+  aura::Window* window1 = shell_surface1->GetWidget()->GetNativeWindow();
+  ash::wm::WindowState* window_state1 = ash::wm::GetWindowState(window1);
+  ash::wm::ClientControlledState* state1 =
+      static_cast<ash::wm::ClientControlledState*>(
+          ash::wm::WindowState::TestApi::GetStateImpl(window_state1));
+  EXPECT_EQ(window_state1->GetStateType(),
+            ash::mojom::WindowStateType::MAXIMIZED);
+
+  // Snap window to left.
+  ash::SplitViewController* split_view_controller =
+      shell->split_view_controller();
+  split_view_controller->SnapWindow(window1, ash::SplitViewController::LEFT);
+  state1->set_bounds_locally(true);
+  window1->SetBounds(split_view_controller->GetSnappedWindowBoundsInScreen(
+      window1, ash::SplitViewController::LEFT));
+  state1->set_bounds_locally(false);
+  EXPECT_EQ(window_state1->GetStateType(),
+            ash::mojom::WindowStateType::LEFT_SNAPPED);
+  EXPECT_EQ(shell_surface1->GetWidget()->GetWindowBoundsInScreen(),
+            split_view_controller->GetSnappedWindowBoundsInScreen(
+                window1, ash::SplitViewController::LEFT));
+  EXPECT_TRUE(HasBackdrop());
+  split_view_controller->EndSplitView();
+
+  // Snap window to right.
+  split_view_controller->SnapWindow(window1, ash::SplitViewController::RIGHT);
+  state1->set_bounds_locally(true);
+  window1->SetBounds(split_view_controller->GetSnappedWindowBoundsInScreen(
+      window1, ash::SplitViewController::RIGHT));
+  state1->set_bounds_locally(false);
+  EXPECT_EQ(window_state1->GetStateType(),
+            ash::mojom::WindowStateType::RIGHT_SNAPPED);
+  EXPECT_EQ(shell_surface1->GetWidget()->GetWindowBoundsInScreen(),
+            split_view_controller->GetSnappedWindowBoundsInScreen(
+                window1, ash::SplitViewController::RIGHT));
+  EXPECT_TRUE(HasBackdrop());
+}
+
 }  // namespace exo
diff --git a/components/exo/test/test_client_controlled_state_delegate.cc b/components/exo/test/test_client_controlled_state_delegate.cc
index d229677..f5db0bc 100644
--- a/components/exo/test/test_client_controlled_state_delegate.cc
+++ b/components/exo/test/test_client_controlled_state_delegate.cc
@@ -47,6 +47,7 @@
 
 void TestClientControlledStateDelegate::HandleBoundsRequest(
     ash::wm::WindowState* window_state,
+    ash::mojom::WindowStateType requested_state,
     const gfx::Rect& bounds) {
   ash::wm::ClientControlledState* state_impl =
       static_cast<ash::wm::ClientControlledState*>(
@@ -54,6 +55,21 @@
   state_impl->set_bounds_locally(true);
   window_state->window()->SetBounds(bounds);
   state_impl->set_bounds_locally(false);
+
+  views::Widget* widget =
+      views::Widget::GetWidgetForNativeWindow(window_state->window());
+  ClientControlledShellSurface* shell_surface =
+      static_cast<ClientControlledShellSurface*>(widget->widget_delegate());
+
+  if (requested_state != window_state->GetStateType()) {
+    DCHECK(requested_state == ash::mojom::WindowStateType::LEFT_SNAPPED ||
+           requested_state == ash::mojom::WindowStateType::RIGHT_SNAPPED);
+    if (requested_state == ash::mojom::WindowStateType::LEFT_SNAPPED)
+      shell_surface->SetSnappedToLeft();
+    else
+      shell_surface->SetSnappedToRight();
+  }
+  shell_surface->OnSurfaceCommit();
 }
 
 // static
diff --git a/components/exo/test/test_client_controlled_state_delegate.h b/components/exo/test/test_client_controlled_state_delegate.h
index a39ebb7a..2ba4f96a 100644
--- a/components/exo/test/test_client_controlled_state_delegate.h
+++ b/components/exo/test/test_client_controlled_state_delegate.h
@@ -24,6 +24,7 @@
       ash::wm::WindowState* window_state,
       ash::mojom::WindowStateType next_state) override;
   void HandleBoundsRequest(ash::wm::WindowState* window_state,
+                           ash::mojom::WindowStateType requested_state,
                            const gfx::Rect& bounds) override;
 
  private:
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
index 18539e3f..78e0332 100644
--- a/components/exo/wayland/server.cc
+++ b/components/exo/wayland/server.cc
@@ -2116,6 +2116,16 @@
       gfx::Size(width, height));
 }
 
+void remote_surface_set_snapped_to_left(wl_client* client,
+                                        wl_resource* resource) {
+  GetUserDataAs<ClientControlledShellSurface>(resource)->SetSnappedToLeft();
+}
+
+void remote_surface_set_snapped_to_right(wl_client* client,
+                                         wl_resource* resource) {
+  GetUserDataAs<ClientControlledShellSurface>(resource)->SetSnappedToRight();
+}
+
 const struct zcr_remote_surface_v1_interface remote_surface_implementation = {
     remote_surface_destroy,
     remote_surface_set_app_id,
@@ -2149,7 +2159,9 @@
     remote_surface_set_can_maximize,
     remote_surface_unset_can_maximize,
     remote_surface_set_min_size,
-    remote_surface_set_max_size};
+    remote_surface_set_max_size,
+    remote_surface_set_snapped_to_left,
+    remote_surface_set_snapped_to_right};
 
 ////////////////////////////////////////////////////////////////////////////////
 // notification_surface_interface:
@@ -2404,6 +2416,12 @@
     case ash::mojom::WindowStateType::TRUSTED_PINNED:
       state_type = ZCR_REMOTE_SHELL_V1_STATE_TYPE_TRUSTED_PINNED;
       break;
+    case ash::mojom::WindowStateType::LEFT_SNAPPED:
+      state_type = ZCR_REMOTE_SHELL_V1_STATE_TYPE_LEFT_SNAPPED;
+      break;
+    case ash::mojom::WindowStateType::RIGHT_SNAPPED:
+      state_type = ZCR_REMOTE_SHELL_V1_STATE_TYPE_RIGHT_SNAPPED;
+      break;
     default:
       break;
   }
@@ -2414,7 +2432,8 @@
 
 void HandleRemoteSurfaceBoundsChangedCallback(
     wl_resource* resource,
-    ash::mojom::WindowStateType current_state_type,
+    ash::mojom::WindowStateType current_state,
+    ash::mojom::WindowStateType requested_state,
     int64_t display_id,
     const gfx::Rect& bounds,
     bool resize,
@@ -2426,6 +2445,10 @@
     reason = ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_DRAG_RESIZE;
   } else if (bounds_change & ash::WindowResizer::kBoundsChange_Repositions) {
     reason = ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_DRAG_MOVE;
+  } else if (requested_state == ash::mojom::WindowStateType::LEFT_SNAPPED) {
+    reason = ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_SNAP_TO_LEFT;
+  } else if (requested_state == ash::mojom::WindowStateType::RIGHT_SNAPPED) {
+    reason = ZCR_REMOTE_SURFACE_V1_BOUNDS_CHANGE_REASON_SNAP_TO_RIGHT;
   }
   zcr_remote_surface_v1_send_bounds_changed(
       resource, static_cast<uint32_t>(display_id >> 32),
@@ -2593,7 +2616,7 @@
     remote_shell_destroy, remote_shell_get_remote_surface,
     remote_shell_get_notification_surface};
 
-const uint32_t remote_shell_version = 10;
+const uint32_t remote_shell_version = 11;
 
 void bind_remote_shell(wl_client* client,
                        void* data,
diff --git a/components/history/core/browser/history_service_unittest.cc b/components/history/core/browser/history_service_unittest.cc
index ea2c852..4ed089e1 100644
--- a/components/history/core/browser/history_service_unittest.cc
+++ b/components/history/core/browser/history_service_unittest.cc
@@ -35,8 +35,6 @@
 #include "components/history/core/browser/history_db_task.h"
 #include "components/history/core/test/database_test_utils.h"
 #include "components/history/core/test/test_history_database.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_change.h"
 #include "components/sync/model/sync_change_processor.h"
@@ -754,12 +752,8 @@
           .ToInternalValue());
   global_id_directive->set_start_time_usec(3);
   global_id_directive->set_end_time_usec(10);
-  directives.push_back(syncer::SyncData::CreateRemoteData(
-      1,
-      entity_specs,
-      base::Time(),
-      syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create()));
+  directives.push_back(
+      syncer::SyncData::CreateRemoteData(1, entity_specs, base::Time()));
 
   // 2nd directive.
   global_id_directive->Clear();
@@ -768,12 +762,8 @@
           .ToInternalValue());
   global_id_directive->set_start_time_usec(13);
   global_id_directive->set_end_time_usec(19);
-  directives.push_back(syncer::SyncData::CreateRemoteData(
-      2,
-      entity_specs,
-      base::Time(),
-      syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create()));
+  directives.push_back(
+      syncer::SyncData::CreateRemoteData(2, entity_specs, base::Time()));
 
   syncer::FakeSyncChangeProcessor change_processor;
   EXPECT_FALSE(history_service_
@@ -840,23 +830,15 @@
           ->mutable_time_range_directive();
   time_range_directive->set_start_time_usec(2);
   time_range_directive->set_end_time_usec(5);
-  directives.push_back(syncer::SyncData::CreateRemoteData(
-      1,
-      entity_specs,
-      base::Time(),
-      syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create()));
+  directives.push_back(
+      syncer::SyncData::CreateRemoteData(1, entity_specs, base::Time()));
 
   // 2nd directive.
   time_range_directive->Clear();
   time_range_directive->set_start_time_usec(8);
   time_range_directive->set_end_time_usec(10);
-  directives.push_back(syncer::SyncData::CreateRemoteData(
-      2,
-      entity_specs,
-      base::Time(),
-      syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create()));
+  directives.push_back(
+      syncer::SyncData::CreateRemoteData(2, entity_specs, base::Time()));
 
   syncer::FakeSyncChangeProcessor change_processor;
   EXPECT_FALSE(history_service_
diff --git a/components/history/core/browser/typed_url_syncable_service_unittest.cc b/components/history/core/browser/typed_url_syncable_service_unittest.cc
index 7206a2a..cccac39 100644
--- a/components/history/core/browser/typed_url_syncable_service_unittest.cc
+++ b/components/history/core/browser/typed_url_syncable_service_unittest.cc
@@ -23,7 +23,6 @@
 #include "components/history/core/browser/history_types.h"
 #include "components/history/core/browser/in_memory_history_backend.h"
 #include "components/history/core/test/test_history_database.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_change_processor_wrapper_for_test.h"
 #include "components/sync/model/sync_error.h"
@@ -374,9 +373,8 @@
   sync_pb::TypedUrlSpecifics* typed_url_specifics =
       entity_specifics.mutable_typed_url();
   WriteToTypedUrlSpecifics(row, visits, typed_url_specifics);
-  syncer::SyncData sync_data = syncer::SyncData::CreateRemoteData(
-      1, entity_specifics, base::Time(), syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create());
+  syncer::SyncData sync_data =
+      syncer::SyncData::CreateRemoteData(1, entity_specifics, base::Time());
   syncer::SyncChange sync_change(FROM_HERE, change_type, sync_data);
   change_list.push_back(sync_change);
   typed_url_sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
diff --git a/components/payments/content/payment_request_state.cc b/components/payments/content/payment_request_state.cc
index b3c4a4a..a3923fb 100644
--- a/components/payments/content/payment_request_state.cc
+++ b/components/payments/content/payment_request_state.cc
@@ -60,9 +60,8 @@
         payment_request_delegate_->GetPaymentManifestWebDataService(),
         spec_->method_data(),
         base::BindOnce(&PaymentRequestState::GetAllPaymentAppsCallback,
-                       weak_ptr_factory_.GetWeakPtr(),
-                       web_contents->GetBrowserContext(), top_level_origin,
-                       frame_origin),
+                       weak_ptr_factory_.GetWeakPtr(), web_contents,
+                       top_level_origin, frame_origin),
         base::BindOnce([]() {
           /* Nothing needs to be done after writing cache. This callback is used
            * only in tests. */
@@ -77,24 +76,35 @@
 PaymentRequestState::~PaymentRequestState() {}
 
 void PaymentRequestState::GetAllPaymentAppsCallback(
-    content::BrowserContext* context,
+    content::WebContents* web_contents,
     const GURL& top_level_origin,
     const GURL& frame_origin,
     content::PaymentAppProvider::PaymentApps apps,
     ServiceWorkerPaymentAppFactory::InstallablePaymentApps installable_apps) {
-  number_of_pending_sw_payment_instruments_ = apps.size();
+  number_of_pending_sw_payment_instruments_ =
+      apps.size() + installable_apps.size();
   if (number_of_pending_sw_payment_instruments_ == 0U) {
     FinishedGetAllSWPaymentInstruments();
     return;
   }
 
-  // TODO(crbug.com/782270): Create installable service worker payment
-  // instruments based on |installable_apps|.
   for (auto& app : apps) {
     std::unique_ptr<ServiceWorkerPaymentInstrument> instrument =
         std::make_unique<ServiceWorkerPaymentInstrument>(
-            context, top_level_origin, frame_origin, spec_,
-            std::move(app.second), payment_request_delegate_);
+            web_contents->GetBrowserContext(), top_level_origin, frame_origin,
+            spec_, std::move(app.second), payment_request_delegate_);
+    instrument->ValidateCanMakePayment(
+        base::BindOnce(&PaymentRequestState::OnSWPaymentInstrumentValidated,
+                       weak_ptr_factory_.GetWeakPtr()));
+    available_instruments_.push_back(std::move(instrument));
+  }
+
+  for (auto& installable_app : installable_apps) {
+    std::unique_ptr<ServiceWorkerPaymentInstrument> instrument =
+        std::make_unique<ServiceWorkerPaymentInstrument>(
+            web_contents, top_level_origin, frame_origin, spec_,
+            std::move(installable_app.second), installable_app.first.spec(),
+            payment_request_delegate_);
     instrument->ValidateCanMakePayment(
         base::BindOnce(&PaymentRequestState::OnSWPaymentInstrumentValidated,
                        weak_ptr_factory_.GetWeakPtr()));
diff --git a/components/payments/content/payment_request_state.h b/components/payments/content/payment_request_state.h
index 6750fe5..3e7a29e 100644
--- a/components/payments/content/payment_request_state.h
+++ b/components/payments/content/payment_request_state.h
@@ -229,7 +229,7 @@
 
   // The PaymentAppProvider::GetAllPaymentAppsCallback.
   void GetAllPaymentAppsCallback(
-      content::BrowserContext* context,
+      content::WebContents* web_contents,
       const GURL& top_level_origin,
       const GURL& frame_origin,
       content::PaymentAppProvider::PaymentApps apps,
diff --git a/components/payments/content/service_worker_payment_instrument.cc b/components/payments/content/service_worker_payment_instrument.cc
index 9ef9fe2..ccf5979 100644
--- a/components/payments/content/service_worker_payment_instrument.cc
+++ b/components/payments/content/service_worker_payment_instrument.cc
@@ -10,6 +10,7 @@
 #include "components/payments/core/payment_request_delegate.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/payment_app_provider.h"
+#include "content/public/browser/web_contents.h"
 #include "ui/gfx/image/image_skia.h"
 
 namespace payments {
@@ -17,14 +18,14 @@
 // Service worker payment app provides icon through bitmap, so set 0 as invalid
 // resource Id.
 ServiceWorkerPaymentInstrument::ServiceWorkerPaymentInstrument(
-    content::BrowserContext* context,
+    content::BrowserContext* browser_context,
     const GURL& top_level_origin,
     const GURL& frame_origin,
     const PaymentRequestSpec* spec,
     std::unique_ptr<content::StoredPaymentApp> stored_payment_app_info,
     PaymentRequestDelegate* payment_request_delegate)
     : PaymentInstrument(0, PaymentInstrument::Type::SERVICE_WORKER_APP),
-      browser_context_(context),
+      browser_context_(browser_context),
       top_level_origin_(top_level_origin),
       frame_origin_(frame_origin),
       spec_(spec),
@@ -32,6 +33,7 @@
       delegate_(nullptr),
       payment_request_delegate_(payment_request_delegate),
       can_make_payment_result_(false),
+      needs_installation_(false),
       weak_ptr_factory_(this) {
   DCHECK(browser_context_);
   DCHECK(top_level_origin_.is_valid());
@@ -48,11 +50,45 @@
   }
 }
 
+// Service worker payment app provides icon through bitmap, so set 0 as invalid
+// resource Id.
+ServiceWorkerPaymentInstrument::ServiceWorkerPaymentInstrument(
+    content::WebContents* web_contents,
+    const GURL& top_level_origin,
+    const GURL& frame_origin,
+    const PaymentRequestSpec* spec,
+    std::unique_ptr<WebAppInstallationInfo> installable_payment_app_info,
+    const std::string& enabled_method,
+    PaymentRequestDelegate* payment_request_delegate)
+    : PaymentInstrument(0, PaymentInstrument::Type::SERVICE_WORKER_APP),
+      top_level_origin_(top_level_origin),
+      frame_origin_(frame_origin),
+      spec_(spec),
+      delegate_(nullptr),
+      payment_request_delegate_(payment_request_delegate),
+      can_make_payment_result_(false),
+      needs_installation_(true),
+      web_contents_(web_contents),
+      installable_web_app_info_(std::move(installable_payment_app_info)),
+      installable_enabled_method_(enabled_method),
+      weak_ptr_factory_(this) {
+  DCHECK(web_contents_);
+  DCHECK(top_level_origin_.is_valid());
+  DCHECK(frame_origin_.is_valid());
+  DCHECK(spec_);
+
+  // Icon is not available in WebAppInstallationInfo for now, so create an empty
+  // icon image to avoid using invalid icon resource id.
+  icon_image_ = gfx::ImageSkia::CreateFrom1xBitmap(SkBitmap()).DeepCopy();
+}
+
 ServiceWorkerPaymentInstrument::~ServiceWorkerPaymentInstrument() {
-  if (delegate_) {
-    // If there's a payment handler in progress, abort it before destroying this
+  // TODO(crbug.com/782270): Implement abort InstallAndInvokePaymentApp for
+  // payment app that needs installation.
+  if (delegate_ && !needs_installation_) {
+    // If there's a payment in progress, abort it before destroying this
     // so that it can close its window. Since the PaymentRequest will be
-    // destroyed, pass an empty callback to the payment handler.
+    // destroyed, pass an empty callback to the payment app.
     content::PaymentAppProvider::GetInstance()->AbortPayment(
         browser_context_, stored_payment_app_info_->registration_id,
         base::Bind([](bool) {}));
@@ -61,12 +97,18 @@
 
 void ServiceWorkerPaymentInstrument::ValidateCanMakePayment(
     ValidateCanMakePaymentCallback callback) {
+  // Returns true for payment app that needs installation.
+  if (needs_installation_) {
+    OnCanMakePayment(std::move(callback), true);
+    return;
+  }
+
   mojom::CanMakePaymentEventDataPtr event_data =
       CreateCanMakePaymentEventData();
   if (event_data.is_null()) {
     // This could only happen if this instrument only supports non-url based
     // payment methods of the payment request, then return true
-    // and do not send CanMakePaymentEvent to the payment handler.
+    // and do not send CanMakePaymentEvent to the payment app.
     OnCanMakePayment(std::move(callback), true);
     return;
   }
@@ -145,11 +187,22 @@
 void ServiceWorkerPaymentInstrument::InvokePaymentApp(Delegate* delegate) {
   delegate_ = delegate;
 
-  content::PaymentAppProvider::GetInstance()->InvokePaymentApp(
-      browser_context_, stored_payment_app_info_->registration_id,
-      CreatePaymentRequestEventData(),
-      base::BindOnce(&ServiceWorkerPaymentInstrument::OnPaymentAppInvoked,
-                     weak_ptr_factory_.GetWeakPtr()));
+  if (needs_installation_) {
+    content::PaymentAppProvider::GetInstance()->InstallAndInvokePaymentApp(
+        web_contents_, CreatePaymentRequestEventData(),
+        installable_web_app_info_->name, installable_web_app_info_->sw_js_url,
+        installable_web_app_info_->sw_scope,
+        installable_web_app_info_->sw_use_cache,
+        std::vector<std::string>(1, installable_enabled_method_),
+        base::BindOnce(&ServiceWorkerPaymentInstrument::OnPaymentAppInvoked,
+                       weak_ptr_factory_.GetWeakPtr()));
+  } else {
+    content::PaymentAppProvider::GetInstance()->InvokePaymentApp(
+        browser_context_, stored_payment_app_info_->registration_id,
+        CreatePaymentRequestEventData(),
+        base::BindOnce(&ServiceWorkerPaymentInstrument::OnPaymentAppInvoked,
+                       weak_ptr_factory_.GetWeakPtr()));
+  }
 
   payment_request_delegate_->ShowProcessingSpinner();
 }
@@ -168,8 +221,12 @@
   event_data->total = spec_->details().total->amount.Clone();
 
   std::unordered_set<std::string> supported_methods;
-  supported_methods.insert(stored_payment_app_info_->enabled_methods.begin(),
-                           stored_payment_app_info_->enabled_methods.end());
+  if (needs_installation_) {
+    supported_methods.insert(installable_enabled_method_);
+  } else {
+    supported_methods.insert(stored_payment_app_info_->enabled_methods.begin(),
+                             stored_payment_app_info_->enabled_methods.end());
+  }
   for (const auto& modifier : spec_->details().modifiers) {
     std::vector<std::string>::const_iterator it =
         modifier->method_data->supported_methods.begin();
@@ -228,6 +285,11 @@
   // , so this interface should not be invoked.
   DCHECK(can_make_payment_result_);
 
+  // Returns false for PaymentRequest.CanMakePayment query if the app needs
+  // installation.
+  if (needs_installation_)
+    return false;
+
   return true;
 }
 
@@ -236,10 +298,17 @@
 }
 
 base::string16 ServiceWorkerPaymentInstrument::GetLabel() const {
-  return base::UTF8ToUTF16(stored_payment_app_info_->name);
+  return base::UTF8ToUTF16(needs_installation_
+                               ? installable_web_app_info_->name
+                               : stored_payment_app_info_->name);
 }
 
 base::string16 ServiceWorkerPaymentInstrument::GetSublabel() const {
+  if (needs_installation_) {
+    DCHECK(GURL(installable_web_app_info_->sw_scope).is_valid());
+    return base::UTF8ToUTF16(
+        GURL(installable_web_app_info_->sw_scope).GetOrigin().spec());
+  }
   return base::UTF8ToUTF16(stored_payment_app_info_->scope.GetOrigin().spec());
 }
 
@@ -249,6 +318,13 @@
     const std::set<std::string>& supported_networks,
     bool supported_types_specified,
     const std::set<autofill::CreditCard::CardType>& supported_types) const {
+  // Payment app that needs installation only supports url based payment
+  // methods.
+  if (needs_installation_) {
+    return std::find(methods.begin(), methods.end(),
+                     installable_enabled_method_) != methods.end();
+  }
+
   std::vector<std::string> matched_methods;
   for (const auto& modifier_supported_method : methods) {
     if (base::ContainsValue(stored_payment_app_info_->enabled_methods,
@@ -260,6 +336,8 @@
   if (matched_methods.empty())
     return false;
 
+  // Return true if 'basic-card' is not the only matched payment method. This
+  // assumes that there is no duplicated payment methods.
   if (matched_methods.size() > 1U || matched_methods[0] != "basic-card")
     return true;
 
diff --git a/components/payments/content/service_worker_payment_instrument.h b/components/payments/content/service_worker_payment_instrument.h
index f599ee4..37e8063 100644
--- a/components/payments/content/service_worker_payment_instrument.h
+++ b/components/payments/content/service_worker_payment_instrument.h
@@ -6,12 +6,17 @@
 #define COMPONENTS_PAYMENTS_CONTENT_SERVICE_WORKER_PAYMENT_INSTRUMENT_H_
 
 #include "components/payments/content/payment_request_spec.h"
+#include "components/payments/content/web_app_manifest.h"
 #include "components/payments/core/payment_instrument.h"
-#include "content/public/browser/browser_context.h"
 #include "content/public/browser/stored_payment_app.h"
 #include "third_party/WebKit/public/platform/modules/payments/payment_app.mojom.h"
 #include "third_party/WebKit/public/platform/modules/payments/payment_request.mojom.h"
 
+namespace content {
+class BrowserContext;
+class WebContents;
+}  // namespace content
+
 namespace payments {
 
 class PaymentRequestDelegate;
@@ -19,13 +24,26 @@
 // Represents a service worker based payment app.
 class ServiceWorkerPaymentInstrument : public PaymentInstrument {
  public:
+  // This constructor is used for a payment app that has been installed in
+  // Chrome.
   ServiceWorkerPaymentInstrument(
-      content::BrowserContext* context,
+      content::BrowserContext* browser_context,
       const GURL& top_level_origin,
       const GURL& frame_origin,
       const PaymentRequestSpec* spec,
       std::unique_ptr<content::StoredPaymentApp> stored_payment_app_info,
       PaymentRequestDelegate* payment_request_delegate);
+
+  // This contructor is used for a payment app that has not been installed in
+  // Chrome but can be installed when paying with it.
+  ServiceWorkerPaymentInstrument(
+      content::WebContents* web_contents,
+      const GURL& top_level_origin,
+      const GURL& frame_origin,
+      const PaymentRequestSpec* spec,
+      std::unique_ptr<WebAppInstallationInfo> installable_payment_app_info,
+      const std::string& enabled_methods,
+      PaymentRequestDelegate* payment_request_delegate);
   ~ServiceWorkerPaymentInstrument() override;
 
   // The callback for ValidateCanMakePayment.
@@ -36,10 +54,10 @@
       base::OnceCallback<void(ServiceWorkerPaymentInstrument*, bool)>;
 
   // Validates whether this payment instrument can be used for this payment
-  // request. It fires CanMakePaymentEvent to the payment handler to do
-  // validation. The result is returned through callback.If the returned result
-  // is false, then this instrument should not be used for this payment request.
-  // This interface must be called before any other interfaces in this class.
+  // request. It fires CanMakePaymentEvent to the payment app to do validation.
+  // The result is returned through callback.If the returned result is false,
+  // then this instrument should not be used for this payment request. This
+  // interface must be called before any other interfaces in this class.
   void ValidateCanMakePayment(ValidateCanMakePaymentCallback callback);
 
   // PaymentInstrument:
@@ -85,6 +103,13 @@
   // PaymentAppProvider::CanMakePayment result of this payment instrument.
   bool can_make_payment_result_;
 
+  // Below variables are used for installable ServiceWorkerPaymentInstrument
+  // specifically.
+  bool needs_installation_;
+  content::WebContents* web_contents_;
+  std::unique_ptr<WebAppInstallationInfo> installable_web_app_info_;
+  std::string installable_enabled_method_;
+
   base::WeakPtrFactory<ServiceWorkerPaymentInstrument> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerPaymentInstrument);
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc
index e4917473..6fc6fd8d 100644
--- a/components/policy/core/common/cloud/cloud_policy_client.cc
+++ b/components/policy/core/common/cloud/cloud_policy_client.cc
@@ -130,6 +130,7 @@
 
 void CloudPolicyClient::Register(em::DeviceRegisterRequest::Type type,
                                  em::DeviceRegisterRequest::Flavor flavor,
+                                 em::DeviceRegisterRequest::Lifetime lifetime,
                                  em::LicenseType::LicenseTypeEnum license_type,
                                  const std::string& auth_token,
                                  const std::string& client_id,
@@ -163,6 +164,7 @@
   request->set_flavor(flavor);
   if (license_type != em::LicenseType::UNDEFINED)
     request->mutable_license_type()->set_license_type(license_type);
+  request->set_lifetime(lifetime);
 
   policy_fetch_request_job_->SetRetryCallback(
       base::Bind(&CloudPolicyClient::OnRetryRegister,
@@ -176,6 +178,7 @@
 void CloudPolicyClient::RegisterWithCertificate(
     em::DeviceRegisterRequest::Type type,
     em::DeviceRegisterRequest::Flavor flavor,
+    em::DeviceRegisterRequest::Lifetime lifetime,
     em::LicenseType::LicenseTypeEnum license_type,
     const std::string& pem_certificate_chain,
     const std::string& client_id,
@@ -207,6 +210,7 @@
   request->set_flavor(flavor);
   if (license_type != em::LicenseType::UNDEFINED)
     request->mutable_license_type()->set_license_type(license_type);
+  request->set_lifetime(lifetime);
 
   signing_service_->SignData(data.SerializeAsString(),
       base::Bind(&CloudPolicyClient::OnRegisterWithCertificateRequestSigned,
diff --git a/components/policy/core/common/cloud/cloud_policy_client.h b/components/policy/core/common/cloud/cloud_policy_client.h
index d21c1d2..bd9e2c8a 100644
--- a/components/policy/core/common/cloud/cloud_policy_client.h
+++ b/components/policy/core/common/cloud/cloud_policy_client.h
@@ -113,6 +113,7 @@
   virtual void Register(
       enterprise_management::DeviceRegisterRequest::Type registration_type,
       enterprise_management::DeviceRegisterRequest::Flavor flavor,
+      enterprise_management::DeviceRegisterRequest::Lifetime lifetime,
       enterprise_management::LicenseType::LicenseTypeEnum license_type,
       const std::string& auth_token,
       const std::string& client_id,
@@ -125,6 +126,7 @@
   virtual void RegisterWithCertificate(
       enterprise_management::DeviceRegisterRequest::Type registration_type,
       enterprise_management::DeviceRegisterRequest::Flavor flavor,
+      enterprise_management::DeviceRegisterRequest::Lifetime lifetime,
       enterprise_management::LicenseType::LicenseTypeEnum license_type,
       const std::string& pem_certificate_chain,
       const std::string& client_id,
diff --git a/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc b/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc
index 5e34c08..1c885bf 100644
--- a/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc
+++ b/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc
@@ -265,6 +265,7 @@
   client_->Register(
       registration_type_,
       enterprise_management::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
+      enterprise_management::DeviceRegisterRequest::LIFETIME_INDEFINITE,
       enterprise_management::LicenseType::UNDEFINED, oauth_access_token_,
       std::string(), std::string(), std::string());
 }
diff --git a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
index ff6c109..38fc638 100644
--- a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
+++ b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
@@ -53,7 +53,6 @@
 const char kAssetId[] = "fake-asset-id";
 const char kLocation[] = "fake-location";
 const char kGcmID[] = "fake-gcm-id";
-
 const int64_t kAgeOfCommand = 123123123;
 const int64_t kLastCommandId = 123456789;
 const int64_t kTimestamp = 987654321;
@@ -103,6 +102,8 @@
     register_request->set_type(em::DeviceRegisterRequest::USER);
     register_request->set_machine_id(kMachineID);
     register_request->set_machine_model(kMachineModel);
+    register_request->set_lifetime(
+        em::DeviceRegisterRequest::LIFETIME_INDEFINITE);
     register_request->set_flavor(
         em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION);
 
@@ -115,6 +116,7 @@
     request->set_type(em::DeviceRegisterRequest::DEVICE);
     request->set_machine_id(kMachineID);
     request->set_machine_model(kMachineModel);
+    request->set_lifetime(em::DeviceRegisterRequest::LIFETIME_INDEFINITE);
     request->set_flavor(
         em::DeviceRegisterRequest::FLAVOR_ENROLLMENT_ATTESTATION);
 
@@ -438,6 +440,7 @@
   EXPECT_CALL(observer_, OnRegistrationStateChanged(_));
   client_->Register(em::DeviceRegisterRequest::USER,
                     em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
+                    em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
                     em::LicenseType::UNDEFINED, kOAuthToken, std::string(),
                     std::string(), std::string());
   EXPECT_TRUE(client_->is_registered());
@@ -458,6 +461,7 @@
   client_->RegisterWithCertificate(
       em::DeviceRegisterRequest::DEVICE,
       em::DeviceRegisterRequest::FLAVOR_ENROLLMENT_ATTESTATION,
+      em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
       em::LicenseType::UNDEFINED, kEnrollmentCertificate, std::string(),
       std::string(), std::string());
   EXPECT_TRUE(client_->is_registered());
@@ -477,6 +481,7 @@
   client_->RegisterWithCertificate(
       em::DeviceRegisterRequest::DEVICE,
       em::DeviceRegisterRequest::FLAVOR_ENROLLMENT_ATTESTATION,
+      em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
       em::LicenseType::UNDEFINED, kEnrollmentCertificate, std::string(),
       std::string(), std::string());
   EXPECT_FALSE(client_->is_registered());
@@ -495,6 +500,7 @@
   EXPECT_CALL(observer_, OnRegistrationStateChanged(_));
   client_->Register(em::DeviceRegisterRequest::USER,
                     em::DeviceRegisterRequest::FLAVOR_ENROLLMENT_MANUAL,
+                    em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
                     em::LicenseType::UNDEFINED, kOAuthToken, kClientID,
                     kRequisition, kStateKey);
   EXPECT_EQ(kClientID, client_id_);
@@ -507,6 +513,7 @@
   EXPECT_CALL(observer_, OnClientError(_));
   client_->Register(em::DeviceRegisterRequest::USER,
                     em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
+                    em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
                     em::LicenseType::UNDEFINED, kOAuthToken, std::string(),
                     std::string(), std::string());
   EXPECT_FALSE(client_->is_registered());
@@ -523,6 +530,7 @@
   EXPECT_CALL(observer_, OnClientError(_));
   client_->Register(em::DeviceRegisterRequest::USER,
                     em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
+                    em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
                     em::LicenseType::UNDEFINED, kOAuthToken, std::string(),
                     std::string(), std::string());
   EXPECT_FALSE(client_->is_registered());
@@ -545,6 +553,7 @@
                        MatchProto(registration_request_)));
   client_->Register(em::DeviceRegisterRequest::USER,
                     em::DeviceRegisterRequest::FLAVOR_USER_REGISTRATION,
+                    em::DeviceRegisterRequest::LIFETIME_INDEFINITE,
                     em::LicenseType::UNDEFINED, kOAuthToken, std::string(),
                     std::string(), std::string());
   EXPECT_FALSE(client_->is_registered());
diff --git a/components/policy/core/common/cloud/mock_cloud_policy_client.h b/components/policy/core/common/cloud/mock_cloud_policy_client.h
index 29678d1b..ff45774 100644
--- a/components/policy/core/common/cloud/mock_cloud_policy_client.h
+++ b/components/policy/core/common/cloud/mock_cloud_policy_client.h
@@ -21,10 +21,11 @@
   virtual ~MockCloudPolicyClient();
 
   MOCK_METHOD2(SetupRegistration, void(const std::string&, const std::string&));
-  MOCK_METHOD7(
+  MOCK_METHOD8(
       Register,
       void(enterprise_management::DeviceRegisterRequest::Type type,
            enterprise_management::DeviceRegisterRequest::Flavor flavor,
+           enterprise_management::DeviceRegisterRequest::Lifetime lifetime,
            enterprise_management::LicenseType::LicenseTypeEnum license_type,
            const std::string&,
            const std::string&,
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto
index dc155d5..d801dd5 100644
--- a/components/policy/proto/device_management_backend.proto
+++ b/components/policy/proto/device_management_backend.proto
@@ -128,6 +128,17 @@
 
   // If specified, represents the license type selected by user on the device.
   optional LicenseType license_type = 9;
+
+  // Enumerates different expected lifetimes of registration.
+  enum Lifetime {
+    // Default case, no expiration.
+    LIFETIME_INDEFINITE = 0;
+    // Lifetime for ephemeral user policy registration.
+    LIFETIME_EPHEMERAL_USER = 1;
+  }
+
+  // Indicates the expected lifetime of registration.
+  optional Lifetime lifetime = 10;
 }
 
 // Response from server to device register request.
diff --git a/components/safe_browsing/browser/threat_details.cc b/components/safe_browsing/browser/threat_details.cc
index 901b2b1..ff81c5f 100644
--- a/components/safe_browsing/browser/threat_details.cc
+++ b/components/safe_browsing/browser/threat_details.cc
@@ -197,11 +197,11 @@
   }
 
   // Take a second pass and determine which element IDs to keep. We want to keep
-  // both siblings and children of the target ids. We start by identifying the
-  // siblings by finding the common parent of each target element, and keeping
-  // all of its children (ie: the siblings of the target elements).
+  // the immediate parent, the siblings, and the children of the target ids.
+  // By keeping the parent of the target and all of its children, this covers
+  // the target's siblings as well.
   std::vector<int> ids_to_keep;
-  // Keep track of ids that were kept to avoid duplicated. We still need the
+  // Keep track of ids that were kept to avoid duplication. We still need the
   // vector above for handling the children where it is used like a queue.
   std::unordered_set<int> kept_ids;
   for (int target_id : target_ids) {
@@ -213,12 +213,12 @@
       return;
     }
 
-    const HTMLElement* parent_element = elements_by_id[parent_id];
-    for (int sibling_id : parent_element->child_ids()) {
-      if (kept_ids.count(sibling_id) == 0) {
-        ids_to_keep.push_back(sibling_id);
-        kept_ids.insert(sibling_id);
-      }
+    // Otherwise, insert the parent ID into the list of ids to keep. This will
+    // capture the parent and siblings of the target element, as well as each of
+    // their children.
+    if (kept_ids.count(parent_id) == 0) {
+      ids_to_keep.push_back(parent_id);
+      kept_ids.insert(parent_id);
     }
   }
 
diff --git a/components/safe_browsing/triggers/ad_sampler_trigger.cc b/components/safe_browsing/triggers/ad_sampler_trigger.cc
index ba8237b..2205297 100644
--- a/components/safe_browsing/triggers/ad_sampler_trigger.cc
+++ b/components/safe_browsing/triggers/ad_sampler_trigger.cc
@@ -32,6 +32,10 @@
 // A frequency denominator with this value indicates sampling is disabled.
 const size_t kSamplerFrequencyDisabled = 0;
 
+// Number of milliseconds to wait after a page finished loading before starting
+// a report. Allows ads which load in the background to finish loading.
+const int64_t kAdSampleCollectionStartDelayMilliseconds = 1000;
+
 // Number of milliseconds to allow data collection to run before sending a
 // report (since this trigger runs in the background).
 const int64_t kAdSampleCollectionPeriodMilliseconds = 5000;
@@ -99,11 +103,13 @@
     history::HistoryService* history_service)
     : content::WebContentsObserver(web_contents),
       sampler_frequency_denominator_(GetSamplerFrequencyDenominator()),
+      start_report_delay_ms_(kAdSampleCollectionStartDelayMilliseconds),
       finish_report_delay_ms_(kAdSampleCollectionPeriodMilliseconds),
       trigger_manager_(trigger_manager),
       prefs_(prefs),
       request_context_(request_context),
-      history_service_(history_service) {}
+      history_service_(history_service),
+      weak_ptr_factory_(this) {}
 
 AdSamplerTrigger::~AdSamplerTrigger() {}
 
@@ -141,6 +147,16 @@
     return;
   }
 
+  // Create a report after a short delay. The delay gives more time for ads to
+  // finish loading in the background. This is best-effort.
+  content::BrowserThread::PostDelayedTask(
+      content::BrowserThread::UI, FROM_HERE,
+      base::BindOnce(&AdSamplerTrigger::CreateAdSampleReport,
+                     weak_ptr_factory_.GetWeakPtr()),
+      base::TimeDelta::FromMilliseconds(start_report_delay_ms_));
+}
+
+void AdSamplerTrigger::CreateAdSampleReport() {
   SBErrorOptions error_options =
       TriggerManager::GetSBErrorDisplayOptions(*prefs_, *web_contents());
 
diff --git a/components/safe_browsing/triggers/ad_sampler_trigger.h b/components/safe_browsing/triggers/ad_sampler_trigger.h
index 21ca643d..e4a9be5 100644
--- a/components/safe_browsing/triggers/ad_sampler_trigger.h
+++ b/components/safe_browsing/triggers/ad_sampler_trigger.h
@@ -6,6 +6,7 @@
 #define COMPONENTS_SAFE_BROWSING_TRIGGERS_AD_SAMPLER_TRIGGER_H_
 
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 
@@ -80,10 +81,17 @@
                    net::URLRequestContextGetter* request_context,
                    history::HistoryService* history_service);
 
+  // Called to create an ad sample report.
+  void CreateAdSampleReport();
+
   // Ad samples will be collected with frequency
   // 1/|sampler_frequency_denominator_|
   size_t sampler_frequency_denominator_;
 
+  // The delay (in milliseconds) to wait before starting a report. Can be
+  // ovewritten for tests.
+  int64_t start_report_delay_ms_;
+
   // The delay (in milliseconds) to wait before finishing a report. Can be
   // overwritten for tests.
   int64_t finish_report_delay_ms_;
@@ -96,6 +104,8 @@
   net::URLRequestContextGetter* request_context_;
   history::HistoryService* history_service_;
 
+  base::WeakPtrFactory<AdSamplerTrigger> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(AdSamplerTrigger);
 };
 
diff --git a/components/safe_browsing/triggers/ad_sampler_trigger_unittest.cc b/components/safe_browsing/triggers/ad_sampler_trigger_unittest.cc
index 02bc9e5..a78ace6d 100644
--- a/components/safe_browsing/triggers/ad_sampler_trigger_unittest.cc
+++ b/components/safe_browsing/triggers/ad_sampler_trigger_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/metrics/field_trial_params.h"
 #include "base/test/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/test/test_simple_task_runner.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/safe_browsing/features.h"
 #include "components/safe_browsing/triggers/trigger_manager.h"
@@ -58,12 +59,17 @@
 
 class AdSamplerTriggerTest : public content::RenderViewHostTestHarness {
  public:
-  AdSamplerTriggerTest() {}
+  AdSamplerTriggerTest() : task_runner_(new base::TestSimpleTaskRunner) {}
   ~AdSamplerTriggerTest() override {}
 
   void SetUp() override {
     content::RenderViewHostTestHarness::SetUp();
 
+    // Replace the task runner for the UI thread (since tests run on UI, and
+    // so does the trigger) with a testing task runner that specific tests
+    // can synchronize on.
+    base::MessageLoop::current()->SetTaskRunner(task_runner_);
+
     // Enable any prefs required for the trigger to run.
     safe_browsing::RegisterProfilePrefs(prefs_.registry());
     prefs_.SetBoolean(prefs::kSafeBrowsingExtendedReportingOptInAllowed, true);
@@ -76,6 +82,9 @@
         web_contents(), &trigger_manager_, &prefs_, nullptr, nullptr);
     safe_browsing::AdSamplerTrigger::FromWebContents(web_contents())
         ->sampler_frequency_denominator_ = denominator;
+    // Set delay timers artificially to keep tests fast.
+    safe_browsing::AdSamplerTrigger::FromWebContents(web_contents())
+        ->start_report_delay_ms_ = 0;
     safe_browsing::AdSamplerTrigger::FromWebContents(web_contents())
         ->finish_report_delay_ms_ = 0;
   }
@@ -110,6 +119,11 @@
     return NavigateFrame(url, subframe);
   }
 
+  void WaitForTaskRunnerIdle() {
+    task_runner_->RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
+  }
+
   MockTriggerManager* get_trigger_manager() { return &trigger_manager_; }
   base::HistogramTester* get_histograms() { return &histograms_; }
 
@@ -117,6 +131,7 @@
   TestingPrefServiceSimple prefs_;
   MockTriggerManager trigger_manager_;
   base::HistogramTester histograms_;
+  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
 };
 
 TEST_F(AdSamplerTriggerTest, TriggerDisabledBySamplingFrequency) {
@@ -188,6 +203,9 @@
   CreateAndNavigateSubFrame(kAdUrl, kNonAdName, main_frame);
   CreateAndNavigateSubFrame(kNonAdUrl, kAdName, main_frame);
 
+  // Wait for any posted tasks to finish.
+  WaitForTaskRunnerIdle();
+
   // Three navigations (main frame, two subframes). Main frame with no ads, and
   // two sampled ads
   get_histograms()->ExpectBucketCount(kAdSamplerTriggerActionMetricName,
@@ -217,6 +235,9 @@
   CreateAndNavigateSubFrame(kAdUrl, kNonAdName, main_frame);
   CreateAndNavigateSubFrame(kNonAdUrl, kNonAdName, main_frame);
 
+  // Wait for any posted tasks to finish.
+  WaitForTaskRunnerIdle();
+
   // Three navigations (main frame, two subframes). Two frames with no ads, and
   // one ad rejected by trigger manager.
   get_histograms()->ExpectBucketCount(kAdSamplerTriggerActionMetricName,
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn
index a1ec9be..3202b92 100644
--- a/components/sync/BUILD.gn
+++ b/components/sync/BUILD.gn
@@ -159,24 +159,6 @@
     "driver/user_selectable_sync_type.h",
     "engine/activation_context.cc",
     "engine/activation_context.h",
-    "engine/attachments/attachment_downloader.cc",
-    "engine/attachments/attachment_downloader.h",
-    "engine/attachments/attachment_store_backend.cc",
-    "engine/attachments/attachment_store_backend.h",
-    "engine/attachments/attachment_store_frontend.cc",
-    "engine/attachments/attachment_store_frontend.h",
-    "engine/attachments/attachment_uploader.cc",
-    "engine/attachments/attachment_uploader.h",
-    "engine/attachments/attachment_util.cc",
-    "engine/attachments/attachment_util.h",
-    "engine/attachments/fake_attachment_downloader.cc",
-    "engine/attachments/fake_attachment_downloader.h",
-    "engine/attachments/fake_attachment_uploader.cc",
-    "engine/attachments/fake_attachment_uploader.h",
-    "engine/attachments/in_memory_attachment_store.cc",
-    "engine/attachments/in_memory_attachment_store.h",
-    "engine/attachments/on_disk_attachment_store.cc",
-    "engine/attachments/on_disk_attachment_store.h",
     "engine/commit_queue.cc",
     "engine/commit_queue.h",
     "engine/configure_reason.h",
@@ -254,10 +236,6 @@
     "engine_impl/all_status.h",
     "engine_impl/apply_control_data_updates.cc",
     "engine_impl/apply_control_data_updates.h",
-    "engine_impl/attachments/attachment_downloader_impl.cc",
-    "engine_impl/attachments/attachment_downloader_impl.h",
-    "engine_impl/attachments/attachment_uploader_impl.cc",
-    "engine_impl/attachments/attachment_uploader_impl.h",
     "engine_impl/backoff_delay_provider.cc",
     "engine_impl/backoff_delay_provider.h",
     "engine_impl/clear_server_data.cc",
@@ -401,20 +379,6 @@
     "js/js_event_handler.h",
     "js/sync_js_controller.cc",
     "js/sync_js_controller.h",
-    "model/attachments/attachment.cc",
-    "model/attachments/attachment.h",
-    "model/attachments/attachment_id.cc",
-    "model/attachments/attachment_id.h",
-    "model/attachments/attachment_metadata.cc",
-    "model/attachments/attachment_metadata.h",
-    "model/attachments/attachment_service.cc",
-    "model/attachments/attachment_service.h",
-    "model/attachments/attachment_service_proxy.cc",
-    "model/attachments/attachment_service_proxy.h",
-    "model/attachments/attachment_service_proxy_for_test.cc",
-    "model/attachments/attachment_service_proxy_for_test.h",
-    "model/attachments/attachment_store.cc",
-    "model/attachments/attachment_store.h",
     "model/change_processor.cc",
     "model/change_processor.h",
     "model/conflict_resolution.cc",
@@ -462,9 +426,6 @@
     "model/time.h",
     "model_impl/accumulating_metadata_change_list.cc",
     "model_impl/accumulating_metadata_change_list.h",
-    "model_impl/attachments/attachment_service_impl.cc",
-    "model_impl/attachments/attachment_service_impl.h",
-    "model_impl/attachments/task_queue.h",
     "model_impl/in_memory_metadata_change_list.cc",
     "model_impl/in_memory_metadata_change_list.h",
     "model_impl/model_type_store_backend.cc",
@@ -602,7 +563,6 @@
     "//components/reading_list/features:reading_list_enable_flags",
     "//components/signin/core/browser",
     "//components/strings",
-    "//components/sync/engine_impl/attachments/proto",
     "//components/variations",
     "//components/version_info",
     "//crypto",
@@ -873,12 +833,6 @@
     "driver/startup_controller_unittest.cc",
     "driver/sync_stopped_reporter_unittest.cc",
     "driver/sync_util_unittest.cc",
-    "engine/attachments/attachment_store_frontend_unittest.cc",
-    "engine/attachments/attachment_store_test_template.h",
-    "engine/attachments/fake_attachment_downloader_unittest.cc",
-    "engine/attachments/fake_attachment_uploader_unittest.cc",
-    "engine/attachments/in_memory_attachment_store_unittest.cc",
-    "engine/attachments/on_disk_attachment_store_unittest.cc",
     "engine/cycle/sync_cycle_snapshot_unittest.cc",
     "engine/model_safe_worker_unittest.cc",
     "engine/net/http_bridge_unittest.cc",
@@ -886,8 +840,6 @@
     "engine/sync_backend_registrar_unittest.cc",
     "engine/ui_model_worker_unittest.cc",
     "engine_impl/apply_control_data_updates_unittest.cc",
-    "engine_impl/attachments/attachment_downloader_impl_unittest.cc",
-    "engine_impl/attachments/attachment_uploader_impl_unittest.cc",
     "engine_impl/backoff_delay_provider_unittest.cc",
     "engine_impl/cycle/nudge_tracker_unittest.cc",
     "engine_impl/cycle/status_controller_unittest.cc",
@@ -917,10 +869,6 @@
     "engine_impl/worker_entity_tracker_unittest.cc",
     "js/js_event_details_unittest.cc",
     "js/sync_js_controller_unittest.cc",
-    "model/attachments/attachment_id_unittest.cc",
-    "model/attachments/attachment_metadata_unittest.cc",
-    "model/attachments/attachment_service_proxy_unittest.cc",
-    "model/attachments/attachment_unittest.cc",
     "model/entity_data_unittest.cc",
     "model/model_type_sync_bridge_unittest.cc",
     "model/mutable_data_batch_unittest.cc",
@@ -929,8 +877,6 @@
     "model/sync_error_unittest.cc",
     "model/sync_merge_result_unittest.cc",
     "model_impl/accumulating_metadata_change_list_unittest.cc",
-    "model_impl/attachments/attachment_service_impl_unittest.cc",
-    "model_impl/attachments/task_queue_unittest.cc",
     "model_impl/model_type_store_backend_unittest.cc",
     "model_impl/model_type_store_impl_unittest.cc",
     "model_impl/passthrough_metadata_change_list_unittest.cc",
@@ -978,7 +924,6 @@
     "//components/os_crypt:test_support",
     "//components/prefs:test_support",
     "//components/signin/core/browser:test_support",
-    "//components/sync/engine_impl/attachments/proto",
     "//components/sync_preferences",
     "//components/sync_preferences:test_support",
     "//components/variations",
diff --git a/components/sync/driver/fake_generic_change_processor.cc b/components/sync/driver/fake_generic_change_processor.cc
index eff644e..0694f0117 100644
--- a/components/sync/driver/fake_generic_change_processor.cc
+++ b/components/sync/driver/fake_generic_change_processor.cc
@@ -19,8 +19,7 @@
                              base::WeakPtr<SyncableService>(),
                              base::WeakPtr<SyncMergeResult>(),
                              nullptr,
-                             sync_client,
-                             nullptr),
+                             sync_client),
       sync_model_has_user_created_nodes_(true),
       sync_model_has_user_created_nodes_success_(true) {}
 
diff --git a/components/sync/driver/generic_change_processor.cc b/components/sync/driver/generic_change_processor.cc
index 6fda063f..7faedce 100644
--- a/components/sync/driver/generic_change_processor.cc
+++ b/components/sync/driver/generic_change_processor.cc
@@ -44,31 +44,7 @@
   }
 }
 
-// Helper function to convert AttachmentId to AttachmentMetadataRecord.
-sync_pb::AttachmentMetadataRecord AttachmentIdToRecord(
-    const AttachmentId& attachment_id) {
-  sync_pb::AttachmentMetadataRecord record;
-  *record.mutable_id() = attachment_id.GetProto();
-  return record;
-}
-
-// Replace |write_nodes|'s attachment ids with |attachment_ids|.
-void SetAttachmentMetadata(const AttachmentIdList& attachment_ids,
-                           WriteNode* write_node) {
-  DCHECK(write_node);
-  sync_pb::AttachmentMetadata attachment_metadata;
-  std::transform(
-      attachment_ids.begin(), attachment_ids.end(),
-      RepeatedFieldBackInserter(attachment_metadata.mutable_record()),
-      AttachmentIdToRecord);
-  write_node->SetAttachmentMetadata(attachment_metadata);
-}
-
-SyncData BuildRemoteSyncData(
-    int64_t sync_id,
-    const ReadNode& read_node,
-    const AttachmentServiceProxy& attachment_service_proxy) {
-  const AttachmentIdList& attachment_ids = read_node.GetAttachmentIds();
+SyncData BuildRemoteSyncData(int64_t sync_id, const ReadNode& read_node) {
   switch (read_node.GetModelType()) {
     case PASSWORDS: {
       // Passwords must be accessed differently, to account for their
@@ -77,9 +53,8 @@
       password_holder.mutable_password()
           ->mutable_client_only_encrypted_data()
           ->CopyFrom(read_node.GetPasswordSpecifics());
-      return SyncData::CreateRemoteData(
-          sync_id, password_holder, read_node.GetModificationTime(),
-          attachment_ids, attachment_service_proxy);
+      return SyncData::CreateRemoteData(sync_id, password_holder,
+                                        read_node.GetModificationTime());
     }
     case SESSIONS:
       // Include tag hashes for sessions data type to allow discarding during
@@ -91,14 +66,12 @@
       // another copy of this string around.
       return SyncData::CreateRemoteData(
           sync_id, read_node.GetEntitySpecifics(),
-          read_node.GetModificationTime(), attachment_ids,
-          attachment_service_proxy, read_node.GetEntry()->GetUniqueClientTag());
+          read_node.GetModificationTime(),
+          read_node.GetEntry()->GetUniqueClientTag());
     default:
       // Use the specifics directly, encryption has already been handled.
       return SyncData::CreateRemoteData(sync_id, read_node.GetEntitySpecifics(),
-                                        read_node.GetModificationTime(),
-                                        attachment_ids,
-                                        attachment_service_proxy);
+                                        read_node.GetModificationTime());
   }
 }
 
@@ -110,8 +83,7 @@
     const base::WeakPtr<SyncableService>& local_service,
     const base::WeakPtr<SyncMergeResult>& merge_result,
     UserShare* user_share,
-    SyncClient* sync_client,
-    std::unique_ptr<AttachmentStoreForSync> attachment_store)
+    SyncClient* sync_client)
     : ChangeProcessor(std::move(error_handler)),
       type_(type),
       local_service_(local_service),
@@ -120,28 +92,6 @@
       weak_ptr_factory_(this) {
   DCHECK(sequence_checker_.CalledOnValidSequence());
   DCHECK_NE(type_, UNSPECIFIED);
-  if (attachment_store) {
-    std::string store_birthday;
-    {
-      ReadTransaction trans(FROM_HERE, share_handle());
-      store_birthday = trans.GetStoreBirthday();
-    }
-    attachment_service_ =
-        sync_client->GetSyncApiComponentFactory()->CreateAttachmentService(
-            std::move(attachment_store), *user_share, store_birthday, type,
-            this);
-    attachment_service_weak_ptr_factory_ =
-        std::make_unique<base::WeakPtrFactory<AttachmentService>>(
-            attachment_service_.get());
-    attachment_service_proxy_ = AttachmentServiceProxy(
-        base::SequencedTaskRunnerHandle::Get(),
-        attachment_service_weak_ptr_factory_->GetWeakPtr());
-    UploadAllAttachmentsNotOnServer();
-  } else {
-    attachment_service_proxy_ =
-        AttachmentServiceProxy(base::SequencedTaskRunnerHandle::Get(),
-                               base::WeakPtr<AttachmentService>());
-  }
 }
 
 GenericChangeProcessor::~GenericChangeProcessor() {
@@ -165,12 +115,10 @@
             ->mutable_client_only_encrypted_data()
             ->CopyFrom(it->extra->unencrypted());
       }
-      const AttachmentIdList empty_list_of_attachment_ids;
       syncer_changes_.push_back(SyncChange(
           FROM_HERE, SyncChange::ACTION_DELETE,
           SyncData::CreateRemoteData(
-              it->id, specifics ? *specifics : it->specifics, base::Time(),
-              empty_list_of_attachment_ids, attachment_service_proxy_)));
+              it->id, specifics ? *specifics : it->specifics, base::Time())));
     } else {
       SyncChange::SyncChangeType action =
           (it->action == ChangeRecord::ACTION_ADD) ? SyncChange::ACTION_ADD
@@ -186,8 +134,7 @@
         return;
       }
       syncer_changes_.push_back(SyncChange(
-          FROM_HERE, action,
-          BuildRemoteSyncData(it->id, read_node, attachment_service_proxy_)));
+          FROM_HERE, action, BuildRemoteSyncData(it->id, read_node)));
     }
   }
 }
@@ -249,12 +196,6 @@
   local_change_observers_.RemoveObserver(observer);
 }
 
-void GenericChangeProcessor::OnAttachmentUploaded(
-    const AttachmentId& attachment_id) {
-  WriteTransaction trans(FROM_HERE, share_handle());
-  trans.UpdateEntriesMarkAttachmentAsOnServer(attachment_id);
-}
-
 SyncError GenericChangeProcessor::GetAllSyncDataReturnError(
     SyncDataList* current_sync_data) const {
   DCHECK(sequence_checker_.CalledOnValidSequence());
@@ -285,8 +226,8 @@
                       type_);
       return error;
     }
-    current_sync_data->push_back(BuildRemoteSyncData(
-        sync_child_node.GetId(), sync_child_node, attachment_service_proxy_));
+    current_sync_data->push_back(
+        BuildRemoteSyncData(sync_child_node.GetId(), sync_child_node));
   }
   return SyncError();
 }
@@ -430,10 +371,6 @@
     return SyncError();
   }
 
-  // Keep track of brand new attachments so we can persist them on this device
-  // and upload them to the server.
-  AttachmentIdSet new_attachments;
-
   WriteTransaction trans(from_here, share_handle());
 
   for (SyncChangeList::const_iterator iter = list_of_changes.begin();
@@ -452,14 +389,12 @@
             merge_result_->num_items_deleted() + 1);
       }
     } else if (change.change_type() == SyncChange::ACTION_ADD) {
-      SyncError error = HandleActionAdd(change, type_str, trans, &sync_node,
-                                        &new_attachments);
+      SyncError error = HandleActionAdd(change, type_str, trans, &sync_node);
       if (error.IsSet()) {
         return error;
       }
     } else if (change.change_type() == SyncChange::ACTION_UPDATE) {
-      SyncError error = HandleActionUpdate(change, type_str, trans, &sync_node,
-                                           &new_attachments);
+      SyncError error = HandleActionUpdate(change, type_str, trans, &sync_node);
       if (error.IsSet()) {
         return error;
       }
@@ -475,26 +410,6 @@
     }
   }
 
-  if (!new_attachments.empty()) {
-    // If datatype uses attachments it should have supplied attachment store
-    // which would initialize attachment_service_. Fail if it isn't so.
-    if (!attachment_service_.get()) {
-      SyncError error(
-          FROM_HERE, SyncError::DATATYPE_ERROR,
-          "Datatype performs attachment operation without initializing "
-          "attachment store",
-          type_);
-      error_handler()->OnUnrecoverableError(error);
-      NOTREACHED();
-      return error;
-    }
-    AttachmentIdList ids_to_upload;
-    ids_to_upload.reserve(new_attachments.size());
-    std::copy(new_attachments.begin(), new_attachments.end(),
-              std::back_inserter(ids_to_upload));
-    attachment_service_->UploadAttachments(ids_to_upload);
-  }
-
   return SyncError();
 }
 
@@ -502,12 +417,10 @@
 // modifying any code around an OnUnrecoverableError call, else the compiler
 // attempts to merge it with other calls, losing useful information in
 // breakpad uploads.
-SyncError GenericChangeProcessor::HandleActionAdd(
-    const SyncChange& change,
-    const std::string& type_str,
-    const WriteTransaction& trans,
-    WriteNode* sync_node,
-    AttachmentIdSet* new_attachments) {
+SyncError GenericChangeProcessor::HandleActionAdd(const SyncChange& change,
+                                                  const std::string& type_str,
+                                                  const WriteTransaction& trans,
+                                                  WriteNode* sync_node) {
   // TODO(sync): Handle other types of creation (custom parents, folders,
   // etc.).
   const SyncDataLocal sync_data_local(change.sync_data());
@@ -561,11 +474,6 @@
   sync_node->SetTitle(change.sync_data().GetTitle());
   SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node);
 
-  AttachmentIdList attachment_ids = sync_data_local.GetAttachmentIds();
-  SetAttachmentMetadata(attachment_ids, sync_node);
-
-  // Return any newly added attachments.
-  new_attachments->insert(attachment_ids.begin(), attachment_ids.end());
   if (merge_result_.get()) {
     merge_result_->set_num_items_added(merge_result_->num_items_added() + 1);
   }
@@ -579,8 +487,7 @@
     const SyncChange& change,
     const std::string& type_str,
     const WriteTransaction& trans,
-    WriteNode* sync_node,
-    AttachmentIdSet* new_attachments) {
+    WriteNode* sync_node) {
   const SyncDataLocal sync_data_local(change.sync_data());
   BaseNode::InitByLookupResult result = sync_node->InitByClientTagLookup(
       sync_data_local.GetDataType(), sync_data_local.GetTag());
@@ -625,11 +532,6 @@
 
   sync_node->SetTitle(change.sync_data().GetTitle());
   SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node);
-  AttachmentIdList attachment_ids = sync_data_local.GetAttachmentIds();
-  SetAttachmentMetadata(attachment_ids, sync_node);
-
-  // Return any newly added attachments.
-  new_attachments->insert(attachment_ids.begin(), attachment_ids.end());
 
   if (merge_result_.get()) {
     merge_result_->set_num_items_modified(merge_result_->num_items_modified() +
@@ -676,19 +578,6 @@
   return share_handle_;
 }
 
-void GenericChangeProcessor::UploadAllAttachmentsNotOnServer() {
-  DCHECK(sequence_checker_.CalledOnValidSequence());
-  DCHECK(attachment_service_.get());
-  AttachmentIdList ids;
-  {
-    ReadTransaction trans(FROM_HERE, share_handle());
-    trans.GetAttachmentIdsToUpload(type_, &ids);
-  }
-  if (!ids.empty()) {
-    attachment_service_->UploadAttachments(ids);
-  }
-}
-
 void GenericChangeProcessor::NotifyLocalChangeObservers(
     const syncable::Entry* current_entry,
     const SyncChange& change) {
@@ -696,10 +585,4 @@
     observer.OnLocalChange(current_entry, change);
 }
 
-std::unique_ptr<AttachmentService>
-GenericChangeProcessor::GetAttachmentService() const {
-  return std::unique_ptr<AttachmentService>(
-      new AttachmentServiceProxy(attachment_service_proxy_));
-}
-
 }  // namespace syncer
diff --git a/components/sync/driver/generic_change_processor.h b/components/sync/driver/generic_change_processor.h
index a4f9601..b1fdb34 100644
--- a/components/sync/driver/generic_change_processor.h
+++ b/components/sync/driver/generic_change_processor.h
@@ -15,9 +15,6 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
-#include "components/sync/model/attachments/attachment_service.h"
-#include "components/sync/model/attachments/attachment_service_proxy.h"
-#include "components/sync/model/attachments/attachment_store.h"
 #include "components/sync/model/change_processor.h"
 #include "components/sync/model/data_type_error_handler.h"
 #include "components/sync/model/sync_change_processor.h"
@@ -46,20 +43,15 @@
 // As a rule, the GenericChangeProcessor is not thread safe, and should only
 // be used on the same sequence in which it was created.
 class GenericChangeProcessor : public ChangeProcessor,
-                               public SyncChangeProcessor,
-                               public AttachmentService::Delegate {
+                               public SyncChangeProcessor {
  public:
   // Create a change processor for |type| and connect it to the syncer.
-  // |attachment_store| can be null which means that datatype will not use sync
-  // attachments.
-  GenericChangeProcessor(
-      ModelType type,
-      std::unique_ptr<DataTypeErrorHandler> error_handler,
-      const base::WeakPtr<SyncableService>& local_service,
-      const base::WeakPtr<SyncMergeResult>& merge_result,
-      UserShare* user_share,
-      SyncClient* sync_client,
-      std::unique_ptr<AttachmentStoreForSync> attachment_store);
+  GenericChangeProcessor(ModelType type,
+                         std::unique_ptr<DataTypeErrorHandler> error_handler,
+                         const base::WeakPtr<SyncableService>& local_service,
+                         const base::WeakPtr<SyncMergeResult>& merge_result,
+                         UserShare* user_share,
+                         SyncClient* sync_client);
   ~GenericChangeProcessor() override;
 
   // ChangeProcessor interface.
@@ -83,9 +75,6 @@
   void AddLocalChangeObserver(LocalChangeObserver* observer) override;
   void RemoveLocalChangeObserver(LocalChangeObserver* observer) override;
 
-  // AttachmentService::Delegate implementation.
-  void OnAttachmentUploaded(const AttachmentId& attachment_id) override;
-
   // Similar to above, but returns a SyncError for use by direct clients
   // of GenericChangeProcessor that may need more error visibility.
   virtual SyncError GetAllSyncDataReturnError(SyncDataList* data) const;
@@ -103,9 +92,6 @@
   virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
   virtual bool CryptoReadyIfNecessary();
 
-  // Gets AttachmentService proxy for datatype.
-  std::unique_ptr<AttachmentService> GetAttachmentService() const;
-
  protected:
   // ChangeProcessor interface.
   void StartImpl() override;  // Does nothing.
@@ -118,28 +104,16 @@
                           WriteNode* node,
                           DataTypeErrorHandler* error_handler);
   // Logically part of ProcessSyncChanges.
-  //
-  // |new_attachments| is an output parameter containing newly added attachments
-  // that need to be stored.  This method will append to it.
   SyncError HandleActionAdd(const SyncChange& change,
                             const std::string& type_str,
                             const WriteTransaction& trans,
-                            WriteNode* sync_node,
-                            AttachmentIdSet* new_attachments);
+                            WriteNode* sync_node);
 
   // Logically part of ProcessSyncChanges.
-  //
-  // |new_attachments| is an output parameter containing newly added attachments
-  // that need to be stored.  This method will append to it.
   SyncError HandleActionUpdate(const SyncChange& change,
                                const std::string& type_str,
                                const WriteTransaction& trans,
-                               WriteNode* sync_node,
-                               AttachmentIdSet* new_attachments);
-
-  // Begin uploading attachments that have not yet been uploaded to the sync
-  // server.
-  void UploadAllAttachmentsNotOnServer();
+                               WriteNode* sync_node);
 
   // Notify every registered local change observer that |change| is about to be
   // applied to |current_entry|.
@@ -172,19 +146,9 @@
   // and have to keep a local pointer to the user_share.
   UserShare* const share_handle_;
 
-  // AttachmentService for datatype. Can be null if datatype doesn't use
-  // attachments.
-  std::unique_ptr<AttachmentService> attachment_service_;
-
   // List of observers that want to be notified of local changes being written.
   base::ObserverList<LocalChangeObserver> local_change_observers_;
 
-  // Must be destroyed before attachment_service_ to ensure WeakPtrs are
-  // invalidated before attachment_service_ is destroyed.
-  // Can be null if attachment_service_ is null;
-  std::unique_ptr<base::WeakPtrFactory<AttachmentService>>
-      attachment_service_weak_ptr_factory_;
-  AttachmentServiceProxy attachment_service_proxy_;
   base::WeakPtrFactory<GenericChangeProcessor> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(GenericChangeProcessor);
diff --git a/components/sync/driver/generic_change_processor_factory.cc b/components/sync/driver/generic_change_processor_factory.cc
index d7f524a..f08f2ca 100644
--- a/components/sync/driver/generic_change_processor_factory.cc
+++ b/components/sync/driver/generic_change_processor_factory.cc
@@ -26,7 +26,7 @@
   DCHECK(user_share);
   return std::make_unique<GenericChangeProcessor>(
       type, std::move(error_handler), local_service, merge_result, user_share,
-      sync_client, local_service->GetAttachmentStoreForSync());
+      sync_client);
 }
 
 }  // namespace syncer
diff --git a/components/sync/driver/generic_change_processor_factory.h b/components/sync/driver/generic_change_processor_factory.h
index 0d9d7c3..be032d0 100644
--- a/components/sync/driver/generic_change_processor_factory.h
+++ b/components/sync/driver/generic_change_processor_factory.h
@@ -27,8 +27,6 @@
 // The GCP is created "on the fly" at just the right time, on just the right
 // thread. Given that, we use a factory to instantiate GenericChangeProcessors
 // so that tests can choose to use a fake processor (i.e instead of injection).
-// |sync_factory| is used to create AttachmentServicefor GenericChangeProcessor.
-// It is not retained after CreateGenericChangeProcessor exits.
 class GenericChangeProcessorFactory {
  public:
   GenericChangeProcessorFactory();
diff --git a/components/sync/driver/generic_change_processor_unittest.cc b/components/sync/driver/generic_change_processor_unittest.cc
index 42882d3..37d8e2f 100644
--- a/components/sync/driver/generic_change_processor_unittest.cc
+++ b/components/sync/driver/generic_change_processor_unittest.cc
@@ -15,10 +15,7 @@
 #include "components/sync/device_info/local_device_info_provider.h"
 #include "components/sync/driver/fake_sync_client.h"
 #include "components/sync/driver/sync_api_component_factory.h"
-#include "components/sync/engine/attachments/fake_attachment_downloader.h"
-#include "components/sync/engine/attachments/fake_attachment_uploader.h"
 #include "components/sync/engine/sync_encryption_handler.h"
-#include "components/sync/model/attachments/attachment_id.h"
 #include "components/sync/model/data_type_error_handler_mock.h"
 #include "components/sync/model/fake_syncable_service.h"
 #include "components/sync/model/sync_change.h"
@@ -35,30 +32,7 @@
 
 namespace {
 
-// A mock that keeps track of attachments passed to UploadAttachments.
-class MockAttachmentService : public AttachmentService {
- public:
-  MockAttachmentService() {}
-  ~MockAttachmentService() override {}
-
-  void GetOrDownloadAttachments(
-      const AttachmentIdList& attachment_ids,
-      const GetOrDownloadCallback& callback) override {}
-
-  void UploadAttachments(const AttachmentIdList& attachment_ids) override {
-    attachment_id_lists_.push_back(attachment_ids);
-  }
-
-  std::vector<AttachmentIdList>* attachment_id_lists() {
-    return &attachment_id_lists_;
-  }
-
- private:
-  std::vector<AttachmentIdList> attachment_id_lists_;
-};
-
-// MockSyncApiComponentFactory needed to initialize GenericChangeProcessor and
-// pass MockAttachmentService to it.
+// MockSyncApiComponentFactory needed to initialize GenericChangeProcessor.
 class MockSyncApiComponentFactory : public SyncApiComponentFactory {
  public:
   MockSyncApiComponentFactory() {}
@@ -91,28 +65,6 @@
       std::unique_ptr<DataTypeErrorHandler> error_handler) override {
     return SyncComponents(nullptr, nullptr);
   }
-
-  std::unique_ptr<AttachmentService> CreateAttachmentService(
-      std::unique_ptr<AttachmentStoreForSync> attachment_store,
-      const UserShare& user_share,
-      const std::string& store_birthday,
-      ModelType model_type,
-      AttachmentService::Delegate* delegate) override {
-    auto attachment_service = std::make_unique<MockAttachmentService>();
-    // GenericChangeProcessor takes ownership of the AttachmentService, but we
-    // need to have a pointer to it so we can see that it was used properly.
-    // Take a pointer and trust that GenericChangeProcessor does not prematurely
-    // destroy it.
-    mock_attachment_service_ = attachment_service.get();
-    return std::move(attachment_service);
-  }
-
-  MockAttachmentService* GetMockAttachmentService() {
-    return mock_attachment_service_;
-  }
-
- private:
-  MockAttachmentService* mock_attachment_service_;
 };
 
 class SyncGenericChangeProcessorTest : public testing::Test {
@@ -125,7 +77,6 @@
       : scoped_task_environment_(
             base::test::ScopedTaskEnvironment::MainThreadType::UI),
         syncable_service_ptr_factory_(&fake_syncable_service_),
-        mock_attachment_service_(nullptr),
         sync_client_(&sync_factory_) {}
 
   void SetUp() override {
@@ -136,7 +87,6 @@
   }
 
   void TearDown() override {
-    mock_attachment_service_ = nullptr;
     if (test_user_share_) {
       test_user_share_->TearDown();
     }
@@ -162,14 +112,11 @@
   }
 
   void ConstructGenericChangeProcessor(ModelType type) {
-    std::unique_ptr<AttachmentStore> attachment_store =
-        AttachmentStore::CreateInMemoryStore();
     change_processor_ = std::make_unique<GenericChangeProcessor>(
         type, std::make_unique<DataTypeErrorHandlerMock>(),
         syncable_service_ptr_factory_.GetWeakPtr(),
         merge_result_ptr_factory_->GetWeakPtr(), test_user_share_->user_share(),
-        &sync_client_, attachment_store->CreateAttachmentStoreForSync());
-    mock_attachment_service_ = sync_factory_.GetMockAttachmentService();
+        &sync_client_);
   }
 
   void BuildChildNodes(ModelType type, int n) {
@@ -184,10 +131,6 @@
 
   UserShare* user_share() { return test_user_share_->user_share(); }
 
-  MockAttachmentService* mock_attachment_service() {
-    return mock_attachment_service_;
-  }
-
   void RunLoop() {
     base::RunLoop run_loop;
     run_loop.RunUntilIdle();
@@ -204,7 +147,6 @@
   base::WeakPtrFactory<FakeSyncableService> syncable_service_ptr_factory_;
 
   std::unique_ptr<TestUserShare> test_user_share_;
-  MockAttachmentService* mock_attachment_service_;
   FakeSyncClient sync_client_;
   MockSyncApiComponentFactory sync_factory_;
 
@@ -359,119 +301,6 @@
   }
 }
 
-// Verify that attachments on newly added or updated SyncData are passed to the
-// AttachmentService.
-TEST_F(SyncGenericChangeProcessorTest,
-       ProcessSyncChanges_AddUpdateWithAttachment) {
-  std::string tag = "client_tag";
-  std::string title = "client_title";
-  sync_pb::EntitySpecifics specifics;
-  sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference();
-  pref_specifics->set_name("test");
-
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-
-  // Add a SyncData with two attachments.
-  SyncChangeList change_list;
-  change_list.push_back(SyncChange(FROM_HERE, SyncChange::ACTION_ADD,
-                                   SyncData::CreateLocalDataWithAttachments(
-                                       tag, title, specifics, attachment_ids)));
-  ASSERT_FALSE(
-      change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
-  RunLoop();
-
-  // Check that the AttachmentService received the new attachments.
-  ASSERT_EQ(mock_attachment_service()->attachment_id_lists()->size(), 1U);
-  const AttachmentIdList& attachments_added =
-      mock_attachment_service()->attachment_id_lists()->front();
-  ASSERT_THAT(attachments_added, testing::UnorderedElementsAre(
-                                     attachment_ids[0], attachment_ids[1]));
-
-  // Update the SyncData, replacing its two attachments with one new attachment.
-  AttachmentIdList new_attachment_ids;
-  new_attachment_ids.push_back(AttachmentId::Create(0, 0));
-  mock_attachment_service()->attachment_id_lists()->clear();
-  change_list.clear();
-  change_list.push_back(
-      SyncChange(FROM_HERE, SyncChange::ACTION_UPDATE,
-                 SyncData::CreateLocalDataWithAttachments(tag, title, specifics,
-                                                          new_attachment_ids)));
-  ASSERT_FALSE(
-      change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
-  RunLoop();
-
-  // Check that the AttachmentService received it.
-  ASSERT_EQ(mock_attachment_service()->attachment_id_lists()->size(), 1U);
-  const AttachmentIdList& new_attachments_added =
-      mock_attachment_service()->attachment_id_lists()->front();
-  ASSERT_THAT(new_attachments_added,
-              testing::UnorderedElementsAre(new_attachment_ids[0]));
-}
-
-// Verify that after attachment is uploaded GenericChangeProcessor updates
-// corresponding entries
-TEST_F(SyncGenericChangeProcessorTest, AttachmentUploaded) {
-  std::string tag = "client_tag";
-  std::string title = "client_title";
-  sync_pb::EntitySpecifics specifics;
-  sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference();
-  pref_specifics->set_name("test");
-
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-
-  // Add a SyncData with two attachments.
-  SyncChangeList change_list;
-  change_list.push_back(SyncChange(FROM_HERE, SyncChange::ACTION_ADD,
-                                   SyncData::CreateLocalDataWithAttachments(
-                                       tag, title, specifics, attachment_ids)));
-  ASSERT_FALSE(
-      change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
-
-  sync_pb::AttachmentIdProto attachment_id_proto = attachment_ids[0].GetProto();
-  AttachmentId attachment_id =
-      AttachmentId::CreateFromProto(attachment_id_proto);
-
-  change_processor()->OnAttachmentUploaded(attachment_id);
-  ReadTransaction read_transaction(FROM_HERE, user_share());
-  ReadNode node(&read_transaction);
-  ASSERT_EQ(node.InitByClientTagLookup(kType, tag), BaseNode::INIT_OK);
-  attachment_ids = node.GetAttachmentIds();
-  EXPECT_EQ(1U, attachment_ids.size());
-}
-
-// Verify that upon construction, all attachments not yet on the server are
-// scheduled for upload.
-TEST_F(SyncGenericChangeProcessorTest, UploadAllAttachmentsNotOnServer) {
-  // Create two attachment ids.  id2 will be marked as "on server".
-  AttachmentId id1 = AttachmentId::Create(0, 0);
-  AttachmentId id2 = AttachmentId::Create(0, 0);
-  {
-    // Write an entry containing these two attachment ids.
-    WriteTransaction trans(FROM_HERE, user_share());
-    ReadNode root(&trans);
-    ASSERT_EQ(BaseNode::INIT_OK, root.InitTypeRoot(kType));
-    WriteNode node(&trans);
-    node.InitUniqueByCreation(kType, root, "some node");
-    sync_pb::AttachmentMetadata metadata;
-    sync_pb::AttachmentMetadataRecord* record1 = metadata.add_record();
-    *record1->mutable_id() = id1.GetProto();
-    sync_pb::AttachmentMetadataRecord* record2 = metadata.add_record();
-    *record2->mutable_id() = id2.GetProto();
-    record2->set_is_on_server(true);
-    node.SetAttachmentMetadata(metadata);
-  }
-
-  // Construct the GenericChangeProcessor and see that it asks the
-  // AttachmentService to upload id1 only.
-  ConstructGenericChangeProcessor(kType);
-  ASSERT_EQ(1U, mock_attachment_service()->attachment_id_lists()->size());
-  ASSERT_THAT(mock_attachment_service()->attachment_id_lists()->front(),
-              testing::UnorderedElementsAre(id1));
-}
-
 // Test that attempting to add an entry that already exists still works.
 TEST_F(SyncGenericChangeProcessorTest, AddExistingEntry) {
   InitializeForType(SESSIONS);
diff --git a/components/sync/driver/shared_change_processor.cc b/components/sync/driver/shared_change_processor.cc
index 811349d..4d204e7c 100644
--- a/components/sync/driver/shared_change_processor.cc
+++ b/components/sync/driver/shared_change_processor.cc
@@ -20,8 +20,6 @@
 
 namespace syncer {
 
-class AttachmentService;
-
 SharedChangeProcessor::SharedChangeProcessor(ModelType type)
     : disconnected_(false),
       type_(type),
@@ -164,12 +162,6 @@
                                       type_, user_share, error_handler_->Copy(),
                                       local_service, merge_result, sync_client)
                                   .release();
-  // If available, propagate attachment service to the syncable service.
-  std::unique_ptr<AttachmentService> attachment_service =
-      generic_change_processor_->GetAttachmentService();
-  if (attachment_service) {
-    local_service->SetAttachmentService(std::move(attachment_service));
-  }
   return local_service;
 }
 
diff --git a/components/sync/driver/shared_change_processor_unittest.cc b/components/sync/driver/shared_change_processor_unittest.cc
index 1ff0a262..8200373 100644
--- a/components/sync/driver/shared_change_processor_unittest.cc
+++ b/components/sync/driver/shared_change_processor_unittest.cc
@@ -18,9 +18,6 @@
 #include "components/sync/driver/generic_change_processor.h"
 #include "components/sync/driver/generic_change_processor_factory.h"
 #include "components/sync/driver/sync_api_component_factory.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service.h"
-#include "components/sync/model/attachments/attachment_store.h"
 #include "components/sync/model/data_type_error_handler_mock.h"
 #include "components/sync/model/fake_syncable_service.h"
 #include "components/sync/syncable/test_user_share.h"
@@ -67,14 +64,6 @@
       std::unique_ptr<DataTypeErrorHandler> error_handler) override {
     return SyncApiComponentFactory::SyncComponents(nullptr, nullptr);
   }
-  std::unique_ptr<AttachmentService> CreateAttachmentService(
-      std::unique_ptr<AttachmentStoreForSync> attachment_store,
-      const UserShare& user_share,
-      const std::string& store_birthday,
-      ModelType model_type,
-      AttachmentService::Delegate* delegate) override {
-    return AttachmentService::CreateForTest();
-  }
 };
 
 class SyncSharedChangeProcessorTest : public testing::Test,
@@ -83,8 +72,7 @@
   SyncSharedChangeProcessorTest()
       : FakeSyncClient(&factory_),
         model_thread_("dbthread"),
-        did_connect_(false),
-        has_attachment_service_(false) {}
+        did_connect_(false) {}
 
   ~SyncSharedChangeProcessorTest() override {
     EXPECT_FALSE(db_syncable_service_.get());
@@ -137,25 +125,6 @@
                    base::Unretained(this), shared_change_processor_)));
   }
 
-  void SetAttachmentStore() {
-    EXPECT_TRUE(model_thread_.task_runner()->PostTask(
-        FROM_HERE,
-        base::Bind(&SyncSharedChangeProcessorTest::SetAttachmentStoreOnDBThread,
-                   base::Unretained(this))));
-  }
-
-  bool HasAttachmentService() {
-    base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
-                              base::WaitableEvent::InitialState::NOT_SIGNALED);
-    EXPECT_TRUE(model_thread_.task_runner()->PostTask(
-        FROM_HERE,
-        base::Bind(
-            &SyncSharedChangeProcessorTest::CheckAttachmentServiceOnDBThread,
-            base::Unretained(this), base::Unretained(&event))));
-    event.Wait();
-    return has_attachment_service_;
-  }
-
  private:
   // Used by SetUp().
   void SetUpDBSyncableService() {
@@ -171,13 +140,6 @@
     db_syncable_service_.reset();
   }
 
-  void SetAttachmentStoreOnDBThread() {
-    DCHECK(model_thread_.task_runner()->BelongsToCurrentThread());
-    DCHECK(db_syncable_service_.get());
-    db_syncable_service_->set_attachment_store(
-        AttachmentStore::CreateInMemoryStore());
-  }
-
   // Used by Connect().  The SharedChangeProcessor is passed in
   // because we modify |shared_change_processor_| on the main thread
   // (in TearDown()).
@@ -191,13 +153,6 @@
     did_connect_ = true;
   }
 
-  void CheckAttachmentServiceOnDBThread(base::WaitableEvent* event) {
-    DCHECK(model_thread_.task_runner()->BelongsToCurrentThread());
-    DCHECK(db_syncable_service_.get());
-    has_attachment_service_ = !!db_syncable_service_->attachment_service();
-    event->Signal();
-  }
-
   base::MessageLoop frontend_loop_;
   base::Thread model_thread_;
   TestUserShare test_user_share_;
@@ -207,7 +162,6 @@
 
   GenericChangeProcessorFactory processor_factory_;
   bool did_connect_;
-  bool has_attachment_service_;
 
   // Used only on DB thread.
   std::unique_ptr<FakeSyncableService> db_syncable_service_;
@@ -219,15 +173,6 @@
   Connect();
 }
 
-// Connect the shared change processor to a syncable service with
-// AttachmentStore. Verify that shared change processor implementation
-// creates AttachmentService and passes it back to the syncable service.
-TEST_F(SyncSharedChangeProcessorTest, ConnectWithAttachmentStore) {
-  SetAttachmentStore();
-  Connect();
-  EXPECT_TRUE(HasAttachmentService());
-}
-
 }  // namespace
 
 }  // namespace syncer
diff --git a/components/sync/driver/sync_api_component_factory.h b/components/sync/driver/sync_api_component_factory.h
index a8e0692..fad52a0 100644
--- a/components/sync/driver/sync_api_component_factory.h
+++ b/components/sync/driver/sync_api_component_factory.h
@@ -11,7 +11,6 @@
 #include "base/memory/weak_ptr.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/driver/data_type_controller.h"
-#include "components/sync/model/attachments/attachment_service.h"
 #include "components/sync/model/data_type_error_handler.h"
 #include "components/sync/model/syncable_service.h"
 
@@ -37,7 +36,6 @@
 class SyncPrefs;
 class SyncService;
 class SyncableService;
-struct UserShare;
 
 // This factory provides sync driver code with the model type specific sync/api
 // service (like SyncableService) implementations.
@@ -102,24 +100,6 @@
   virtual SyncComponents CreateBookmarkSyncComponents(
       SyncService* sync_service,
       std::unique_ptr<DataTypeErrorHandler> error_handler) = 0;
-
-  // Creates attachment service.
-  // Note: Should only be called from the model type thread.
-  //
-  // |store_birthday| is the store birthday.  Must not be empty.
-  //
-  // |model_type| is the model type this AttachmentService will be used with.
-  //
-  // |delegate| is optional delegate for AttachmentService to notify about
-  // asynchronous events (AttachmentUploaded). Pass null if delegate is not
-  // provided. AttachmentService doesn't take ownership of delegate, the pointer
-  // must be valid throughout AttachmentService lifetime.
-  virtual std::unique_ptr<AttachmentService> CreateAttachmentService(
-      std::unique_ptr<AttachmentStoreForSync> attachment_store,
-      const UserShare& user_share,
-      const std::string& store_birthday,
-      ModelType model_type,
-      AttachmentService::Delegate* delegate) = 0;
 };
 
 }  // namespace syncer
diff --git a/components/sync/driver/sync_api_component_factory_mock.cc b/components/sync/driver/sync_api_component_factory_mock.cc
index 24522443..4697cab 100644
--- a/components/sync/driver/sync_api_component_factory_mock.cc
+++ b/components/sync/driver/sync_api_component_factory_mock.cc
@@ -8,8 +8,6 @@
 
 #include "components/sync/device_info/local_device_info_provider_mock.h"
 #include "components/sync/driver/model_associator.h"
-#include "components/sync/model/attachments/attachment_service.h"
-#include "components/sync/model/attachments/attachment_store.h"
 #include "components/sync/model/change_processor.h"
 
 using testing::_;
@@ -30,16 +28,6 @@
 
 SyncApiComponentFactoryMock::~SyncApiComponentFactoryMock() {}
 
-std::unique_ptr<AttachmentService>
-SyncApiComponentFactoryMock::CreateAttachmentService(
-    std::unique_ptr<AttachmentStoreForSync> attachment_store,
-    const UserShare& user_share,
-    const std::string& store_birthday,
-    ModelType model_type,
-    AttachmentService::Delegate* delegate) {
-  return AttachmentService::CreateForTest();
-}
-
 SyncApiComponentFactory::SyncComponents
 SyncApiComponentFactoryMock::CreateBookmarkSyncComponents(
     SyncService* sync_service,
diff --git a/components/sync/driver/sync_api_component_factory_mock.h b/components/sync/driver/sync_api_component_factory_mock.h
index 65643da..239f67b 100644
--- a/components/sync/driver/sync_api_component_factory_mock.h
+++ b/components/sync/driver/sync_api_component_factory_mock.h
@@ -47,12 +47,6 @@
   void SetLocalDeviceInfoProvider(
       std::unique_ptr<LocalDeviceInfoProvider> local_device);
 
-  std::unique_ptr<AttachmentService> CreateAttachmentService(
-      std::unique_ptr<AttachmentStoreForSync> attachment_store,
-      const UserShare& user_share,
-      const std::string& store_birthday,
-      ModelType model_type,
-      AttachmentService::Delegate* delegate) override;
   SyncComponents CreateBookmarkSyncComponents(
       SyncService* sync_service,
       std::unique_ptr<DataTypeErrorHandler> error_handler) override;
diff --git a/components/sync/engine/attachments/DEPS b/components/sync/engine/attachments/DEPS
deleted file mode 100644
index 2527ffa..0000000
--- a/components/sync/engine/attachments/DEPS
+++ /dev/null
@@ -1,5 +0,0 @@
-include_rules = [
-  "+net",
-  "+third_party/crc32c",
-  "+third_party/leveldatabase",
-]
diff --git a/components/sync/engine/attachments/attachment_downloader.cc b/components/sync/engine/attachments/attachment_downloader.cc
deleted file mode 100644
index 382214c..0000000
--- a/components/sync/engine/attachments/attachment_downloader.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2014 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/sync/engine/attachments/attachment_downloader.h"
-
-#include "components/sync/engine_impl/attachments/attachment_downloader_impl.h"
-
-namespace syncer {
-
-AttachmentDownloader::~AttachmentDownloader() {}
-
-std::unique_ptr<AttachmentDownloader> AttachmentDownloader::Create(
-    const GURL& sync_service_url,
-    const scoped_refptr<net::URLRequestContextGetter>&
-        url_request_context_getter,
-    const std::string& account_id,
-    const OAuth2TokenService::ScopeSet scopes,
-    const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
-        token_service_provider,
-    const std::string& store_birthday,
-    ModelType model_type) {
-  return std::make_unique<AttachmentDownloaderImpl>(
-      sync_service_url, url_request_context_getter, account_id, scopes,
-      token_service_provider, store_birthday, model_type);
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/attachment_downloader.h b/components/sync/engine/attachments/attachment_downloader.h
deleted file mode 100644
index 71b61c63..0000000
--- a/components/sync/engine/attachments/attachment_downloader.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2014 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_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_DOWNLOADER_H_
-#define COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_DOWNLOADER_H_
-
-#include <memory>
-#include <string>
-
-#include "base/callback.h"
-#include "components/sync/base/model_type.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "google_apis/gaia/oauth2_token_service_request.h"
-
-namespace net {
-class URLRequestContextGetter;
-}  // namespace net
-
-namespace syncer {
-
-// AttachmentDownloader is responsible for downloading attachments from server.
-class AttachmentDownloader {
- public:
-  // The result of a DownloadAttachment operation.
-  enum DownloadResult {
-    DOWNLOAD_SUCCESS,            // No error, attachment was downloaded
-                                 // successfully.
-    DOWNLOAD_TRANSIENT_ERROR,    // A transient error occurred, try again later.
-    DOWNLOAD_UNSPECIFIED_ERROR,  // An unspecified error occurred.
-  };
-
-  using DownloadCallback =
-      base::Callback<void(const DownloadResult&, std::unique_ptr<Attachment>)>;
-
-  virtual ~AttachmentDownloader();
-
-  // Download attachment referred by |attachment_id| and invoke |callback| when
-  // done.
-  //
-  // |callback| will receive a DownloadResult code and an Attachment object. If
-  // DownloadResult is not DOWNLOAD_SUCCESS then attachment pointer is null.
-  virtual void DownloadAttachment(const AttachmentId& attachment_id,
-                                  const DownloadCallback& callback) = 0;
-
-  // Create an instance of AttachmentDownloader.
-  //
-  // |sync_service_url| is the URL of the sync service.
-  //
-  // |url_request_context_getter| provides a URLRequestContext.
-  //
-  // |account_id| is the account id to use for downloads.
-  //
-  // |scopes| is the set of scopes to use for downloads.
-  //
-  // |token_service_provider| provides an OAuth2 token service.
-  //
-  // |store_birthday| is the raw, sync store birthday.
-  //
-  // |model_type| is the model type this downloader is used with.
-  static std::unique_ptr<AttachmentDownloader> Create(
-      const GURL& sync_service_url,
-      const scoped_refptr<net::URLRequestContextGetter>&
-          url_request_context_getter,
-      const std::string& account_id,
-      const OAuth2TokenService::ScopeSet scopes,
-      const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
-          token_service_provider,
-      const std::string& store_birthday,
-      ModelType model_type);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_DOWNLOADER_H_
diff --git a/components/sync/engine/attachments/attachment_store_backend.cc b/components/sync/engine/attachments/attachment_store_backend.cc
deleted file mode 100644
index 4fe5114..0000000
--- a/components/sync/engine/attachments/attachment_store_backend.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/sync/engine/attachments/attachment_store_backend.h"
-
-#include "base/location.h"
-#include "base/sequenced_task_runner.h"
-
-namespace syncer {
-
-AttachmentStoreBackend::AttachmentStoreBackend(
-    const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner)
-    : callback_task_runner_(callback_task_runner) {}
-
-AttachmentStoreBackend::~AttachmentStoreBackend() {}
-
-void AttachmentStoreBackend::PostCallback(const base::Closure& callback) {
-  callback_task_runner_->PostTask(FROM_HERE, callback);
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/attachment_store_backend.h b/components/sync/engine/attachments/attachment_store_backend.h
deleted file mode 100644
index 219c29a..0000000
--- a/components/sync/engine/attachments/attachment_store_backend.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_STORE_BACKEND_H_
-#define COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_STORE_BACKEND_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_store.h"
-
-namespace base {
-class SequencedTaskRunner;
-}  // namespace base
-
-namespace syncer {
-
-// Interface for AttachmentStore backends.
-//
-// AttachmentStoreBackend provides interface for different backends (on-disk,
-// in-memory). Factory methods in AttachmentStore create corresponding backend
-// and pass reference to AttachmentStore.
-// All functions in AttachmentStoreBackend mirror corresponding functions in
-// AttachmentStore.
-// All callbacks and result codes are used directly from AttachmentStore.
-// AttachmentStoreFrontend only passes callbacks and results without modifying
-// them, there is no need to declare separate set.
-class AttachmentStoreBackend {
- public:
-  explicit AttachmentStoreBackend(
-      const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner);
-  virtual ~AttachmentStoreBackend();
-  virtual void Init(const AttachmentStore::InitCallback& callback) = 0;
-  virtual void Read(AttachmentStore::Component component,
-                    const AttachmentIdList& ids,
-                    const AttachmentStore::ReadCallback& callback) = 0;
-  virtual void Write(AttachmentStore::Component component,
-                     const AttachmentList& attachments,
-                     const AttachmentStore::WriteCallback& callback) = 0;
-  virtual void SetReference(AttachmentStore::Component component,
-                            const AttachmentIdList& ids) = 0;
-  virtual void DropReference(AttachmentStore::Component component,
-                             const AttachmentIdList& ids,
-                             const AttachmentStore::DropCallback& callback) = 0;
-  virtual void ReadMetadataById(
-      AttachmentStore::Component component,
-      const AttachmentIdList& ids,
-      const AttachmentStore::ReadMetadataCallback& callback) = 0;
-  virtual void ReadMetadata(
-      AttachmentStore::Component component,
-      const AttachmentStore::ReadMetadataCallback& callback) = 0;
-
- protected:
-  // Helper function to post callback on callback_task_runner.
-  void PostCallback(const base::Closure& callback);
-
- private:
-  scoped_refptr<base::SequencedTaskRunner> callback_task_runner_;
-
-  DISALLOW_COPY_AND_ASSIGN(AttachmentStoreBackend);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_STORE_BACKEND_H_
diff --git a/components/sync/engine/attachments/attachment_store_frontend.cc b/components/sync/engine/attachments/attachment_store_frontend.cc
deleted file mode 100644
index d67c2c14..0000000
--- a/components/sync/engine/attachments/attachment_store_frontend.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/sync/engine/attachments/attachment_store_frontend.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/sequenced_task_runner.h"
-#include "components/sync/engine/attachments/attachment_store_backend.h"
-#include "components/sync/model/attachments/attachment.h"
-
-namespace syncer {
-
-namespace {
-
-// NoOp is needed to bind base::Passed(backend) in AttachmentStoreFrontend dtor.
-// It doesn't need to do anything.
-void NoOp(std::unique_ptr<AttachmentStoreBackend> backend) {}
-
-}  // namespace
-
-AttachmentStoreFrontend::AttachmentStoreFrontend(
-    std::unique_ptr<AttachmentStoreBackend> backend,
-    const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner)
-    : backend_(std::move(backend)), backend_task_runner_(backend_task_runner) {
-  DCHECK(backend_);
-  DCHECK(backend_task_runner_.get());
-}
-
-AttachmentStoreFrontend::~AttachmentStoreFrontend() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(backend_);
-  // To delete backend post task that doesn't do anything, but binds backend
-  // through base::Passed. This way backend will be deleted regardless whether
-  // task runs or not.
-  backend_task_runner_->PostTask(FROM_HERE,
-                                 base::Bind(&NoOp, base::Passed(&backend_)));
-}
-
-void AttachmentStoreFrontend::Init(
-    const AttachmentStore::InitCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  backend_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&AttachmentStoreBackend::Init,
-                            base::Unretained(backend_.get()), callback));
-}
-
-void AttachmentStoreFrontend::Read(
-    AttachmentStore::Component component,
-    const AttachmentIdList& ids,
-    const AttachmentStore::ReadCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  backend_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&AttachmentStoreBackend::Read,
-                 base::Unretained(backend_.get()), component, ids, callback));
-}
-
-void AttachmentStoreFrontend::Write(
-    AttachmentStore::Component component,
-    const AttachmentList& attachments,
-    const AttachmentStore::WriteCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  backend_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&AttachmentStoreBackend::Write,
-                            base::Unretained(backend_.get()), component,
-                            attachments, callback));
-}
-
-void AttachmentStoreFrontend::SetReference(AttachmentStore::Component component,
-                                           const AttachmentIdList& ids) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  backend_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&AttachmentStoreBackend::SetReference,
-                            base::Unretained(backend_.get()), component, ids));
-}
-
-void AttachmentStoreFrontend::DropReference(
-    AttachmentStore::Component component,
-    const AttachmentIdList& ids,
-    const AttachmentStore::DropCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  backend_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&AttachmentStoreBackend::DropReference,
-                 base::Unretained(backend_.get()), component, ids, callback));
-}
-
-void AttachmentStoreFrontend::ReadMetadataById(
-    AttachmentStore::Component component,
-    const AttachmentIdList& ids,
-    const AttachmentStore::ReadMetadataCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  backend_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&AttachmentStoreBackend::ReadMetadataById,
-                 base::Unretained(backend_.get()), component, ids, callback));
-}
-
-void AttachmentStoreFrontend::ReadMetadata(
-    AttachmentStore::Component component,
-    const AttachmentStore::ReadMetadataCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  backend_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&AttachmentStoreBackend::ReadMetadata,
-                 base::Unretained(backend_.get()), component, callback));
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/attachment_store_frontend.h b/components/sync/engine/attachments/attachment_store_frontend.h
deleted file mode 100644
index c146896..0000000
--- a/components/sync/engine/attachments/attachment_store_frontend.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_STORE_FRONTEND_H_
-#define COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_STORE_FRONTEND_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/sequence_checker.h"
-#include "components/sync/model/attachments/attachment_store.h"
-
-namespace base {
-class SequencedTaskRunner;
-}  // namespace base
-
-namespace syncer {
-
-class AttachmentStoreBackend;
-
-// AttachmentStoreFrontend is helper to post AttachmentStore calls to backend on
-// different thread. Backend is expected to know on which thread to post
-// callbacks with results.
-// AttachmentStoreFrontend takes ownership of backend. Backend is deleted on
-// backend thread.
-// AttachmentStoreFrontend is not thread safe, it should only be accessed from
-// model thread.
-// Method signatures of AttachmentStoreFrontend match exactly methods of
-// AttachmentStoreBackend.
-class AttachmentStoreFrontend
-    : public base::RefCounted<AttachmentStoreFrontend> {
- public:
-  AttachmentStoreFrontend(
-      std::unique_ptr<AttachmentStoreBackend> backend,
-      const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner);
-
-  void Init(const AttachmentStore::InitCallback& callback);
-
-  void Read(AttachmentStore::Component component,
-            const AttachmentIdList& ids,
-            const AttachmentStore::ReadCallback& callback);
-
-  void Write(AttachmentStore::Component component,
-             const AttachmentList& attachments,
-             const AttachmentStore::WriteCallback& callback);
-  void SetReference(AttachmentStore::Component component,
-                    const AttachmentIdList& ids);
-  void DropReference(AttachmentStore::Component component,
-                     const AttachmentIdList& ids,
-                     const AttachmentStore::DropCallback& callback);
-
-  void ReadMetadataById(AttachmentStore::Component component,
-                        const AttachmentIdList& ids,
-                        const AttachmentStore::ReadMetadataCallback& callback);
-
-  void ReadMetadata(AttachmentStore::Component component,
-                    const AttachmentStore::ReadMetadataCallback& callback);
-
- private:
-  friend class base::RefCounted<AttachmentStoreFrontend>;
-  virtual ~AttachmentStoreFrontend();
-
-  std::unique_ptr<AttachmentStoreBackend> backend_;
-  scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(AttachmentStoreFrontend);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_STORE_FRONTEND_H_
diff --git a/components/sync/engine/attachments/attachment_store_frontend_unittest.cc b/components/sync/engine/attachments/attachment_store_frontend_unittest.cc
deleted file mode 100644
index 99b25fc..0000000
--- a/components/sync/engine/attachments/attachment_store_frontend_unittest.cc
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2014 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/sync/engine/attachments/attachment_store_frontend.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/sync/engine/attachments/attachment_store_backend.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace syncer {
-
-namespace {
-
-class MockAttachmentStore : public AttachmentStoreBackend {
- public:
-  MockAttachmentStore(const base::Closure& init_called,
-                      const base::Closure& read_called,
-                      const base::Closure& write_called,
-                      const base::Closure& set_reference_called,
-                      const base::Closure& drop_reference_called,
-                      const base::Closure& read_metadata_by_id_called,
-                      const base::Closure& read_metadata_called,
-                      const base::Closure& dtor_called)
-      : AttachmentStoreBackend(nullptr),
-        init_called_(init_called),
-        read_called_(read_called),
-        write_called_(write_called),
-        set_reference_called_(set_reference_called),
-        drop_reference_called_(drop_reference_called),
-        read_metadata_by_id_called_(read_metadata_by_id_called),
-        read_metadata_called_(read_metadata_called),
-        dtor_called_(dtor_called) {}
-
-  ~MockAttachmentStore() override { dtor_called_.Run(); }
-
-  void Init(const AttachmentStore::InitCallback& callback) override {
-    init_called_.Run();
-  }
-
-  void Read(AttachmentStore::Component component,
-            const AttachmentIdList& ids,
-            const AttachmentStore::ReadCallback& callback) override {
-    read_called_.Run();
-  }
-
-  void Write(AttachmentStore::Component component,
-             const AttachmentList& attachments,
-             const AttachmentStore::WriteCallback& callback) override {
-    write_called_.Run();
-  }
-
-  void SetReference(AttachmentStore::Component component,
-                    const AttachmentIdList& ids) override {
-    set_reference_called_.Run();
-  }
-
-  void DropReference(AttachmentStore::Component component,
-                     const AttachmentIdList& ids,
-                     const AttachmentStore::DropCallback& callback) override {
-    drop_reference_called_.Run();
-  }
-
-  void ReadMetadataById(
-      AttachmentStore::Component component,
-      const AttachmentIdList& ids,
-      const AttachmentStore::ReadMetadataCallback& callback) override {
-    read_metadata_by_id_called_.Run();
-  }
-
-  void ReadMetadata(
-      AttachmentStore::Component component,
-      const AttachmentStore::ReadMetadataCallback& callback) override {
-    read_metadata_called_.Run();
-  }
-
-  base::Closure init_called_;
-  base::Closure read_called_;
-  base::Closure write_called_;
-  base::Closure set_reference_called_;
-  base::Closure drop_reference_called_;
-  base::Closure read_metadata_by_id_called_;
-  base::Closure read_metadata_called_;
-  base::Closure dtor_called_;
-};
-
-}  // namespace
-
-class AttachmentStoreFrontendTest : public testing::Test {
- protected:
-  AttachmentStoreFrontendTest()
-      : init_call_count_(0),
-        read_call_count_(0),
-        write_call_count_(0),
-        add_component_call_count_(0),
-        drop_call_count_(0),
-        read_metadata_by_id_call_count_(0),
-        read_metadata_call_count_(0),
-        dtor_call_count_(0) {}
-
-  void SetUp() override {
-    std::unique_ptr<AttachmentStoreBackend> backend(new MockAttachmentStore(
-        base::Bind(&AttachmentStoreFrontendTest::InitCalled,
-                   base::Unretained(this)),
-        base::Bind(&AttachmentStoreFrontendTest::ReadCalled,
-                   base::Unretained(this)),
-        base::Bind(&AttachmentStoreFrontendTest::WriteCalled,
-                   base::Unretained(this)),
-        base::Bind(&AttachmentStoreFrontendTest::SetReferenceCalled,
-                   base::Unretained(this)),
-        base::Bind(&AttachmentStoreFrontendTest::DropReferenceCalled,
-                   base::Unretained(this)),
-        base::Bind(&AttachmentStoreFrontendTest::ReadMetadataByIdCalled,
-                   base::Unretained(this)),
-        base::Bind(&AttachmentStoreFrontendTest::ReadMetadataCalled,
-                   base::Unretained(this)),
-        base::Bind(&AttachmentStoreFrontendTest::DtorCalled,
-                   base::Unretained(this))));
-    attachment_store_frontend_ = new AttachmentStoreFrontend(
-        std::move(backend), base::ThreadTaskRunnerHandle::Get());
-  }
-
-  static void DoneWithResult(const AttachmentStore::Result& result) {
-    NOTREACHED();
-  }
-
-  static void ReadDone(
-      const AttachmentStore::Result& result,
-      std::unique_ptr<AttachmentMap> attachments,
-      std::unique_ptr<AttachmentIdList> unavailable_attachments) {
-    NOTREACHED();
-  }
-
-  static void ReadMetadataDone(
-      const AttachmentStore::Result& result,
-      std::unique_ptr<AttachmentMetadataList> metadata) {
-    NOTREACHED();
-  }
-
-  void InitCalled() { ++init_call_count_; }
-
-  void ReadCalled() { ++read_call_count_; }
-
-  void WriteCalled() { ++write_call_count_; }
-
-  void SetReferenceCalled() { ++add_component_call_count_; }
-
-  void DropReferenceCalled() { ++drop_call_count_; }
-
-  void ReadMetadataByIdCalled() { ++read_metadata_by_id_call_count_; }
-
-  void ReadMetadataCalled() { ++read_metadata_call_count_; }
-
-  void DtorCalled() { ++dtor_call_count_; }
-
-  void RunMessageLoop() {
-    base::RunLoop run_loop;
-    run_loop.RunUntilIdle();
-  }
-
-  base::MessageLoop message_loop_;
-  scoped_refptr<AttachmentStoreFrontend> attachment_store_frontend_;
-  int init_call_count_;
-  int read_call_count_;
-  int write_call_count_;
-  int add_component_call_count_;
-  int drop_call_count_;
-  int read_metadata_by_id_call_count_;
-  int read_metadata_call_count_;
-  int dtor_call_count_;
-};
-
-// Test that method calls are forwarded to backend loop
-TEST_F(AttachmentStoreFrontendTest, MethodsCalled) {
-  AttachmentIdList id_list;
-  AttachmentList attachments;
-
-  attachment_store_frontend_->Init(
-      base::Bind(&AttachmentStoreFrontendTest::DoneWithResult));
-  EXPECT_EQ(init_call_count_, 0);
-  RunMessageLoop();
-  EXPECT_EQ(init_call_count_, 1);
-
-  attachment_store_frontend_->Read(
-      AttachmentStore::SYNC, id_list,
-      base::Bind(&AttachmentStoreFrontendTest::ReadDone));
-  EXPECT_EQ(read_call_count_, 0);
-  RunMessageLoop();
-  EXPECT_EQ(read_call_count_, 1);
-
-  attachment_store_frontend_->Write(
-      AttachmentStore::SYNC, attachments,
-      base::Bind(&AttachmentStoreFrontendTest::DoneWithResult));
-  EXPECT_EQ(write_call_count_, 0);
-  RunMessageLoop();
-  EXPECT_EQ(write_call_count_, 1);
-
-  attachment_store_frontend_->SetReference(AttachmentStore::SYNC, id_list);
-
-  attachment_store_frontend_->DropReference(
-      AttachmentStore::SYNC, id_list,
-      base::Bind(&AttachmentStoreFrontendTest::DoneWithResult));
-  EXPECT_EQ(drop_call_count_, 0);
-  RunMessageLoop();
-  EXPECT_EQ(drop_call_count_, 1);
-
-  attachment_store_frontend_->ReadMetadataById(
-      AttachmentStore::SYNC, id_list,
-      base::Bind(&AttachmentStoreFrontendTest::ReadMetadataDone));
-  EXPECT_EQ(read_metadata_by_id_call_count_, 0);
-  RunMessageLoop();
-  EXPECT_EQ(read_metadata_by_id_call_count_, 1);
-
-  attachment_store_frontend_->ReadMetadata(
-      AttachmentStore::SYNC,
-      base::Bind(&AttachmentStoreFrontendTest::ReadMetadataDone));
-  EXPECT_EQ(read_metadata_call_count_, 0);
-  RunMessageLoop();
-  EXPECT_EQ(read_metadata_call_count_, 1);
-
-  // Releasing referehce to AttachmentStoreFrontend should result in
-  // MockAttachmentStore being deleted on backend loop.
-  attachment_store_frontend_ = nullptr;
-  EXPECT_EQ(dtor_call_count_, 0);
-  RunMessageLoop();
-  EXPECT_EQ(dtor_call_count_, 1);
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/attachment_store_test_template.h b/components/sync/engine/attachments/attachment_store_test_template.h
deleted file mode 100644
index b047934c..0000000
--- a/components/sync/engine/attachments/attachment_store_test_template.h
+++ /dev/null
@@ -1,523 +0,0 @@
-// Copyright 2014 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_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_STORE_TEST_TEMPLATE_H_
-#define COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_STORE_TEST_TEMPLATE_H_
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/sync/engine/attachments/attachment_util.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "components/sync/model/attachments/attachment_store.h"
-#include "components/sync/protocol/sync.pb.h"
-#include "testing/gmock/include/gmock/gmock-matchers.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-// AttachmentStoreTest defines tests for AttachmentStore. To instantiate these
-// tests for a particular implementation you need to:
-//  - Include this file in test.
-//  - Create factory class for attachment store that implements factory method.
-//  - add INSTANTIATE_TYPED_TEST_CASE_P statement.
-// Here is how to do it for MyAttachmentStore:
-//
-// class MyAttachmentStoreFactory {
-//  public:
-//   scoped_refptr<AttachmentStore> CreateAttachmentStore() {
-//     return new MyAttachmentStore();
-//   }
-// };
-//
-// INSTANTIATE_TYPED_TEST_CASE_P(My,
-//                               AttachmentStoreTest,
-//                               MyAttachmentStoreFactory);
-
-namespace syncer {
-
-const char kTestData1[] = "test data 1";
-const char kTestData2[] = "test data 2";
-
-template <typename AttachmentStoreFactory>
-class AttachmentStoreTest : public testing::Test {
- protected:
-  AttachmentStoreFactory attachment_store_factory;
-  base::MessageLoop message_loop;
-  std::unique_ptr<AttachmentStore> store;
-  std::unique_ptr<AttachmentStoreForSync> store_for_sync;
-  AttachmentStore::Result result;
-  std::unique_ptr<AttachmentMap> attachments;
-  std::unique_ptr<AttachmentIdList> failed_attachment_ids;
-  std::unique_ptr<AttachmentMetadataList> attachment_metadata;
-
-  AttachmentStore::ReadCallback read_callback;
-  AttachmentStore::WriteCallback write_callback;
-  AttachmentStore::DropCallback drop_callback;
-  AttachmentStore::ReadMetadataCallback read_metadata_callback;
-
-  scoped_refptr<base::RefCountedString> some_data1;
-  scoped_refptr<base::RefCountedString> some_data2;
-
-  AttachmentStoreTest() {}
-
-  void SetUp() override {
-    store = attachment_store_factory.CreateAttachmentStore();
-    store_for_sync = store->CreateAttachmentStoreForSync();
-
-    Clear();
-    read_callback = base::Bind(&AttachmentStoreTest::CopyResultAttachments,
-                               base::Unretained(this), &result, &attachments,
-                               &failed_attachment_ids);
-    write_callback = base::Bind(&AttachmentStoreTest::CopyResult,
-                                base::Unretained(this), &result);
-    drop_callback = write_callback;
-    read_metadata_callback =
-        base::Bind(&AttachmentStoreTest::CopyResultMetadata,
-                   base::Unretained(this), &result, &attachment_metadata);
-
-    some_data1 = new base::RefCountedString;
-    some_data1->data() = kTestData1;
-
-    some_data2 = new base::RefCountedString;
-    some_data2->data() = kTestData2;
-  }
-
-  void ClearAndPumpLoop() {
-    Clear();
-    base::RunLoop().RunUntilIdle();
-  }
-
- private:
-  void Clear() {
-    result = AttachmentStore::UNSPECIFIED_ERROR;
-    attachments.reset();
-    failed_attachment_ids.reset();
-    attachment_metadata.reset();
-  }
-
-  void CopyResult(AttachmentStore::Result* destination_result,
-                  const AttachmentStore::Result& source_result) {
-    *destination_result = source_result;
-  }
-
-  void CopyResultAttachments(
-      AttachmentStore::Result* destination_result,
-      std::unique_ptr<AttachmentMap>* destination_attachments,
-      std::unique_ptr<AttachmentIdList>* destination_failed_attachment_ids,
-      const AttachmentStore::Result& source_result,
-      std::unique_ptr<AttachmentMap> source_attachments,
-      std::unique_ptr<AttachmentIdList> source_failed_attachment_ids) {
-    CopyResult(destination_result, source_result);
-    *destination_attachments = std::move(source_attachments);
-    *destination_failed_attachment_ids =
-        std::move(source_failed_attachment_ids);
-  }
-
-  void CopyResultMetadata(
-      AttachmentStore::Result* destination_result,
-      std::unique_ptr<AttachmentMetadataList>* destination_metadata,
-      const AttachmentStore::Result& source_result,
-      std::unique_ptr<AttachmentMetadataList> source_metadata) {
-    CopyResult(destination_result, source_result);
-    *destination_metadata = std::move(source_metadata);
-  }
-};
-
-TYPED_TEST_CASE_P(AttachmentStoreTest);
-
-// Verify that CreateAttachmentStoreForSync() creates valid object.
-TYPED_TEST_P(AttachmentStoreTest, CreateAttachmentStoreForSync) {
-  std::unique_ptr<AttachmentStoreForSync> attachment_store_for_sync =
-      this->store->CreateAttachmentStoreForSync();
-  EXPECT_NE(nullptr, attachment_store_for_sync);
-}
-
-// Verify that we do not overwrite existing attachments and that we do not treat
-// it as an error.
-TYPED_TEST_P(AttachmentStoreTest, Write_NoOverwriteNoError) {
-  // Create two attachments with the same id but different data.
-  Attachment attachment1 = Attachment::Create(this->some_data1);
-  Attachment attachment2 =
-      Attachment::CreateFromParts(attachment1.GetId(), this->some_data2);
-
-  // Write the first one.
-  AttachmentList some_attachments;
-  some_attachments.push_back(attachment1);
-  this->store->Write(some_attachments, this->write_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  // Write the second one.
-  some_attachments.clear();
-  some_attachments.push_back(attachment2);
-  this->store->Write(some_attachments, this->write_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  // Read it back and see that it was not overwritten.
-  AttachmentIdList some_attachment_ids;
-  some_attachment_ids.push_back(attachment1.GetId());
-  this->store->Read(some_attachment_ids, this->read_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(1U, this->attachments->size());
-  EXPECT_EQ(0U, this->failed_attachment_ids->size());
-  AttachmentMap::const_iterator a1 =
-      this->attachments->find(attachment1.GetId());
-  EXPECT_TRUE(a1 != this->attachments->end());
-  EXPECT_TRUE(attachment1.GetData()->Equals(a1->second.GetData()));
-}
-
-// Verify that we can write some attachments and read them back.
-TYPED_TEST_P(AttachmentStoreTest, Write_RoundTrip) {
-  Attachment attachment1 = Attachment::Create(this->some_data1);
-  Attachment attachment2 = Attachment::Create(this->some_data2);
-  AttachmentList some_attachments;
-  some_attachments.push_back(attachment1);
-  some_attachments.push_back(attachment2);
-
-  this->store->Write(some_attachments, this->write_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  AttachmentIdList some_attachment_ids;
-  some_attachment_ids.push_back(attachment1.GetId());
-  some_attachment_ids.push_back(attachment2.GetId());
-  this->store->Read(some_attachment_ids, this->read_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(2U, this->attachments->size());
-  EXPECT_EQ(0U, this->failed_attachment_ids->size());
-
-  AttachmentMap::const_iterator a1 =
-      this->attachments->find(attachment1.GetId());
-  EXPECT_TRUE(a1 != this->attachments->end());
-  EXPECT_TRUE(attachment1.GetData()->Equals(a1->second.GetData()));
-
-  AttachmentMap::const_iterator a2 =
-      this->attachments->find(attachment2.GetId());
-  EXPECT_TRUE(a2 != this->attachments->end());
-  EXPECT_TRUE(attachment2.GetData()->Equals(a2->second.GetData()));
-}
-
-// Try to read two attachments when only one exists.
-TYPED_TEST_P(AttachmentStoreTest, Read_OneNotFound) {
-  Attachment attachment1 = Attachment::Create(this->some_data1);
-  Attachment attachment2 = Attachment::Create(this->some_data2);
-
-  AttachmentList some_attachments;
-  // Write attachment1 only.
-  some_attachments.push_back(attachment1);
-  this->store->Write(some_attachments, this->write_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  // Try to read both attachment1 and attachment2.
-  AttachmentIdList ids;
-  ids.push_back(attachment1.GetId());
-  ids.push_back(attachment2.GetId());
-  this->store->Read(ids, this->read_callback);
-  this->ClearAndPumpLoop();
-
-  // See that only attachment1 was read.
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, this->result);
-  EXPECT_EQ(1U, this->attachments->size());
-  EXPECT_EQ(1U, this->failed_attachment_ids->size());
-}
-
-// Try to drop two attachments when only one exists. Verify that no error occurs
-// and that the existing attachment was dropped.
-TYPED_TEST_P(AttachmentStoreTest, Drop_DropTwoButOnlyOneExists) {
-  // First, create two attachments.
-  Attachment attachment1 = Attachment::Create(this->some_data1);
-  Attachment attachment2 = Attachment::Create(this->some_data2);
-  AttachmentList some_attachments;
-  some_attachments.push_back(attachment1);
-  some_attachments.push_back(attachment2);
-  this->store->Write(some_attachments, this->write_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  // Drop attachment1 only.
-  AttachmentIdList ids;
-  ids.push_back(attachment1.GetId());
-  this->store->Drop(ids, this->drop_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  // See that attachment1 is gone.
-  this->store->Read(ids, this->read_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, this->result);
-  EXPECT_EQ(0U, this->attachments->size());
-  EXPECT_EQ(1U, this->failed_attachment_ids->size());
-  EXPECT_EQ(attachment1.GetId(), (*this->failed_attachment_ids)[0]);
-
-  // Drop both attachment1 and attachment2.
-  ids.clear();
-  ids.push_back(attachment1.GetId());
-  ids.push_back(attachment2.GetId());
-  this->store->Drop(ids, this->drop_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  // See that attachment2 is now gone.
-  ids.clear();
-  ids.push_back(attachment2.GetId());
-  this->store->Read(ids, this->read_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, this->result);
-  EXPECT_EQ(0U, this->attachments->size());
-  EXPECT_EQ(1U, this->failed_attachment_ids->size());
-  EXPECT_EQ(attachment2.GetId(), (*this->failed_attachment_ids)[0]);
-}
-
-// Verify that attempting to drop an attachment that does not exist is not an
-// error.
-TYPED_TEST_P(AttachmentStoreTest, Drop_DoesNotExist) {
-  Attachment attachment1 = Attachment::Create(this->some_data1);
-  AttachmentList some_attachments;
-  some_attachments.push_back(attachment1);
-  this->store->Write(some_attachments, this->write_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  // Drop the attachment.
-  AttachmentIdList ids;
-  ids.push_back(attachment1.GetId());
-  this->store->Drop(ids, this->drop_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  // See that it's gone.
-  this->store->Read(ids, this->read_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, this->result);
-  EXPECT_EQ(0U, this->attachments->size());
-  EXPECT_EQ(1U, this->failed_attachment_ids->size());
-  EXPECT_EQ(attachment1.GetId(), (*this->failed_attachment_ids)[0]);
-
-  // Drop again, see that no error occurs.
-  ids.clear();
-  ids.push_back(attachment1.GetId());
-  this->store->Drop(ids, this->drop_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-}
-
-// Verify getting metadata for specific attachments.
-TYPED_TEST_P(AttachmentStoreTest, ReadMetadataById) {
-  Attachment attachment1 = Attachment::Create(this->some_data1);
-  Attachment attachment2 = Attachment::Create(this->some_data2);
-
-  AttachmentList some_attachments;
-  // Write attachment1 only.
-  some_attachments.push_back(attachment1);
-  this->store->Write(some_attachments, this->write_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  // Try to read metadata for both attachment1 and attachment2.
-  AttachmentIdList ids;
-  ids.push_back(attachment1.GetId());
-  ids.push_back(attachment2.GetId());
-  this->store->ReadMetadataById(ids, this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-
-  // See that only one entry was read.
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, this->result);
-  EXPECT_EQ(1U, this->attachment_metadata->size());
-
-  // Now write attachment2.
-  some_attachments[0] = attachment2;
-  this->store->Write(some_attachments, this->write_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  // Try to read metadata for both attachment1 and attachment2 again.
-  this->store->ReadMetadataById(ids, this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(2U, this->attachment_metadata->size());
-
-  // Verify that we've got both entries back in the right order.
-  AttachmentMetadataList::const_iterator iter =
-      this->attachment_metadata->begin();
-  EXPECT_EQ(attachment1.GetId(), iter->GetId());
-  ++iter;
-  EXPECT_EQ(attachment2.GetId(), iter->GetId());
-}
-
-// Verify that ReadMetadata/ReadMetadataForSync returns metadata for correct
-// set of attachments.
-TYPED_TEST_P(AttachmentStoreTest, ReadMetadata) {
-  // Try to read all metadata from an empty store.
-  this->store->ReadMetadata(this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(0U, this->attachment_metadata->size());
-
-  // Create and write attachments with different set of references.
-  Attachment attachment_mt = Attachment::Create(this->some_data1);
-  Attachment attachment_sync = Attachment::Create(this->some_data1);
-  Attachment attachment_both = Attachment::Create(this->some_data1);
-
-  AttachmentList attachments;
-  attachments.push_back(attachment_mt);
-  attachments.push_back(attachment_sync);
-  attachments.push_back(attachment_both);
-  this->store->Write(attachments, this->write_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  AttachmentIdList ids;
-  ids.push_back(attachment_sync.GetId());
-  ids.push_back(attachment_both.GetId());
-  this->store_for_sync->SetSyncReference(ids);
-
-  ids.clear();
-  ids.push_back(attachment_sync.GetId());
-  this->store->Drop(ids, this->drop_callback);
-  this->ClearAndPumpLoop();
-
-  // Calling ReadMetadataById for above three attachments should only return
-  // attachments with model type reference.
-  ids.clear();
-  ids.push_back(attachment_mt.GetId());
-  ids.push_back(attachment_sync.GetId());
-  ids.push_back(attachment_both.GetId());
-  this->store->ReadMetadataById(ids, this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, this->result);
-  EXPECT_EQ(2U, this->attachment_metadata->size());
-  AttachmentIdSet model_type_id_set;
-  model_type_id_set.insert(attachment_mt.GetId());
-  model_type_id_set.insert(attachment_both.GetId());
-  EXPECT_THAT(model_type_id_set,
-              testing::Contains((*this->attachment_metadata)[0].GetId()));
-  EXPECT_THAT(model_type_id_set,
-              testing::Contains((*this->attachment_metadata)[1].GetId()));
-
-  // Call to ReadMetadata() should only return attachments with model type
-  // reference.
-  this->store->ReadMetadata(this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(2U, this->attachment_metadata->size());
-
-  // Verify that we get all attachments back (the order is undefined).
-  EXPECT_THAT(model_type_id_set,
-              testing::Contains((*this->attachment_metadata)[0].GetId()));
-  EXPECT_THAT(model_type_id_set,
-              testing::Contains((*this->attachment_metadata)[1].GetId()));
-
-  // Call to ReadMetadataForSync() should only return attachments with sync
-  // reference.
-  this->store_for_sync->ReadMetadataForSync(this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(2U, this->attachment_metadata->size());
-
-  AttachmentIdSet sync_id_set;
-  sync_id_set.insert(attachment_sync.GetId());
-  sync_id_set.insert(attachment_both.GetId());
-  EXPECT_THAT(sync_id_set,
-              testing::Contains((*this->attachment_metadata)[0].GetId()));
-  EXPECT_THAT(sync_id_set,
-              testing::Contains((*this->attachment_metadata)[1].GetId()));
-}
-
-// Verify that setting/droping references gets reflected in ReadMetadata and
-// that attachment is only deleted after last reference is droped.
-TYPED_TEST_P(AttachmentStoreTest, SetSyncReference_DropSyncReference) {
-  Attachment attachment = Attachment::Create(this->some_data1);
-  AttachmentList attachments;
-  attachments.push_back(attachment);
-  AttachmentIdList ids;
-  ids.push_back(attachment.GetId());
-
-  // When writing attachment to store only model type reference should be set.
-  this->store->Write(attachments, this->write_callback);
-
-  this->store->ReadMetadata(this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(1U, this->attachment_metadata->size());
-  EXPECT_EQ(attachment.GetId(), this->attachment_metadata->begin()->GetId());
-
-  this->store_for_sync->ReadMetadataForSync(this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(0U, this->attachment_metadata->size());
-
-  // After call to SetSyncReference() ReadMetadataForSync should start returning
-  // attachment.
-  this->store_for_sync->SetSyncReference(ids);
-
-  this->store_for_sync->ReadMetadataForSync(this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(1U, this->attachment_metadata->size());
-
-  // Call SetSyncReference() to verify it is idempotent.
-  this->store_for_sync->SetSyncReference(ids);
-  this->ClearAndPumpLoop();
-
-  // Droping attachment should remove model type reference, but there is still
-  // sync reference.
-  this->store->Drop(ids, this->drop_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  this->store->ReadMetadata(this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(0U, this->attachment_metadata->size());
-
-  this->store_for_sync->ReadMetadataForSync(this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(1U, this->attachment_metadata->size());
-
-  // ReadMetadataById should return UNSPECIFIED_ERROR, attachment doesn't have
-  // model type reference.
-  this->store->ReadMetadataById(ids, this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, this->result);
-  EXPECT_EQ(0U, this->attachment_metadata->size());
-
-  // Call Drop() again to ensure it doesn't fail.
-  this->store->Drop(ids, this->drop_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-
-  // After droping sync reference attachment should be deleted from store.
-  // ReadMetadataForSync should return empty result.
-  this->store_for_sync->DropSyncReference(ids);
-
-  this->store_for_sync->ReadMetadataForSync(this->read_metadata_callback);
-  this->ClearAndPumpLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, this->result);
-  EXPECT_EQ(0U, this->attachment_metadata->size());
-}
-
-REGISTER_TYPED_TEST_CASE_P(AttachmentStoreTest,
-                           CreateAttachmentStoreForSync,
-                           Write_NoOverwriteNoError,
-                           Write_RoundTrip,
-                           Read_OneNotFound,
-                           Drop_DropTwoButOnlyOneExists,
-                           Drop_DoesNotExist,
-                           ReadMetadataById,
-                           ReadMetadata,
-                           SetSyncReference_DropSyncReference);
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_STORE_TEST_TEMPLATE_H_
diff --git a/components/sync/engine/attachments/attachment_uploader.cc b/components/sync/engine/attachments/attachment_uploader.cc
deleted file mode 100644
index 8fa4ad01..0000000
--- a/components/sync/engine/attachments/attachment_uploader.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2014 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/sync/engine/attachments/attachment_uploader.h"
-
-#include "components/sync/engine_impl/attachments/attachment_uploader_impl.h"
-
-namespace syncer {
-
-AttachmentUploader::~AttachmentUploader() {}
-
-std::unique_ptr<AttachmentUploader> AttachmentUploader::Create(
-    const GURL& sync_service_url,
-    const scoped_refptr<net::URLRequestContextGetter>&
-        url_request_context_getter,
-    const std::string& account_id,
-    const OAuth2TokenService::ScopeSet scopes,
-    const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
-        token_service_provider,
-    const std::string& store_birthday,
-    ModelType model_type) {
-  return std::make_unique<AttachmentUploaderImpl>(
-      sync_service_url, url_request_context_getter, account_id, scopes,
-      token_service_provider, store_birthday, model_type);
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/attachment_uploader.h b/components/sync/engine/attachments/attachment_uploader.h
deleted file mode 100644
index f086c6f..0000000
--- a/components/sync/engine/attachments/attachment_uploader.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2014 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_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_UPLOADER_H_
-#define COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_UPLOADER_H_
-
-#include <memory>
-#include <string>
-
-#include "base/callback.h"
-#include "components/sync/base/model_type.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "google_apis/gaia/oauth2_token_service_request.h"
-
-namespace net {
-class URLRequestContextGetter;
-}  // namespace net
-
-namespace syncer {
-
-// AttachmentUploader is responsible for uploading attachments to the server.
-class AttachmentUploader {
- public:
-  // The result of an UploadAttachment operation.
-  enum UploadResult {
-    UPLOAD_SUCCESS,            // No error, attachment was uploaded
-                               // successfully.
-    UPLOAD_TRANSIENT_ERROR,    // A transient error occurred, try again later.
-    UPLOAD_UNSPECIFIED_ERROR,  // An unspecified error occurred.
-  };
-
-  using UploadCallback =
-      base::Callback<void(const UploadResult&, const AttachmentId&)>;
-
-  virtual ~AttachmentUploader();
-
-  // Upload |attachment| and invoke |callback| when done.
-  //
-  // |callback| will be invoked when the operation has completed (successfully
-  // or otherwise).
-  //
-  // |callback| will receive an UploadResult code and the AttachmentId of the
-  // newly uploaded attachment.
-  virtual void UploadAttachment(const Attachment& attachment,
-                                const UploadCallback& callback) = 0;
-
-  // Create an instance of AttachmentUploader.
-  //
-  // |sync_service_url| is the URL of the sync service.
-  //
-  // |url_request_context_getter| provides a URLRequestContext.
-  //
-  // |account_id| is the account id to use for uploads.
-  //
-  // |scopes| is the set of scopes to use for uploads.
-  //
-  // |token_service_provider| provides an OAuth2 token service.
-  //
-  // |store_birthday| is the raw, sync store birthday.
-  //
-  // |model_type| is the model type this uploader is used with.
-  static std::unique_ptr<AttachmentUploader> Create(
-      const GURL& sync_service_url,
-      const scoped_refptr<net::URLRequestContextGetter>&
-          url_request_context_getter,
-      const std::string& account_id,
-      const OAuth2TokenService::ScopeSet scopes,
-      const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
-          token_service_provider,
-      const std::string& store_birthday,
-      ModelType model_type);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_UPLOADER_H_
diff --git a/components/sync/engine/attachments/attachment_util.cc b/components/sync/engine/attachments/attachment_util.cc
deleted file mode 100644
index 5360865ee..0000000
--- a/components/sync/engine/attachments/attachment_util.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 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/sync/engine/attachments/attachment_util.h"
-
-#include "base/memory/ref_counted_memory.h"
-#include "third_party/crc32c/src/include/crc32c/crc32c.h"
-
-namespace syncer {
-
-uint32_t ComputeCrc32c(const scoped_refptr<base::RefCountedMemory>& data) {
-  return crc32c::Crc32c(data->front_as<char>(), data->size());
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/attachment_util.h b/components/sync/engine/attachments/attachment_util.h
deleted file mode 100644
index 3ecb053..0000000
--- a/components/sync/engine/attachments/attachment_util.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2014 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_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_UTIL_H_
-#define COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_UTIL_H_
-
-#include <stdint.h>
-
-#include "base/memory/ref_counted.h"
-
-namespace base {
-class RefCountedMemory;
-}
-
-namespace syncer {
-
-// Return the crc32c of the memory described by |data|.
-//
-// Potentially expensive.
-// Ideally this function should be static function in Attachment class, but
-// include_rules from sync/api/DEPS don't allow direct dependency on
-// third_party.
-uint32_t ComputeCrc32c(const scoped_refptr<base::RefCountedMemory>& data);
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ATTACHMENT_UTIL_H_
diff --git a/components/sync/engine/attachments/fake_attachment_downloader.cc b/components/sync/engine/attachments/fake_attachment_downloader.cc
deleted file mode 100644
index d07e8f0e..0000000
--- a/components/sync/engine/attachments/fake_attachment_downloader.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 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/sync/engine/attachments/fake_attachment_downloader.h"
-
-#include <memory>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/sync/engine/attachments/attachment_util.h"
-
-namespace syncer {
-
-FakeAttachmentDownloader::FakeAttachmentDownloader() {}
-
-FakeAttachmentDownloader::~FakeAttachmentDownloader() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-void FakeAttachmentDownloader::DownloadAttachment(
-    const AttachmentId& attachment_id,
-    const DownloadCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // This is happy fake downloader, it always successfully downloads empty
-  // attachment.
-  scoped_refptr<base::RefCountedMemory> data(new base::RefCountedBytes());
-  std::unique_ptr<Attachment> attachment = std::make_unique<Attachment>(
-      Attachment::CreateFromParts(attachment_id, data));
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(callback, DOWNLOAD_SUCCESS, base::Passed(&attachment)));
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/fake_attachment_downloader.h b/components/sync/engine/attachments/fake_attachment_downloader.h
deleted file mode 100644
index 13eb7e2..0000000
--- a/components/sync/engine/attachments/fake_attachment_downloader.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 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_SYNC_ENGINE_ATTACHMENTS_FAKE_ATTACHMENT_DOWNLOADER_H_
-#define COMPONENTS_SYNC_ENGINE_ATTACHMENTS_FAKE_ATTACHMENT_DOWNLOADER_H_
-
-#include "base/macros.h"
-#include "base/sequence_checker.h"
-#include "components/sync/engine/attachments/attachment_downloader.h"
-
-namespace syncer {
-
-// FakeAttachmentDownloader is for tests. For every request it posts a success
-// callback with empty attachment.
-class FakeAttachmentDownloader : public AttachmentDownloader {
- public:
-  FakeAttachmentDownloader();
-  ~FakeAttachmentDownloader() override;
-
-  // AttachmentDownloader implementation.
-  void DownloadAttachment(const AttachmentId& attachment_id,
-                          const DownloadCallback& callback) override;
-
- private:
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(FakeAttachmentDownloader);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_ENGINE_ATTACHMENTS_FAKE_ATTACHMENT_DOWNLOADER_H_
diff --git a/components/sync/engine/attachments/fake_attachment_downloader_unittest.cc b/components/sync/engine/attachments/fake_attachment_downloader_unittest.cc
deleted file mode 100644
index cc5498bb..0000000
--- a/components/sync/engine/attachments/fake_attachment_downloader_unittest.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2014 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/sync/engine/attachments/fake_attachment_downloader.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace syncer {
-
-class FakeAttachmentDownloaderTest : public testing::Test {
- protected:
-  FakeAttachmentDownloaderTest() {}
-
-  void SetUp() override {}
-
-  void TearDown() override {}
-
-  AttachmentDownloader* downloader() { return &attachment_downloader_; }
-
-  AttachmentDownloader::DownloadCallback download_callback() {
-    return base::Bind(&FakeAttachmentDownloaderTest::DownloadDone,
-                      base::Unretained(this));
-  }
-
-  const std::vector<AttachmentDownloader::DownloadResult>& download_results() {
-    return download_results_;
-  }
-
-  void RunMessageLoop() {
-    base::RunLoop run_loop;
-    run_loop.RunUntilIdle();
-  }
-
- private:
-  void DownloadDone(const AttachmentDownloader::DownloadResult& result,
-                    std::unique_ptr<Attachment> attachment) {
-    download_results_.push_back(result);
-  }
-
-  base::MessageLoop message_loop_;
-  FakeAttachmentDownloader attachment_downloader_;
-  std::vector<AttachmentDownloader::DownloadResult> download_results_;
-};
-
-TEST_F(FakeAttachmentDownloaderTest, DownloadAttachment) {
-  AttachmentId attachment_id = AttachmentId::Create(0, 0);
-  downloader()->DownloadAttachment(attachment_id, download_callback());
-  RunMessageLoop();
-  EXPECT_EQ(1U, download_results().size());
-  EXPECT_EQ(AttachmentDownloader::DOWNLOAD_SUCCESS, download_results()[0]);
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/fake_attachment_uploader.cc b/components/sync/engine/attachments/fake_attachment_uploader.cc
deleted file mode 100644
index f5f7ad59..0000000
--- a/components/sync/engine/attachments/fake_attachment_uploader.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2014 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/sync/engine/attachments/fake_attachment_uploader.h"
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "components/sync/protocol/sync.pb.h"
-
-namespace syncer {
-
-FakeAttachmentUploader::FakeAttachmentUploader() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-FakeAttachmentUploader::~FakeAttachmentUploader() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-void FakeAttachmentUploader::UploadAttachment(const Attachment& attachment,
-                                              const UploadCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(!attachment.GetId().GetProto().unique_id().empty());
-
-  UploadResult result = UPLOAD_SUCCESS;
-  AttachmentId id = attachment.GetId();
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(callback, result, id));
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/fake_attachment_uploader.h b/components/sync/engine/attachments/fake_attachment_uploader.h
deleted file mode 100644
index 6e8d114..0000000
--- a/components/sync/engine/attachments/fake_attachment_uploader.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 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_SYNC_ENGINE_ATTACHMENTS_FAKE_ATTACHMENT_UPLOADER_H_
-#define COMPONENTS_SYNC_ENGINE_ATTACHMENTS_FAKE_ATTACHMENT_UPLOADER_H_
-
-#include "base/macros.h"
-#include "base/sequence_checker.h"
-#include "components/sync/engine/attachments/attachment_uploader.h"
-
-namespace syncer {
-
-// A fake implementation of AttachmentUploader.
-class FakeAttachmentUploader : public AttachmentUploader {
- public:
-  FakeAttachmentUploader();
-  ~FakeAttachmentUploader() override;
-
-  // AttachmentUploader implementation.
-  void UploadAttachment(const Attachment& attachment,
-                        const UploadCallback& callback) override;
-
- private:
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(FakeAttachmentUploader);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_ENGINE_ATTACHMENTS_FAKE_ATTACHMENT_UPLOADER_H_
diff --git a/components/sync/engine/attachments/fake_attachment_uploader_unittest.cc b/components/sync/engine/attachments/fake_attachment_uploader_unittest.cc
deleted file mode 100644
index ab27843..0000000
--- a/components/sync/engine/attachments/fake_attachment_uploader_unittest.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2014 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/sync/engine/attachments/fake_attachment_uploader.h"
-
-#include "base/bind.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace syncer {
-
-namespace {
-
-const char kAttachmentData[] = "some data";
-
-}  // namespace
-
-class FakeAttachmentUploaderTest : public testing::Test {
- protected:
-  void SetUp() override {
-    upload_callback_count = 0;
-    upload_callback =
-        base::Bind(&FakeAttachmentUploaderTest::Increment,
-                   base::Unretained(this), &upload_callback_count);
-  }
-  base::MessageLoop message_loop;
-  FakeAttachmentUploader uploader;
-  int upload_callback_count;
-  AttachmentUploader::UploadCallback upload_callback;
-
- private:
-  void Increment(int* success_count,
-                 const AttachmentUploader::UploadResult& result,
-                 const AttachmentId& ignored) {
-    if (result == AttachmentUploader::UPLOAD_SUCCESS) {
-      ++(*success_count);
-    }
-  }
-};
-
-// Call upload attachment several times, see that the supplied callback is
-// invoked the same number of times with a result of SUCCESS.
-TEST_F(FakeAttachmentUploaderTest, UploadAttachment) {
-  scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
-  some_data->data() = kAttachmentData;
-  Attachment attachment1 = Attachment::Create(some_data);
-  Attachment attachment2 = Attachment::Create(some_data);
-  Attachment attachment3 = Attachment::Create(some_data);
-  uploader.UploadAttachment(attachment1, upload_callback);
-  uploader.UploadAttachment(attachment2, upload_callback);
-  uploader.UploadAttachment(attachment3, upload_callback);
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(upload_callback_count, 3);
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/in_memory_attachment_store.cc b/components/sync/engine/attachments/in_memory_attachment_store.cc
deleted file mode 100644
index 0af71ba..0000000
--- a/components/sync/engine/attachments/in_memory_attachment_store.cc
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2014 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/sync/engine/attachments/in_memory_attachment_store.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/location.h"
-#include "base/sequenced_task_runner.h"
-
-namespace syncer {
-
-namespace {
-
-void AppendMetadata(AttachmentMetadataList* list,
-                    const Attachment& attachment) {
-  list->push_back(
-      AttachmentMetadata(attachment.GetId(), attachment.GetData()->size()));
-}
-
-}  // namespace
-
-InMemoryAttachmentStore::InMemoryAttachmentStore(
-    const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner)
-    : AttachmentStoreBackend(callback_task_runner) {
-  // Object is created on one thread but used on another.
-  DETACH_FROM_SEQUENCE(sequence_checker_);
-}
-
-InMemoryAttachmentStore::~InMemoryAttachmentStore() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-void InMemoryAttachmentStore::Init(
-    const AttachmentStore::InitCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  PostCallback(base::Bind(callback, AttachmentStore::SUCCESS));
-}
-
-void InMemoryAttachmentStore::Read(
-    AttachmentStore::Component component,
-    const AttachmentIdList& ids,
-    const AttachmentStore::ReadCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AttachmentStore::Result result_code = AttachmentStore::SUCCESS;
-  std::unique_ptr<AttachmentMap> result_map(new AttachmentMap);
-  std::unique_ptr<AttachmentIdList> unavailable_attachments(
-      new AttachmentIdList);
-
-  for (const auto& id : ids) {
-    AttachmentEntryMap::iterator iter = attachments_.find(id);
-    if (iter != attachments_.end() &&
-        iter->second.components.count(component) > 0) {
-      const Attachment& attachment = iter->second.attachment;
-      result_map->insert(std::make_pair(id, attachment));
-    } else {
-      unavailable_attachments->push_back(id);
-    }
-  }
-  if (!unavailable_attachments->empty()) {
-    result_code = AttachmentStore::UNSPECIFIED_ERROR;
-  }
-  PostCallback(base::Bind(callback, result_code, base::Passed(&result_map),
-                          base::Passed(&unavailable_attachments)));
-}
-
-void InMemoryAttachmentStore::Write(
-    AttachmentStore::Component component,
-    const AttachmentList& attachments,
-    const AttachmentStore::WriteCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  for (const auto& attachment : attachments) {
-    attachments_.insert(std::make_pair(attachment.GetId(),
-                                       AttachmentEntry(attachment, component)));
-  }
-  PostCallback(base::Bind(callback, AttachmentStore::SUCCESS));
-}
-
-void InMemoryAttachmentStore::SetReference(AttachmentStore::Component component,
-                                           const AttachmentIdList& ids) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  for (const auto& id : ids) {
-    AttachmentEntryMap::iterator attachments_iter = attachments_.find(id);
-    if (attachments_iter != attachments_.end()) {
-      attachments_iter->second.components.insert(component);
-    }
-  }
-}
-
-void InMemoryAttachmentStore::DropReference(
-    AttachmentStore::Component component,
-    const AttachmentIdList& ids,
-    const AttachmentStore::DropCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AttachmentStore::Result result = AttachmentStore::SUCCESS;
-  for (const auto& id : ids) {
-    AttachmentEntryMap::iterator attachments_iter = attachments_.find(id);
-    if (attachments_iter == attachments_.end()) {
-      continue;
-    }
-    attachments_iter->second.components.erase(component);
-    if (attachments_iter->second.components.empty()) {
-      attachments_.erase(attachments_iter);
-    }
-  }
-  PostCallback(base::Bind(callback, result));
-}
-
-void InMemoryAttachmentStore::ReadMetadataById(
-    AttachmentStore::Component component,
-    const AttachmentIdList& ids,
-    const AttachmentStore::ReadMetadataCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AttachmentStore::Result result_code = AttachmentStore::SUCCESS;
-  std::unique_ptr<AttachmentMetadataList> metadata_list(
-      new AttachmentMetadataList());
-
-  for (const auto& id : ids) {
-    AttachmentEntryMap::iterator iter = attachments_.find(id);
-    if (iter == attachments_.end()) {
-      result_code = AttachmentStore::UNSPECIFIED_ERROR;
-      continue;
-    }
-    DCHECK_GT(iter->second.components.size(), 0u);
-    if (iter->second.components.count(component) == 0) {
-      result_code = AttachmentStore::UNSPECIFIED_ERROR;
-      continue;
-    }
-    AppendMetadata(metadata_list.get(), iter->second.attachment);
-  }
-  PostCallback(base::Bind(callback, result_code, base::Passed(&metadata_list)));
-}
-
-void InMemoryAttachmentStore::ReadMetadata(
-    AttachmentStore::Component component,
-    const AttachmentStore::ReadMetadataCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AttachmentStore::Result result_code = AttachmentStore::SUCCESS;
-  std::unique_ptr<AttachmentMetadataList> metadata_list(
-      new AttachmentMetadataList());
-
-  for (AttachmentEntryMap::const_iterator iter = attachments_.begin();
-       iter != attachments_.end(); ++iter) {
-    DCHECK_GT(iter->second.components.size(), 0u);
-    if (iter->second.components.count(component) > 0) {
-      AppendMetadata(metadata_list.get(), iter->second.attachment);
-    }
-  }
-  PostCallback(base::Bind(callback, result_code, base::Passed(&metadata_list)));
-}
-
-InMemoryAttachmentStore::AttachmentEntry::AttachmentEntry(
-    const Attachment& attachment,
-    AttachmentStore::Component initial_reference_component)
-    : attachment(attachment) {
-  components.insert(initial_reference_component);
-}
-
-InMemoryAttachmentStore::AttachmentEntry::AttachmentEntry(
-    const AttachmentEntry& other) = default;
-
-InMemoryAttachmentStore::AttachmentEntry::~AttachmentEntry() {}
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/in_memory_attachment_store.h b/components/sync/engine/attachments/in_memory_attachment_store.h
deleted file mode 100644
index e5f1e67..0000000
--- a/components/sync/engine/attachments/in_memory_attachment_store.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2014 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_SYNC_ENGINE_ATTACHMENTS_IN_MEMORY_ATTACHMENT_STORE_H_
-#define COMPONENTS_SYNC_ENGINE_ATTACHMENTS_IN_MEMORY_ATTACHMENT_STORE_H_
-
-#include <map>
-#include <set>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/sequence_checker.h"
-#include "components/sync/engine/attachments/attachment_store_backend.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_store.h"
-
-namespace base {
-class SequencedTaskRunner;
-}  // namespace base
-
-namespace syncer {
-
-// An in-memory implementation of AttachmentStore used for testing.
-// InMemoryAttachmentStore is not threadsafe, it lives on backend thread and
-// posts callbacks with results on |callback_task_runner|.
-class InMemoryAttachmentStore : public AttachmentStoreBackend {
- public:
-  InMemoryAttachmentStore(
-      const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner);
-  ~InMemoryAttachmentStore() override;
-
-  // AttachmentStoreBackend implementation.
-  void Init(const AttachmentStore::InitCallback& callback) override;
-  void Read(AttachmentStore::Component component,
-            const AttachmentIdList& ids,
-            const AttachmentStore::ReadCallback& callback) override;
-  void Write(AttachmentStore::Component component,
-             const AttachmentList& attachments,
-             const AttachmentStore::WriteCallback& callback) override;
-  void SetReference(AttachmentStore::Component component,
-                    const AttachmentIdList& ids) override;
-  void DropReference(AttachmentStore::Component component,
-                     const AttachmentIdList& ids,
-                     const AttachmentStore::DropCallback& callback) override;
-  void ReadMetadataById(
-      AttachmentStore::Component component,
-      const AttachmentIdList& ids,
-      const AttachmentStore::ReadMetadataCallback& callback) override;
-  void ReadMetadata(
-      AttachmentStore::Component component,
-      const AttachmentStore::ReadMetadataCallback& callback) override;
-
- private:
-  struct AttachmentEntry {
-    AttachmentEntry(const Attachment& attachment,
-                    AttachmentStore::Component initial_reference_component);
-    AttachmentEntry(const AttachmentEntry& other);
-    ~AttachmentEntry();
-
-    Attachment attachment;
-    std::set<AttachmentStore::Component> components;
-  };
-
-  using AttachmentEntryMap = std::map<AttachmentId, AttachmentEntry>;
-  AttachmentEntryMap attachments_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(InMemoryAttachmentStore);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_ENGINE_ATTACHMENTS_IN_MEMORY_ATTACHMENT_STORE_H_
diff --git a/components/sync/engine/attachments/in_memory_attachment_store_unittest.cc b/components/sync/engine/attachments/in_memory_attachment_store_unittest.cc
deleted file mode 100644
index 728f1a4..0000000
--- a/components/sync/engine/attachments/in_memory_attachment_store_unittest.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2014 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/sync/model/attachments/attachment_store.h"
-
-#include "components/sync/engine/attachments/attachment_store_test_template.h"
-
-namespace syncer {
-
-class InMemoryAttachmentStoreFactory {
- public:
-  InMemoryAttachmentStoreFactory() {}
-  ~InMemoryAttachmentStoreFactory() {}
-
-  std::unique_ptr<AttachmentStore> CreateAttachmentStore() {
-    return AttachmentStore::CreateInMemoryStore();
-  }
-};
-
-INSTANTIATE_TYPED_TEST_CASE_P(InMemory,
-                              AttachmentStoreTest,
-                              InMemoryAttachmentStoreFactory);
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/on_disk_attachment_store.cc b/components/sync/engine/attachments/on_disk_attachment_store.cc
deleted file mode 100644
index 14ce88f..0000000
--- a/components/sync/engine/attachments/on_disk_attachment_store.cc
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright 2014 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/sync/engine/attachments/on_disk_attachment_store.h"
-
-#include <stdint.h>
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/location.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/sequenced_task_runner.h"
-#include "components/sync/engine/attachments/attachment_util.h"
-#include "components/sync/engine_impl/attachments/proto/attachment_store.pb.h"
-#include "components/sync/protocol/attachments.pb.h"
-#include "third_party/leveldatabase/env_chromium.h"
-#include "third_party/leveldatabase/src/include/leveldb/db.h"
-#include "third_party/leveldatabase/src/include/leveldb/options.h"
-#include "third_party/leveldatabase/src/include/leveldb/slice.h"
-#include "third_party/leveldatabase/src/include/leveldb/status.h"
-#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
-
-namespace syncer {
-
-namespace {
-
-// Prefix for records containing attachment data.
-const char kAttachmentDataPrefix[] = "data-";
-
-// Prefix for records containing attachment metadata.
-const char kAttachmentMetadataPrefix[] = "metadata-";
-
-const char kDatabaseMetadataKey[] = "database-metadata";
-
-const int32_t kCurrentSchemaVersion = 1;
-
-const base::FilePath::CharType kLeveldbDirectory[] =
-    FILE_PATH_LITERAL("leveldb");
-
-// Converts AttachmentStore::Component values into
-// attachment_store_pb::RecordMetadata::Component.
-attachment_store_pb::RecordMetadata::Component ComponentToProto(
-    AttachmentStore::Component component) {
-  switch (component) {
-    case AttachmentStore::MODEL_TYPE:
-      return attachment_store_pb::RecordMetadata::MODEL_TYPE;
-    case AttachmentStore::SYNC:
-      return attachment_store_pb::RecordMetadata::SYNC;
-  }
-  NOTREACHED();
-  return attachment_store_pb::RecordMetadata::UNKNOWN;
-}
-
-leveldb::WriteOptions MakeWriteOptions() {
-  leveldb::WriteOptions write_options;
-  write_options.sync = true;
-  return write_options;
-}
-
-leveldb::ReadOptions MakeNonCachingReadOptions() {
-  leveldb::ReadOptions read_options;
-  read_options.fill_cache = false;
-  read_options.verify_checksums = true;
-  return read_options;
-}
-
-leveldb::ReadOptions MakeCachingReadOptions() {
-  leveldb::ReadOptions read_options;
-  read_options.fill_cache = true;
-  read_options.verify_checksums = true;
-  return read_options;
-}
-
-leveldb::Status ReadStoreMetadata(
-    leveldb::DB* db,
-    attachment_store_pb::StoreMetadata* metadata) {
-  std::string data_str;
-
-  leveldb::Status status =
-      db->Get(MakeCachingReadOptions(), kDatabaseMetadataKey, &data_str);
-  if (!status.ok())
-    return status;
-  if (!metadata->ParseFromString(data_str))
-    return leveldb::Status::Corruption("Metadata record corruption");
-  return leveldb::Status::OK();
-}
-
-leveldb::Status WriteStoreMetadata(
-    leveldb::DB* db,
-    const attachment_store_pb::StoreMetadata& metadata) {
-  std::string data_str;
-
-  metadata.SerializeToString(&data_str);
-  return db->Put(MakeWriteOptions(), kDatabaseMetadataKey, data_str);
-}
-
-// Adds reference to component into RecordMetadata::component set.
-// Returns true if record_metadata was modified and needs to be written to disk.
-bool SetReferenceInRecordMetadata(
-    attachment_store_pb::RecordMetadata* record_metadata,
-    attachment_store_pb::RecordMetadata::Component proto_component) {
-  DCHECK(record_metadata);
-  for (const int component : record_metadata->component()) {
-    if (component == proto_component)
-      return false;
-  }
-  record_metadata->add_component(proto_component);
-  return true;
-}
-
-// Drops reference to component from RecordMetadata::component set.
-// Returns true if record_metadata was modified and needs to be written to disk.
-bool DropReferenceInRecordMetadata(
-    attachment_store_pb::RecordMetadata* record_metadata,
-    attachment_store_pb::RecordMetadata::Component proto_component) {
-  DCHECK(record_metadata);
-  bool component_removed = false;
-  ::google::protobuf::RepeatedField<int>* mutable_components =
-      record_metadata->mutable_component();
-  for (int i = 0; i < mutable_components->size();) {
-    if (mutable_components->Get(i) == proto_component) {
-      if (i < mutable_components->size() - 1) {
-        // Don't swap last element with itself.
-        mutable_components->SwapElements(i, mutable_components->size() - 1);
-      }
-      mutable_components->RemoveLast();
-      component_removed = true;
-    } else {
-      ++i;
-    }
-  }
-  return component_removed;
-}
-
-bool AttachmentHasReferenceFromComponent(
-    const attachment_store_pb::RecordMetadata& record_metadata,
-    attachment_store_pb::RecordMetadata::Component proto_component) {
-  for (const auto& reference_component : record_metadata.component()) {
-    if (reference_component == proto_component) {
-      return true;
-    }
-  }
-  return false;
-}
-
-}  // namespace
-
-OnDiskAttachmentStore::OnDiskAttachmentStore(
-    const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner,
-    const base::FilePath& path)
-    : AttachmentStoreBackend(callback_task_runner), path_(path) {}
-
-OnDiskAttachmentStore::~OnDiskAttachmentStore() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-void OnDiskAttachmentStore::Init(
-    const AttachmentStore::InitCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AttachmentStore::Result result_code = OpenOrCreate(path_);
-  UMA_HISTOGRAM_ENUMERATION("Sync.Attachments.StoreInitResult", result_code,
-                            AttachmentStore::RESULT_SIZE);
-  PostCallback(base::Bind(callback, result_code));
-}
-
-void OnDiskAttachmentStore::Read(
-    AttachmentStore::Component component,
-    const AttachmentIdList& ids,
-    const AttachmentStore::ReadCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  std::unique_ptr<AttachmentMap> result_map(new AttachmentMap());
-  std::unique_ptr<AttachmentIdList> unavailable_attachments(
-      new AttachmentIdList());
-
-  AttachmentStore::Result result_code =
-      AttachmentStore::STORE_INITIALIZATION_FAILED;
-
-  if (db_) {
-    result_code = AttachmentStore::SUCCESS;
-    for (const auto& id : ids) {
-      std::unique_ptr<Attachment> attachment;
-      attachment = ReadSingleAttachment(id, component);
-      if (attachment) {
-        result_map->insert(std::make_pair(id, *attachment));
-      } else {
-        unavailable_attachments->push_back(id);
-      }
-    }
-    result_code = unavailable_attachments->empty()
-                      ? AttachmentStore::SUCCESS
-                      : AttachmentStore::UNSPECIFIED_ERROR;
-  } else {
-    *unavailable_attachments = ids;
-  }
-
-  PostCallback(base::Bind(callback, result_code, base::Passed(&result_map),
-                          base::Passed(&unavailable_attachments)));
-}
-
-void OnDiskAttachmentStore::Write(
-    AttachmentStore::Component component,
-    const AttachmentList& attachments,
-    const AttachmentStore::WriteCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AttachmentStore::Result result_code =
-      AttachmentStore::STORE_INITIALIZATION_FAILED;
-
-  if (db_) {
-    result_code = AttachmentStore::SUCCESS;
-    AttachmentList::const_iterator iter = attachments.begin();
-    const AttachmentList::const_iterator end = attachments.end();
-    for (; iter != end; ++iter) {
-      if (!WriteSingleAttachment(*iter, component))
-        result_code = AttachmentStore::UNSPECIFIED_ERROR;
-    }
-  }
-  PostCallback(base::Bind(callback, result_code));
-}
-
-void OnDiskAttachmentStore::SetReference(AttachmentStore::Component component,
-                                         const AttachmentIdList& ids) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (!db_)
-    return;
-  attachment_store_pb::RecordMetadata::Component proto_component =
-      ComponentToProto(component);
-  for (const auto& id : ids) {
-    attachment_store_pb::RecordMetadata record_metadata;
-    if (!ReadSingleRecordMetadata(id, &record_metadata))
-      continue;
-    if (SetReferenceInRecordMetadata(&record_metadata, proto_component))
-      WriteSingleRecordMetadata(id, record_metadata);
-  }
-}
-
-void OnDiskAttachmentStore::DropReference(
-    AttachmentStore::Component component,
-    const AttachmentIdList& ids,
-    const AttachmentStore::DropCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AttachmentStore::Result result_code =
-      AttachmentStore::STORE_INITIALIZATION_FAILED;
-  if (db_) {
-    attachment_store_pb::RecordMetadata::Component proto_component =
-        ComponentToProto(component);
-    result_code = AttachmentStore::SUCCESS;
-    leveldb::WriteOptions write_options = MakeWriteOptions();
-    for (const auto& id : ids) {
-      attachment_store_pb::RecordMetadata record_metadata;
-      if (!ReadSingleRecordMetadata(id, &record_metadata))
-        continue;  // Record not found.
-      if (!DropReferenceInRecordMetadata(&record_metadata, proto_component))
-        continue;  // Component is not in components set. Metadata was not
-                   // updated.
-      if (record_metadata.component_size() == 0) {
-        // Last reference dropped. Need to delete attachment.
-        leveldb::WriteBatch write_batch;
-        write_batch.Delete(MakeDataKeyFromAttachmentId(id));
-        write_batch.Delete(MakeMetadataKeyFromAttachmentId(id));
-
-        leveldb::Status status = db_->Write(write_options, &write_batch);
-        if (!status.ok()) {
-          // DB::Delete doesn't check if record exists, it returns ok just like
-          // AttachmentStore::Drop should.
-          DVLOG(1) << "DB::Write failed: status=" << status.ToString();
-          result_code = AttachmentStore::UNSPECIFIED_ERROR;
-        }
-      } else {
-        WriteSingleRecordMetadata(id, record_metadata);
-      }
-    }
-  }
-  PostCallback(base::Bind(callback, result_code));
-}
-
-void OnDiskAttachmentStore::ReadMetadataById(
-    AttachmentStore::Component component,
-    const AttachmentIdList& ids,
-    const AttachmentStore::ReadMetadataCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AttachmentStore::Result result_code =
-      AttachmentStore::STORE_INITIALIZATION_FAILED;
-  std::unique_ptr<AttachmentMetadataList> metadata_list(
-      new AttachmentMetadataList());
-  if (db_) {
-    result_code = AttachmentStore::SUCCESS;
-    for (const auto& id : ids) {
-      attachment_store_pb::RecordMetadata record_metadata;
-      if (!ReadSingleRecordMetadata(id, &record_metadata)) {
-        result_code = AttachmentStore::UNSPECIFIED_ERROR;
-        continue;
-      }
-      if (!AttachmentHasReferenceFromComponent(record_metadata,
-                                               ComponentToProto(component))) {
-        result_code = AttachmentStore::UNSPECIFIED_ERROR;
-        continue;
-      }
-      metadata_list->push_back(MakeAttachmentMetadata(id, record_metadata));
-    }
-  }
-  PostCallback(base::Bind(callback, result_code, base::Passed(&metadata_list)));
-}
-
-void OnDiskAttachmentStore::ReadMetadata(
-    AttachmentStore::Component component,
-    const AttachmentStore::ReadMetadataCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AttachmentStore::Result result_code =
-      AttachmentStore::STORE_INITIALIZATION_FAILED;
-  std::unique_ptr<AttachmentMetadataList> metadata_list(
-      new AttachmentMetadataList());
-
-  if (db_) {
-    attachment_store_pb::RecordMetadata::Component proto_component =
-        ComponentToProto(component);
-    result_code = AttachmentStore::SUCCESS;
-    std::unique_ptr<leveldb::Iterator> db_iterator(
-        db_->NewIterator(MakeNonCachingReadOptions()));
-    DCHECK(db_iterator);
-    for (db_iterator->Seek(kAttachmentMetadataPrefix); db_iterator->Valid();
-         db_iterator->Next()) {
-      leveldb::Slice key = db_iterator->key();
-      if (!key.starts_with(kAttachmentMetadataPrefix)) {
-        break;
-      }
-      // Make AttachmentId from levelDB key.
-      key.remove_prefix(strlen(kAttachmentMetadataPrefix));
-      sync_pb::AttachmentIdProto id_proto;
-      id_proto.set_unique_id(key.ToString());
-      AttachmentId id = AttachmentId::CreateFromProto(id_proto);
-      // Parse metadata record.
-      attachment_store_pb::RecordMetadata record_metadata;
-      if (!record_metadata.ParseFromString(db_iterator->value().ToString())) {
-        DVLOG(1) << "RecordMetadata::ParseFromString failed";
-        result_code = AttachmentStore::UNSPECIFIED_ERROR;
-        continue;
-      }
-      DCHECK_GT(record_metadata.component_size(), 0);
-      if (AttachmentHasReferenceFromComponent(record_metadata, proto_component))
-        metadata_list->push_back(MakeAttachmentMetadata(id, record_metadata));
-    }
-
-    if (!db_iterator->status().ok()) {
-      DVLOG(1) << "DB Iterator failed: status="
-               << db_iterator->status().ToString();
-      result_code = AttachmentStore::UNSPECIFIED_ERROR;
-    }
-  }
-
-  PostCallback(base::Bind(callback, result_code, base::Passed(&metadata_list)));
-}
-
-AttachmentStore::Result OnDiskAttachmentStore::OpenOrCreate(
-    const base::FilePath& path) {
-  DCHECK(!db_);
-  base::FilePath leveldb_path = path.Append(kLeveldbDirectory);
-
-  std::unique_ptr<leveldb::DB> db;
-  leveldb_env::Options options;
-  options.create_if_missing = true;
-  // TODO(pavely): crbug/424287 Consider adding info_log, block_cache and
-  // filter_policy to options.
-  leveldb::Status status =
-      leveldb_env::OpenDB(options, leveldb_path.AsUTF8Unsafe(), &db);
-  if (!status.ok()) {
-    DVLOG(1) << "OpenDB failed: status=" << status.ToString()
-             << ", path=" << path.AsUTF8Unsafe();
-    return AttachmentStore::UNSPECIFIED_ERROR;
-  }
-
-  attachment_store_pb::StoreMetadata metadata;
-  status = ReadStoreMetadata(db.get(), &metadata);
-  if (!status.ok() && !status.IsNotFound()) {
-    DVLOG(1) << "ReadStoreMetadata failed: status=" << status.ToString();
-    return AttachmentStore::UNSPECIFIED_ERROR;
-  }
-  if (status.IsNotFound()) {
-    // Brand new database.
-    metadata.set_schema_version(kCurrentSchemaVersion);
-    status = WriteStoreMetadata(db.get(), metadata);
-    if (!status.ok()) {
-      DVLOG(1) << "WriteStoreMetadata failed: status=" << status.ToString();
-      return AttachmentStore::UNSPECIFIED_ERROR;
-    }
-  }
-  DCHECK(status.ok());
-
-  // Upgrade code goes here.
-
-  if (metadata.schema_version() != kCurrentSchemaVersion) {
-    DVLOG(1) << "Unknown schema version: " << metadata.schema_version();
-    return AttachmentStore::UNSPECIFIED_ERROR;
-  }
-
-  db_ = std::move(db);
-  return AttachmentStore::SUCCESS;
-}
-
-std::unique_ptr<Attachment> OnDiskAttachmentStore::ReadSingleAttachment(
-    const AttachmentId& attachment_id,
-    AttachmentStore::Component component) {
-  std::unique_ptr<Attachment> attachment;
-  attachment_store_pb::RecordMetadata record_metadata;
-  if (!ReadSingleRecordMetadata(attachment_id, &record_metadata)) {
-    return attachment;
-  }
-  if (!AttachmentHasReferenceFromComponent(record_metadata,
-                                           ComponentToProto(component)))
-    return attachment;
-
-  const std::string key = MakeDataKeyFromAttachmentId(attachment_id);
-  std::string data_str;
-  leveldb::Status status =
-      db_->Get(MakeNonCachingReadOptions(), key, &data_str);
-  if (!status.ok()) {
-    DVLOG(1) << "DB::Get for data failed: status=" << status.ToString();
-    return attachment;
-  }
-  scoped_refptr<base::RefCountedMemory> data =
-      base::RefCountedString::TakeString(&data_str);
-  uint32_t crc32c = ComputeCrc32c(data);
-  if (record_metadata.has_crc32c()) {
-    if (record_metadata.crc32c() != crc32c) {
-      DVLOG(1) << "Attachment crc32c does not match value read from store";
-      return attachment;
-    }
-    if (record_metadata.crc32c() != attachment_id.GetCrc32c()) {
-      DVLOG(1) << "Attachment crc32c does not match value in AttachmentId";
-      return attachment;
-    }
-  }
-  attachment = std::make_unique<Attachment>(
-      Attachment::CreateFromParts(attachment_id, data));
-  return attachment;
-}
-
-bool OnDiskAttachmentStore::WriteSingleAttachment(
-    const Attachment& attachment,
-    AttachmentStore::Component component) {
-  const std::string metadata_key =
-      MakeMetadataKeyFromAttachmentId(attachment.GetId());
-  const std::string data_key = MakeDataKeyFromAttachmentId(attachment.GetId());
-
-  std::string metadata_str;
-  leveldb::Status status =
-      db_->Get(MakeCachingReadOptions(), metadata_key, &metadata_str);
-  if (status.ok()) {
-    // Entry exists, don't overwrite.
-    return true;
-  } else if (!status.IsNotFound()) {
-    // Entry exists but failed to read.
-    DVLOG(1) << "DB::Get failed: status=" << status.ToString();
-    return false;
-  }
-  DCHECK(status.IsNotFound());
-
-  leveldb::WriteBatch write_batch;
-  // Write metadata.
-  attachment_store_pb::RecordMetadata metadata;
-  metadata.set_attachment_size(attachment.GetData()->size());
-  metadata.set_crc32c(attachment.GetCrc32c());
-  SetReferenceInRecordMetadata(&metadata, ComponentToProto(component));
-  metadata_str = metadata.SerializeAsString();
-  write_batch.Put(metadata_key, metadata_str);
-  // Write data.
-  scoped_refptr<base::RefCountedMemory> data = attachment.GetData();
-  leveldb::Slice data_slice(data->front_as<char>(), data->size());
-  write_batch.Put(data_key, data_slice);
-
-  status = db_->Write(MakeWriteOptions(), &write_batch);
-  if (!status.ok()) {
-    // Failed to write.
-    DVLOG(1) << "DB::Write failed: status=" << status.ToString();
-    return false;
-  }
-  return true;
-}
-
-bool OnDiskAttachmentStore::ReadSingleRecordMetadata(
-    const AttachmentId& attachment_id,
-    attachment_store_pb::RecordMetadata* record_metadata) {
-  DCHECK(record_metadata);
-  const std::string metadata_key =
-      MakeMetadataKeyFromAttachmentId(attachment_id);
-  std::string metadata_str;
-  leveldb::Status status =
-      db_->Get(MakeCachingReadOptions(), metadata_key, &metadata_str);
-  if (!status.ok()) {
-    DVLOG(1) << "DB::Get for metadata failed: status=" << status.ToString();
-    return false;
-  }
-  if (!record_metadata->ParseFromString(metadata_str)) {
-    DVLOG(1) << "RecordMetadata::ParseFromString failed";
-    return false;
-  }
-  DCHECK_GT(record_metadata->component_size(), 0);
-  return true;
-}
-
-bool OnDiskAttachmentStore::WriteSingleRecordMetadata(
-    const AttachmentId& attachment_id,
-    const attachment_store_pb::RecordMetadata& record_metadata) {
-  const std::string metadata_key =
-      MakeMetadataKeyFromAttachmentId(attachment_id);
-  std::string metadata_str;
-  metadata_str = record_metadata.SerializeAsString();
-  leveldb::Status status =
-      db_->Put(MakeWriteOptions(), metadata_key, metadata_str);
-  if (!status.ok()) {
-    DVLOG(1) << "DB::Put failed: status=" << status.ToString();
-    return false;
-  }
-  return true;
-}
-
-std::string OnDiskAttachmentStore::MakeDataKeyFromAttachmentId(
-    const AttachmentId& attachment_id) {
-  std::string key =
-      kAttachmentDataPrefix + attachment_id.GetProto().unique_id();
-  return key;
-}
-
-std::string OnDiskAttachmentStore::MakeMetadataKeyFromAttachmentId(
-    const AttachmentId& attachment_id) {
-  std::string key =
-      kAttachmentMetadataPrefix + attachment_id.GetProto().unique_id();
-  return key;
-}
-
-AttachmentMetadata OnDiskAttachmentStore::MakeAttachmentMetadata(
-    const AttachmentId& attachment_id,
-    const attachment_store_pb::RecordMetadata& record_metadata) {
-  return AttachmentMetadata(attachment_id, record_metadata.attachment_size());
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine/attachments/on_disk_attachment_store.h b/components/sync/engine/attachments/on_disk_attachment_store.h
deleted file mode 100644
index af63ecf..0000000
--- a/components/sync/engine/attachments/on_disk_attachment_store.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2014 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_SYNC_ENGINE_ATTACHMENTS_ON_DISK_ATTACHMENT_STORE_H_
-#define COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ON_DISK_ATTACHMENT_STORE_H_
-
-#include <memory>
-#include <string>
-
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/sequence_checker.h"
-#include "components/sync/engine/attachments/attachment_store_backend.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_store.h"
-
-namespace attachment_store_pb {
-class RecordMetadata;
-}  // namespace attachment_store_pb
-
-namespace base {
-class SequencedTaskRunner;
-}  // namespace base
-
-namespace leveldb {
-class DB;
-}  // namespace leveldb
-
-namespace syncer {
-
-// On-disk implementation of AttachmentStore. Stores attachments in leveldb
-// database in |path| directory.
-class OnDiskAttachmentStore : public AttachmentStoreBackend {
- public:
-  // Constructs attachment store.
-  OnDiskAttachmentStore(
-      const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner,
-      const base::FilePath& path);
-  ~OnDiskAttachmentStore() override;
-
-  // AttachmentStoreBackend implementation.
-  void Init(const AttachmentStore::InitCallback& callback) override;
-  void Read(AttachmentStore::Component component,
-            const AttachmentIdList& ids,
-            const AttachmentStore::ReadCallback& callback) override;
-  void Write(AttachmentStore::Component component,
-             const AttachmentList& attachments,
-             const AttachmentStore::WriteCallback& callback) override;
-  void SetReference(AttachmentStore::Component component,
-                    const AttachmentIdList& ids) override;
-  void DropReference(AttachmentStore::Component component,
-                     const AttachmentIdList& ids,
-                     const AttachmentStore::DropCallback& callback) override;
-  void ReadMetadataById(
-      AttachmentStore::Component component,
-      const AttachmentIdList& ids,
-      const AttachmentStore::ReadMetadataCallback& callback) override;
-  void ReadMetadata(
-      AttachmentStore::Component component,
-      const AttachmentStore::ReadMetadataCallback& callback) override;
-
- private:
-  friend class OnDiskAttachmentStoreSpecificTest;
-
-  // Opens leveldb database at |path|, creating it if needed. In the future
-  // upgrade code will be invoked from OpenOrCreate as well. If open fails
-  // result is UNSPECIFIED_ERROR.
-  AttachmentStore::Result OpenOrCreate(const base::FilePath& path);
-  // Reads single attachment from store. Returns nullptr in case of errors.
-  std::unique_ptr<Attachment> ReadSingleAttachment(
-      const AttachmentId& attachment_id,
-      AttachmentStore::Component component);
-  // Writes single attachment to store. Returns false in case of errors.
-  bool WriteSingleAttachment(const Attachment& attachment,
-                             AttachmentStore::Component component);
-  // Reads single attachment_store_pb::RecordMetadata from levelDB into the
-  // provided buffer. Returns false in case of an error.
-  bool ReadSingleRecordMetadata(
-      const AttachmentId& attachment_id,
-      attachment_store_pb::RecordMetadata* record_metadata);
-  // Writes single attachment_store_pb::RecordMetadata to levelDB. Returns false
-  // in case of an error.
-  bool WriteSingleRecordMetadata(
-      const AttachmentId& attachment_id,
-      const attachment_store_pb::RecordMetadata& record_metadata);
-
-  static std::string MakeDataKeyFromAttachmentId(
-      const AttachmentId& attachment_id);
-  static std::string MakeMetadataKeyFromAttachmentId(
-      const AttachmentId& attachment_id);
-  static AttachmentMetadata MakeAttachmentMetadata(
-      const AttachmentId& attachment_id,
-      const attachment_store_pb::RecordMetadata& record_metadata);
-
-  const base::FilePath path_;
-  std::unique_ptr<leveldb::DB> db_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(OnDiskAttachmentStore);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_ENGINE_ATTACHMENTS_ON_DISK_ATTACHMENT_STORE_H_
diff --git a/components/sync/engine/attachments/on_disk_attachment_store_unittest.cc b/components/sync/engine/attachments/on_disk_attachment_store_unittest.cc
deleted file mode 100644
index 85a5c97..0000000
--- a/components/sync/engine/attachments/on_disk_attachment_store_unittest.cc
+++ /dev/null
@@ -1,518 +0,0 @@
-// Copyright 2014 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/sync/engine/attachments/on_disk_attachment_store.h"
-
-#include <stdint.h>
-
-#include <utility>
-
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "components/sync/engine/attachments/attachment_store_test_template.h"
-#include "components/sync/engine_impl/attachments/proto/attachment_store.pb.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/leveldatabase/env_chromium.h"
-#include "third_party/leveldatabase/leveldb_chrome.h"
-#include "third_party/leveldatabase/src/include/leveldb/db.h"
-#include "third_party/leveldatabase/src/include/leveldb/options.h"
-#include "third_party/leveldatabase/src/include/leveldb/slice.h"
-#include "third_party/leveldatabase/src/include/leveldb/status.h"
-
-namespace syncer {
-
-namespace {
-
-void AttachmentStoreCreated(AttachmentStore::Result* result_dest,
-                            const AttachmentStore::Result& result) {
-  *result_dest = result;
-}
-
-}  // namespace
-
-// Instantiation of common attachment store tests.
-class OnDiskAttachmentStoreFactory {
- public:
-  OnDiskAttachmentStoreFactory() {}
-  ~OnDiskAttachmentStoreFactory() {}
-
-  std::unique_ptr<AttachmentStore> CreateAttachmentStore() {
-    EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
-    std::unique_ptr<AttachmentStore> store;
-    AttachmentStore::Result result = AttachmentStore::UNSPECIFIED_ERROR;
-    store = AttachmentStore::CreateOnDiskStore(
-        temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-        base::Bind(&AttachmentStoreCreated, &result));
-    base::RunLoop run_loop;
-    run_loop.RunUntilIdle();
-    EXPECT_EQ(AttachmentStore::SUCCESS, result);
-    return store;
-  }
-
- private:
-  base::ScopedTempDir temp_dir_;
-};
-
-INSTANTIATE_TYPED_TEST_CASE_P(OnDisk,
-                              AttachmentStoreTest,
-                              OnDiskAttachmentStoreFactory);
-
-// Tests specific to OnDiskAttachmentStore.
-class OnDiskAttachmentStoreSpecificTest : public testing::Test {
- public:
-  base::ScopedTempDir temp_dir_;
-  base::FilePath db_path_;
-  base::MessageLoop message_loop_;
-  std::unique_ptr<AttachmentStore> store_;
-
-  OnDiskAttachmentStoreSpecificTest() {}
-
-  void SetUp() override {
-    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-    db_path_ = temp_dir_.GetPath().Append(FILE_PATH_LITERAL("leveldb"));
-    base::CreateDirectory(db_path_);
-  }
-
-  void CopyResult(AttachmentStore::Result* destination_result,
-                  const AttachmentStore::Result& source_result) {
-    *destination_result = source_result;
-  }
-
-  void CopyResultAttachments(
-      AttachmentStore::Result* destination_result,
-      AttachmentIdList* destination_failed_attachment_ids,
-      const AttachmentStore::Result& source_result,
-      std::unique_ptr<AttachmentMap> source_attachments,
-      std::unique_ptr<AttachmentIdList> source_failed_attachment_ids) {
-    CopyResult(destination_result, source_result);
-    *destination_failed_attachment_ids = *source_failed_attachment_ids;
-  }
-
-  void CopyResultMetadata(
-      AttachmentStore::Result* destination_result,
-      std::unique_ptr<AttachmentMetadataList>* destination_metadata,
-      const AttachmentStore::Result& source_result,
-      std::unique_ptr<AttachmentMetadataList> source_metadata) {
-    CopyResult(destination_result, source_result);
-    *destination_metadata = std::move(source_metadata);
-  }
-
-  std::unique_ptr<leveldb::DB> OpenLevelDB() {
-    std::unique_ptr<leveldb::DB> db;
-    leveldb_env::Options options;
-    options.create_if_missing = true;
-    leveldb::Status s =
-        leveldb_env::OpenDB(options, db_path_.AsUTF8Unsafe(), &db);
-    EXPECT_TRUE(s.ok());
-    return db;
-  }
-
-  void UpdateRecord(const std::string& key, const std::string& content) {
-    std::unique_ptr<leveldb::DB> db = OpenLevelDB();
-    leveldb::Status s = db->Put(leveldb::WriteOptions(), key, content);
-    EXPECT_TRUE(s.ok());
-  }
-
-  void UpdateStoreMetadataRecord(const std::string& content) {
-    UpdateRecord("database-metadata", content);
-  }
-
-  void UpdateAttachmentMetadataRecord(const AttachmentId& attachment_id,
-                                      const std::string& content) {
-    std::string metadata_key =
-        OnDiskAttachmentStore::MakeMetadataKeyFromAttachmentId(attachment_id);
-    UpdateRecord(metadata_key, content);
-  }
-
-  std::string ReadStoreMetadataRecord() {
-    std::unique_ptr<leveldb::DB> db = OpenLevelDB();
-    std::string content;
-    leveldb::Status s =
-        db->Get(leveldb::ReadOptions(), "database-metadata", &content);
-    EXPECT_TRUE(s.ok());
-    return content;
-  }
-
-  void VerifyAttachmentRecordsPresent(const AttachmentId& attachment_id,
-                                      bool expect_records_present) {
-    std::unique_ptr<leveldb::DB> db = OpenLevelDB();
-
-    std::string metadata_key =
-        OnDiskAttachmentStore::MakeMetadataKeyFromAttachmentId(attachment_id);
-    std::string data_key =
-        OnDiskAttachmentStore::MakeDataKeyFromAttachmentId(attachment_id);
-    std::string data;
-    leveldb::Status s = db->Get(leveldb::ReadOptions(), data_key, &data);
-    if (expect_records_present)
-      EXPECT_TRUE(s.ok());
-    else
-      EXPECT_TRUE(s.IsNotFound());
-    s = db->Get(leveldb::ReadOptions(), metadata_key, &data);
-    if (expect_records_present)
-      EXPECT_TRUE(s.ok());
-    else
-      EXPECT_TRUE(s.IsNotFound());
-  }
-
-  void RunLoop() {
-    base::RunLoop run_loop;
-    run_loop.RunUntilIdle();
-  }
-};
-
-// Ensure that store can be closed and reopen while retaining stored
-// attachments.
-TEST_F(OnDiskAttachmentStoreSpecificTest, CloseAndReopen) {
-  AttachmentStore::Result result;
-
-  result = AttachmentStore::UNSPECIFIED_ERROR;
-  store_ = AttachmentStore::CreateOnDiskStore(
-      temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-      base::Bind(&AttachmentStoreCreated, &result));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, result);
-
-  result = AttachmentStore::UNSPECIFIED_ERROR;
-  std::string some_data = "data";
-  Attachment attachment =
-      Attachment::Create(base::RefCountedString::TakeString(&some_data));
-  AttachmentList attachments;
-  attachments.push_back(attachment);
-  store_->Write(attachments,
-                base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
-                           base::Unretained(this), &result));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, result);
-
-  // Close and reopen attachment store.
-  store_ = nullptr;
-  result = AttachmentStore::UNSPECIFIED_ERROR;
-  store_ = AttachmentStore::CreateOnDiskStore(
-      temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-      base::Bind(&AttachmentStoreCreated, &result));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, result);
-
-  result = AttachmentStore::UNSPECIFIED_ERROR;
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(attachment.GetId());
-  AttachmentIdList failed_attachment_ids;
-  store_->Read(
-      attachment_ids,
-      base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultAttachments,
-                 base::Unretained(this), &result, &failed_attachment_ids));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, result);
-  EXPECT_TRUE(failed_attachment_ids.empty());
-}
-
-// Ensure loading corrupt attachment store fails.
-TEST_F(OnDiskAttachmentStoreSpecificTest, FailToOpen) {
-  EXPECT_TRUE(base::CreateDirectory(db_path_));
-  EXPECT_TRUE(leveldb_chrome::CorruptClosedDBForTesting(db_path_));
-
-  AttachmentStore::Result result = AttachmentStore::SUCCESS;
-  store_ = AttachmentStore::CreateOnDiskStore(
-      temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-      base::Bind(&AttachmentStoreCreated, &result));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, result);
-}
-
-// Ensure that attachment store works correctly when store metadata is missing,
-// corrupt or has unknown schema version.
-TEST_F(OnDiskAttachmentStoreSpecificTest, StoreMetadata) {
-  // Create and close empty database.
-  OpenLevelDB();
-  // Open database with AttachmentStore.
-  AttachmentStore::Result result = AttachmentStore::UNSPECIFIED_ERROR;
-  store_ = AttachmentStore::CreateOnDiskStore(
-      temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-      base::Bind(&AttachmentStoreCreated, &result));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, result);
-  // Close AttachmentStore so that test can check content.
-  store_ = nullptr;
-  RunLoop();
-
-  // AttachmentStore should create metadata record.
-  std::string data = ReadStoreMetadataRecord();
-  attachment_store_pb::StoreMetadata metadata;
-  EXPECT_TRUE(metadata.ParseFromString(data));
-  EXPECT_EQ(1, metadata.schema_version());
-
-  // Set unknown future schema version.
-  metadata.set_schema_version(2);
-  data = metadata.SerializeAsString();
-  UpdateStoreMetadataRecord(data);
-
-  // AttachmentStore should fail to load.
-  result = AttachmentStore::SUCCESS;
-  store_ = AttachmentStore::CreateOnDiskStore(
-      temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-      base::Bind(&AttachmentStoreCreated, &result));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, result);
-
-  // Write garbage into metadata record.
-  UpdateStoreMetadataRecord("abra.cadabra");
-
-  // AttachmentStore should fail to load.
-  result = AttachmentStore::SUCCESS;
-  store_ = AttachmentStore::CreateOnDiskStore(
-      temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-      base::Bind(&AttachmentStoreCreated, &result));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, result);
-}
-
-// Ensure that attachment store correctly maintains metadata records for
-// attachments.
-TEST_F(OnDiskAttachmentStoreSpecificTest, RecordMetadata) {
-  // Create attachment store.
-  AttachmentStore::Result create_result = AttachmentStore::UNSPECIFIED_ERROR;
-  store_ = AttachmentStore::CreateOnDiskStore(
-      temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-      base::Bind(&AttachmentStoreCreated, &create_result));
-
-  // Write two attachments.
-  AttachmentStore::Result write_result = AttachmentStore::UNSPECIFIED_ERROR;
-  std::string some_data;
-  AttachmentList attachments;
-  some_data = "data1";
-  attachments.push_back(
-      Attachment::Create(base::RefCountedString::TakeString(&some_data)));
-  some_data = "data2";
-  attachments.push_back(
-      Attachment::Create(base::RefCountedString::TakeString(&some_data)));
-  store_->Write(attachments,
-                base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
-                           base::Unretained(this), &write_result));
-
-  // Delete one of written attachments.
-  AttachmentStore::Result drop_result = AttachmentStore::UNSPECIFIED_ERROR;
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(attachments[0].GetId());
-  store_->Drop(attachment_ids,
-               base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
-                          base::Unretained(this), &drop_result));
-  store_ = nullptr;
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, create_result);
-  EXPECT_EQ(AttachmentStore::SUCCESS, write_result);
-  EXPECT_EQ(AttachmentStore::SUCCESS, drop_result);
-
-  // Verify that attachment store contains only records for second attachment.
-  VerifyAttachmentRecordsPresent(attachments[0].GetId(), false);
-  VerifyAttachmentRecordsPresent(attachments[1].GetId(), true);
-}
-
-// Ensure that attachment store fails to load attachment if the crc in the store
-// does not match the data.
-TEST_F(OnDiskAttachmentStoreSpecificTest, MismatchedCrcInStore) {
-  // Create attachment store.
-  AttachmentStore::Result create_result = AttachmentStore::UNSPECIFIED_ERROR;
-  store_ = AttachmentStore::CreateOnDiskStore(
-      temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-      base::Bind(&AttachmentStoreCreated, &create_result));
-
-  // Write attachment with incorrect crc32c.
-  AttachmentStore::Result write_result = AttachmentStore::UNSPECIFIED_ERROR;
-  const uint32_t intentionally_wrong_crc32c = 0;
-
-  scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString());
-  some_data->data() = "data1";
-  Attachment attachment = Attachment::CreateFromParts(
-      AttachmentId::Create(some_data->size(), intentionally_wrong_crc32c),
-      some_data);
-  AttachmentList attachments;
-  attachments.push_back(attachment);
-  store_->Write(attachments,
-                base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
-                           base::Unretained(this), &write_result));
-
-  // Read attachment.
-  AttachmentStore::Result read_result = AttachmentStore::UNSPECIFIED_ERROR;
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(attachment.GetId());
-  AttachmentIdList failed_attachment_ids;
-  store_->Read(
-      attachment_ids,
-      base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultAttachments,
-                 base::Unretained(this), &read_result, &failed_attachment_ids));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, create_result);
-  EXPECT_EQ(AttachmentStore::SUCCESS, write_result);
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, read_result);
-  EXPECT_THAT(failed_attachment_ids, testing::ElementsAre(attachment.GetId()));
-}
-
-// Ensure that attachment store fails to load attachment if the crc in the id
-// does not match the data.
-TEST_F(OnDiskAttachmentStoreSpecificTest, MismatchedCrcInId) {
-  // Create attachment store.
-  AttachmentStore::Result create_result = AttachmentStore::UNSPECIFIED_ERROR;
-  store_ = AttachmentStore::CreateOnDiskStore(
-      temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-      base::Bind(&AttachmentStoreCreated, &create_result));
-
-  AttachmentStore::Result write_result = AttachmentStore::UNSPECIFIED_ERROR;
-  scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString());
-  some_data->data() = "data1";
-  Attachment attachment = Attachment::Create(some_data);
-  AttachmentList attachments;
-  attachments.push_back(attachment);
-  store_->Write(attachments,
-                base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
-                           base::Unretained(this), &write_result));
-
-  // Read, but with the wrong crc32c in the id.
-  AttachmentStore::Result read_result = AttachmentStore::SUCCESS;
-
-  AttachmentId id_with_bad_crc32c =
-      AttachmentId::Create(attachment.GetId().GetSize(), 12345);
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(id_with_bad_crc32c);
-  AttachmentIdList failed_attachment_ids;
-  store_->Read(
-      attachment_ids,
-      base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultAttachments,
-                 base::Unretained(this), &read_result, &failed_attachment_ids));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, create_result);
-  EXPECT_EQ(AttachmentStore::SUCCESS, write_result);
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, read_result);
-  EXPECT_THAT(failed_attachment_ids, testing::ElementsAre(id_with_bad_crc32c));
-}
-
-// Ensure that after store initialization failure ReadWrite/Drop operations fail
-// with correct error.
-TEST_F(OnDiskAttachmentStoreSpecificTest, OpsAfterInitializationFailed) {
-  EXPECT_TRUE(base::CreateDirectory(db_path_));
-  EXPECT_TRUE(leveldb_chrome::CorruptClosedDBForTesting(db_path_));
-
-  AttachmentStore::Result create_result = AttachmentStore::SUCCESS;
-  store_ = AttachmentStore::CreateOnDiskStore(
-      temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-      base::Bind(&AttachmentStoreCreated, &create_result));
-
-  // Reading from uninitialized store should result in
-  // STORE_INITIALIZATION_FAILED.
-  AttachmentStore::Result read_result = AttachmentStore::SUCCESS;
-  AttachmentIdList attachment_ids;
-  std::string some_data("data1");
-  Attachment attachment =
-      Attachment::Create(base::RefCountedString::TakeString(&some_data));
-  attachment_ids.push_back(attachment.GetId());
-  AttachmentIdList failed_attachment_ids;
-  store_->Read(
-      attachment_ids,
-      base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultAttachments,
-                 base::Unretained(this), &read_result, &failed_attachment_ids));
-
-  // Dropping from uninitialized store should result in
-  // STORE_INITIALIZATION_FAILED.
-  AttachmentStore::Result drop_result = AttachmentStore::SUCCESS;
-  store_->Drop(attachment_ids,
-               base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
-                          base::Unretained(this), &drop_result));
-
-  // Writing to uninitialized store should result in
-  // STORE_INITIALIZATION_FAILED.
-  AttachmentStore::Result write_result = AttachmentStore::SUCCESS;
-  AttachmentList attachments;
-  attachments.push_back(attachment);
-  store_->Write(attachments,
-                base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
-                           base::Unretained(this), &write_result));
-
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, create_result);
-  EXPECT_EQ(AttachmentStore::STORE_INITIALIZATION_FAILED, read_result);
-  EXPECT_THAT(failed_attachment_ids, testing::ElementsAre(attachment_ids[0]));
-  EXPECT_EQ(AttachmentStore::STORE_INITIALIZATION_FAILED, drop_result);
-  EXPECT_EQ(AttachmentStore::STORE_INITIALIZATION_FAILED, write_result);
-}
-
-// Ensure that attachment store handles the case of having an unexpected
-// record at the end without crashing.
-TEST_F(OnDiskAttachmentStoreSpecificTest, ReadMetadataWithUnexpectedRecord) {
-  // Write a bogus entry at the end of the database.
-  UpdateRecord("zzz", "foobar");
-
-  // Create attachment store.
-  AttachmentStore::Result create_result = AttachmentStore::UNSPECIFIED_ERROR;
-  store_ = AttachmentStore::CreateOnDiskStore(
-      temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-      base::Bind(&AttachmentStoreCreated, &create_result));
-
-  // Read all metadata. Should be getting no error and zero entries.
-  AttachmentStore::Result metadata_result = AttachmentStore::UNSPECIFIED_ERROR;
-  std::unique_ptr<AttachmentMetadataList> metadata_list;
-  store_->ReadMetadata(
-      base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultMetadata,
-                 base::Unretained(this), &metadata_result, &metadata_list));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, create_result);
-  EXPECT_EQ(AttachmentStore::SUCCESS, metadata_result);
-  EXPECT_EQ(0U, metadata_list->size());
-  metadata_list.reset();
-
-  // Write 3 attachments to the store
-  AttachmentList attachments;
-
-  for (int i = 0; i < 3; i++) {
-    std::string some_data = "data";
-    Attachment attachment =
-        Attachment::Create(base::RefCountedString::TakeString(&some_data));
-    attachments.push_back(attachment);
-  }
-  AttachmentStore::Result write_result = AttachmentStore::UNSPECIFIED_ERROR;
-  store_->Write(attachments,
-                base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResult,
-                           base::Unretained(this), &write_result));
-
-  // Read all metadata back. We should be getting 3 entries.
-  store_->ReadMetadata(
-      base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultMetadata,
-                 base::Unretained(this), &metadata_result, &metadata_list));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, write_result);
-  EXPECT_EQ(AttachmentStore::SUCCESS, metadata_result);
-  EXPECT_EQ(3U, metadata_list->size());
-  // Get Id of the attachment in the middle.
-  AttachmentId id = (*metadata_list.get())[1].GetId();
-  metadata_list.reset();
-
-  // Close the store.
-  store_ = nullptr;
-  RunLoop();
-
-  // Modify the middle attachment metadata entry so that it isn't valid anymore.
-  UpdateAttachmentMetadataRecord(id, "foobar");
-
-  // Reopen the store.
-  create_result = AttachmentStore::UNSPECIFIED_ERROR;
-  metadata_result = AttachmentStore::UNSPECIFIED_ERROR;
-  store_ = AttachmentStore::CreateOnDiskStore(
-      temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get(),
-      base::Bind(&AttachmentStoreCreated, &create_result));
-
-  // Read all metadata back. We should be getting a failure and
-  // only 2 entries now.
-  store_->ReadMetadata(
-      base::Bind(&OnDiskAttachmentStoreSpecificTest::CopyResultMetadata,
-                 base::Unretained(this), &metadata_result, &metadata_list));
-  RunLoop();
-  EXPECT_EQ(AttachmentStore::SUCCESS, create_result);
-  EXPECT_EQ(AttachmentStore::UNSPECIFIED_ERROR, metadata_result);
-  EXPECT_EQ(2U, metadata_list->size());
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine_impl/attachments/DEPS b/components/sync/engine_impl/attachments/DEPS
deleted file mode 100644
index af87ba3..0000000
--- a/components/sync/engine_impl/attachments/DEPS
+++ /dev/null
@@ -1,5 +0,0 @@
-include_rules = [
-  "+net",
-  "+third_party/crc32c",
-  "+components/data_use_measurement/core",
-]
diff --git a/components/sync/engine_impl/attachments/attachment_downloader_impl.cc b/components/sync/engine_impl/attachments/attachment_downloader_impl.cc
deleted file mode 100644
index 932ea3a..0000000
--- a/components/sync/engine_impl/attachments/attachment_downloader_impl.cc
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright 2014 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/sync/engine_impl/attachments/attachment_downloader_impl.h"
-
-#include <utility>
-
-#include "base/base64.h"
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/single_thread_task_runner.h"
-#include "base/sys_byteorder.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "components/data_use_measurement/core/data_use_user_data.h"
-#include "components/sync/engine/attachments/attachment_util.h"
-#include "components/sync/engine_impl/attachments/attachment_uploader_impl.h"
-#include "components/sync/protocol/sync.pb.h"
-#include "net/base/load_flags.h"
-#include "net/http/http_response_headers.h"
-#include "net/http/http_status_code.h"
-#include "net/http/http_util.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_request_status.h"
-
-namespace syncer {
-
-struct AttachmentDownloaderImpl::DownloadState {
- public:
-  DownloadState(const AttachmentId& attachment_id,
-                const AttachmentUrl& attachment_url);
-
-  AttachmentId attachment_id;
-  AttachmentUrl attachment_url;
-  // |access_token| needed to invalidate if downloading attachment fails with
-  // HTTP_UNAUTHORIZED.
-  std::string access_token;
-  std::unique_ptr<net::URLFetcher> url_fetcher;
-  std::vector<DownloadCallback> user_callbacks;
-  base::TimeTicks start_time;
-};
-
-AttachmentDownloaderImpl::DownloadState::DownloadState(
-    const AttachmentId& attachment_id,
-    const AttachmentUrl& attachment_url)
-    : attachment_id(attachment_id), attachment_url(attachment_url) {}
-
-AttachmentDownloaderImpl::AttachmentDownloaderImpl(
-    const GURL& sync_service_url,
-    const scoped_refptr<net::URLRequestContextGetter>&
-        url_request_context_getter,
-    const std::string& account_id,
-    const OAuth2TokenService::ScopeSet& scopes,
-    const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
-        token_service_provider,
-    const std::string& store_birthday,
-    ModelType model_type)
-    : OAuth2TokenService::Consumer("attachment-downloader-impl"),
-      sync_service_url_(sync_service_url),
-      url_request_context_getter_(url_request_context_getter),
-      account_id_(account_id),
-      oauth2_scopes_(scopes),
-      token_service_provider_(token_service_provider),
-      raw_store_birthday_(store_birthday),
-      model_type_(model_type) {
-  DCHECK(url_request_context_getter_.get());
-  DCHECK(!account_id.empty());
-  DCHECK(!scopes.empty());
-  DCHECK(token_service_provider_.get());
-  DCHECK(!raw_store_birthday_.empty());
-}
-
-AttachmentDownloaderImpl::~AttachmentDownloaderImpl() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-void AttachmentDownloaderImpl::DownloadAttachment(
-    const AttachmentId& attachment_id,
-    const DownloadCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  AttachmentUrl url = AttachmentUploaderImpl::GetURLForAttachmentId(
-                          sync_service_url_, attachment_id)
-                          .spec();
-
-  StateMap::iterator iter = state_map_.find(url);
-  DownloadState* download_state =
-      iter != state_map_.end() ? iter->second.get() : nullptr;
-  if (!download_state) {
-    // There is no request started for this attachment id. Let's create
-    // DownloadState and request access token for it.
-    std::unique_ptr<DownloadState> new_download_state(
-        new DownloadState(attachment_id, url));
-    download_state = new_download_state.get();
-    state_map_[url] = std::move(new_download_state);
-    RequestAccessToken(download_state);
-  }
-  DCHECK(download_state->attachment_id == attachment_id);
-  download_state->user_callbacks.push_back(callback);
-}
-
-void AttachmentDownloaderImpl::OnGetTokenSuccess(
-    const OAuth2TokenService::Request* request,
-    const std::string& access_token,
-    const base::Time& expiration_time) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(request == access_token_request_.get());
-  access_token_request_.reset();
-  StateList::const_iterator iter;
-  // Start downloads for all download requests waiting for access token.
-  for (iter = requests_waiting_for_access_token_.begin();
-       iter != requests_waiting_for_access_token_.end(); ++iter) {
-    DownloadState* download_state = *iter;
-    download_state->access_token = access_token;
-    download_state->url_fetcher =
-        CreateFetcher(download_state->attachment_url, access_token);
-    download_state->start_time = base::TimeTicks::Now();
-    download_state->url_fetcher->Start();
-  }
-  requests_waiting_for_access_token_.clear();
-}
-
-void AttachmentDownloaderImpl::OnGetTokenFailure(
-    const OAuth2TokenService::Request* request,
-    const GoogleServiceAuthError& error) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(request == access_token_request_.get());
-  access_token_request_.reset();
-  StateList::const_iterator iter;
-  // Without access token all downloads fail.
-  for (iter = requests_waiting_for_access_token_.begin();
-       iter != requests_waiting_for_access_token_.end(); ++iter) {
-    DownloadState* download_state = *iter;
-    scoped_refptr<base::RefCountedString> null_attachment_data;
-    ReportResult(*download_state, DOWNLOAD_TRANSIENT_ERROR,
-                 null_attachment_data);
-    // Don't delete using the URL directly to avoid an access after free error
-    // due to std::unordered_map's implementation. See crbug.com/603275.
-    auto erase_iter = state_map_.find(download_state->attachment_url);
-    DCHECK(erase_iter != state_map_.end());
-    state_map_.erase(erase_iter);
-  }
-  requests_waiting_for_access_token_.clear();
-}
-
-void AttachmentDownloaderImpl::OnURLFetchComplete(
-    const net::URLFetcher* source) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  // Find DownloadState by url.
-  AttachmentUrl url = source->GetOriginalURL().spec();
-  StateMap::iterator iter = state_map_.find(url);
-  DCHECK(iter != state_map_.end());
-  const DownloadState& download_state = *iter->second;
-  DCHECK(source == download_state.url_fetcher.get());
-
-  DownloadResult result = DOWNLOAD_TRANSIENT_ERROR;
-  scoped_refptr<base::RefCountedString> attachment_data;
-  uint32_t attachment_crc32c = 0;
-
-  net::URLRequestStatus status = source->GetStatus();
-  const int response_code = source->GetResponseCode();
-  base::UmaHistogramSparse(
-      "Sync.Attachments.DownloadResponseCode",
-      status.is_success() ? response_code : status.error());
-  if (response_code == net::HTTP_OK) {
-    std::string data_as_string;
-    source->GetResponseAsString(&data_as_string);
-    attachment_data = base::RefCountedString::TakeString(&data_as_string);
-
-    UMA_HISTOGRAM_LONG_TIMES(
-        "Sync.Attachments.DownloadTotalTime",
-        base::TimeTicks::Now() - download_state.start_time);
-
-    attachment_crc32c = ComputeCrc32c(attachment_data);
-    uint32_t crc32c_from_headers = 0;
-    if (ExtractCrc32c(source->GetResponseHeaders(), &crc32c_from_headers) &&
-        attachment_crc32c != crc32c_from_headers) {
-      // Fail download only if there is useful crc32c in header and it doesn't
-      // match data. All other cases are fine. When crc32c is not in headers
-      // locally calculated one will be stored and used for further checks.
-      result = DOWNLOAD_TRANSIENT_ERROR;
-    } else {
-      // If the id's crc32c doesn't match that of the downloaded attachment,
-      // then we're stuck and retrying is unlikely to help.
-      if (attachment_crc32c != download_state.attachment_id.GetCrc32c()) {
-        result = DOWNLOAD_UNSPECIFIED_ERROR;
-      } else {
-        result = DOWNLOAD_SUCCESS;
-      }
-    }
-    UMA_HISTOGRAM_BOOLEAN("Sync.Attachments.DownloadChecksumResult",
-                          result == DOWNLOAD_SUCCESS);
-  } else if (response_code == net::HTTP_UNAUTHORIZED) {
-    // Server tells us we've got a bad token so invalidate it.
-    OAuth2TokenServiceRequest::InvalidateToken(token_service_provider_.get(),
-                                               account_id_, oauth2_scopes_,
-                                               download_state.access_token);
-    // Fail the request, but indicate that it may be successful if retried.
-    result = DOWNLOAD_TRANSIENT_ERROR;
-  } else if (response_code == net::HTTP_FORBIDDEN) {
-    // User is not allowed to use attachments.  Retrying won't help.
-    result = DOWNLOAD_UNSPECIFIED_ERROR;
-  } else if (response_code == net::URLFetcher::RESPONSE_CODE_INVALID) {
-    result = DOWNLOAD_TRANSIENT_ERROR;
-  }
-  ReportResult(download_state, result, attachment_data);
-  state_map_.erase(iter);
-}
-
-std::unique_ptr<net::URLFetcher> AttachmentDownloaderImpl::CreateFetcher(
-    const AttachmentUrl& url,
-    const std::string& access_token) {
-  net::NetworkTrafficAnnotationTag traffic_annotation =
-      net::DefineNetworkTrafficAnnotation("sync_attachment_downloader", R"(
-        semantics {
-          sender: "Chrome Sync"
-          description:
-            "Chrome Sync synchronizes profile data between Chromium clients "
-            "and Google for a given user account."
-          trigger:
-            "User makes a change to syncable profile data after enabling sync "
-            "on the device."
-          data:
-            "The device and user identifiers, along with any profile data that "
-            "is changing."
-          destination: GOOGLE_OWNED_SERVICE
-        }
-        policy {
-          cookies_allowed: NO
-          setting:
-            "Users can disable Chrome Sync by going into the profile settings "
-            "and choosing to Sign Out."
-          chrome_policy {
-            SyncDisabled {
-              policy_options {mode: MANDATORY}
-              SyncDisabled: true
-            }
-          }
-        })");
-  std::unique_ptr<net::URLFetcher> url_fetcher = net::URLFetcher::Create(
-      GURL(url), net::URLFetcher::GET, this, traffic_annotation);
-  AttachmentUploaderImpl::ConfigureURLFetcherCommon(
-      url_fetcher.get(), access_token, raw_store_birthday_, model_type_,
-      url_request_context_getter_.get());
-  data_use_measurement::DataUseUserData::AttachToFetcher(
-      url_fetcher.get(), data_use_measurement::DataUseUserData::SYNC);
-  return url_fetcher;
-}
-
-void AttachmentDownloaderImpl::RequestAccessToken(
-    DownloadState* download_state) {
-  requests_waiting_for_access_token_.push_back(download_state);
-  // Start access token request if there is no active one.
-  if (access_token_request_ == nullptr) {
-    access_token_request_ = OAuth2TokenServiceRequest::CreateAndStart(
-        token_service_provider_.get(), account_id_, oauth2_scopes_, this);
-  }
-}
-
-void AttachmentDownloaderImpl::ReportResult(
-    const DownloadState& download_state,
-    const DownloadResult& result,
-    const scoped_refptr<base::RefCountedString>& attachment_data) {
-  std::vector<DownloadCallback>::const_iterator iter;
-  for (iter = download_state.user_callbacks.begin();
-       iter != download_state.user_callbacks.end(); ++iter) {
-    std::unique_ptr<Attachment> attachment;
-    if (result == DOWNLOAD_SUCCESS) {
-      attachment = std::make_unique<Attachment>(Attachment::CreateFromParts(
-          download_state.attachment_id, attachment_data));
-    }
-
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(*iter, result, base::Passed(&attachment)));
-  }
-}
-
-bool AttachmentDownloaderImpl::ExtractCrc32c(
-    const net::HttpResponseHeaders* headers,
-    uint32_t* crc32c) {
-  DCHECK(crc32c);
-  if (!headers) {
-    return false;
-  }
-
-  std::string crc32c_encoded;
-  std::string header_value;
-  size_t iter = 0;
-  // Iterate over all matching headers.
-  while (headers->EnumerateHeader(&iter, "x-goog-hash", &header_value)) {
-    // Because EnumerateHeader is smart about list values, header_value will
-    // either be empty or a single name=value pair.
-    net::HttpUtil::NameValuePairsIterator pair_iter(header_value.begin(),
-                                                    header_value.end(), ',');
-    if (pair_iter.GetNext()) {
-      if (pair_iter.name() == "crc32c") {
-        crc32c_encoded = pair_iter.value();
-        DCHECK(!pair_iter.GetNext());
-        break;
-      }
-    }
-  }
-  // Check if header was found
-  if (crc32c_encoded.empty())
-    return false;
-  std::string crc32c_raw;
-  if (!base::Base64Decode(crc32c_encoded, &crc32c_raw))
-    return false;
-
-  if (crc32c_raw.size() != sizeof(*crc32c))
-    return false;
-
-  *crc32c =
-      base::NetToHost32(*reinterpret_cast<const uint32_t*>(crc32c_raw.c_str()));
-  return true;
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine_impl/attachments/attachment_downloader_impl.h b/components/sync/engine_impl/attachments/attachment_downloader_impl.h
deleted file mode 100644
index 56b2f6f..0000000
--- a/components/sync/engine_impl/attachments/attachment_downloader_impl.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2014 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_SYNC_ENGINE_IMPL_ATTACHMENTS_ATTACHMENT_DOWNLOADER_IMPL_H_
-#define COMPONENTS_SYNC_ENGINE_IMPL_ATTACHMENTS_ATTACHMENT_DOWNLOADER_IMPL_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/sequence_checker.h"
-#include "components/sync/base/model_type.h"
-#include "components/sync/engine/attachments/attachment_downloader.h"
-#include "google_apis/gaia/oauth2_token_service_request.h"
-#include "net/url_request/url_fetcher_delegate.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "url/gurl.h"
-
-namespace net {
-class HttpResponseHeaders;
-}  // namespace net
-
-namespace syncer {
-
-// An implementation of AttachmentDownloader.
-class AttachmentDownloaderImpl : public AttachmentDownloader,
-                                 public OAuth2TokenService::Consumer,
-                                 public net::URLFetcherDelegate {
- public:
-  // |sync_service_url| is the URL of the sync service.
-  //
-  // |url_request_context_getter| provides a URLRequestContext.
-  //
-  // |account_id| is the account id to use for downloads.
-  //
-  // |scopes| is the set of scopes to use for downloads.
-  //
-  // |token_service_provider| provides an OAuth2 token service.
-  //
-  // |store_birthday| is the raw, sync store birthday.
-  //
-  // |model_type| is the model type this downloader is used with.
-  AttachmentDownloaderImpl(
-      const GURL& sync_service_url,
-      const scoped_refptr<net::URLRequestContextGetter>&
-          url_request_context_getter,
-      const std::string& account_id,
-      const OAuth2TokenService::ScopeSet& scopes,
-      const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
-          token_service_provider,
-      const std::string& store_birthday,
-      ModelType model_type);
-  ~AttachmentDownloaderImpl() override;
-
-  // AttachmentDownloader implementation.
-  void DownloadAttachment(const AttachmentId& attachment_id,
-                          const DownloadCallback& callback) override;
-
-  // OAuth2TokenService::Consumer implementation.
-  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                         const std::string& access_token,
-                         const base::Time& expiration_time) override;
-  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                         const GoogleServiceAuthError& error) override;
-
-  // net::URLFetcherDelegate implementation.
-  void OnURLFetchComplete(const net::URLFetcher* source) override;
-
- private:
-  FRIEND_TEST_ALL_PREFIXES(AttachmentDownloaderImplTest,
-                           ExtractCrc32c_NoHeaders);
-  FRIEND_TEST_ALL_PREFIXES(AttachmentDownloaderImplTest, ExtractCrc32c_First);
-  FRIEND_TEST_ALL_PREFIXES(AttachmentDownloaderImplTest, ExtractCrc32c_TooLong);
-  FRIEND_TEST_ALL_PREFIXES(AttachmentDownloaderImplTest, ExtractCrc32c_None);
-  FRIEND_TEST_ALL_PREFIXES(AttachmentDownloaderImplTest, ExtractCrc32c_Empty);
-
-  struct DownloadState;
-  using AttachmentUrl = std::string;
-  using StateMap =
-      std::unordered_map<AttachmentUrl, std::unique_ptr<DownloadState>>;
-  using StateList = std::vector<DownloadState*>;
-
-  std::unique_ptr<net::URLFetcher> CreateFetcher(
-      const AttachmentUrl& url,
-      const std::string& access_token);
-  void RequestAccessToken(DownloadState* download_state);
-  void ReportResult(
-      const DownloadState& download_state,
-      const DownloadResult& result,
-      const scoped_refptr<base::RefCountedString>& attachment_data);
-
-  // Extract the crc32c from an X-Goog-Hash header in |headers|.
-  //
-  // Return true if a crc32c was found and useable for checking data integrity.
-  // "Usable" means headers are present, there is "x-goog-hash" header with
-  // "crc32c" hash in it, this hash is correctly base64 encoded 32 bit integer.
-  static bool ExtractCrc32c(const net::HttpResponseHeaders* headers,
-                            uint32_t* crc32c);
-
-  GURL sync_service_url_;
-  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
-
-  std::string account_id_;
-  OAuth2TokenService::ScopeSet oauth2_scopes_;
-  scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>
-      token_service_provider_;
-  std::unique_ptr<OAuth2TokenService::Request> access_token_request_;
-  std::string raw_store_birthday_;
-
-  StateMap state_map_;
-  // |requests_waiting_for_access_token_| only keeps references to DownloadState
-  // objects while access token request is pending. It doesn't control objects'
-  // lifetime.
-  StateList requests_waiting_for_access_token_;
-
-  ModelType model_type_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(AttachmentDownloaderImpl);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_ENGINE_IMPL_ATTACHMENTS_ATTACHMENT_DOWNLOADER_IMPL_H_
diff --git a/components/sync/engine_impl/attachments/attachment_downloader_impl_unittest.cc b/components/sync/engine_impl/attachments/attachment_downloader_impl_unittest.cc
deleted file mode 100644
index 7c4682b..0000000
--- a/components/sync/engine_impl/attachments/attachment_downloader_impl_unittest.cc
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright 2014 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/sync/engine_impl/attachments/attachment_downloader_impl.h"
-
-#include <map>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/sequence_checker.h"
-#include "base/single_thread_task_runner.h"
-#include "base/test/histogram_tester.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/sync/engine/attachments/attachment_util.h"
-#include "components/sync/engine_impl/attachments/attachment_uploader_impl.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "google_apis/gaia/fake_oauth2_token_service.h"
-#include "google_apis/gaia/gaia_constants.h"
-#include "net/http/http_response_headers.h"
-#include "net/url_request/test_url_fetcher_factory.h"
-#include "net/url_request/url_request_test_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/crc32c/src/include/crc32c/crc32c.h"
-
-namespace syncer {
-
-namespace {
-
-const char kAccountId[] = "attachments@gmail.com";
-const char kAccessToken[] = "access.token";
-const char kAttachmentServerUrl[] = "http://attachments.com/";
-const char kAttachmentContent[] = "attachment.content";
-const char kStoreBirthday[] = "z00000000-0000-007b-0000-0000000004d2";
-const ModelType kModelType = ModelType::ARTICLES;
-
-// MockOAuth2TokenService remembers last request for access token and verifies
-// that only one request is active at a time.
-// Call RespondToAccessTokenRequest to respond to it.
-class MockOAuth2TokenService : public FakeOAuth2TokenService {
- public:
-  MockOAuth2TokenService() : num_invalidate_token_(0) {}
-
-  ~MockOAuth2TokenService() override {}
-
-  void RespondToAccessTokenRequest(GoogleServiceAuthError error);
-
-  int num_invalidate_token() const { return num_invalidate_token_; }
-
- protected:
-  void FetchOAuth2Token(RequestImpl* request,
-                        const std::string& account_id,
-                        net::URLRequestContextGetter* getter,
-                        const std::string& client_id,
-                        const std::string& client_secret,
-                        const ScopeSet& scopes) override;
-
-  void InvalidateAccessTokenImpl(const std::string& account_id,
-                                 const std::string& client_id,
-                                 const ScopeSet& scopes,
-                                 const std::string& access_token) override;
-
- private:
-  base::WeakPtr<RequestImpl> last_request_;
-  int num_invalidate_token_;
-};
-
-void MockOAuth2TokenService::RespondToAccessTokenRequest(
-    GoogleServiceAuthError error) {
-  EXPECT_TRUE(last_request_);
-  std::string access_token;
-  base::Time expiration_time;
-  if (error == GoogleServiceAuthError::AuthErrorNone()) {
-    access_token = kAccessToken;
-    expiration_time = base::Time::Max();
-  }
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(&OAuth2TokenService::RequestImpl::InformConsumer,
-                 last_request_, error, access_token, expiration_time));
-}
-
-void MockOAuth2TokenService::FetchOAuth2Token(
-    RequestImpl* request,
-    const std::string& account_id,
-    net::URLRequestContextGetter* getter,
-    const std::string& client_id,
-    const std::string& client_secret,
-    const ScopeSet& scopes) {
-  // Only one request at a time is allowed.
-  EXPECT_FALSE(last_request_);
-  last_request_ = request->AsWeakPtr();
-}
-
-void MockOAuth2TokenService::InvalidateAccessTokenImpl(
-    const std::string& account_id,
-    const std::string& client_id,
-    const ScopeSet& scopes,
-    const std::string& access_token) {
-  ++num_invalidate_token_;
-}
-
-class TokenServiceProvider
-    : public OAuth2TokenServiceRequest::TokenServiceProvider {
- public:
-  explicit TokenServiceProvider(OAuth2TokenService* token_service);
-
-  // OAuth2TokenService::TokenServiceProvider implementation.
-  scoped_refptr<base::SingleThreadTaskRunner> GetTokenServiceTaskRunner()
-      override;
-  OAuth2TokenService* GetTokenService() override;
-
- private:
-  ~TokenServiceProvider() override;
-
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  OAuth2TokenService* token_service_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-TokenServiceProvider::TokenServiceProvider(OAuth2TokenService* token_service)
-    : task_runner_(base::ThreadTaskRunnerHandle::Get()),
-      token_service_(token_service) {
-  DCHECK(token_service_);
-}
-
-TokenServiceProvider::~TokenServiceProvider() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-TokenServiceProvider::GetTokenServiceTaskRunner() {
-  return task_runner_;
-}
-
-OAuth2TokenService* TokenServiceProvider::GetTokenService() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  return token_service_;
-}
-
-}  // namespace
-
-class AttachmentDownloaderImplTest : public testing::Test {
- protected:
-  using ResultsMap =
-      std::map<AttachmentId, AttachmentDownloader::DownloadResult>;
-
-  enum HashHeaderType {
-    HASH_HEADER_NONE,
-    HASH_HEADER_VALID,
-    HASH_HEADER_INVALID
-  };
-
-  AttachmentDownloaderImplTest()
-      : num_completed_downloads_(0),
-        attachment_id_(Attachment::Create(new base::RefCountedStaticMemory(
-                                              kAttachmentContent,
-                                              strlen(kAttachmentContent)))
-                           .GetId()) {}
-
-  void SetUp() override;
-  void TearDown() override;
-
-  AttachmentDownloader* downloader() { return attachment_downloader_.get(); }
-
-  MockOAuth2TokenService* token_service() { return token_service_.get(); }
-
-  int num_completed_downloads() { return num_completed_downloads_; }
-
-  const AttachmentId attachment_id() const { return attachment_id_; }
-
-  AttachmentDownloader::DownloadCallback download_callback(
-      const AttachmentId& id) {
-    return base::Bind(&AttachmentDownloaderImplTest::DownloadDone,
-                      base::Unretained(this), id);
-  }
-
-  // Respond with |response_code| and hash header of type |hash_header_type|.
-  void CompleteDownload(int response_code, HashHeaderType hash_header_type);
-
-  void DownloadDone(const AttachmentId& attachment_id,
-                    const AttachmentDownloader::DownloadResult& result,
-                    std::unique_ptr<Attachment> attachment);
-
-  void VerifyDownloadResult(const AttachmentId& attachment_id,
-                            const AttachmentDownloader::DownloadResult& result);
-
-  void RunMessageLoop();
-
- private:
-  static void AddHashHeader(HashHeaderType hash_header_type,
-                            net::TestURLFetcher* fetcher);
-
-  base::MessageLoopForIO message_loop_;
-  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
-  net::TestURLFetcherFactory url_fetcher_factory_;
-  std::unique_ptr<MockOAuth2TokenService> token_service_;
-  std::unique_ptr<AttachmentDownloader> attachment_downloader_;
-  ResultsMap download_results_;
-  int num_completed_downloads_;
-  const AttachmentId attachment_id_;
-};
-
-void AttachmentDownloaderImplTest::SetUp() {
-  url_request_context_getter_ =
-      new net::TestURLRequestContextGetter(message_loop_.task_runner());
-  url_fetcher_factory_.set_remove_fetcher_on_delete(true);
-  token_service_ = std::make_unique<MockOAuth2TokenService>();
-  token_service_->AddAccount(kAccountId);
-  scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>
-      token_service_provider(new TokenServiceProvider(token_service_.get()));
-
-  OAuth2TokenService::ScopeSet scopes;
-  scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope);
-  attachment_downloader_ = AttachmentDownloader::Create(
-      GURL(kAttachmentServerUrl), url_request_context_getter_, kAccountId,
-      scopes, token_service_provider, std::string(kStoreBirthday), kModelType);
-}
-
-void AttachmentDownloaderImplTest::TearDown() {
-  RunMessageLoop();
-}
-
-void AttachmentDownloaderImplTest::CompleteDownload(
-    int response_code,
-    HashHeaderType hash_header_type) {
-  // TestURLFetcherFactory remembers last active URLFetcher.
-  net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
-  // There should be outstanding url fetch request.
-  EXPECT_TRUE(fetcher);
-  fetcher->set_status(net::URLRequestStatus());
-  fetcher->set_response_code(response_code);
-  if (response_code == net::HTTP_OK) {
-    fetcher->SetResponseString(kAttachmentContent);
-  }
-  AddHashHeader(hash_header_type, fetcher);
-
-  // Call URLFetcherDelegate.
-  net::URLFetcherDelegate* delegate = fetcher->delegate();
-  delegate->OnURLFetchComplete(fetcher);
-  RunMessageLoop();
-  // Once result is processed URLFetcher should be deleted.
-  fetcher = url_fetcher_factory_.GetFetcherByID(0);
-  EXPECT_FALSE(fetcher);
-}
-
-void AttachmentDownloaderImplTest::DownloadDone(
-    const AttachmentId& attachment_id,
-    const AttachmentDownloader::DownloadResult& result,
-    std::unique_ptr<Attachment> attachment) {
-  download_results_.insert(std::make_pair(attachment_id, result));
-  if (result == AttachmentDownloader::DOWNLOAD_SUCCESS) {
-    // Successful download should be accompanied by valid attachment with
-    // matching id and valid data.
-    EXPECT_TRUE(attachment);
-    EXPECT_EQ(attachment_id, attachment->GetId());
-
-    scoped_refptr<base::RefCountedMemory> data = attachment->GetData();
-    std::string data_as_string(data->front_as<char>(), data->size());
-    EXPECT_EQ(data_as_string, kAttachmentContent);
-  } else {
-    EXPECT_FALSE(attachment);
-  }
-  ++num_completed_downloads_;
-}
-
-void AttachmentDownloaderImplTest::VerifyDownloadResult(
-    const AttachmentId& attachment_id,
-    const AttachmentDownloader::DownloadResult& result) {
-  ResultsMap::const_iterator iter = download_results_.find(attachment_id);
-  EXPECT_TRUE(iter != download_results_.end());
-  EXPECT_EQ(iter->second, result);
-}
-
-void AttachmentDownloaderImplTest::RunMessageLoop() {
-  base::RunLoop run_loop;
-  run_loop.RunUntilIdle();
-}
-
-void AttachmentDownloaderImplTest::AddHashHeader(
-    HashHeaderType hash_header_type,
-    net::TestURLFetcher* fetcher) {
-  std::string header = "X-Goog-Hash: crc32c=";
-  scoped_refptr<net::HttpResponseHeaders> headers(
-      new net::HttpResponseHeaders(""));
-  switch (hash_header_type) {
-    case HASH_HEADER_NONE:
-      break;
-    case HASH_HEADER_VALID:
-      header += AttachmentUploaderImpl::FormatCrc32cHash(
-          crc32c::Crc32c(kAttachmentContent, strlen(kAttachmentContent)));
-      headers->AddHeader(header);
-      break;
-    case HASH_HEADER_INVALID:
-      header += "BOGUS1==";
-      headers->AddHeader(header);
-      break;
-  }
-  fetcher->set_response_headers(headers);
-}
-
-TEST_F(AttachmentDownloaderImplTest, HappyCase) {
-  AttachmentId id1 = attachment_id();
-  // DownloadAttachment should trigger RequestAccessToken.
-  downloader()->DownloadAttachment(id1, download_callback(id1));
-  RunMessageLoop();
-  // Return valid access token.
-  token_service()->RespondToAccessTokenRequest(
-      GoogleServiceAuthError::AuthErrorNone());
-  RunMessageLoop();
-  // Catch histogram entries.
-  base::HistogramTester histogram_tester;
-  // Check that there is outstanding URLFetcher request and complete it.
-  CompleteDownload(net::HTTP_OK, HASH_HEADER_VALID);
-  // Verify that the response code was logged properly.
-  histogram_tester.ExpectUniqueSample("Sync.Attachments.DownloadResponseCode",
-                                      net::HTTP_OK, 1);
-  // Verify that callback was called for the right id with the right result.
-  VerifyDownloadResult(id1, AttachmentDownloader::DOWNLOAD_SUCCESS);
-}
-
-TEST_F(AttachmentDownloaderImplTest, SameIdMultipleDownloads) {
-  AttachmentId id1 = attachment_id();
-  base::HistogramTester histogram_tester;
-  // Call DownloadAttachment two times for the same id.
-  downloader()->DownloadAttachment(id1, download_callback(id1));
-  downloader()->DownloadAttachment(id1, download_callback(id1));
-  RunMessageLoop();
-  // Return valid access token.
-  token_service()->RespondToAccessTokenRequest(
-      GoogleServiceAuthError::AuthErrorNone());
-  RunMessageLoop();
-  // Start one more download after access token is received.
-  downloader()->DownloadAttachment(id1, download_callback(id1));
-  // Complete URLFetcher request.
-  CompleteDownload(net::HTTP_OK, HASH_HEADER_VALID);
-  // Verify that all download requests completed.
-  VerifyDownloadResult(id1, AttachmentDownloader::DOWNLOAD_SUCCESS);
-  EXPECT_EQ(3, num_completed_downloads());
-
-  // Let's download the same attachment again.
-  downloader()->DownloadAttachment(id1, download_callback(id1));
-  RunMessageLoop();
-  // Verify that it didn't finish prematurely.
-  EXPECT_EQ(3, num_completed_downloads());
-  // Return valid access token.
-  token_service()->RespondToAccessTokenRequest(
-      GoogleServiceAuthError::AuthErrorNone());
-  RunMessageLoop();
-  // Complete URLFetcher request.
-  CompleteDownload(net::HTTP_OK, HASH_HEADER_VALID);
-  // Verify that all download requests completed.
-  VerifyDownloadResult(id1, AttachmentDownloader::DOWNLOAD_SUCCESS);
-  EXPECT_EQ(4, num_completed_downloads());
-  histogram_tester.ExpectUniqueSample("Sync.Attachments.DownloadResponseCode",
-                                      net::HTTP_OK, 2);
-}
-
-TEST_F(AttachmentDownloaderImplTest, RequestAccessTokenFails) {
-  AttachmentId id1 = attachment_id();
-  AttachmentId id2 = AttachmentId::Create(id1.GetSize(), id1.GetCrc32c());
-  // Trigger first RequestAccessToken.
-  downloader()->DownloadAttachment(id1, download_callback(id1));
-  RunMessageLoop();
-  // Return valid access token.
-  token_service()->RespondToAccessTokenRequest(
-      GoogleServiceAuthError::AuthErrorNone());
-  RunMessageLoop();
-  // Trigger second RequestAccessToken.
-  downloader()->DownloadAttachment(id2, download_callback(id2));
-  RunMessageLoop();
-  // Fail RequestAccessToken.
-  token_service()->RespondToAccessTokenRequest(
-      GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
-  RunMessageLoop();
-  // Only id2 should fail.
-  VerifyDownloadResult(id2, AttachmentDownloader::DOWNLOAD_TRANSIENT_ERROR);
-  // Complete request for id1.
-  CompleteDownload(net::HTTP_OK, HASH_HEADER_VALID);
-  VerifyDownloadResult(id1, AttachmentDownloader::DOWNLOAD_SUCCESS);
-}
-
-TEST_F(AttachmentDownloaderImplTest, URLFetcher_BadToken) {
-  AttachmentId id1 = attachment_id();
-  downloader()->DownloadAttachment(id1, download_callback(id1));
-  RunMessageLoop();
-  // Return valid access token.
-  token_service()->RespondToAccessTokenRequest(
-      GoogleServiceAuthError::AuthErrorNone());
-  RunMessageLoop();
-  // Fail URLFetcher. This should trigger download failure and access token
-  // invalidation.
-  base::HistogramTester histogram_tester;
-  CompleteDownload(net::HTTP_UNAUTHORIZED, HASH_HEADER_VALID);
-  EXPECT_EQ(1, token_service()->num_invalidate_token());
-  VerifyDownloadResult(id1, AttachmentDownloader::DOWNLOAD_TRANSIENT_ERROR);
-  histogram_tester.ExpectUniqueSample("Sync.Attachments.DownloadResponseCode",
-                                      net::HTTP_UNAUTHORIZED, 1);
-}
-
-TEST_F(AttachmentDownloaderImplTest, URLFetcher_ServiceUnavailable) {
-  AttachmentId id1 = attachment_id();
-  downloader()->DownloadAttachment(id1, download_callback(id1));
-  RunMessageLoop();
-  // Return valid access token.
-  token_service()->RespondToAccessTokenRequest(
-      GoogleServiceAuthError::AuthErrorNone());
-  RunMessageLoop();
-  // Fail URLFetcher. This should trigger download failure. Access token
-  // shouldn't be invalidated.
-  base::HistogramTester histogram_tester;
-  CompleteDownload(net::HTTP_SERVICE_UNAVAILABLE, HASH_HEADER_VALID);
-  EXPECT_EQ(0, token_service()->num_invalidate_token());
-  VerifyDownloadResult(id1, AttachmentDownloader::DOWNLOAD_TRANSIENT_ERROR);
-  histogram_tester.ExpectUniqueSample("Sync.Attachments.DownloadResponseCode",
-                                      net::HTTP_SERVICE_UNAVAILABLE, 1);
-}
-
-// Verify that if no hash is present on the response the downloader accepts the
-// received attachment.
-TEST_F(AttachmentDownloaderImplTest, NoHash) {
-  AttachmentId id1 = attachment_id();
-  downloader()->DownloadAttachment(id1, download_callback(id1));
-  RunMessageLoop();
-  token_service()->RespondToAccessTokenRequest(
-      GoogleServiceAuthError::AuthErrorNone());
-  RunMessageLoop();
-  CompleteDownload(net::HTTP_OK, HASH_HEADER_NONE);
-  VerifyDownloadResult(id1, AttachmentDownloader::DOWNLOAD_SUCCESS);
-}
-
-// Verify that if an invalid hash is present on the response the downloader
-// treats it as a transient error.
-TEST_F(AttachmentDownloaderImplTest, InvalidHash) {
-  AttachmentId id1 = attachment_id();
-  downloader()->DownloadAttachment(id1, download_callback(id1));
-  RunMessageLoop();
-  token_service()->RespondToAccessTokenRequest(
-      GoogleServiceAuthError::AuthErrorNone());
-  RunMessageLoop();
-  CompleteDownload(net::HTTP_OK, HASH_HEADER_INVALID);
-  VerifyDownloadResult(id1, AttachmentDownloader::DOWNLOAD_TRANSIENT_ERROR);
-}
-
-// Verify that when the hash from the attachment id does not match the one on
-// the response the result is an unspecified error.
-TEST_F(AttachmentDownloaderImplTest, IdHashDoesNotMatch) {
-  // id1 has the wrong crc32c.
-  AttachmentId id1 = AttachmentId::Create(attachment_id().GetSize(), 12345);
-  downloader()->DownloadAttachment(id1, download_callback(id1));
-  RunMessageLoop();
-  token_service()->RespondToAccessTokenRequest(
-      GoogleServiceAuthError::AuthErrorNone());
-  RunMessageLoop();
-  CompleteDownload(net::HTTP_OK, HASH_HEADER_VALID);
-  VerifyDownloadResult(id1, AttachmentDownloader::DOWNLOAD_UNSPECIFIED_ERROR);
-}
-
-// Verify that extract fails when there is no headers object.
-TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_NoHeaders) {
-  uint32_t extracted;
-  ASSERT_FALSE(AttachmentDownloaderImpl::ExtractCrc32c(nullptr, &extracted));
-}
-
-// Verify that extract fails when there is no crc32c value.
-TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_Empty) {
-  std::string raw;
-  raw += "HTTP/1.1 200 OK\n";
-  raw += "Foo: bar\n";
-  raw += "X-Goog-HASH: crc32c=\n";
-  raw += "\n";
-  std::replace(raw.begin(), raw.end(), '\n', '\0');
-  scoped_refptr<net::HttpResponseHeaders> headers(
-      new net::HttpResponseHeaders(raw));
-  uint32_t extracted;
-  ASSERT_FALSE(
-      AttachmentDownloaderImpl::ExtractCrc32c(headers.get(), &extracted));
-}
-
-// Verify that extract finds the first crc32c and ignores others.
-TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_First) {
-  const std::string expected_encoded = "z8SuHQ==";
-  const uint32_t expected = 3485773341;
-  std::string raw;
-  raw += "HTTP/1.1 200 OK\n";
-  raw += "Foo: bar\n";
-  // Ignored because it's the wrong header.
-  raw += "X-Goog-Hashes: crc32c=AAAAAA==\n";
-  // Header name matches.  The md5 item is ignored.
-  raw += "X-Goog-HASH: md5=rL0Y20zC+Fzt72VPzMSk2A==,crc32c=" +
-         expected_encoded + "\n";
-  // Ignored because we already found a crc32c in the one above.
-  raw += "X-Goog-HASH: crc32c=AAAAAA==\n";
-  raw += "\n";
-  std::replace(raw.begin(), raw.end(), '\n', '\0');
-  scoped_refptr<net::HttpResponseHeaders> headers(
-      new net::HttpResponseHeaders(raw));
-  uint32_t extracted;
-  ASSERT_TRUE(
-      AttachmentDownloaderImpl::ExtractCrc32c(headers.get(), &extracted));
-  ASSERT_EQ(expected, extracted);
-}
-
-// Verify that extract fails when encoded value is too long.
-TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_TooLong) {
-  std::string raw;
-  raw += "HTTP/1.1 200 OK\n";
-  raw += "Foo: bar\n";
-  raw += "X-Goog-HASH: crc32c=AAAAAAAA\n";
-  raw += "\n";
-  std::replace(raw.begin(), raw.end(), '\n', '\0');
-  scoped_refptr<net::HttpResponseHeaders> headers(
-      new net::HttpResponseHeaders(raw));
-  uint32_t extracted;
-  ASSERT_FALSE(
-      AttachmentDownloaderImpl::ExtractCrc32c(headers.get(), &extracted));
-}
-
-// Verify that extract fails if there is no crc32c.
-TEST_F(AttachmentDownloaderImplTest, ExtractCrc32c_None) {
-  std::string raw;
-  raw += "HTTP/1.1 200 OK\n";
-  raw += "Foo: bar\n";
-  raw += "X-Goog-Hash: md5=rL0Y20zC+Fzt72VPzMSk2A==\n";
-  raw += "\n";
-  std::replace(raw.begin(), raw.end(), '\n', '\0');
-  scoped_refptr<net::HttpResponseHeaders> headers(
-      new net::HttpResponseHeaders(raw));
-  uint32_t extracted;
-  ASSERT_FALSE(
-      AttachmentDownloaderImpl::ExtractCrc32c(headers.get(), &extracted));
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine_impl/attachments/attachment_uploader_impl.cc b/components/sync/engine_impl/attachments/attachment_uploader_impl.cc
deleted file mode 100644
index 683a6549b..0000000
--- a/components/sync/engine_impl/attachments/attachment_uploader_impl.cc
+++ /dev/null
@@ -1,431 +0,0 @@
-// Copyright 2014 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/sync/engine_impl/attachments/attachment_uploader_impl.h"
-
-#include <utility>
-#include <vector>
-
-#include "base/base64.h"
-#include "base/base64url.h"
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/memory/weak_ptr.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/stringprintf.h"
-#include "base/sys_byteorder.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/data_use_measurement/core/data_use_user_data.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "components/sync/protocol/sync.pb.h"
-#include "google_apis/gaia/gaia_constants.h"
-#include "net/base/load_flags.h"
-#include "net/http/http_status_code.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_fetcher_delegate.h"
-#include "net/url_request/url_request_status.h"
-
-namespace {
-
-const char kContentType[] = "application/octet-stream";
-const char kAttachments[] = "attachments/";
-const char kSyncStoreBirthday[] = "X-Sync-Store-Birthday";
-const char kSyncDataTypeId[] = "X-Sync-Data-Type-Id";
-
-}  // namespace
-
-namespace syncer {
-
-// Encapsulates all the state associated with a single upload.
-class AttachmentUploaderImpl::UploadState
-    : public net::URLFetcherDelegate,
-      public OAuth2TokenService::Consumer {
- public:
-  // Construct an UploadState.
-  //
-  // UploadState encapsulates the state associated with a single upload.  When
-  // the upload completes, the UploadState object becomes "stopped".
-  //
-  // |owner| is a pointer to the object that owns this UploadState.  Upon
-  // completion this object will PostTask to owner's OnUploadStateStopped
-  // method.
-  UploadState(
-      const GURL& upload_url,
-      const scoped_refptr<net::URLRequestContextGetter>&
-          url_request_context_getter,
-      const Attachment& attachment,
-      const UploadCallback& user_callback,
-      const std::string& account_id,
-      const OAuth2TokenService::ScopeSet& scopes,
-      OAuth2TokenServiceRequest::TokenServiceProvider* token_service_provider,
-      const std::string& raw_store_birthday,
-      const base::WeakPtr<AttachmentUploaderImpl>& owner,
-      ModelType model_type);
-
-  ~UploadState() override;
-
-  // Returns true if this object is stopped.  Once stopped, this object is
-  // effectively dead and can be destroyed.
-  bool IsStopped() const;
-
-  // Add |user_callback| to the list of callbacks to be invoked when this upload
-  // completed.
-  //
-  // It is an error to call |AddUserCallback| on a stopped UploadState (see
-  // |IsStopped|).
-  void AddUserCallback(const UploadCallback& user_callback);
-
-  // Return the Attachment this object is uploading.
-  const Attachment& GetAttachment();
-
-  // URLFetcher implementation.
-  void OnURLFetchComplete(const net::URLFetcher* source) override;
-
-  // OAuth2TokenService::Consumer.
-  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                         const std::string& access_token,
-                         const base::Time& expiration_time) override;
-  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                         const GoogleServiceAuthError& error) override;
-
- private:
-  using UploadCallbackList = std::vector<UploadCallback>;
-
-  void GetToken();
-
-  void StopAndReportResult(const UploadResult& result,
-                           const AttachmentId& attachment_id);
-
-  bool is_stopped_;
-  GURL upload_url_;
-  const scoped_refptr<net::URLRequestContextGetter>&
-      url_request_context_getter_;
-  Attachment attachment_;
-  UploadCallbackList user_callbacks_;
-  std::unique_ptr<net::URLFetcher> fetcher_;
-  std::string account_id_;
-  OAuth2TokenService::ScopeSet scopes_;
-  std::string access_token_;
-  std::string raw_store_birthday_;
-  OAuth2TokenServiceRequest::TokenServiceProvider* token_service_provider_;
-  // Pointer to the AttachmentUploaderImpl that owns this object.
-  base::WeakPtr<AttachmentUploaderImpl> owner_;
-  std::unique_ptr<OAuth2TokenServiceRequest> access_token_request_;
-  ModelType model_type_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(UploadState);
-};
-
-AttachmentUploaderImpl::UploadState::UploadState(
-    const GURL& upload_url,
-    const scoped_refptr<net::URLRequestContextGetter>&
-        url_request_context_getter,
-    const Attachment& attachment,
-    const UploadCallback& user_callback,
-    const std::string& account_id,
-    const OAuth2TokenService::ScopeSet& scopes,
-    OAuth2TokenServiceRequest::TokenServiceProvider* token_service_provider,
-    const std::string& raw_store_birthday,
-    const base::WeakPtr<AttachmentUploaderImpl>& owner,
-    ModelType model_type)
-    : OAuth2TokenService::Consumer("attachment-uploader-impl"),
-      is_stopped_(false),
-      upload_url_(upload_url),
-      url_request_context_getter_(url_request_context_getter),
-      attachment_(attachment),
-      user_callbacks_(1, user_callback),
-      account_id_(account_id),
-      scopes_(scopes),
-      raw_store_birthday_(raw_store_birthday),
-      token_service_provider_(token_service_provider),
-      owner_(owner),
-      model_type_(model_type) {
-  DCHECK(upload_url_.is_valid());
-  DCHECK(url_request_context_getter_.get());
-  DCHECK(!account_id_.empty());
-  DCHECK(!scopes_.empty());
-  DCHECK(token_service_provider_);
-  DCHECK(!raw_store_birthday_.empty());
-  GetToken();
-}
-
-AttachmentUploaderImpl::UploadState::~UploadState() {}
-
-bool AttachmentUploaderImpl::UploadState::IsStopped() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return is_stopped_;
-}
-
-void AttachmentUploaderImpl::UploadState::AddUserCallback(
-    const UploadCallback& user_callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(!is_stopped_);
-  user_callbacks_.push_back(user_callback);
-}
-
-const Attachment& AttachmentUploaderImpl::UploadState::GetAttachment() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return attachment_;
-}
-
-void AttachmentUploaderImpl::UploadState::OnURLFetchComplete(
-    const net::URLFetcher* source) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (is_stopped_) {
-    return;
-  }
-
-  UploadResult result = UPLOAD_TRANSIENT_ERROR;
-  AttachmentId attachment_id = attachment_.GetId();
-  net::URLRequestStatus status = source->GetStatus();
-  const int response_code = source->GetResponseCode();
-  base::UmaHistogramSparse(
-      "Sync.Attachments.UploadResponseCode",
-      status.is_success() ? response_code : status.error());
-  if (response_code == net::HTTP_OK) {
-    result = UPLOAD_SUCCESS;
-  } else if (response_code == net::HTTP_UNAUTHORIZED) {
-    // Server tells us we've got a bad token so invalidate it.
-    OAuth2TokenServiceRequest::InvalidateToken(
-        token_service_provider_, account_id_, scopes_, access_token_);
-    // Fail the request, but indicate that it may be successful if retried.
-    result = UPLOAD_TRANSIENT_ERROR;
-  } else if (response_code == net::HTTP_FORBIDDEN) {
-    // User is not allowed to use attachments.  Retrying won't help.
-    result = UPLOAD_UNSPECIFIED_ERROR;
-  } else if (response_code == net::URLFetcher::RESPONSE_CODE_INVALID) {
-    result = UPLOAD_TRANSIENT_ERROR;
-  }
-  StopAndReportResult(result, attachment_id);
-}
-
-void AttachmentUploaderImpl::UploadState::OnGetTokenSuccess(
-    const OAuth2TokenService::Request* request,
-    const std::string& access_token,
-    const base::Time& expiration_time) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (is_stopped_) {
-    return;
-  }
-
-  DCHECK_EQ(access_token_request_.get(), request);
-  access_token_request_.reset();
-  access_token_ = access_token;
-  net::NetworkTrafficAnnotationTag traffic_annotation =
-      net::DefineNetworkTrafficAnnotation("sync_attachment_uploader", R"(
-        semantics {
-          sender: "Chrome Sync"
-          description:
-            "Chrome Sync synchronizes profile data between Chromium clients "
-            "and Google for a given user account."
-          trigger:
-            "User makes a change to syncable profile data after enabling sync "
-            "on the device."
-          data:
-            "The device and user identifiers, along with any profile data that "
-            "is changing."
-          destination: GOOGLE_OWNED_SERVICE
-        }
-        policy {
-          cookies_allowed: NO
-          setting:
-            "Users can disable Chrome Sync by going into the profile settings "
-            "and choosing to Sign Out."
-          chrome_policy {
-            SyncDisabled {
-              policy_options {mode: MANDATORY}
-              SyncDisabled: true
-            }
-          }
-        })");
-  fetcher_ = net::URLFetcher::Create(upload_url_, net::URLFetcher::POST, this,
-                                     traffic_annotation);
-  ConfigureURLFetcherCommon(fetcher_.get(), access_token_, raw_store_birthday_,
-                            model_type_, url_request_context_getter_.get());
-  data_use_measurement::DataUseUserData::AttachToFetcher(
-      fetcher_.get(), data_use_measurement::DataUseUserData::SYNC);
-  const uint32_t crc32c = attachment_.GetCrc32c();
-  fetcher_->AddExtraRequestHeader(base::StringPrintf(
-      "X-Goog-Hash: crc32c=%s", FormatCrc32cHash(crc32c).c_str()));
-
-  // TODO(maniscalco): Is there a better way?  Copying the attachment data into
-  // a string feels wrong given how large attachments may be (several MBs).  If
-  // we may end up switching from URLFetcher to URLRequest, this copy won't be
-  // necessary.
-  scoped_refptr<base::RefCountedMemory> memory = attachment_.GetData();
-  const std::string upload_content(memory->front_as<char>(), memory->size());
-  fetcher_->SetUploadData(kContentType, upload_content);
-
-  fetcher_->Start();
-}
-
-void AttachmentUploaderImpl::UploadState::OnGetTokenFailure(
-    const OAuth2TokenService::Request* request,
-    const GoogleServiceAuthError& error) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (is_stopped_) {
-    return;
-  }
-
-  DCHECK_EQ(access_token_request_.get(), request);
-  access_token_request_.reset();
-  // TODO(maniscalco): We treat this as a transient error, but it may in fact be
-  // a very long lived error and require user action.  Consider differentiating
-  // between the causes of GetToken failure and act accordingly.  Think about
-  // the causes of GetToken failure. Are there (bug 412802).
-  StopAndReportResult(UPLOAD_TRANSIENT_ERROR, attachment_.GetId());
-}
-
-void AttachmentUploaderImpl::UploadState::GetToken() {
-  access_token_request_ = OAuth2TokenServiceRequest::CreateAndStart(
-      token_service_provider_, account_id_, scopes_, this);
-}
-
-void AttachmentUploaderImpl::UploadState::StopAndReportResult(
-    const UploadResult& result,
-    const AttachmentId& attachment_id) {
-  DCHECK(!is_stopped_);
-  is_stopped_ = true;
-  UploadCallbackList::const_iterator iter = user_callbacks_.begin();
-  UploadCallbackList::const_iterator end = user_callbacks_.end();
-  for (; iter != end; ++iter) {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(*iter, result, attachment_id));
-  }
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&AttachmentUploaderImpl::OnUploadStateStopped,
-                            owner_, attachment_id.GetProto().unique_id()));
-}
-
-AttachmentUploaderImpl::AttachmentUploaderImpl(
-    const GURL& sync_service_url,
-    const scoped_refptr<net::URLRequestContextGetter>&
-        url_request_context_getter,
-    const std::string& account_id,
-    const OAuth2TokenService::ScopeSet& scopes,
-    const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
-        token_service_provider,
-    const std::string& store_birthday,
-    ModelType model_type)
-    : sync_service_url_(sync_service_url),
-      url_request_context_getter_(url_request_context_getter),
-      account_id_(account_id),
-      scopes_(scopes),
-      token_service_provider_(token_service_provider),
-      raw_store_birthday_(store_birthday),
-      model_type_(model_type),
-      weak_ptr_factory_(this) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(!account_id.empty());
-  DCHECK(!scopes.empty());
-  DCHECK(token_service_provider_.get());
-  DCHECK(!raw_store_birthday_.empty());
-}
-
-AttachmentUploaderImpl::~AttachmentUploaderImpl() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-void AttachmentUploaderImpl::UploadAttachment(const Attachment& attachment,
-                                              const UploadCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  const AttachmentId attachment_id = attachment.GetId();
-  const std::string unique_id = attachment_id.GetProto().unique_id();
-  DCHECK(!unique_id.empty());
-  StateMap::iterator iter = state_map_.find(unique_id);
-  if (iter != state_map_.end()) {
-    // We have an old upload request for this attachment...
-    if (!iter->second->IsStopped()) {
-      // "join" to it.
-      DCHECK(attachment.GetData()->Equals(
-          iter->second->GetAttachment().GetData()));
-      iter->second->AddUserCallback(callback);
-      return;
-    } else {
-      // It's stopped so we can't use it.  Delete it.
-      state_map_.erase(iter);
-    }
-  }
-
-  const GURL url = GetURLForAttachmentId(sync_service_url_, attachment_id);
-  std::unique_ptr<UploadState> upload_state(new UploadState(
-      url, url_request_context_getter_, attachment, callback, account_id_,
-      scopes_, token_service_provider_.get(), raw_store_birthday_,
-      weak_ptr_factory_.GetWeakPtr(), model_type_));
-  state_map_[unique_id] = std::move(upload_state);
-}
-
-// Static.
-GURL AttachmentUploaderImpl::GetURLForAttachmentId(
-    const GURL& sync_service_url,
-    const AttachmentId& attachment_id) {
-  std::string path = sync_service_url.path();
-  if (path.empty() || *path.rbegin() != '/') {
-    path += '/';
-  }
-  path += kAttachments;
-  path += attachment_id.GetProto().unique_id();
-  GURL::Replacements replacements;
-  replacements.SetPathStr(path);
-  return sync_service_url.ReplaceComponents(replacements);
-}
-
-void AttachmentUploaderImpl::OnUploadStateStopped(const UniqueId& unique_id) {
-  StateMap::iterator iter = state_map_.find(unique_id);
-  // Only erase if stopped.  Because this method is called asynchronously, it's
-  // possible that a new request for this same id arrived after the UploadState
-  // stopped, but before this method was invoked.  In that case the UploadState
-  // in the map might be a new one.
-  if (iter != state_map_.end() && iter->second->IsStopped()) {
-    state_map_.erase(iter);
-  }
-}
-
-std::string AttachmentUploaderImpl::FormatCrc32cHash(uint32_t crc32c) {
-  const uint32_t crc32c_big_endian = base::HostToNet32(crc32c);
-  const base::StringPiece raw(reinterpret_cast<const char*>(&crc32c_big_endian),
-                              sizeof(crc32c_big_endian));
-  std::string encoded;
-  base::Base64Encode(raw, &encoded);
-  return encoded;
-}
-
-void AttachmentUploaderImpl::ConfigureURLFetcherCommon(
-    net::URLFetcher* fetcher,
-    const std::string& access_token,
-    const std::string& raw_store_birthday,
-    ModelType model_type,
-    net::URLRequestContextGetter* request_context_getter) {
-  DCHECK(request_context_getter);
-  DCHECK(fetcher);
-  fetcher->SetAutomaticallyRetryOn5xx(false);
-  fetcher->SetRequestContext(request_context_getter);
-  fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
-                        net::LOAD_DO_NOT_SEND_COOKIES |
-                        net::LOAD_DISABLE_CACHE);
-  fetcher->AddExtraRequestHeader(base::StringPrintf(
-      "%s: Bearer %s", net::HttpRequestHeaders::kAuthorization,
-      access_token.c_str()));
-  // Encode the birthday.  Birthday is opaque so we assume it could contain
-  // anything.  Encode it so that it's safe to pass as an HTTP header value.
-  std::string encoded_store_birthday;
-  base::Base64UrlEncode(raw_store_birthday,
-                        base::Base64UrlEncodePolicy::OMIT_PADDING,
-                        &encoded_store_birthday);
-  fetcher->AddExtraRequestHeader(base::StringPrintf(
-      "%s: %s", kSyncStoreBirthday, encoded_store_birthday.c_str()));
-
-  // Use field number to pass ModelType because it's stable and we have server
-  // code to decode it.
-  const int field_number = GetSpecificsFieldNumberFromModelType(model_type);
-  fetcher->AddExtraRequestHeader(
-      base::StringPrintf("%s: %d", kSyncDataTypeId, field_number));
-}
-
-}  // namespace syncer
diff --git a/components/sync/engine_impl/attachments/attachment_uploader_impl.h b/components/sync/engine_impl/attachments/attachment_uploader_impl.h
deleted file mode 100644
index 3d59d12..0000000
--- a/components/sync/engine_impl/attachments/attachment_uploader_impl.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2014 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_SYNC_ENGINE_IMPL_ATTACHMENTS_ATTACHMENT_UPLOADER_IMPL_H_
-#define COMPONENTS_SYNC_ENGINE_IMPL_ATTACHMENTS_ATTACHMENT_UPLOADER_IMPL_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <unordered_map>
-
-#include "base/macros.h"
-#include "base/sequence_checker.h"
-#include "components/sync/base/model_type.h"
-#include "components/sync/engine/attachments/attachment_uploader.h"
-#include "google_apis/gaia/oauth2_token_service_request.h"
-#include "net/url_request/url_request_context_getter.h"
-
-class GURL;
-
-namespace net {
-class URLRequestContextGetter;
-}  // namespace net
-
-namespace syncer {
-
-// An implementation of AttachmentUploader.
-class AttachmentUploaderImpl : public AttachmentUploader {
- public:
-  // |sync_service_url| is the URL of the sync service.
-  //
-  // |url_request_context_getter| provides a URLRequestContext.
-  //
-  // |account_id| is the account id to use for uploads.
-  //
-  // |scopes| is the set of scopes to use for uploads.
-  //
-  // |token_service_provider| provides an OAuth2 token service.
-  //
-  // |store_birthday| is the raw, sync store birthday.
-  //
-  // |model_type| is the model type this uploader is used with.
-  AttachmentUploaderImpl(
-      const GURL& sync_service_url,
-      const scoped_refptr<net::URLRequestContextGetter>&
-          url_request_context_getter,
-      const std::string& account_id,
-      const OAuth2TokenService::ScopeSet& scopes,
-      const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>&
-          token_service_provider,
-      const std::string& store_birthday,
-      ModelType model_type);
-  ~AttachmentUploaderImpl() override;
-
-  // AttachmentUploader implementation.
-  void UploadAttachment(const Attachment& attachment,
-                        const UploadCallback& callback) override;
-
-  // Return the URL for the given |sync_service_url| and |attachment_id|.
-  static GURL GetURLForAttachmentId(const GURL& sync_service_url,
-                                    const AttachmentId& attachment_id);
-
-  // Format crc32c to pass into X-Goog-Hash header.
-  //
-  // The value is base64 encoded, big-endian format.  Suitable for use in the
-  // X-Goog-Hash header
-  // (https://cloud.google.com/storage/docs/reference-headers#xgooghash).
-  static std::string FormatCrc32cHash(uint32_t crc32c);
-
-  // Apply common settings to |fetcher|, suitable for both uploads and
-  // downloads.
-  static void ConfigureURLFetcherCommon(
-      net::URLFetcher* fetcher,
-      const std::string& auth_token,
-      const std::string& raw_store_birthday,
-      ModelType model_type,
-      net::URLRequestContextGetter* request_context_getter);
-
- private:
-  class UploadState;
-  using UniqueId = std::string;
-  using StateMap = std::unordered_map<UniqueId, std::unique_ptr<UploadState>>;
-
-  void OnUploadStateStopped(const UniqueId& unique_id);
-
-  GURL sync_service_url_;
-  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
-  std::string account_id_;
-  OAuth2TokenService::ScopeSet scopes_;
-  scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>
-      token_service_provider_;
-  std::string raw_store_birthday_;
-  StateMap state_map_;
-  ModelType model_type_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  // Must be last data member.
-  base::WeakPtrFactory<AttachmentUploaderImpl> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(AttachmentUploaderImpl);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_ENGINE_IMPL_ATTACHMENTS_ATTACHMENT_UPLOADER_IMPL_H_
diff --git a/components/sync/engine_impl/attachments/attachment_uploader_impl_unittest.cc b/components/sync/engine_impl/attachments/attachment_uploader_impl_unittest.cc
deleted file mode 100644
index 5cedce4..0000000
--- a/components/sync/engine_impl/attachments/attachment_uploader_impl_unittest.cc
+++ /dev/null
@@ -1,682 +0,0 @@
-// Copyright 2014 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/sync/engine_impl/attachments/attachment_uploader_impl.h"
-
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/location.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/sequence_checker.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/synchronization/lock.h"
-#include "base/test/histogram_tester.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/sync/engine/attachments/attachment_util.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "components/sync/protocol/sync.pb.h"
-#include "google_apis/gaia/fake_oauth2_token_service.h"
-#include "google_apis/gaia/gaia_constants.h"
-#include "net/http/http_status_code.h"
-#include "net/test/embedded_test_server/embedded_test_server.h"
-#include "net/test/embedded_test_server/http_request.h"
-#include "net/test/embedded_test_server/http_response.h"
-#include "net/url_request/url_request_test_util.h"
-#include "testing/gmock/include/gmock/gmock-matchers.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace syncer {
-
-namespace {
-
-const char kAttachmentData[] = "some data";
-const char kAccountId[] = "some-account-id";
-const char kAccessToken[] = "some-access-token";
-const char kContentTypeValue[] = "application/octet-stream";
-const char kXGoogHash[] = "X-Goog-Hash";
-const char kAttachments[] = "/attachments/";
-const char kStoreBirthday[] =
-    "\x46\xFF\xDD\xE0\x74\x3A\x48\xFD\x9D\x06\x93\x3C\x61\x8E\xA5\x70\x09\x59"
-    "\x99\x05\x61\x46\x21\x61\x1B\x03\xD3\x02\x60\xCD\x41\x55\xFE\x26\x15\xD7"
-    "\x0C";
-const char kBase64URLSafeStoreBirthday[] =
-    "Rv_d4HQ6SP2dBpM8YY6lcAlZmQVhRiFhGwPTAmDNQVX-JhXXDA";
-const char kSyncStoreBirthdayHeader[] = "X-Sync-Store-Birthday";
-const char kSyncDataTypeIdHeader[] = "X-Sync-Data-Type-Id";
-const ModelType kModelType = ModelType::ARTICLES;
-
-}  // namespace
-
-using net::test_server::BasicHttpResponse;
-using net::test_server::HttpRequest;
-using net::test_server::HttpResponse;
-
-class RequestHandler;
-
-// A mock implementation of an OAuth2TokenService.
-//
-// Use |SetResponse| to vary the response to token requests.
-//
-// Use |num_invalidate_token| and |last_token_invalidated| to check the number
-// of invalidate token operations performed and the last token invalidated.
-class MockOAuth2TokenService : public FakeOAuth2TokenService {
- public:
-  MockOAuth2TokenService();
-  ~MockOAuth2TokenService() override;
-
-  void SetResponse(const GoogleServiceAuthError& error,
-                   const std::string& access_token,
-                   const base::Time& expiration);
-
-  int num_invalidate_token() const { return num_invalidate_token_; }
-
-  const std::string& last_token_invalidated() const {
-    return last_token_invalidated_;
-  }
-
- protected:
-  void FetchOAuth2Token(RequestImpl* request,
-                        const std::string& account_id,
-                        net::URLRequestContextGetter* getter,
-                        const std::string& client_id,
-                        const std::string& client_secret,
-                        const ScopeSet& scopes) override;
-
-  void InvalidateAccessTokenImpl(const std::string& account_id,
-                                 const std::string& client_id,
-                                 const ScopeSet& scopes,
-                                 const std::string& access_token) override;
-
- private:
-  GoogleServiceAuthError response_error_;
-  std::string response_access_token_;
-  base::Time response_expiration_;
-  int num_invalidate_token_;
-  std::string last_token_invalidated_;
-};
-
-MockOAuth2TokenService::MockOAuth2TokenService()
-    : response_error_(GoogleServiceAuthError::AuthErrorNone()),
-      response_access_token_(kAccessToken),
-      response_expiration_(base::Time::Max()),
-      num_invalidate_token_(0) {}
-
-MockOAuth2TokenService::~MockOAuth2TokenService() {}
-
-void MockOAuth2TokenService::SetResponse(const GoogleServiceAuthError& error,
-                                         const std::string& access_token,
-                                         const base::Time& expiration) {
-  response_error_ = error;
-  response_access_token_ = access_token;
-  response_expiration_ = expiration;
-}
-
-void MockOAuth2TokenService::FetchOAuth2Token(
-    RequestImpl* request,
-    const std::string& account_id,
-    net::URLRequestContextGetter* getter,
-    const std::string& client_id,
-    const std::string& client_secret,
-    const ScopeSet& scopes) {
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(&OAuth2TokenService::RequestImpl::InformConsumer,
-                            request->AsWeakPtr(), response_error_,
-                            response_access_token_, response_expiration_));
-}
-
-void MockOAuth2TokenService::InvalidateAccessTokenImpl(
-    const std::string& account_id,
-    const std::string& client_id,
-    const ScopeSet& scopes,
-    const std::string& access_token) {
-  ++num_invalidate_token_;
-  last_token_invalidated_ = access_token;
-}
-
-class TokenServiceProvider
-    : public OAuth2TokenServiceRequest::TokenServiceProvider {
- public:
-  explicit TokenServiceProvider(OAuth2TokenService* token_service);
-
-  // OAuth2TokenService::TokenServiceProvider implementation.
-  scoped_refptr<base::SingleThreadTaskRunner> GetTokenServiceTaskRunner()
-      override;
-  OAuth2TokenService* GetTokenService() override;
-
- private:
-  ~TokenServiceProvider() override;
-
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  OAuth2TokenService* token_service_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-TokenServiceProvider::TokenServiceProvider(OAuth2TokenService* token_service)
-    : task_runner_(base::ThreadTaskRunnerHandle::Get()),
-      token_service_(token_service) {
-  DCHECK(token_service_);
-}
-
-TokenServiceProvider::~TokenServiceProvider() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-TokenServiceProvider::GetTokenServiceTaskRunner() {
-  return task_runner_;
-}
-
-OAuth2TokenService* TokenServiceProvider::GetTokenService() {
-  DCHECK(task_runner_->BelongsToCurrentThread());
-  return token_service_;
-}
-
-// Text fixture for AttachmentUploaderImpl test.
-//
-// This fixture provides an embedded HTTP server and a mock OAuth2 token service
-// for interacting with AttachmentUploaderImpl
-class AttachmentUploaderImplTest : public testing::Test {
- public:
-  void OnRequestReceived(const HttpRequest& request);
-
- protected:
-  AttachmentUploaderImplTest();
-  ~AttachmentUploaderImplTest() override;
-  void SetUp() override;
-  void TearDown() override;
-
-  // Run the message loop until UploadDone has been invoked |num_uploads| times.
-  void RunAndWaitFor(int num_uploads);
-
-  // Upload an attachment and have the server respond with |status_code|.
-  //
-  // Returns the attachment that was uploaded.
-  Attachment UploadAndRespondWith(const net::HttpStatusCode& status_code);
-
-  std::unique_ptr<AttachmentUploader>& uploader();
-  const AttachmentUploader::UploadCallback& upload_callback() const;
-  std::vector<HttpRequest>& http_requests_received();
-  std::vector<AttachmentUploader::UploadResult>& upload_results();
-  std::vector<AttachmentId>& attachment_ids();
-  MockOAuth2TokenService& token_service();
-  base::MessageLoopForIO& message_loop();
-  RequestHandler& request_handler();
-
- private:
-  // An UploadCallback invoked by AttachmentUploaderImpl.
-  void UploadDone(const AttachmentUploader::UploadResult& result,
-                  const AttachmentId& attachment_id);
-
-  base::MessageLoopForIO message_loop_;
-  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
-  std::unique_ptr<RequestHandler> request_handler_;
-  std::unique_ptr<AttachmentUploader> uploader_;
-  AttachmentUploader::UploadCallback upload_callback_;
-  net::EmbeddedTestServer server_;
-  // A closure that signals an upload has finished.
-  base::Closure signal_upload_done_;
-  std::vector<HttpRequest> http_requests_received_;
-  std::vector<AttachmentUploader::UploadResult> upload_results_;
-  std::vector<AttachmentId> attachment_ids_;
-  std::unique_ptr<MockOAuth2TokenService> token_service_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  // Must be last data member.
-  base::WeakPtrFactory<AttachmentUploaderImplTest> weak_ptr_factory_;
-};
-
-// Handles HTTP requests received by the EmbeddedTestServer.
-//
-// Responds with HTTP_OK by default.  See |SetStatusCode|.
-class RequestHandler {
- public:
-  // Construct a RequestHandler that will PostTask to |test| using
-  // |test_task_runner|.
-  RequestHandler(
-      const scoped_refptr<base::SingleThreadTaskRunner>& test_task_runner,
-      const base::WeakPtr<AttachmentUploaderImplTest>& test);
-
-  ~RequestHandler();
-
-  std::unique_ptr<HttpResponse> HandleRequest(const HttpRequest& request);
-
-  // Set the HTTP status code to respond with.
-  void SetStatusCode(const net::HttpStatusCode& status_code);
-
-  // Returns the HTTP status code that will be used in responses.
-  net::HttpStatusCode GetStatusCode() const;
-
- private:
-  // Protects status_code_.
-  mutable base::Lock mutex_;
-  net::HttpStatusCode status_code_;
-
-  scoped_refptr<base::SingleThreadTaskRunner> test_task_runner_;
-  base::WeakPtr<AttachmentUploaderImplTest> test_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-AttachmentUploaderImplTest::AttachmentUploaderImplTest()
-    : weak_ptr_factory_(this) {}
-
-AttachmentUploaderImplTest::~AttachmentUploaderImplTest() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-void AttachmentUploaderImplTest::OnRequestReceived(const HttpRequest& request) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  http_requests_received_.push_back(request);
-}
-
-void AttachmentUploaderImplTest::SetUp() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  request_handler_ = std::make_unique<RequestHandler>(
-      message_loop_.task_runner(), weak_ptr_factory_.GetWeakPtr());
-  url_request_context_getter_ =
-      new net::TestURLRequestContextGetter(message_loop_.task_runner());
-
-  server_.RegisterRequestHandler(
-      base::Bind(&RequestHandler::HandleRequest,
-                 base::Unretained(request_handler_.get())));
-  ASSERT_TRUE(server_.Start());
-
-  GURL url(base::StringPrintf("http://localhost:%u/", server_.port()));
-
-  token_service_ = std::make_unique<MockOAuth2TokenService>();
-  scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>
-      token_service_provider(new TokenServiceProvider(token_service_.get()));
-
-  OAuth2TokenService::ScopeSet scopes;
-  scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope);
-  uploader() = std::make_unique<AttachmentUploaderImpl>(
-      url, url_request_context_getter_, kAccountId, scopes,
-      token_service_provider, std::string(kStoreBirthday), kModelType);
-
-  upload_callback_ = base::Bind(&AttachmentUploaderImplTest::UploadDone,
-                                base::Unretained(this));
-}
-
-void AttachmentUploaderImplTest::TearDown() {
-  base::RunLoop().RunUntilIdle();
-}
-
-void AttachmentUploaderImplTest::RunAndWaitFor(int num_uploads) {
-  for (int i = 0; i < num_uploads; ++i) {
-    // Run the loop until one upload completes.
-    base::RunLoop run_loop;
-    signal_upload_done_ = run_loop.QuitClosure();
-    run_loop.Run();
-  }
-}
-
-Attachment AttachmentUploaderImplTest::UploadAndRespondWith(
-    const net::HttpStatusCode& status_code) {
-  token_service().AddAccount(kAccountId);
-  request_handler().SetStatusCode(status_code);
-  scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
-  some_data->data() = kAttachmentData;
-  Attachment attachment = Attachment::Create(some_data);
-  uploader()->UploadAttachment(attachment, upload_callback());
-  return attachment;
-}
-
-std::unique_ptr<AttachmentUploader>& AttachmentUploaderImplTest::uploader() {
-  return uploader_;
-}
-
-const AttachmentUploader::UploadCallback&
-AttachmentUploaderImplTest::upload_callback() const {
-  return upload_callback_;
-}
-
-std::vector<HttpRequest>& AttachmentUploaderImplTest::http_requests_received() {
-  return http_requests_received_;
-}
-
-std::vector<AttachmentUploader::UploadResult>&
-AttachmentUploaderImplTest::upload_results() {
-  return upload_results_;
-}
-
-std::vector<AttachmentId>& AttachmentUploaderImplTest::attachment_ids() {
-  return attachment_ids_;
-}
-
-MockOAuth2TokenService& AttachmentUploaderImplTest::token_service() {
-  return *token_service_;
-}
-
-base::MessageLoopForIO& AttachmentUploaderImplTest::message_loop() {
-  return message_loop_;
-}
-
-RequestHandler& AttachmentUploaderImplTest::request_handler() {
-  return *request_handler_;
-}
-
-void AttachmentUploaderImplTest::UploadDone(
-    const AttachmentUploader::UploadResult& result,
-    const AttachmentId& attachment_id) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  upload_results_.push_back(result);
-  attachment_ids_.push_back(attachment_id);
-  DCHECK(!signal_upload_done_.is_null());
-  signal_upload_done_.Run();
-}
-
-RequestHandler::RequestHandler(
-    const scoped_refptr<base::SingleThreadTaskRunner>& test_task_runner,
-    const base::WeakPtr<AttachmentUploaderImplTest>& test)
-    : status_code_(net::HTTP_OK),
-      test_task_runner_(test_task_runner),
-      test_(test) {
-  DETACH_FROM_SEQUENCE(sequence_checker_);
-}
-
-RequestHandler::~RequestHandler() = default;
-
-std::unique_ptr<HttpResponse> RequestHandler::HandleRequest(
-    const HttpRequest& request) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  test_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&AttachmentUploaderImplTest::OnRequestReceived,
-                            test_, request));
-  std::unique_ptr<BasicHttpResponse> response(new BasicHttpResponse);
-  response->set_code(GetStatusCode());
-  response->set_content_type("text/plain");
-  return std::move(response);
-}
-
-void RequestHandler::SetStatusCode(const net::HttpStatusCode& status_code) {
-  base::AutoLock lock(mutex_);
-  status_code_ = status_code;
-}
-
-net::HttpStatusCode RequestHandler::GetStatusCode() const {
-  base::AutoLock lock(mutex_);
-  return status_code_;
-}
-
-TEST_F(AttachmentUploaderImplTest, GetURLForAttachmentId_NoPath) {
-  AttachmentId id = AttachmentId::Create(0, 0);
-  std::string unique_id = id.GetProto().unique_id();
-  GURL sync_service_url("https://example.com");
-  EXPECT_EQ("https://example.com/attachments/" + unique_id,
-            AttachmentUploaderImpl::GetURLForAttachmentId(sync_service_url, id)
-                .spec());
-}
-
-TEST_F(AttachmentUploaderImplTest, GetURLForAttachmentId_JustSlash) {
-  AttachmentId id = AttachmentId::Create(0, 0);
-  std::string unique_id = id.GetProto().unique_id();
-  GURL sync_service_url("https://example.com/");
-  EXPECT_EQ("https://example.com/attachments/" + unique_id,
-            AttachmentUploaderImpl::GetURLForAttachmentId(sync_service_url, id)
-                .spec());
-}
-
-TEST_F(AttachmentUploaderImplTest, GetURLForAttachmentId_Path) {
-  AttachmentId id = AttachmentId::Create(0, 0);
-  std::string unique_id = id.GetProto().unique_id();
-  GURL sync_service_url("https://example.com/service");
-  EXPECT_EQ("https://example.com/service/attachments/" + unique_id,
-            AttachmentUploaderImpl::GetURLForAttachmentId(sync_service_url, id)
-                .spec());
-}
-
-TEST_F(AttachmentUploaderImplTest, GetURLForAttachmentId_PathAndSlash) {
-  AttachmentId id = AttachmentId::Create(0, 0);
-  std::string unique_id = id.GetProto().unique_id();
-  GURL sync_service_url("https://example.com/service/");
-  EXPECT_EQ("https://example.com/service/attachments/" + unique_id,
-            AttachmentUploaderImpl::GetURLForAttachmentId(sync_service_url, id)
-                .spec());
-}
-
-// Verify the "happy case" of uploading an attachment.
-//
-// Token is requested, token is returned, HTTP request is made, attachment is
-// received by server.
-TEST_F(AttachmentUploaderImplTest, UploadAttachment_HappyCase) {
-  Attachment attachment = UploadAndRespondWith(net::HTTP_OK);
-  base::HistogramTester histogram_tester;
-
-  // Run until the done callback is invoked.
-  RunAndWaitFor(1);
-
-  // See that the done callback was invoked with the right arguments.
-  ASSERT_EQ(1U, upload_results().size());
-  EXPECT_EQ(AttachmentUploader::UPLOAD_SUCCESS, upload_results()[0]);
-  ASSERT_EQ(1U, attachment_ids().size());
-  EXPECT_EQ(attachment.GetId(), attachment_ids()[0]);
-  histogram_tester.ExpectUniqueSample("Sync.Attachments.UploadResponseCode",
-                                      net::HTTP_OK, 1);
-
-  // See that the HTTP server received one request.
-  ASSERT_EQ(1U, http_requests_received().size());
-  const HttpRequest& http_request = http_requests_received().front();
-  EXPECT_EQ(net::test_server::METHOD_POST, http_request.method);
-  std::string expected_relative_url(kAttachments +
-                                    attachment.GetId().GetProto().unique_id());
-  EXPECT_EQ(expected_relative_url, http_request.relative_url);
-  EXPECT_TRUE(http_request.has_content);
-  EXPECT_EQ(kAttachmentData, http_request.content);
-}
-
-// Verify the request contains the appropriate headers.
-TEST_F(AttachmentUploaderImplTest, UploadAttachment_Headers) {
-  Attachment attachment = UploadAndRespondWith(net::HTTP_OK);
-
-  // Run until the done callback is invoked.
-  RunAndWaitFor(1);
-
-  // See that the done callback was invoked with the right arguments.
-  ASSERT_EQ(1U, upload_results().size());
-  EXPECT_EQ(AttachmentUploader::UPLOAD_SUCCESS, upload_results()[0]);
-  ASSERT_EQ(1U, attachment_ids().size());
-  EXPECT_EQ(attachment.GetId(), attachment_ids()[0]);
-
-  // See that the HTTP server received one request.
-  ASSERT_EQ(1U, http_requests_received().size());
-  const HttpRequest& http_request = http_requests_received().front();
-
-  const std::string auth_header_value(std::string("Bearer ") + kAccessToken);
-
-  EXPECT_THAT(http_request.headers,
-              testing::Contains(testing::Pair(
-                  net::HttpRequestHeaders::kAuthorization, auth_header_value)));
-  EXPECT_THAT(
-      http_request.headers,
-      testing::Contains(testing::Key(net::HttpRequestHeaders::kContentLength)));
-  EXPECT_THAT(http_request.headers,
-              testing::Contains(testing::Pair(
-                  net::HttpRequestHeaders::kContentType, kContentTypeValue)));
-  EXPECT_THAT(http_request.headers,
-              testing::Contains(testing::Key(kXGoogHash)));
-  EXPECT_THAT(
-      http_request.headers,
-      testing::Contains(testing::Key(net::HttpRequestHeaders::kUserAgent)));
-  EXPECT_THAT(http_request.headers,
-              testing::Contains(testing::Pair(kSyncStoreBirthdayHeader,
-                                              kBase64URLSafeStoreBirthday)));
-  EXPECT_THAT(http_request.headers,
-              testing::Contains(testing::Pair(
-                  kSyncDataTypeIdHeader,
-                  base::IntToString(
-                      GetSpecificsFieldNumberFromModelType(kModelType)))));
-}
-
-// Verify two overlapping calls to upload the same attachment result in only one
-// HTTP request.
-TEST_F(AttachmentUploaderImplTest, UploadAttachment_Collapse) {
-  Attachment attachment1 = UploadAndRespondWith(net::HTTP_OK);
-  Attachment attachment2 = attachment1;
-  uploader()->UploadAttachment(attachment2, upload_callback());
-
-  // Wait for upload_callback() to be invoked twice.
-  RunAndWaitFor(2);
-  // See there was only one request.
-  EXPECT_EQ(1U, http_requests_received().size());
-}
-
-// Verify that the internal state associated with an upload is removed when the
-// uplaod finishes.  We do this by issuing two non-overlapping uploads for the
-// same attachment and see that it results in two HTTP requests.
-TEST_F(AttachmentUploaderImplTest, UploadAttachment_CleanUpAfterUpload) {
-  Attachment attachment1 = UploadAndRespondWith(net::HTTP_OK);
-
-  // Wait for upload_callback() to be invoked before starting the second upload.
-  RunAndWaitFor(1);
-
-  Attachment attachment2 = attachment1;
-  uploader()->UploadAttachment(attachment2, upload_callback());
-
-  // Wait for upload_callback() to be invoked a second time.
-  RunAndWaitFor(1);
-  // See there were two requests.
-  ASSERT_EQ(2U, http_requests_received().size());
-}
-
-// Verify that we do not issue an HTTP request when we fail to receive an access
-// token.
-//
-// Token is requested, no token is returned, no HTTP request is made
-TEST_F(AttachmentUploaderImplTest, UploadAttachment_FailToGetToken) {
-  // Note, we won't receive a token because we did not add kAccountId to the
-  // token service.
-  scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
-  some_data->data() = kAttachmentData;
-  Attachment attachment = Attachment::Create(some_data);
-  uploader()->UploadAttachment(attachment, upload_callback());
-  base::HistogramTester histogram_tester;
-
-  RunAndWaitFor(1);
-
-  // See that the done callback was invoked.
-  ASSERT_EQ(1U, upload_results().size());
-  EXPECT_EQ(AttachmentUploader::UPLOAD_TRANSIENT_ERROR, upload_results()[0]);
-  ASSERT_EQ(1U, attachment_ids().size());
-  EXPECT_EQ(attachment.GetId(), attachment_ids()[0]);
-  histogram_tester.ExpectTotalCount("Sync.Attachments.UploadResponseCode", 0);
-
-  // See that no HTTP request was received.
-  ASSERT_EQ(0U, http_requests_received().size());
-}
-
-// Verify behavior when the server returns "503 Service Unavailable".
-TEST_F(AttachmentUploaderImplTest, UploadAttachment_ServiceUnavilable) {
-  Attachment attachment = UploadAndRespondWith(net::HTTP_SERVICE_UNAVAILABLE);
-  base::HistogramTester histogram_tester;
-
-  RunAndWaitFor(1);
-
-  // See that the done callback was invoked.
-  ASSERT_EQ(1U, upload_results().size());
-  EXPECT_EQ(AttachmentUploader::UPLOAD_TRANSIENT_ERROR, upload_results()[0]);
-  ASSERT_EQ(1U, attachment_ids().size());
-  EXPECT_EQ(attachment.GetId(), attachment_ids()[0]);
-  histogram_tester.ExpectUniqueSample("Sync.Attachments.UploadResponseCode",
-                                      net::HTTP_SERVICE_UNAVAILABLE, 1);
-
-  // See that the HTTP server received one request.
-  ASSERT_EQ(1U, http_requests_received().size());
-  const HttpRequest& http_request = http_requests_received().front();
-  EXPECT_EQ(net::test_server::METHOD_POST, http_request.method);
-  std::string expected_relative_url(kAttachments +
-                                    attachment.GetId().GetProto().unique_id());
-  EXPECT_EQ(expected_relative_url, http_request.relative_url);
-  EXPECT_TRUE(http_request.has_content);
-  EXPECT_EQ(kAttachmentData, http_request.content);
-
-  // See that we did not invalidate the token.
-  ASSERT_EQ(0, token_service().num_invalidate_token());
-}
-
-// Verify that we "403 Forbidden" as a non-transient error.
-TEST_F(AttachmentUploaderImplTest, UploadAttachment_Forbidden) {
-  Attachment attachment = UploadAndRespondWith(net::HTTP_FORBIDDEN);
-  base::HistogramTester histogram_tester;
-
-  RunAndWaitFor(1);
-
-  // See that the done callback was invoked.
-  ASSERT_EQ(1U, upload_results().size());
-  EXPECT_EQ(AttachmentUploader::UPLOAD_UNSPECIFIED_ERROR, upload_results()[0]);
-  ASSERT_EQ(1U, attachment_ids().size());
-  EXPECT_EQ(attachment.GetId(), attachment_ids()[0]);
-  histogram_tester.ExpectUniqueSample("Sync.Attachments.UploadResponseCode",
-                                      net::HTTP_FORBIDDEN, 1);
-
-  // See that the HTTP server received one request.
-  ASSERT_EQ(1U, http_requests_received().size());
-  const HttpRequest& http_request = http_requests_received().front();
-  EXPECT_EQ(net::test_server::METHOD_POST, http_request.method);
-  std::string expected_relative_url(kAttachments +
-                                    attachment.GetId().GetProto().unique_id());
-  EXPECT_EQ(expected_relative_url, http_request.relative_url);
-  EXPECT_TRUE(http_request.has_content);
-  EXPECT_EQ(kAttachmentData, http_request.content);
-
-  // See that we did not invalidate the token.
-  ASSERT_EQ(0, token_service().num_invalidate_token());
-}
-
-// Verify that when we receive an "401 Unauthorized" we invalidate the access
-// token.
-TEST_F(AttachmentUploaderImplTest, UploadAttachment_BadToken) {
-  Attachment attachment = UploadAndRespondWith(net::HTTP_UNAUTHORIZED);
-  base::HistogramTester histogram_tester;
-
-  RunAndWaitFor(1);
-
-  // See that the done callback was invoked.
-  ASSERT_EQ(1U, upload_results().size());
-  EXPECT_EQ(AttachmentUploader::UPLOAD_TRANSIENT_ERROR, upload_results()[0]);
-  ASSERT_EQ(1U, attachment_ids().size());
-  EXPECT_EQ(attachment.GetId(), attachment_ids()[0]);
-  histogram_tester.ExpectUniqueSample("Sync.Attachments.UploadResponseCode",
-                                      net::HTTP_UNAUTHORIZED, 1);
-
-  // See that the HTTP server received one request.
-  ASSERT_EQ(1U, http_requests_received().size());
-  const HttpRequest& http_request = http_requests_received().front();
-  EXPECT_EQ(net::test_server::METHOD_POST, http_request.method);
-  std::string expected_relative_url(kAttachments +
-                                    attachment.GetId().GetProto().unique_id());
-  EXPECT_EQ(expected_relative_url, http_request.relative_url);
-  EXPECT_TRUE(http_request.has_content);
-  EXPECT_EQ(kAttachmentData, http_request.content);
-
-  // See that we invalidated the token.
-  ASSERT_EQ(1, token_service().num_invalidate_token());
-}
-
-TEST_F(AttachmentUploaderImplTest, FormatCrc32cHash) {
-  scoped_refptr<base::RefCountedString> empty(new base::RefCountedString);
-  empty->data() = "";
-  EXPECT_EQ("AAAAAA==",
-            AttachmentUploaderImpl::FormatCrc32cHash(ComputeCrc32c(empty)));
-
-  scoped_refptr<base::RefCountedString> hello_world(new base::RefCountedString);
-  hello_world->data() = "hello world";
-  EXPECT_EQ("yZRlqg==", AttachmentUploaderImpl::FormatCrc32cHash(
-                            ComputeCrc32c(hello_world)));
-}
-
-// TODO(maniscalco): Add test case for when we are uploading an attachment that
-// already exists.  409 Conflict? (bug 379825)
-
-}  // namespace syncer
diff --git a/components/sync/engine_impl/attachments/proto/BUILD.gn b/components/sync/engine_impl/attachments/proto/BUILD.gn
deleted file mode 100644
index 6b0a0d2..0000000
--- a/components/sync/engine_impl/attachments/proto/BUILD.gn
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 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("//third_party/protobuf/proto_library.gni")
-
-proto_library("proto") {
-  # This should only get compiled into the sync component.
-  visibility = [
-    "//components/sync",
-    "//components/sync:unit_tests",
-  ]
-
-  sources = [
-    "attachment_store.proto",
-  ]
-}
diff --git a/components/sync/engine_impl/attachments/proto/attachment_store.proto b/components/sync/engine_impl/attachments/proto/attachment_store.proto
deleted file mode 100644
index c7ad990b..0000000
--- a/components/sync/engine_impl/attachments/proto/attachment_store.proto
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 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.
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package attachment_store_pb;
-
-// Metadata for leveldb attachment store database.
-message StoreMetadata {
-  // |schema_version| indicates format in which data is written in attachment
-  // store. Needed for upgrade and to prevent newer data from being loaded by
-  // older code that doesn't understand it.
-  optional int32 schema_version = 1;
-}
-
-// Metadata for attachment in attachment store. Storing metadata in separate
-// record from actual data allows us to enumerate attachments in the store
-// without incurring cost to read actual data. It also allows us to update
-// attachment metadata independent of the data.
-message RecordMetadata {
-  // Size of attachment data. Useful for attachment store space management.
-  optional int64 attachment_size = 1;
-  // Crc32c of attachment data.
-  optional fixed32 crc32c = 2;
-
-  // Component enum mirrors values of AttachmentStore::Component.
-  enum Component {
-    UNKNOWN = 0;
-    MODEL_TYPE = 1;
-    SYNC = 2;
-  }
-  // Set of components that reference this attachment.
-  repeated Component component = 3;
-}
diff --git a/components/sync/engine_impl/commit_util.cc b/components/sync/engine_impl/commit_util.cc
index cd5b75e..1aadb66 100644
--- a/components/sync/engine_impl/commit_util.cc
+++ b/components/sync/engine_impl/commit_util.cc
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "base/strings/string_util.h"
-#include "components/sync/base/attachment_id_proto.h"
 #include "components/sync/base/time.h"
 #include "components/sync/base/unique_position.h"
 #include "components/sync/engine_impl/syncer_proto_util.h"
@@ -87,15 +86,6 @@
   DCHECK_EQ(meta_entry.GetModelType(), GetModelType(*sync_entry));
 }
 
-void SetAttachmentIds(const Entry& meta_entry,
-                      sync_pb::SyncEntity* sync_entry) {
-  const sync_pb::AttachmentMetadata& attachment_metadata =
-      meta_entry.GetAttachmentMetadata();
-  for (int i = 0; i < attachment_metadata.record_size(); ++i) {
-    *sync_entry->add_attachment_id() = attachment_metadata.record(i).id();
-  }
-}
-
 }  // namespace
 
 void BuildCommitItem(const syncable::Entry& meta_entry,
@@ -161,8 +151,6 @@
   sync_entry->set_ctime(TimeToProtoTime(meta_entry.GetCtime()));
   sync_entry->set_mtime(TimeToProtoTime(meta_entry.GetMtime()));
 
-  SetAttachmentIds(meta_entry, sync_entry);
-
   // Handle bookmarks separately.
   if (meta_entry.GetSpecifics().has_bookmark()) {
     if (meta_entry.GetIsDel()) {
@@ -299,8 +287,6 @@
       (committed_entry.folder() ||
        committed_entry.bookmarkdata().bookmark_folder()));
   local_entry->PutServerSpecifics(committed_entry.specifics());
-  local_entry->PutServerAttachmentMetadata(
-      CreateAttachmentMetadata(committed_entry.attachment_id()));
   local_entry->PutServerMtime(ProtoTimeToTime(committed_entry.mtime()));
   local_entry->PutServerCtime(ProtoTimeToTime(committed_entry.ctime()));
   if (committed_entry.has_unique_position()) {
diff --git a/components/sync/engine_impl/directory_commit_contribution_unittest.cc b/components/sync/engine_impl/directory_commit_contribution_unittest.cc
index f23b435..821074c 100644
--- a/components/sync/engine_impl/directory_commit_contribution_unittest.cc
+++ b/components/sync/engine_impl/directory_commit_contribution_unittest.cc
@@ -8,7 +8,6 @@
 #include <string>
 
 #include "base/message_loop/message_loop.h"
-#include "components/sync/base/attachment_id_proto.h"
 #include "components/sync/engine_impl/cycle/directory_type_debug_info_emitter.h"
 #include "components/sync/syncable/entry.h"
 #include "components/sync/syncable/mutable_entry.h"
@@ -36,11 +35,9 @@
   void TearDown() override { dir_maker_.TearDown(); }
 
  protected:
-  int64_t CreateUnsyncedItemWithAttachments(
-      syncable::WriteTransaction* trans,
-      ModelType type,
-      const std::string& tag,
-      const sync_pb::AttachmentMetadata& attachment_metadata) {
+  int64_t CreateUnsyncedItem(syncable::WriteTransaction* trans,
+                             ModelType type,
+                             const std::string& tag) {
     // For bookmarks specify the Bookmarks root folder as the parent;
     // for other types leave the parent ID empty
     syncable::Id parent_id;
@@ -50,20 +47,10 @@
     }
 
     syncable::MutableEntry entry(trans, syncable::CREATE, type, parent_id, tag);
-    if (attachment_metadata.record_size() > 0) {
-      entry.PutAttachmentMetadata(attachment_metadata);
-    }
     entry.PutIsUnsynced(true);
     return entry.GetMetahandle();
   }
 
-  int64_t CreateUnsyncedItem(syncable::WriteTransaction* trans,
-                             ModelType type,
-                             const std::string& tag) {
-    return CreateUnsyncedItemWithAttachments(trans, type, tag,
-                                             sync_pb::AttachmentMetadata());
-  }
-
   int64_t CreateSyncedItem(syncable::WriteTransaction* trans,
                            ModelType type,
                            const std::string& tag) {
@@ -375,13 +362,6 @@
   EXPECT_TRUE(commit_message.entries(0).parent_id_string().empty());
 }
 
-void AddAttachment(sync_pb::AttachmentMetadata* metadata, bool is_on_server) {
-  sync_pb::AttachmentMetadataRecord record;
-  *record.mutable_id() = CreateAttachmentIdProto(0, 0);
-  record.set_is_on_server(is_on_server);
-  *metadata->add_record() = record;
-}
-
 // Creates some unsynced items, pretends to commit them, and hands back a
 // specially crafted response to the syncer in order to test commit response
 // processing.  The response simulates a succesful commit scenario.
@@ -449,87 +429,4 @@
   ext_cc->CleanUp();
 }
 
-// Creates some unsynced items with attachments and verifies that only items
-// where all attachments have been uploaded to the server are eligible to be
-// committed.
-TEST_F(DirectoryCommitContributionTest, ProcessCommitResponseWithAttachments) {
-  int64_t art1_handle;
-  int64_t art2_handle;
-  int64_t art3_handle;
-  {
-    syncable::WriteTransaction trans(FROM_HERE, syncable::UNITTEST, dir());
-
-    // art1 has two attachments, both have been uploaded to the server.  art1 is
-    // eligible to be committed.
-    sync_pb::AttachmentMetadata art1_attachments;
-    AddAttachment(&art1_attachments, true /* is_on_server */);
-    AddAttachment(&art1_attachments, true /* is_on_server */);
-    art1_handle = CreateUnsyncedItemWithAttachments(&trans, ARTICLES, "art1",
-                                                    art1_attachments);
-
-    // art2 has two attachments, one of which has been uploaded to the
-    // server. art2 is not eligible to be committed.
-    sync_pb::AttachmentMetadata art2_attachments;
-    AddAttachment(&art2_attachments, false /* is_on_server */);
-    AddAttachment(&art2_attachments, true /* is_on_server */);
-    art2_handle = CreateUnsyncedItemWithAttachments(&trans, ARTICLES, "art2",
-                                                    art2_attachments);
-
-    // art3 has two attachments, neither of which have been uploaded to the
-    // server. art2 is not eligible to be committed.
-    sync_pb::AttachmentMetadata art3_attachments;
-    AddAttachment(&art3_attachments, false /* is_on_server */);
-    AddAttachment(&art3_attachments, false /* is_on_server */);
-    art3_handle = CreateUnsyncedItemWithAttachments(&trans, ARTICLES, "art3",
-                                                    art3_attachments);
-  }
-
-  DirectoryTypeDebugInfoEmitter emitter(ARTICLES, &type_observers_);
-  std::unique_ptr<DirectoryCommitContribution> art_cc(
-      DirectoryCommitContribution::Build(dir(), ARTICLES, 25, &emitter));
-
-  // Only art1 is ready.
-  EXPECT_EQ(1U, art_cc->GetNumEntries());
-
-  sync_pb::ClientToServerMessage message;
-  art_cc->AddToCommitMessage(&message);
-
-  const sync_pb::CommitMessage& commit_message = message.commit();
-  ASSERT_EQ(1, commit_message.entries_size());
-
-  sync_pb::ClientToServerResponse response;
-  for (int i = 0; i < commit_message.entries_size(); ++i) {
-    sync_pb::SyncEntity entity = commit_message.entries(i);
-    sync_pb::CommitResponse_EntryResponse* entry_response =
-        response.mutable_commit()->add_entryresponse();
-    CreateSuccessfulCommitResponse(entity, entry_response);
-  }
-
-  StatusController status;
-  art_cc->ProcessCommitResponse(response, &status);
-  {
-    syncable::ReadTransaction trans(FROM_HERE, dir());
-
-    syncable::Entry a1(&trans, syncable::GET_BY_HANDLE, art1_handle);
-    EXPECT_TRUE(a1.GetId().ServerKnows());
-    EXPECT_FALSE(a1.GetSyncing());
-    EXPECT_FALSE(a1.GetDirtySync());
-    EXPECT_LT(0, a1.GetServerVersion());
-
-    syncable::Entry a2(&trans, syncable::GET_BY_HANDLE, art2_handle);
-    EXPECT_FALSE(a2.GetId().ServerKnows());
-    EXPECT_FALSE(a2.GetSyncing());
-    EXPECT_FALSE(a2.GetDirtySync());
-    EXPECT_EQ(0, a2.GetServerVersion());
-
-    syncable::Entry a3(&trans, syncable::GET_BY_HANDLE, art3_handle);
-    EXPECT_FALSE(a3.GetId().ServerKnows());
-    EXPECT_FALSE(a3.GetSyncing());
-    EXPECT_FALSE(a3.GetDirtySync());
-    EXPECT_EQ(0, a3.GetServerVersion());
-  }
-
-  art_cc->CleanUp();
-}
-
 }  // namespace syncer
diff --git a/components/sync/engine_impl/directory_update_handler_unittest.cc b/components/sync/engine_impl/directory_update_handler_unittest.cc
index 845a591..684e568 100644
--- a/components/sync/engine_impl/directory_update_handler_unittest.cc
+++ b/components/sync/engine_impl/directory_update_handler_unittest.cc
@@ -12,7 +12,6 @@
 
 #include "base/compiler_specific.h"
 #include "base/message_loop/message_loop.h"
-#include "components/sync/base/attachment_id_proto.h"
 #include "components/sync/engine_impl/cycle/directory_type_debug_info_emitter.h"
 #include "components/sync/engine_impl/cycle/status_controller.h"
 #include "components/sync/engine_impl/syncer_proto_util.h"
@@ -491,57 +490,6 @@
   }
 }
 
-// See that updates containing attachment metadata are applied
-// (i.e. server_attachment_metadata is copied to attachment_metadata).
-TEST_F(DirectoryUpdateHandlerProcessUpdateTest,
-       ProcessAndApplyUpdatesWithAttachments) {
-  DirectoryTypeDebugInfoEmitter emitter(ARTICLES, &type_observers_);
-  DirectoryUpdateHandler handler(dir(), ARTICLES, ui_worker(), &emitter);
-  StatusController status;
-
-  sync_pb::DataTypeProgressMarker progress;
-  progress.set_data_type_id(GetSpecificsFieldNumberFromModelType(ARTICLES));
-  progress.set_token("token");
-  progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 10);
-
-  sync_pb::DataTypeContext context;
-  context.set_data_type_id(GetSpecificsFieldNumberFromModelType(ARTICLES));
-  context.set_context("context");
-  context.set_version(1);
-
-  std::unique_ptr<sync_pb::SyncEntity> e1 = CreateUpdate(
-      SyncableIdToProto(Id::CreateFromServerId("e1")), "", ARTICLES);
-  sync_pb::AttachmentIdProto* attachment_id = e1->add_attachment_id();
-  *attachment_id = CreateAttachmentIdProto(0, 0);
-
-  SyncEntityList updates;
-  updates.push_back(e1.get());
-
-  // Process and apply updates.
-  EXPECT_EQ(SYNCER_OK, handler.ProcessGetUpdatesResponse(progress, context,
-                                                         updates, &status));
-  handler.ApplyUpdates(&status);
-
-  ASSERT_TRUE(TypeRootExists(ARTICLES));
-  ASSERT_TRUE(EntryExists(e1->id_string()));
-  {
-    syncable::ReadTransaction trans(FROM_HERE, dir());
-    syncable::Entry e(&trans, syncable::GET_BY_ID,
-                      Id::CreateFromServerId(e1->id_string()));
-
-    // See that the attachment_metadata is correct.
-    sync_pb::AttachmentMetadata attachment_metadata = e.GetAttachmentMetadata();
-    ASSERT_EQ(1, attachment_metadata.record_size());
-    ASSERT_EQ(attachment_id->SerializeAsString(),
-              attachment_metadata.record(0).id().SerializeAsString());
-    ASSERT_TRUE(attachment_metadata.record(0).is_on_server());
-
-    // See that attachment_metadata and server_attachment_metadata are equal.
-    ASSERT_EQ(attachment_metadata.SerializeAsString(),
-              e.GetServerAttachmentMetadata().SerializeAsString());
-  }
-}
-
 // Tests that IsInitialSyncEnded value is updated by ApplyUpdates, but not by
 // ProcessGetUpdatesResponse.
 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, IsInitialSyncEnded) {
@@ -1189,95 +1137,4 @@
   }
 }
 
-TEST_F(DirectoryUpdateHandlerApplyUpdateTest,
-       SimpleConflictDifferentAttachmentMetadata) {
-  const bool is_folder = false;
-  sync_pb::EntitySpecifics specifics;
-  *specifics.mutable_article() = sync_pb::ArticleSpecifics();
-  int64_t handle =
-      entry_factory()->CreateSyncedItem("art1", ARTICLES, is_folder);
-
-  sync_pb::AttachmentIdProto local_attachment_id =
-      CreateAttachmentIdProto(0, 0);
-  sync_pb::AttachmentIdProto server_attachment_id =
-      CreateAttachmentIdProto(0, 0);
-
-  // Add an attachment to the local attachment metadata.
-  sync_pb::AttachmentMetadata local_metadata;
-  sync_pb::AttachmentMetadataRecord* local_record = local_metadata.add_record();
-  *local_record->mutable_id() = local_attachment_id;
-  local_record->set_is_on_server(true);
-  entry_factory()->SetLocalAttachmentMetadataForItem(handle, local_metadata);
-
-  // Add a different attachment to the server attachment metadata.
-  sync_pb::AttachmentMetadata server_metadata;
-  sync_pb::AttachmentMetadataRecord* server_record =
-      server_metadata.add_record();
-  *server_record->mutable_id() = server_attachment_id;
-  server_record->set_is_on_server(true);
-  entry_factory()->SetServerAttachmentMetadataForItem(handle, server_metadata);
-
-  // At this point we have a simple conflict.  The server says art1 should have
-  // server_attachment_id, but the local sync engine says it should have
-  // local_attachment_id.
-
-  StatusController status;
-  ApplyArticlesUpdates(&status);
-
-  // See that the server won.
-  const UpdateCounters& counters = GetArticlesUpdateCounters();
-  EXPECT_EQ(1, counters.num_updates_applied);
-  EXPECT_EQ(1, counters.num_local_overwrites);
-  EXPECT_EQ(0, counters.num_server_overwrites);
-  local_metadata = entry_factory()->GetLocalAttachmentMetadataForItem(handle);
-  EXPECT_EQ(server_metadata.SerializeAsString(),
-            local_metadata.SerializeAsString());
-}
-
-TEST_F(DirectoryUpdateHandlerApplyUpdateTest,
-       SimpleConflictSameAttachmentMetadataDifferentOrder) {
-  const bool is_folder = false;
-  sync_pb::EntitySpecifics specifics;
-  *specifics.mutable_article() = sync_pb::ArticleSpecifics();
-  int64_t handle =
-      entry_factory()->CreateSyncedItem("art1", ARTICLES, is_folder);
-
-  sync_pb::AttachmentIdProto id1 = CreateAttachmentIdProto(0, 0);
-  sync_pb::AttachmentIdProto id2 = CreateAttachmentIdProto(0, 0);
-
-  // Add id1, then id2 to the local attachment metadata.
-  sync_pb::AttachmentMetadata local_metadata;
-  sync_pb::AttachmentMetadataRecord* record = local_metadata.add_record();
-  *record->mutable_id() = id1;
-  record->set_is_on_server(true);
-  record = local_metadata.add_record();
-  *record->mutable_id() = id2;
-  record->set_is_on_server(true);
-  entry_factory()->SetLocalAttachmentMetadataForItem(handle, local_metadata);
-
-  // Add id1 and id2 to the server attachment metadata, but in reverse order.
-  sync_pb::AttachmentMetadata server_metadata;
-  record = server_metadata.add_record();
-  *record->mutable_id() = id2;
-  record->set_is_on_server(true);
-  record = local_metadata.add_record();
-  *record->mutable_id() = id1;
-  record->set_is_on_server(true);
-  entry_factory()->SetServerAttachmentMetadataForItem(handle, server_metadata);
-
-  // At this point we have a (false) conflict.
-
-  StatusController status;
-  ApplyArticlesUpdates(&status);
-
-  // See that the server won.
-  const UpdateCounters& counters = GetArticlesUpdateCounters();
-  EXPECT_EQ(1, counters.num_updates_applied);
-  EXPECT_EQ(1, counters.num_local_overwrites);
-  EXPECT_EQ(0, counters.num_server_overwrites);
-  local_metadata = entry_factory()->GetLocalAttachmentMetadataForItem(handle);
-  EXPECT_EQ(server_metadata.SerializeAsString(),
-            local_metadata.SerializeAsString());
-}
-
 }  // namespace syncer
diff --git a/components/sync/engine_impl/sync_manager_impl_unittest.cc b/components/sync/engine_impl/sync_manager_impl_unittest.cc
index 8ec57c3b..d349dd9 100644
--- a/components/sync/engine_impl/sync_manager_impl_unittest.cc
+++ b/components/sync/engine_impl/sync_manager_impl_unittest.cc
@@ -20,7 +20,6 @@
 #include "base/test/scoped_task_environment.h"
 #include "base/test/values_test_util.h"
 #include "base/values.h"
-#include "components/sync/base/attachment_id_proto.h"
 #include "components/sync/base/cancelation_signal.h"
 #include "components/sync/base/extensions_activity.h"
 #include "components/sync/base/fake_encryptor.h"
@@ -227,12 +226,8 @@
   void TearDown() override { test_user_share_.TearDown(); }
 
  protected:
-  // Create an entry with the given |model_type|, |client_tag| and
-  // |attachment_metadata|.
-  void CreateEntryWithAttachmentMetadata(
-      const ModelType& model_type,
-      const std::string& client_tag,
-      const sync_pb::AttachmentMetadata& attachment_metadata);
+  // Create an entry with the given |model_type| and |client_tag|.
+  void CreateEntry(const ModelType& model_type, const std::string& client_tag);
 
   // Attempts to load the entry specified by |model_type| and |client_tag| and
   // returns the lookup result code.
@@ -278,17 +273,14 @@
   return test_user_share_.Reload();
 }
 
-void SyncApiTest::CreateEntryWithAttachmentMetadata(
-    const ModelType& model_type,
-    const std::string& client_tag,
-    const sync_pb::AttachmentMetadata& attachment_metadata) {
+void SyncApiTest::CreateEntry(const ModelType& model_type,
+                              const std::string& client_tag) {
   WriteTransaction trans(FROM_HERE, user_share());
   ReadNode root_node(&trans);
   root_node.InitByRootLookup();
   WriteNode node(&trans);
   ASSERT_EQ(node.InitUniqueByCreation(model_type, root_node, client_tag),
             WriteNode::INIT_SUCCESS);
-  node.SetAttachmentMetadata(attachment_metadata);
 }
 
 BaseNode::InitByLookupResult SyncApiTest::LookupEntryByClientTag(
@@ -726,57 +718,6 @@
   EXPECT_EQ(4, GetTotalNodeCount(user_share(), parent));
 }
 
-// Verify that Directory keeps track of which attachments are referenced by
-// which entries.
-TEST_F(SyncApiTest, AttachmentLinking) {
-  // Add an entry with an attachment.
-  std::string tag1("some tag");
-  AttachmentId attachment_id(AttachmentId::Create(0, 0));
-  sync_pb::AttachmentMetadata attachment_metadata;
-  sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
-  *record->mutable_id() = attachment_id.GetProto();
-  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
-  CreateEntryWithAttachmentMetadata(PREFERENCES, tag1, attachment_metadata);
-
-  // See that the directory knows it's linked.
-  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
-
-  // Add a second entry referencing the same attachment.
-  std::string tag2("some other tag");
-  CreateEntryWithAttachmentMetadata(PREFERENCES, tag2, attachment_metadata);
-
-  // See that the directory knows it's still linked.
-  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
-
-  // Tombstone the first entry.
-  ReplaceWithTombstone(PREFERENCES, tag1);
-
-  // See that the attachment is still considered linked because the entry hasn't
-  // been purged from the Directory.
-  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
-
-  // Save changes and see that the entry is truly gone.
-  ASSERT_TRUE(dir()->SaveChanges());
-  ASSERT_EQ(LookupEntryByClientTag(PREFERENCES, tag1),
-            WriteNode::INIT_FAILED_ENTRY_NOT_GOOD);
-
-  // However, the attachment is still linked.
-  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
-
-  // Save, destroy, and recreate the directory.  See that it's still linked.
-  ASSERT_TRUE(ReloadDir());
-  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
-
-  // Tombstone the second entry, save changes, see that it's truly gone.
-  ReplaceWithTombstone(PREFERENCES, tag2);
-  ASSERT_TRUE(dir()->SaveChanges());
-  ASSERT_EQ(LookupEntryByClientTag(PREFERENCES, tag2),
-            WriteNode::INIT_FAILED_ENTRY_NOT_GOOD);
-
-  // Finally, the attachment is no longer linked.
-  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id.GetProto()));
-}
-
 // This tests directory integrity in the case of creating a new unique node
 // with client tag matching that of an existing unapplied node with server only
 // data. See crbug.com/505761.
@@ -3380,66 +3321,6 @@
   EXPECT_LT(folder_b_pos, folder_a_pos);
 }
 
-// See that attachment metadata changes are not filtered out by
-// SyncManagerImpl::VisiblePropertiesDiffer.
-TEST_F(SyncManagerChangeProcessingTest, AttachmentMetadataOnlyChanges) {
-  // Create an article with no attachments.  See that a change is generated.
-  int64_t article_id = kInvalidId;
-  {
-    syncable::WriteTransaction trans(FROM_HERE, syncable::SYNCER,
-                                     share()->directory.get());
-    int64_t type_root = GetIdForDataType(ARTICLES);
-    syncable::Entry root(&trans, syncable::GET_BY_HANDLE, type_root);
-    ASSERT_TRUE(root.good());
-    syncable::MutableEntry article(&trans, syncable::CREATE, ARTICLES,
-                                   root.GetId(), "article");
-    ASSERT_TRUE(article.good());
-    SetNodeProperties(&article);
-    article_id = article.GetMetahandle();
-  }
-  ASSERT_EQ(1UL, GetChangeListSize());
-  FindChangeInList(article_id, ChangeRecord::ACTION_ADD);
-  ClearChangeList();
-
-  // Modify the article by adding one attachment.  Don't touch anything else.
-  // See that a change is generated.
-  {
-    syncable::WriteTransaction trans(FROM_HERE, syncable::SYNCER,
-                                     share()->directory.get());
-    syncable::MutableEntry article(&trans, syncable::GET_BY_HANDLE, article_id);
-    sync_pb::AttachmentMetadata metadata;
-    *metadata.add_record()->mutable_id() = CreateAttachmentIdProto(0, 0);
-    article.PutAttachmentMetadata(metadata);
-  }
-  ASSERT_EQ(1UL, GetChangeListSize());
-  FindChangeInList(article_id, ChangeRecord::ACTION_UPDATE);
-  ClearChangeList();
-
-  // Modify the article by replacing its attachment with a different one.  See
-  // that a change is generated.
-  {
-    syncable::WriteTransaction trans(FROM_HERE, syncable::SYNCER,
-                                     share()->directory.get());
-    syncable::MutableEntry article(&trans, syncable::GET_BY_HANDLE, article_id);
-    sync_pb::AttachmentMetadata metadata = article.GetAttachmentMetadata();
-    *metadata.add_record()->mutable_id() = CreateAttachmentIdProto(0, 0);
-    article.PutAttachmentMetadata(metadata);
-  }
-  ASSERT_EQ(1UL, GetChangeListSize());
-  FindChangeInList(article_id, ChangeRecord::ACTION_UPDATE);
-  ClearChangeList();
-
-  // Modify the article by replacing its attachment metadata with the same
-  // attachment metadata.  No change should be generated.
-  {
-    syncable::WriteTransaction trans(FROM_HERE, syncable::SYNCER,
-                                     share()->directory.get());
-    syncable::MutableEntry article(&trans, syncable::GET_BY_HANDLE, article_id);
-    article.PutAttachmentMetadata(article.GetAttachmentMetadata());
-  }
-  ASSERT_EQ(0UL, GetChangeListSize());
-}
-
 // During initialization SyncManagerImpl loads sqlite database. If it fails to
 // do so it should fail initialization. This test verifies this behavior.
 // Test reuses SyncManagerImpl initialization from SyncManagerTest but overrides
diff --git a/components/sync/engine_impl/syncer_util.cc b/components/sync/engine_impl/syncer_util.cc
index ff37c9f5..9b057a3b 100644
--- a/components/sync/engine_impl/syncer_util.cc
+++ b/components/sync/engine_impl/syncer_util.cc
@@ -11,7 +11,6 @@
 #include "base/metrics/histogram.h"
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
-#include "components/sync/base/attachment_id_proto.h"
 #include "components/sync/base/cryptographer.h"
 #include "components/sync/base/hash_util.h"
 #include "components/sync/base/model_type.h"
@@ -410,8 +409,6 @@
                             bookmark.bookmark_url(),
                             bookmark.bookmark_favicon(), target);
   }
-  target->PutServerAttachmentMetadata(
-      CreateAttachmentMetadata(update.attachment_id()));
   if (SyncerProtoUtil::ShouldMaintainPosition(update)) {
     UpdateBookmarkPositioning(update, target);
   }
@@ -466,7 +463,6 @@
   entry->PutBaseVersion(entry->GetServerVersion());
   entry->PutIsDel(entry->GetServerIsDel());
   entry->PutIsUnappliedUpdate(false);
-  entry->PutAttachmentMetadata(entry->GetServerAttachmentMetadata());
 }
 
 void MarkDeletedChildrenSynced(syncable::Directory* dir,
diff --git a/components/sync/engine_impl/test_entry_factory.cc b/components/sync/engine_impl/test_entry_factory.cc
index 5d197c81..d5ece0e 100644
--- a/components/sync/engine_impl/test_entry_factory.cc
+++ b/components/sync/engine_impl/test_entry_factory.cc
@@ -276,48 +276,6 @@
   return entry.GetSpecifics();
 }
 
-bool TestEntryFactory::SetServerAttachmentMetadataForItem(
-    int64_t meta_handle,
-    const sync_pb::AttachmentMetadata metadata) {
-  WriteTransaction trans(FROM_HERE, UNITTEST, directory_);
-  MutableEntry entry(&trans, syncable::GET_BY_HANDLE, meta_handle);
-  if (!entry.good()) {
-    return false;
-  }
-  entry.PutServerAttachmentMetadata(metadata);
-  entry.PutIsUnappliedUpdate(true);
-  return true;
-}
-
-bool TestEntryFactory::SetLocalAttachmentMetadataForItem(
-    int64_t meta_handle,
-    const sync_pb::AttachmentMetadata metadata) {
-  WriteTransaction trans(FROM_HERE, UNITTEST, directory_);
-  MutableEntry entry(&trans, syncable::GET_BY_HANDLE, meta_handle);
-  if (!entry.good()) {
-    return false;
-  }
-  entry.PutAttachmentMetadata(metadata);
-  entry.PutIsUnsynced(true);
-  return true;
-}
-
-const sync_pb::AttachmentMetadata&
-TestEntryFactory::GetServerAttachmentMetadataForItem(
-    int64_t meta_handle) const {
-  syncable::ReadTransaction trans(FROM_HERE, directory_);
-  syncable::Entry entry(&trans, syncable::GET_BY_HANDLE, meta_handle);
-  DCHECK(entry.good());
-  return entry.GetServerAttachmentMetadata();
-}
-
-const sync_pb::AttachmentMetadata&
-TestEntryFactory::GetLocalAttachmentMetadataForItem(int64_t meta_handle) const {
-  syncable::ReadTransaction trans(FROM_HERE, directory_);
-  syncable::Entry entry(&trans, syncable::GET_BY_HANDLE, meta_handle);
-  DCHECK(entry.good());
-  return entry.GetAttachmentMetadata();
-}
 
 bool TestEntryFactory::GetIsUnsyncedForItem(int64_t meta_handle) const {
   syncable::ReadTransaction trans(FROM_HERE, directory_);
diff --git a/components/sync/engine_impl/test_entry_factory.h b/components/sync/engine_impl/test_entry_factory.h
index a02e08f..946e069 100644
--- a/components/sync/engine_impl/test_entry_factory.h
+++ b/components/sync/engine_impl/test_entry_factory.h
@@ -103,32 +103,6 @@
   const sync_pb::EntitySpecifics& GetLocalSpecificsForItem(
       int64_t meta_handle) const;
 
-  // Looks up the item referenced by |meta_handle|. If successful, overwrites
-  // the server attachment metadata with |metadata|, sets
-  // IS_UNAPPLIED_UPDATES/IS_UNSYNCED appropriately, and returns true.
-  // Else, return false.
-  bool SetServerAttachmentMetadataForItem(
-      int64_t meta_handle,
-      const sync_pb::AttachmentMetadata metadata);
-
-  // Looks up the item referenced by |meta_handle|. If successful, overwrites
-  // the local attachment metadata with |metadata|, sets
-  // IS_UNAPPLIED_UPDATES/IS_UNSYNCED appropriately, and returns true.
-  // Else, return false.
-  bool SetLocalAttachmentMetadataForItem(
-      int64_t meta_handle,
-      const sync_pb::AttachmentMetadata metadata);
-
-  // Looks up the item referenced by |meta_handle| and returns its server
-  // attachment metadata.
-  const sync_pb::AttachmentMetadata& GetServerAttachmentMetadataForItem(
-      int64_t meta_handle) const;
-
-  // Looks up the item referenced by |meta_handle| and returns its attachment
-  // metadata.
-  const sync_pb::AttachmentMetadata& GetLocalAttachmentMetadataForItem(
-      int64_t meta_handle) const;
-
   // Getters for IS_UNSYNCED and IS_UNAPPLIED_UPDATE bit fields.
   bool GetIsUnsyncedForItem(int64_t meta_handle) const;
   bool GetIsUnappliedForItem(int64_t meta_handle) const;
diff --git a/components/sync/model/attachments/README b/components/sync/model/attachments/README
deleted file mode 100644
index a102dea..0000000
--- a/components/sync/model/attachments/README
+++ /dev/null
@@ -1,6 +0,0 @@
-This directory contains the sync attachment interface code that is used by both
-consumers of sync and sync itself.
-
-Because parts of sync may depend on this code, it's important that it remains
-"leafy" and never depends on sync/core_impl/ or sync/syncable/, or else we
-may end up with cycles.
diff --git a/components/sync/model/attachments/attachment.cc b/components/sync/model/attachments/attachment.cc
deleted file mode 100644
index 312b5a59..0000000
--- a/components/sync/model/attachments/attachment.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2014 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/sync/model/attachments/attachment.h"
-
-#include "base/logging.h"
-#include "components/sync/engine/attachments/attachment_util.h"
-
-namespace syncer {
-
-Attachment::Attachment(const Attachment& other) = default;
-
-Attachment::~Attachment() {}
-
-// Static.
-Attachment Attachment::Create(
-    const scoped_refptr<base::RefCountedMemory>& data) {
-  uint32_t crc32c = ComputeCrc32c(data);
-  return CreateFromParts(AttachmentId::Create(data->size(), crc32c), data);
-}
-
-// Static.
-Attachment Attachment::CreateFromParts(
-    const AttachmentId& id,
-    const scoped_refptr<base::RefCountedMemory>& data) {
-  return Attachment(id, data);
-}
-
-const AttachmentId& Attachment::GetId() const {
-  return id_;
-}
-
-const scoped_refptr<base::RefCountedMemory>& Attachment::GetData() const {
-  return data_;
-}
-
-uint32_t Attachment::GetCrc32c() const {
-  return id_.GetCrc32c();
-}
-
-Attachment::Attachment(const AttachmentId& id,
-                       const scoped_refptr<base::RefCountedMemory>& data)
-    : id_(id), data_(data) {
-  DCHECK_EQ(id.GetSize(), data->size());
-  DCHECK(data.get());
-}
-
-}  // namespace syncer
diff --git a/components/sync/model/attachments/attachment.h b/components/sync/model/attachments/attachment.h
deleted file mode 100644
index f59aee1..0000000
--- a/components/sync/model/attachments/attachment.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2014 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_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_H_
-#define COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <vector>
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/ref_counted_memory.h"
-#include "components/sync/model/attachments/attachment_id.h"
-
-namespace syncer {
-
-// A blob of in-memory data attached to a sync item.
-//
-// While Attachment objects themselves aren't immutable (they are assignable)
-// the data they wrap is immutable.
-//
-// It is cheap to copy Attachments. Feel free to store and return by value.
-class Attachment {
- public:
-  Attachment(const Attachment& other);
-  ~Attachment();
-
-  // Default copy and assignment are welcome.
-
-  // Creates an attachment with a unique id and the supplied data.
-  //
-  // Used when creating a brand new attachment.
-  static Attachment Create(const scoped_refptr<base::RefCountedMemory>& data);
-
-  // Creates an attachment with the supplied id and data.
-  //
-  // Used when you want to recreate a specific attachment. E.g. creating a local
-  // copy of an attachment that already exists on the sync server.
-  static Attachment CreateFromParts(
-      const AttachmentId& id,
-      const scoped_refptr<base::RefCountedMemory>& data);
-
-  // Returns this attachment's id.
-  const AttachmentId& GetId() const;
-
-  // Returns this attachment's data.
-  const scoped_refptr<base::RefCountedMemory>& GetData() const;
-
-  // Returns precomputed crc32c hash of data. In ideal case this hash is
-  // computed when attachment is first created. It is then passed around through
-  // local attachment store and attachment server. Crc is verified when
-  // attachment is downloaded from server or loaded from local storage.
-  uint32_t GetCrc32c() const;
-
- private:
-  AttachmentId id_;
-  scoped_refptr<base::RefCountedMemory> data_;
-
-  Attachment(const AttachmentId& id,
-             const scoped_refptr<base::RefCountedMemory>& data);
-};
-
-using AttachmentList = std::vector<Attachment>;
-using AttachmentMap = std::map<AttachmentId, Attachment>;
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_H_
diff --git a/components/sync/model/attachments/attachment_id.cc b/components/sync/model/attachments/attachment_id.cc
deleted file mode 100644
index c3f6bd0..0000000
--- a/components/sync/model/attachments/attachment_id.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2014 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/sync/model/attachments/attachment_id.h"
-
-#include "base/logging.h"
-#include "components/sync/base/attachment_id_proto.h"
-#include "components/sync/protocol/sync.pb.h"
-
-namespace syncer {
-
-void AttachmentId::ImmutableAttachmentIdProtoTraits::InitializeWrapper(
-    Wrapper* wrapper) {
-  *wrapper = new sync_pb::AttachmentIdProto();
-}
-
-void AttachmentId::ImmutableAttachmentIdProtoTraits::DestroyWrapper(
-    Wrapper* wrapper) {
-  delete *wrapper;
-}
-
-const sync_pb::AttachmentIdProto&
-AttachmentId::ImmutableAttachmentIdProtoTraits::Unwrap(const Wrapper& wrapper) {
-  return *wrapper;
-}
-
-sync_pb::AttachmentIdProto*
-AttachmentId::ImmutableAttachmentIdProtoTraits::UnwrapMutable(
-    Wrapper* wrapper) {
-  return *wrapper;
-}
-
-void AttachmentId::ImmutableAttachmentIdProtoTraits::Swap(
-    sync_pb::AttachmentIdProto* t1,
-    sync_pb::AttachmentIdProto* t2) {
-  t1->Swap(t2);
-}
-
-AttachmentId::~AttachmentId() {}
-
-bool AttachmentId::operator==(const AttachmentId& other) const {
-  return proto_.Get().unique_id() == other.proto_.Get().unique_id();
-}
-
-bool AttachmentId::operator!=(const AttachmentId& other) const {
-  return !operator==(other);
-}
-
-bool AttachmentId::operator<(const AttachmentId& other) const {
-  return proto_.Get().unique_id() < other.proto_.Get().unique_id();
-}
-
-// Static.
-AttachmentId AttachmentId::Create(size_t size, uint32_t crc32c) {
-  sync_pb::AttachmentIdProto proto = CreateAttachmentIdProto(size, crc32c);
-  return AttachmentId(&proto);
-}
-
-// Static.
-AttachmentId AttachmentId::CreateFromProto(
-    const sync_pb::AttachmentIdProto& proto) {
-  sync_pb::AttachmentIdProto copy_of_proto(proto);
-  return AttachmentId(&copy_of_proto);
-}
-
-const sync_pb::AttachmentIdProto& AttachmentId::GetProto() const {
-  return proto_.Get();
-}
-
-AttachmentId::AttachmentId(sync_pb::AttachmentIdProto* proto) : proto_(proto) {}
-
-AttachmentId::AttachmentId(const AttachmentId& other) = default;
-
-size_t AttachmentId::GetSize() const {
-  return proto_.Get().size_bytes();
-}
-
-uint32_t AttachmentId::GetCrc32c() const {
-  return proto_.Get().crc32c();
-}
-
-}  // namespace syncer
diff --git a/components/sync/model/attachments/attachment_id.h b/components/sync/model/attachments/attachment_id.h
deleted file mode 100644
index 39d20809..0000000
--- a/components/sync/model/attachments/attachment_id.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2014 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_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_ID_H_
-#define COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_ID_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "components/sync/base/immutable.h"
-
-namespace sync_pb {
-class AttachmentIdProto;
-}  // namespace sync_pb
-
-namespace syncer {
-
-// Uniquely identifies an attachment.
-//
-// Two attachments with equal (operator==) AttachmentIds are considered
-// equivalent.
-class AttachmentId {
- public:
-  AttachmentId(const AttachmentId& other);
-  ~AttachmentId();
-
-  // Default copy and assignment are welcome.
-
-  bool operator==(const AttachmentId& other) const;
-
-  bool operator!=(const AttachmentId& other) const;
-
-  // Needed for using AttachmentId as key in std::map.
-  bool operator<(const AttachmentId& other) const;
-
-  // Creates a unique id for an attachment.
-  //
-  // |size| is the attachment's size in bytes.
-  //
-  // |crc32c| is the attachment's crc32c.
-  static AttachmentId Create(size_t size, uint32_t crc32c);
-
-  // Creates an attachment id from an initialized proto.
-  static AttachmentId CreateFromProto(const sync_pb::AttachmentIdProto& proto);
-
-  const sync_pb::AttachmentIdProto& GetProto() const;
-
-  // Returns the size (in bytes) the attachment.
-  size_t GetSize() const;
-
-  // Returns the crc32c the attachment.
-  uint32_t GetCrc32c() const;
-
- private:
-  // Necessary since we forward-declare sync_pb::AttachmentIdProto; see comments
-  // in immutable.h.
-  struct ImmutableAttachmentIdProtoTraits {
-    using Wrapper = sync_pb::AttachmentIdProto*;
-    static void InitializeWrapper(Wrapper* wrapper);
-    static void DestroyWrapper(Wrapper* wrapper);
-    static const sync_pb::AttachmentIdProto& Unwrap(const Wrapper& wrapper);
-    static sync_pb::AttachmentIdProto* UnwrapMutable(Wrapper* wrapper);
-    static void Swap(sync_pb::AttachmentIdProto* t1,
-                     sync_pb::AttachmentIdProto* t2);
-  };
-
-  using ImmutableAttachmentIdProto =
-      Immutable<sync_pb::AttachmentIdProto, ImmutableAttachmentIdProtoTraits>;
-
-  ImmutableAttachmentIdProto proto_;
-
-  explicit AttachmentId(sync_pb::AttachmentIdProto* proto);
-};
-
-// All public interfaces use AttachmentIdList. AttachmentIdSet is used in
-// implementations of algorithms where set properties are needed.
-using AttachmentIdList = std::vector<AttachmentId>;
-using AttachmentIdSet = std::set<AttachmentId>;
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_ID_H_
diff --git a/components/sync/model/attachments/attachment_id_unittest.cc b/components/sync/model/attachments/attachment_id_unittest.cc
deleted file mode 100644
index d44139a..0000000
--- a/components/sync/model/attachments/attachment_id_unittest.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 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/sync/model/attachments/attachment.h"
-
-#include <string>
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace syncer {
-
-class AttachmentIdTest : public testing::Test {};
-
-TEST_F(AttachmentIdTest, Create_IsUnique) {
-  AttachmentId id1 = AttachmentId::Create(0, 0);
-  AttachmentId id2 = AttachmentId::Create(0, 0);
-  EXPECT_NE(id1, id2);
-}
-
-TEST_F(AttachmentIdTest, OperatorEqual) {
-  AttachmentId id1 = AttachmentId::Create(0, 0);
-  AttachmentId id2(id1);
-  EXPECT_EQ(id1, id2);
-}
-
-TEST_F(AttachmentIdTest, OperatorLess) {
-  AttachmentId id1 = AttachmentId::Create(0, 0);
-  EXPECT_FALSE(id1 < id1);
-
-  AttachmentId id2 = AttachmentId::Create(0, 0);
-  EXPECT_FALSE(id1 < id1);
-
-  EXPECT_NE(id1, id2);
-  if (id1 < id2) {
-    EXPECT_FALSE(id2 < id1);
-  } else {
-    EXPECT_TRUE(id2 < id1);
-  }
-}
-
-}  // namespace syncer
diff --git a/components/sync/model/attachments/attachment_metadata.cc b/components/sync/model/attachments/attachment_metadata.cc
deleted file mode 100644
index 8c65d63..0000000
--- a/components/sync/model/attachments/attachment_metadata.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2014 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/sync/model/attachments/attachment_metadata.h"
-
-namespace syncer {
-
-AttachmentMetadata::AttachmentMetadata(const AttachmentId& id, size_t size)
-    : id_(id), size_(size) {}
-
-AttachmentMetadata::~AttachmentMetadata() {}
-
-const AttachmentId& AttachmentMetadata::GetId() const {
-  return id_;
-}
-
-size_t AttachmentMetadata::GetSize() const {
-  return size_;
-}
-
-}  // namespace syncer
diff --git a/components/sync/model/attachments/attachment_metadata.h b/components/sync/model/attachments/attachment_metadata.h
deleted file mode 100644
index 44b4e2f..0000000
--- a/components/sync/model/attachments/attachment_metadata.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2014 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_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_METADATA_H_
-#define COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_METADATA_H_
-
-#include <stddef.h>
-
-#include <vector>
-
-#include "components/sync/model/attachments/attachment_id.h"
-
-namespace syncer {
-
-// This class represents immutable Attachment metadata.
-//
-// It is OK to copy and return AttachmentMetadata by value.
-class AttachmentMetadata {
- public:
-  AttachmentMetadata(const AttachmentId& id, size_t size);
-  ~AttachmentMetadata();
-
-  // Default copy and assignment are welcome.
-
-  // Returns this attachment's id.
-  const AttachmentId& GetId() const;
-
-  // Returns this attachment's size in bytes.
-  size_t GetSize() const;
-
- private:
-  // TODO(maniscalco): Reconcile AttachmentMetadata and
-  // AttachmentId. AttachmentId knows the size of the attachment so
-  // AttachmentMetadata may not be necessary (crbug/465375).
-  AttachmentId id_;
-  size_t size_;
-};
-
-using AttachmentMetadataList = std::vector<AttachmentMetadata>;
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_METADATA_H_
diff --git a/components/sync/model/attachments/attachment_metadata_unittest.cc b/components/sync/model/attachments/attachment_metadata_unittest.cc
deleted file mode 100644
index 6c9672d..0000000
--- a/components/sync/model/attachments/attachment_metadata_unittest.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2014 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/sync/model/attachments/attachment_metadata.h"
-
-#include <stdint.h>
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace syncer {
-
-class AttachmentMetadataTest : public testing::Test {};
-
-TEST_F(AttachmentMetadataTest, Create) {
-  size_t size = 42;
-  uint32_t crc32c = 2349829;
-  AttachmentId id = AttachmentId::Create(size, crc32c);
-  AttachmentMetadata metadata(id, size);
-  EXPECT_EQ(metadata.GetId(), id);
-  EXPECT_EQ(metadata.GetSize(), size);
-}
-
-}  // namespace syncer
diff --git a/components/sync/model/attachments/attachment_service.cc b/components/sync/model/attachments/attachment_service.cc
deleted file mode 100644
index c700250..0000000
--- a/components/sync/model/attachments/attachment_service.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2014 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/sync/model/attachments/attachment_service.h"
-
-#include <utility>
-
-#include "components/sync/engine/attachments/fake_attachment_downloader.h"
-#include "components/sync/engine/attachments/fake_attachment_uploader.h"
-#include "components/sync/model/attachments/attachment_store.h"
-#include "components/sync/model_impl/attachments/attachment_service_impl.h"
-
-namespace syncer {
-
-// static
-std::unique_ptr<AttachmentService> AttachmentService::Create(
-    std::unique_ptr<AttachmentStoreForSync> attachment_store,
-    std::unique_ptr<AttachmentUploader> attachment_uploader,
-    std::unique_ptr<AttachmentDownloader> attachment_downloader,
-    Delegate* delegate,
-    const base::TimeDelta& initial_backoff_delay,
-    const base::TimeDelta& max_backoff_delay) {
-  return std::make_unique<AttachmentServiceImpl>(
-      std::move(attachment_store), std::move(attachment_uploader),
-      std::move(attachment_downloader), delegate, initial_backoff_delay,
-      max_backoff_delay);
-}
-
-// static
-std::unique_ptr<AttachmentService> AttachmentService::CreateForTest() {
-  std::unique_ptr<AttachmentStore> attachment_store =
-      AttachmentStore::CreateInMemoryStore();
-  return std::make_unique<AttachmentServiceImpl>(
-      attachment_store->CreateAttachmentStoreForSync(),
-      std::make_unique<FakeAttachmentUploader>(),
-      std::make_unique<FakeAttachmentDownloader>(), nullptr, base::TimeDelta(),
-      base::TimeDelta());
-}
-
-AttachmentService::~AttachmentService() {}
-
-}  // namespace syncer
diff --git a/components/sync/model/attachments/attachment_service.h b/components/sync/model/attachments/attachment_service.h
deleted file mode 100644
index 25845ba..0000000
--- a/components/sync/model/attachments/attachment_service.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2014 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_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_SERVICE_H_
-#define COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_SERVICE_H_
-
-#include <memory>
-
-#include "base/callback.h"
-#include "base/memory/weak_ptr.h"
-#include "components/sync/model/attachments/attachment.h"
-
-namespace syncer {
-
-class AttachmentDownloader;
-class AttachmentStoreForSync;
-class AttachmentUploader;
-class SyncData;
-
-// AttachmentService is responsible for managing a model type's attachments.
-//
-// Outside of sync code, AttachmentService shouldn't be used directly. Instead
-// use the functionality provided by SyncData and SyncChangeProcessor.
-//
-// Destroying this object does not necessarily cancel outstanding async
-// operations. If you need cancel like semantics, use WeakPtr in the callbacks.
-class AttachmentService {
- public:
-  // The result of a GetOrDownloadAttachments operation.
-  enum GetOrDownloadResult {
-    GET_SUCCESS,            // No error, all attachments returned.
-    GET_UNSPECIFIED_ERROR,  // An unspecified error occurred.
-  };
-
-  using GetOrDownloadCallback =
-      base::Callback<void(const GetOrDownloadResult&,
-                          std::unique_ptr<AttachmentMap> attachments)>;
-
-  // An interface that embedder code implements to be notified about different
-  // events that originate from AttachmentService.
-  // This interface will be called from the same thread AttachmentService was
-  // created and called.
-  class Delegate {
-   public:
-    virtual ~Delegate() {}
-
-    // Attachment is uploaded to server and attachment_id is updated with server
-    // url.
-    virtual void OnAttachmentUploaded(const AttachmentId& attachment_id) = 0;
-  };
-
-  // Create a concrete AttachmentService.
-  static std::unique_ptr<AttachmentService> Create(
-      std::unique_ptr<AttachmentStoreForSync> attachment_store,
-      std::unique_ptr<AttachmentUploader> attachment_uploader,
-      std::unique_ptr<AttachmentDownloader> attachment_downloader,
-      Delegate* delegate,
-      const base::TimeDelta& initial_backoff_delay,
-      const base::TimeDelta& max_backoff_delay);
-
-  // Create an AttachmentService suitable for use in tests.
-  static std::unique_ptr<AttachmentService> CreateForTest();
-
-  virtual ~AttachmentService();
-
-  // See SyncData::GetOrDownloadAttachments.
-  virtual void GetOrDownloadAttachments(
-      const AttachmentIdList& attachment_ids,
-      const GetOrDownloadCallback& callback) = 0;
-
-  // Schedules the attachments identified by |attachment_ids| to be uploaded to
-  // the server.
-  //
-  // Assumes the attachments are already in the attachment store.
-  //
-  // A request to upload attachments is persistent in that uploads will be
-  // automatically retried if transient errors occur.
-  //
-  // A request to upload attachments does not persist across restarts of Chrome.
-  //
-  // Invokes OnAttachmentUploaded on the Delegate (if provided).
-  virtual void UploadAttachments(const AttachmentIdList& attachment_ids) = 0;
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_SERVICE_H_
diff --git a/components/sync/model/attachments/attachment_service_proxy.cc b/components/sync/model/attachments/attachment_service_proxy.cc
deleted file mode 100644
index 31660a9..0000000
--- a/components/sync/model/attachments/attachment_service_proxy.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2014 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/sync/model/attachments/attachment_service_proxy.h"
-
-#include <memory>
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
-
-namespace syncer {
-
-namespace {
-
-// These ProxyFooCallback functions are used to invoke a callback in a specific
-// thread.
-
-// Invokes |callback| with |result| and |attachments| in the |task_runner|
-// thread.
-void ProxyGetOrDownloadCallback(
-    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
-    const AttachmentService::GetOrDownloadCallback& callback,
-    const AttachmentService::GetOrDownloadResult& result,
-    std::unique_ptr<AttachmentMap> attachments) {
-  task_runner->PostTask(
-      FROM_HERE, base::Bind(callback, result, base::Passed(&attachments)));
-}
-
-}  // namespace
-
-AttachmentServiceProxy::AttachmentServiceProxy() {}
-
-AttachmentServiceProxy::AttachmentServiceProxy(
-    const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
-    const base::WeakPtr<AttachmentService>& wrapped)
-    : wrapped_task_runner_(wrapped_task_runner), core_(new Core(wrapped)) {
-  DCHECK(wrapped_task_runner_.get());
-}
-
-AttachmentServiceProxy::AttachmentServiceProxy(
-    const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
-    const scoped_refptr<Core>& core)
-    : wrapped_task_runner_(wrapped_task_runner), core_(core) {
-  DCHECK(wrapped_task_runner_.get());
-  DCHECK(core_.get());
-}
-
-AttachmentServiceProxy::AttachmentServiceProxy(
-    const AttachmentServiceProxy& other) = default;
-
-AttachmentServiceProxy::~AttachmentServiceProxy() {}
-
-void AttachmentServiceProxy::GetOrDownloadAttachments(
-    const AttachmentIdList& attachment_ids,
-    const GetOrDownloadCallback& callback) {
-  DCHECK(wrapped_task_runner_.get());
-  GetOrDownloadCallback proxy_callback =
-      base::Bind(&ProxyGetOrDownloadCallback,
-                 base::ThreadTaskRunnerHandle::Get(), callback);
-  wrapped_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&AttachmentService::GetOrDownloadAttachments, core_,
-                            attachment_ids, proxy_callback));
-}
-
-void AttachmentServiceProxy::UploadAttachments(
-    const AttachmentIdList& attachment_ids) {
-  DCHECK(wrapped_task_runner_.get());
-  wrapped_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&AttachmentService::UploadAttachments, core_, attachment_ids));
-}
-
-AttachmentServiceProxy::Core::Core(
-    const base::WeakPtr<AttachmentService>& wrapped)
-    : wrapped_(wrapped) {}
-
-AttachmentServiceProxy::Core::~Core() {}
-
-void AttachmentServiceProxy::Core::GetOrDownloadAttachments(
-    const AttachmentIdList& attachment_ids,
-    const GetOrDownloadCallback& callback) {
-  if (!wrapped_) {
-    return;
-  }
-  wrapped_->GetOrDownloadAttachments(attachment_ids, callback);
-}
-
-void AttachmentServiceProxy::Core::UploadAttachments(
-    const AttachmentIdList& attachment_ids) {
-  if (!wrapped_) {
-    return;
-  }
-  wrapped_->UploadAttachments(attachment_ids);
-}
-
-}  // namespace syncer
diff --git a/components/sync/model/attachments/attachment_service_proxy.h b/components/sync/model/attachments/attachment_service_proxy.h
deleted file mode 100644
index 946aa88..0000000
--- a/components/sync/model/attachments/attachment_service_proxy.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2014 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_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_SERVICE_PROXY_H_
-#define COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_SERVICE_PROXY_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner.h"
-#include "base/task_runner.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "components/sync/model/attachments/attachment_service.h"
-
-namespace syncer {
-
-// AttachmentServiceProxy wraps an AttachmentService allowing multiple threads
-// to share the wrapped AttachmentService and invoke its methods in the
-// appropriate thread.
-//
-// Callbacks passed to methods on this class will be invoked in the same thread
-// from which the method was called.
-//
-// This class does not own its wrapped AttachmentService object.  This class
-// holds a WeakPtr to the wrapped object.  Once the the wrapped object is
-// destroyed, method calls on this object will be no-ops.
-//
-// Users of this class should take care to destroy the wrapped object on the
-// correct thread (wrapped_task_runner).
-//
-// This class is thread-safe and is designed to be passed by const-ref.
-class AttachmentServiceProxy : public AttachmentService {
- public:
-  // Default copy and assignment are welcome.
-
-  // Construct an invalid AttachmentServiceProxy.
-  AttachmentServiceProxy();
-
-  // Construct an AttachmentServiceProxy that forwards calls to |wrapped| on the
-  // |wrapped_task_runner| thread.
-  //
-  // Note, this object does not own |wrapped|.  When |wrapped| is destroyed,
-  // calls to this object become no-ops.
-  AttachmentServiceProxy(
-      const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
-      const base::WeakPtr<AttachmentService>& wrapped);
-
-  AttachmentServiceProxy(const AttachmentServiceProxy& other);
-
-  ~AttachmentServiceProxy() override;
-
-  void GetOrDownloadAttachments(const AttachmentIdList& attachment_ids,
-                                const GetOrDownloadCallback& callback) override;
-  void UploadAttachments(const AttachmentIdList& attachment_ids) override;
-
- protected:
-  // Core does the work of proxying calls to AttachmentService methods from one
-  // thread to another so AttachmentServiceProxy can be an easy-to-use,
-  // non-ref-counted A ref-counted class.
-  //
-  // Callback from AttachmentService are proxied back using free functions
-  // defined in the .cc file (ProxyFooCallback functions).
-  //
-  // Core is ref-counted because we want to allow AttachmentServiceProxy to be
-  // copy-constructable while allowing for different implementations of Core
-  // (e.g. one type of core might own the wrapped AttachmentService).
-  //
-  // Calls to objects of this class become no-ops once its wrapped object is
-  // destroyed.
-  class Core : public AttachmentService,
-               public base::RefCountedThreadSafe<Core> {
-   public:
-    // Construct an AttachmentServiceProxyCore that forwards calls to |wrapped|.
-    explicit Core(const base::WeakPtr<AttachmentService>& wrapped);
-
-    // AttachmentService implementation.
-    void GetOrDownloadAttachments(
-        const AttachmentIdList& attachment_ids,
-        const GetOrDownloadCallback& callback) override;
-    void UploadAttachments(const AttachmentIdList& attachment_ids) override;
-
-   protected:
-    ~Core() override;
-
-   private:
-    friend class base::RefCountedThreadSafe<Core>;
-
-    base::WeakPtr<AttachmentService> wrapped_;
-
-    DISALLOW_COPY_AND_ASSIGN(Core);
-  };
-
-  // Used in tests to create an AttachmentServiceProxy with a custom Core.
-  AttachmentServiceProxy(
-      const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
-      const scoped_refptr<Core>& core);
-
- private:
-  scoped_refptr<base::SequencedTaskRunner> wrapped_task_runner_;
-  scoped_refptr<Core> core_;
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_SERVICE_PROXY_H_
diff --git a/components/sync/model/attachments/attachment_service_proxy_for_test.cc b/components/sync/model/attachments/attachment_service_proxy_for_test.cc
deleted file mode 100644
index 8c8fb22f..0000000
--- a/components/sync/model/attachments/attachment_service_proxy_for_test.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2014 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/sync/model/attachments/attachment_service_proxy_for_test.h"
-
-#include <utility>
-
-#include "base/message_loop/message_loop.h"
-#include "base/sequenced_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/sync/model/attachments/attachment_service.h"
-
-namespace syncer {
-
-AttachmentServiceProxyForTest::OwningCore::OwningCore(
-    std::unique_ptr<AttachmentService> wrapped,
-    std::unique_ptr<base::WeakPtrFactory<AttachmentService>> weak_ptr_factory)
-    : Core(weak_ptr_factory->GetWeakPtr()),
-      wrapped_(std::move(wrapped)),
-      weak_ptr_factory_(std::move(weak_ptr_factory)) {
-  DCHECK(wrapped_);
-}
-
-AttachmentServiceProxyForTest::OwningCore::~OwningCore() {}
-
-// Static.
-AttachmentServiceProxy AttachmentServiceProxyForTest::Create() {
-  std::unique_ptr<AttachmentService> wrapped(
-      AttachmentService::CreateForTest());
-  // This class's base class, AttachmentServiceProxy, must be initialized with a
-  // WeakPtr to an AttachmentService.  Because the base class ctor must be
-  // invoked before any of this class's members are initialized, we create the
-  // WeakPtrFactory here and pass it to the ctor so that it may initialize its
-  // base class and own the WeakPtrFactory.
-  //
-  // We must pass by unique_ptr because WeakPtrFactory has no copy constructor.
-  std::unique_ptr<base::WeakPtrFactory<AttachmentService>> weak_ptr_factory(
-      new base::WeakPtrFactory<AttachmentService>(wrapped.get()));
-
-  scoped_refptr<Core> core_for_test(
-      new OwningCore(std::move(wrapped), std::move(weak_ptr_factory)));
-
-  scoped_refptr<base::SequencedTaskRunner> runner;
-  if (base::ThreadTaskRunnerHandle::IsSet()) {
-    runner = base::ThreadTaskRunnerHandle::Get();
-  } else {
-    // Dummy runner for tests that don't have MessageLoop.
-    DVLOG(1) << "Creating dummy MessageLoop for AttachmentServiceProxy.";
-    base::MessageLoop loop;
-    // This works because |runner| takes a ref to the proxy.
-    runner = base::ThreadTaskRunnerHandle::Get();
-  }
-  return AttachmentServiceProxyForTest(runner, core_for_test);
-}
-
-AttachmentServiceProxyForTest::~AttachmentServiceProxyForTest() {}
-
-AttachmentServiceProxyForTest::AttachmentServiceProxyForTest(
-    const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
-    const scoped_refptr<Core>& core)
-    : AttachmentServiceProxy(wrapped_task_runner, core) {}
-
-}  // namespace syncer
diff --git a/components/sync/model/attachments/attachment_service_proxy_for_test.h b/components/sync/model/attachments/attachment_service_proxy_for_test.h
deleted file mode 100644
index bcf7a0b5..0000000
--- a/components/sync/model/attachments/attachment_service_proxy_for_test.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2014 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_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_SERVICE_PROXY_FOR_TEST_H_
-#define COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_SERVICE_PROXY_FOR_TEST_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "components/sync/model/attachments/attachment_service_proxy.h"
-
-namespace syncer {
-
-// An self-contained AttachmentServiceProxy to reduce boilerplate code in tests.
-//
-// Constructs and owns an AttachmentService suitable for use in tests.
-// NOTE: This class does not require the current thread to have a MessageLoop,
-// however all methods will effectively become no-op stubs in that case.
-class AttachmentServiceProxyForTest : public AttachmentServiceProxy {
- public:
-  static AttachmentServiceProxy Create();
-  ~AttachmentServiceProxyForTest() override;
-
- private:
-  // A Core that owns the wrapped AttachmentService.
-  class OwningCore : public AttachmentServiceProxy::Core {
-   public:
-    OwningCore(std::unique_ptr<AttachmentService>,
-               std::unique_ptr<base::WeakPtrFactory<AttachmentService>>
-                   weak_ptr_factory);
-
-   private:
-    ~OwningCore() override;
-
-    std::unique_ptr<AttachmentService> wrapped_;
-    // WeakPtrFactory for wrapped_. See Create() for why this is a unique_ptr.
-    std::unique_ptr<base::WeakPtrFactory<AttachmentService>> weak_ptr_factory_;
-
-    DISALLOW_COPY_AND_ASSIGN(OwningCore);
-  };
-
-  AttachmentServiceProxyForTest(
-      const scoped_refptr<base::SequencedTaskRunner>& wrapped_task_runner,
-      const scoped_refptr<Core>& core);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_SERVICE_PROXY_FOR_TEST_H_
diff --git a/components/sync/model/attachments/attachment_service_proxy_unittest.cc b/components/sync/model/attachments/attachment_service_proxy_unittest.cc
deleted file mode 100644
index 72ed7b4..0000000
--- a/components/sync/model/attachments/attachment_service_proxy_unittest.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2014 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/sync/model/attachments/attachment_service_proxy.h"
-
-#include <memory>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/sequence_checker.h"
-#include "base/single_thread_task_runner.h"
-#include "base/synchronization/lock.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/sync/base/model_type.h"
-#include "components/sync/protocol/sync.pb.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace syncer {
-
-// A stub implementation of AttachmentService that counts the number of times
-// its methods are invoked.
-class StubAttachmentService : public AttachmentService {
- public:
-  StubAttachmentService() : call_count_(0), weak_ptr_factory_(this) {
-    // DetachFromThread because we will be constructed in one thread and
-    // used/destroyed in another.
-    DETACH_FROM_SEQUENCE(sequence_checker_);
-  }
-
-  ~StubAttachmentService() override {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  }
-
-  void GetOrDownloadAttachments(
-      const AttachmentIdList& attachment_ids,
-      const GetOrDownloadCallback& callback) override {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    Increment();
-    std::unique_ptr<AttachmentMap> attachments(new AttachmentMap());
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::Bind(callback, AttachmentService::GET_UNSPECIFIED_ERROR,
-                   base::Passed(&attachments)));
-  }
-
-  void UploadAttachments(const AttachmentIdList& attachments_ids) override {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    Increment();
-  }
-
-  virtual base::WeakPtr<AttachmentService> AsWeakPtr() {
-    return weak_ptr_factory_.GetWeakPtr();
-  }
-
-  // Return the number of method invocations.
-  int GetCallCount() const {
-    base::AutoLock lock(mutex_);
-    return call_count_;
-  }
-
- private:
-  // Protects call_count_.
-  mutable base::Lock mutex_;
-  int call_count_;
-
-  // Must be last data member.
-  base::WeakPtrFactory<AttachmentService> weak_ptr_factory_;
-
-  void Increment() {
-    base::AutoLock lock(mutex_);
-    ++call_count_;
-  }
-
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-class AttachmentServiceProxyTest : public testing::Test {
- protected:
-  AttachmentServiceProxyTest() {}
-
-  void SetUp() override {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    stub_thread_ =
-        std::make_unique<base::Thread>("attachment service stub thread");
-    stub_thread_->Start();
-    stub_ = std::make_unique<StubAttachmentService>();
-    proxy_ = std::make_unique<AttachmentServiceProxy>(
-        stub_thread_->task_runner(), stub_->AsWeakPtr());
-
-    callback_get_or_download_ =
-        base::Bind(&AttachmentServiceProxyTest::IncrementGetOrDownload,
-                   base::Unretained(this));
-    count_callback_get_or_download_ = 0;
-  }
-
-  void TearDown() override {
-    // We must take care to call the stub's destructor on the stub_thread_
-    // because that's the thread to which its WeakPtrs are bound.
-    if (stub_) {
-      stub_thread_->task_runner()->DeleteSoon(FROM_HERE, stub_.release());
-      WaitForStubThread();
-    }
-    stub_thread_->Stop();
-  }
-
-  // a GetOrDownloadCallback
-  void IncrementGetOrDownload(const AttachmentService::GetOrDownloadResult&,
-                              std::unique_ptr<AttachmentMap>) {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    ++count_callback_get_or_download_;
-  }
-
-  void WaitForStubThread() {
-    base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
-                             base::WaitableEvent::InitialState::NOT_SIGNALED);
-    stub_thread_->task_runner()->PostTask(
-        FROM_HERE,
-        base::Bind(&base::WaitableEvent::Signal, base::Unretained(&done)));
-    done.Wait();
-  }
-
-  base::MessageLoop loop_;
-  std::unique_ptr<base::Thread> stub_thread_;
-  std::unique_ptr<StubAttachmentService> stub_;
-  std::unique_ptr<AttachmentServiceProxy> proxy_;
-
-  AttachmentService::GetOrDownloadCallback callback_get_or_download_;
-
-  // number of times callback_get_or_download_ was invoked
-  int count_callback_get_or_download_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-};
-
-// Verify that each of AttachmentServiceProxy's methods are invoked on the stub.
-// Verify that the methods that take callbacks invoke passed callbacks on this
-// thread.
-TEST_F(AttachmentServiceProxyTest, MethodsAreProxied) {
-  proxy_->GetOrDownloadAttachments(AttachmentIdList(),
-                                   callback_get_or_download_);
-  proxy_->UploadAttachments(AttachmentIdList());
-  // Wait for the posted calls to execute in the stub thread.
-  WaitForStubThread();
-  EXPECT_EQ(2, stub_->GetCallCount());
-  // At this point the stub thread has finished executed the calls. However, the
-  // result callbacks it has posted may not have executed yet. Wait a second
-  // time to ensure the stub thread has executed the posted result callbacks.
-  WaitForStubThread();
-
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(1, count_callback_get_or_download_);
-}
-
-// Verify that it's safe to use an AttachmentServiceProxy even after its wrapped
-// AttachmentService has been destroyed.
-TEST_F(AttachmentServiceProxyTest, WrappedIsDestroyed) {
-  proxy_->GetOrDownloadAttachments(AttachmentIdList(),
-                                   callback_get_or_download_);
-  // Wait for the posted calls to execute in the stub thread.
-  WaitForStubThread();
-  EXPECT_EQ(1, stub_->GetCallCount());
-  // Wait a second time ensure the stub thread has executed the posted result
-  // callbacks.
-  WaitForStubThread();
-
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(1, count_callback_get_or_download_);
-
-  // Destroy the stub and call GetOrDownloadAttachments again.
-  stub_thread_->task_runner()->DeleteSoon(FROM_HERE, stub_.release());
-  WaitForStubThread();
-
-  // Now that the wrapped object has been destroyed, call again and see that we
-  // don't crash and the count remains the same.
-  proxy_->GetOrDownloadAttachments(AttachmentIdList(),
-                                   callback_get_or_download_);
-  WaitForStubThread();
-  WaitForStubThread();
-  base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(1, count_callback_get_or_download_);
-}
-
-}  // namespace syncer
diff --git a/components/sync/model/attachments/attachment_store.cc b/components/sync/model/attachments/attachment_store.cc
deleted file mode 100644
index 6b052b7..0000000
--- a/components/sync/model/attachments/attachment_store.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2014 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/sync/model/attachments/attachment_store.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/message_loop/message_loop.h"
-#include "base/sequenced_task_runner.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/sync/engine/attachments/attachment_store_frontend.h"
-#include "components/sync/engine/attachments/in_memory_attachment_store.h"
-#include "components/sync/engine/attachments/on_disk_attachment_store.h"
-
-namespace syncer {
-
-namespace {
-
-void NoOpDropCallback(const AttachmentStore::Result& result) {}
-}
-
-AttachmentStore::AttachmentStore(
-    const scoped_refptr<AttachmentStoreFrontend>& frontend,
-    Component component)
-    : frontend_(frontend), component_(component) {}
-
-AttachmentStore::~AttachmentStore() {}
-
-void AttachmentStore::Read(const AttachmentIdList& ids,
-                           const ReadCallback& callback) {
-  frontend_->Read(component_, ids, callback);
-}
-
-void AttachmentStore::Write(const AttachmentList& attachments,
-                            const WriteCallback& callback) {
-  frontend_->Write(component_, attachments, callback);
-}
-
-void AttachmentStore::Drop(const AttachmentIdList& ids,
-                           const DropCallback& callback) {
-  frontend_->DropReference(component_, ids, callback);
-}
-
-void AttachmentStore::ReadMetadataById(const AttachmentIdList& ids,
-                                       const ReadMetadataCallback& callback) {
-  frontend_->ReadMetadataById(component_, ids, callback);
-}
-
-void AttachmentStore::ReadMetadata(const ReadMetadataCallback& callback) {
-  frontend_->ReadMetadata(component_, callback);
-}
-
-std::unique_ptr<AttachmentStoreForSync>
-AttachmentStore::CreateAttachmentStoreForSync() const {
-  std::unique_ptr<AttachmentStoreForSync> attachment_store_for_sync(
-      new AttachmentStoreForSync(frontend_, component_, SYNC));
-  return attachment_store_for_sync;
-}
-
-std::unique_ptr<AttachmentStore> AttachmentStore::CreateInMemoryStore() {
-  // Both frontend and backend of attachment store will live on current thread.
-  scoped_refptr<base::SingleThreadTaskRunner> runner;
-  if (base::ThreadTaskRunnerHandle::IsSet()) {
-    runner = base::ThreadTaskRunnerHandle::Get();
-  } else {
-    // Dummy runner for tests that don't have MessageLoop.
-    base::MessageLoop loop;
-    // This works because |runner| takes a ref to the proxy.
-    runner = base::ThreadTaskRunnerHandle::Get();
-  }
-  std::unique_ptr<AttachmentStoreBackend> backend(
-      new InMemoryAttachmentStore(runner));
-  scoped_refptr<AttachmentStoreFrontend> frontend(
-      new AttachmentStoreFrontend(std::move(backend), runner));
-  std::unique_ptr<AttachmentStore> attachment_store(
-      new AttachmentStore(frontend, MODEL_TYPE));
-  return attachment_store;
-}
-
-std::unique_ptr<AttachmentStore> AttachmentStore::CreateOnDiskStore(
-    const base::FilePath& path,
-    const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner,
-    const InitCallback& callback) {
-  std::unique_ptr<OnDiskAttachmentStore> backend(
-      new OnDiskAttachmentStore(base::ThreadTaskRunnerHandle::Get(), path));
-
-  scoped_refptr<AttachmentStoreFrontend> frontend =
-      new AttachmentStoreFrontend(std::move(backend), backend_task_runner);
-  std::unique_ptr<AttachmentStore> attachment_store(
-      new AttachmentStore(frontend, MODEL_TYPE));
-  frontend->Init(callback);
-
-  return attachment_store;
-}
-
-std::unique_ptr<AttachmentStore> AttachmentStore::CreateMockStoreForTest(
-    std::unique_ptr<AttachmentStoreBackend> backend) {
-  scoped_refptr<base::SingleThreadTaskRunner> runner =
-      base::ThreadTaskRunnerHandle::Get();
-  scoped_refptr<AttachmentStoreFrontend> attachment_store_frontend(
-      new AttachmentStoreFrontend(std::move(backend), runner));
-  std::unique_ptr<AttachmentStore> attachment_store(
-      new AttachmentStore(attachment_store_frontend, MODEL_TYPE));
-  return attachment_store;
-}
-
-AttachmentStoreForSync::AttachmentStoreForSync(
-    const scoped_refptr<AttachmentStoreFrontend>& frontend,
-    Component consumer_component,
-    Component sync_component)
-    : AttachmentStore(frontend, consumer_component),
-      sync_component_(sync_component) {}
-
-AttachmentStoreForSync::~AttachmentStoreForSync() {}
-
-void AttachmentStoreForSync::SetSyncReference(const AttachmentIdList& ids) {
-  frontend()->SetReference(sync_component_, ids);
-}
-
-void AttachmentStoreForSync::SetModelTypeReference(
-    const AttachmentIdList& ids) {
-  frontend()->SetReference(component(), ids);
-}
-
-void AttachmentStoreForSync::DropSyncReference(const AttachmentIdList& ids) {
-  frontend()->DropReference(sync_component_, ids,
-                            base::Bind(&NoOpDropCallback));
-}
-
-void AttachmentStoreForSync::ReadMetadataForSync(
-    const ReadMetadataCallback& callback) {
-  frontend()->ReadMetadata(sync_component_, callback);
-}
-
-}  // namespace syncer
diff --git a/components/sync/model/attachments/attachment_store.h b/components/sync/model/attachments/attachment_store.h
deleted file mode 100644
index 58a0921..0000000
--- a/components/sync/model/attachments/attachment_store.h
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2014 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_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_STORE_H_
-#define COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_STORE_H_
-
-#include <memory>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "components/sync/model/attachments/attachment.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_metadata.h"
-
-namespace base {
-class FilePath;
-class SequencedTaskRunner;
-}  // namespace base
-
-namespace syncer {
-
-class AttachmentStoreBackend;
-class AttachmentStoreForSync;
-class AttachmentStoreFrontend;
-
-// AttachmentStore is a place to locally store and access Attachments.
-//
-// AttachmentStore class is an interface exposed to data type and
-// AttachmentService code.
-// It also contains factory methods for default attachment store
-// implementations.
-// Destroying this object does not necessarily cancel outstanding async
-// operations. If you need cancel like semantics, use WeakPtr in the callbacks.
-class AttachmentStore {
- public:
-  // TODO(maniscalco): Consider udpating Read and Write methods to support
-  // resumable transfers (bug 353292).
-
-  // The result status of an attachment store operation.
-  // Do not re-order or delete these entries; they are used in a UMA histogram.
-  enum Result {
-    SUCCESS = 0,            // No error, all completed successfully.
-    UNSPECIFIED_ERROR = 1,  // An unspecified error occurred for >= 1 item.
-    STORE_INITIALIZATION_FAILED = 2,  // AttachmentStore initialization failed.
-    // When adding a value here, you must increment RESULT_SIZE below.
-  };
-  static const int RESULT_SIZE =
-      10;  // Size of the Result enum; used for histograms.
-
-  // Each attachment can have references from sync or model type. Tracking these
-  // references is needed for lifetime management of attachment, it can only be
-  // deleted from the store when it doesn't have references.
-  enum Component {
-    MODEL_TYPE,
-    SYNC,
-  };
-
-  using InitCallback = base::Callback<void(const Result&)>;
-  using ReadCallback = base::Callback<void(const Result&,
-                                           std::unique_ptr<AttachmentMap>,
-                                           std::unique_ptr<AttachmentIdList>)>;
-  using WriteCallback = base::Callback<void(const Result&)>;
-  using DropCallback = base::Callback<void(const Result&)>;
-  using ReadMetadataCallback =
-      base::Callback<void(const Result&,
-                          std::unique_ptr<AttachmentMetadataList>)>;
-
-  ~AttachmentStore();
-
-  // Asynchronously reads the attachments identified by |ids|.
-  //
-  // |callback| will be invoked when finished. AttachmentStore will attempt to
-  // read all attachments specified in ids. If any of the attachments do not
-  // exist or could not be read, |callback|'s Result will be UNSPECIFIED_ERROR.
-  // Callback's AttachmentMap will contain all attachments that were
-  // successfully read, AttachmentIdList will contain attachment ids of
-  // attachments that are unavailable in attachment store, these need to be
-  // downloaded from server.
-  //
-  // Reads on individual attachments are treated atomically; |callback| will not
-  // read only part of an attachment.
-  void Read(const AttachmentIdList& ids, const ReadCallback& callback);
-
-  // Asynchronously writes |attachments| to the store.
-  //
-  // Will not overwrite stored attachments. Attempting to overwrite an
-  // attachment that already exists is not an error.
-  //
-  // |callback| will be invoked when finished. If any of the attachments could
-  // not be written |callback|'s Result will be UNSPECIFIED_ERROR. When this
-  // happens, some or none of the attachments may have been written
-  // successfully.
-  void Write(const AttachmentList& attachments, const WriteCallback& callback);
-
-  // Asynchronously drops |attchments| from this store.
-  //
-  // This does not remove attachments from the server.
-  //
-  // |callback| will be invoked when finished. Attempting to drop an attachment
-  // that does not exist is not an error. If any of the existing attachment
-  // could not be dropped, |callback|'s Result will be UNSPECIFIED_ERROR. When
-  // this happens, some or none of the attachments may have been dropped
-  // successfully.
-  void Drop(const AttachmentIdList& ids, const DropCallback& callback);
-
-  // Asynchronously reads metadata for the attachments identified by |ids|.
-  //
-  // |callback| will be invoked when finished. AttachmentStore will attempt to
-  // read metadata for all attachments specified in ids. If any of the
-  // metadata entries do not exist or could not be read, |callback|'s Result
-  // will be UNSPECIFIED_ERROR.
-  void ReadMetadataById(const AttachmentIdList& ids,
-                        const ReadMetadataCallback& callback);
-
-  // Asynchronously reads metadata for all attachments with |component_|
-  // reference in the store.
-  //
-  // |callback| will be invoked when finished. If any of the metadata entries
-  // could not be read, |callback|'s Result will be UNSPECIFIED_ERROR.
-  void ReadMetadata(const ReadMetadataCallback& callback);
-
-  // Given current AttachmentStore (this) creates separate AttachmentStore that
-  // will be used by sync components (AttachmentService). Resulting
-  // AttachmentStore is backed by the same frontend/backend.
-  std::unique_ptr<AttachmentStoreForSync> CreateAttachmentStoreForSync() const;
-
-  // Creates an AttachmentStore backed by in-memory implementation of attachment
-  // store. For now frontend lives on the same thread as backend.
-  static std::unique_ptr<AttachmentStore> CreateInMemoryStore();
-
-  // Creates an AttachmentStore backed by on-disk implementation of attachment
-  // store. Opens corresponding leveldb database located at |path|. All backend
-  // operations are scheduled to |backend_task_runner|. Opening attachment store
-  // is asynchronous, once it finishes |callback| will be called on the thread
-  // that called CreateOnDiskStore. Calling Read/Write/Drop before
-  // initialization completed is allowed.  Later if initialization fails these
-  // operations will fail with STORE_INITIALIZATION_FAILED error.
-  static std::unique_ptr<AttachmentStore> CreateOnDiskStore(
-      const base::FilePath& path,
-      const scoped_refptr<base::SequencedTaskRunner>& backend_task_runner,
-      const InitCallback& callback);
-
-  // Creates set of AttachmentStore/AttachmentStoreFrontend instances for tests
-  // that provide their own implementation of AttachmentstoreBackend for
-  // mocking.
-  static std::unique_ptr<AttachmentStore> CreateMockStoreForTest(
-      std::unique_ptr<AttachmentStoreBackend> backend);
-
- protected:
-  AttachmentStore(const scoped_refptr<AttachmentStoreFrontend>& frontend,
-                  Component component);
-
-  const scoped_refptr<AttachmentStoreFrontend>& frontend() { return frontend_; }
-  Component component() const { return component_; }
-
- private:
-  scoped_refptr<AttachmentStoreFrontend> frontend_;
-  // Modification operations with attachment store will be performed on behalf
-  // of |component_|.
-  const Component component_;
-
-  DISALLOW_COPY_AND_ASSIGN(AttachmentStore);
-};
-
-// AttachmentStoreForSync extends AttachmentStore and provides additional
-// functions necessary for AttachmentService. These are needed when
-// AttachmentService writes attachment on behalf of model type after download
-// and takes reference on attachment for the duration of upload.
-// Model type implementation shouldn't use this interface.
-class AttachmentStoreForSync : public AttachmentStore {
- public:
-  ~AttachmentStoreForSync();
-
-  // Asynchronously adds reference from sync to attachments.
-  void SetSyncReference(const AttachmentIdList& ids);
-
-  // Asynchronously adds reference from model type to attachments.
-  // Needed in GetOrDownloadAttachments when attachment is in local store but
-  // doesn't have model type reference.
-  void SetModelTypeReference(const AttachmentIdList& ids);
-
-  // Asynchronously drops sync reference from attachments.
-  void DropSyncReference(const AttachmentIdList& ids);
-
-  // Asynchronously reads metadata for all attachments with |sync_component_|
-  // reference in the store.
-  //
-  // |callback| will be invoked when finished. If any of the metadata entries
-  // could not be read, |callback|'s Result will be UNSPECIFIED_ERROR.
-  void ReadMetadataForSync(const ReadMetadataCallback& callback);
-
- private:
-  friend class AttachmentStore;
-  AttachmentStoreForSync(const scoped_refptr<AttachmentStoreFrontend>& frontend,
-                         Component consumer_component,
-                         Component sync_component);
-
-  // |sync_component_| is passed to frontend when sync related operations are
-  // performed.
-  const Component sync_component_;
-
-  DISALLOW_COPY_AND_ASSIGN(AttachmentStoreForSync);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_MODEL_ATTACHMENTS_ATTACHMENT_STORE_H_
diff --git a/components/sync/model/attachments/attachment_unittest.cc b/components/sync/model/attachments/attachment_unittest.cc
deleted file mode 100644
index 8d2a1c3..0000000
--- a/components/sync/model/attachments/attachment_unittest.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2014 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/sync/model/attachments/attachment.h"
-
-#include <string>
-
-#include "components/sync/engine/attachments/attachment_util.h"
-#include "components/sync/protocol/sync.pb.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace syncer {
-
-namespace {
-
-const char kAttachmentData[] = "some data";
-
-}  // namespace
-
-class AttachmentTest : public testing::Test {};
-
-TEST_F(AttachmentTest, Create_UniqueIdIsUnique) {
-  scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
-  some_data->data() = kAttachmentData;
-  Attachment a1 = Attachment::Create(some_data);
-  Attachment a2 = Attachment::Create(some_data);
-  EXPECT_NE(a1.GetId(), a2.GetId());
-  EXPECT_EQ(a1.GetData(), a2.GetData());
-}
-
-TEST_F(AttachmentTest, Create_WithEmptyData) {
-  scoped_refptr<base::RefCountedString> empty_data(new base::RefCountedString);
-  Attachment a = Attachment::Create(empty_data);
-  EXPECT_EQ(empty_data, a.GetData());
-}
-
-TEST_F(AttachmentTest, CreateFromParts_HappyCase) {
-  scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
-  some_data->data() = kAttachmentData;
-  uint32_t crc32c = ComputeCrc32c(some_data);
-  AttachmentId id = AttachmentId::Create(some_data->size(), crc32c);
-  Attachment a = Attachment::CreateFromParts(id, some_data);
-  EXPECT_EQ(id, a.GetId());
-  EXPECT_EQ(some_data, a.GetData());
-}
-
-}  // namespace syncer
diff --git a/components/sync/model/fake_syncable_service.cc b/components/sync/model/fake_syncable_service.cc
index da0fa123..8792bdd 100644
--- a/components/sync/model/fake_syncable_service.cc
+++ b/components/sync/model/fake_syncable_service.cc
@@ -26,15 +26,6 @@
   process_sync_changes_error_ = error;
 }
 
-void FakeSyncableService::set_attachment_store(
-    std::unique_ptr<AttachmentStore> attachment_store) {
-  attachment_store_ = std::move(attachment_store);
-}
-
-const AttachmentService* FakeSyncableService::attachment_service() const {
-  return attachment_service_.get();
-}
-
 bool FakeSyncableService::syncing() const {
   return syncing_;
 }
@@ -71,15 +62,4 @@
   return process_sync_changes_error_;
 }
 
-std::unique_ptr<AttachmentStoreForSync>
-FakeSyncableService::GetAttachmentStoreForSync() {
-  return attachment_store_ ? attachment_store_->CreateAttachmentStoreForSync()
-                           : std::unique_ptr<AttachmentStoreForSync>();
-}
-
-void FakeSyncableService::SetAttachmentService(
-    std::unique_ptr<AttachmentService> attachment_service) {
-  attachment_service_ = std::move(attachment_service);
-}
-
 }  // namespace syncer
diff --git a/components/sync/model/fake_syncable_service.h b/components/sync/model/fake_syncable_service.h
index 0391ff5..93e8878 100644
--- a/components/sync/model/fake_syncable_service.h
+++ b/components/sync/model/fake_syncable_service.h
@@ -24,13 +24,6 @@
   void set_merge_data_and_start_syncing_error(const SyncError& error);
   void set_process_sync_changes_error(const SyncError& error);
 
-  // Setter for AttachmentStore.
-  void set_attachment_store(std::unique_ptr<AttachmentStore> attachment_store);
-
-  // AttachmentService should be set when this syncable service is connected,
-  // just before MergeDataAndStartSyncing. Null is returned by default.
-  const AttachmentService* attachment_service() const;
-
   // Whether we're syncing or not. Set on a successful MergeDataAndStartSyncing,
   // unset on StopSyncing. False by default.
   bool syncing() const;
@@ -45,9 +38,6 @@
   SyncDataList GetAllSyncData(ModelType type) const override;
   SyncError ProcessSyncChanges(const base::Location& from_here,
                                const SyncChangeList& change_list) override;
-  std::unique_ptr<AttachmentStoreForSync> GetAttachmentStoreForSync() override;
-  void SetAttachmentService(
-      std::unique_ptr<AttachmentService> attachment_service) override;
 
  private:
   std::unique_ptr<SyncChangeProcessor> sync_processor_;
@@ -55,8 +45,6 @@
   SyncError process_sync_changes_error_;
   bool syncing_;
   ModelType type_;
-  std::unique_ptr<AttachmentStore> attachment_store_;
-  std::unique_ptr<AttachmentService> attachment_service_;
 };
 
 }  // namespace syncer
diff --git a/components/sync/model/sync_change_unittest.cc b/components/sync/model/sync_change_unittest.cc
index 9b34c6d..909b7e1 100644
--- a/components/sync/model/sync_change_unittest.cc
+++ b/components/sync/model/sync_change_unittest.cc
@@ -9,8 +9,6 @@
 #include "base/message_loop/message_loop.h"
 #include "base/time/time.h"
 #include "base/values.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/protocol/preference_specifics.pb.h"
 #include "components/sync/protocol/proto_value_conversions.h"
 #include "components/sync/protocol/sync.pb.h"
@@ -88,19 +86,15 @@
   pref_specifics->set_name("update");
   change_list.push_back(SyncChange(
       FROM_HERE, SyncChange::ACTION_UPDATE,
-      SyncData::CreateRemoteData(1, update_specifics, base::Time(),
-                                 AttachmentIdList(),
-                                 AttachmentServiceProxyForTest::Create())));
+      SyncData::CreateRemoteData(1, update_specifics, base::Time())));
 
   // Create an add.
   sync_pb::EntitySpecifics add_specifics;
   pref_specifics = add_specifics.mutable_preference();
   pref_specifics->set_name("add");
-  change_list.push_back(SyncChange(
-      FROM_HERE, SyncChange::ACTION_ADD,
-      SyncData::CreateRemoteData(2, add_specifics, base::Time(),
-                                 AttachmentIdList(),
-                                 AttachmentServiceProxyForTest::Create())));
+  change_list.push_back(
+      SyncChange(FROM_HERE, SyncChange::ACTION_ADD,
+                 SyncData::CreateRemoteData(2, add_specifics, base::Time())));
 
   // Create a delete.
   sync_pb::EntitySpecifics delete_specifics;
@@ -108,9 +102,7 @@
   pref_specifics->set_name("add");
   change_list.push_back(SyncChange(
       FROM_HERE, SyncChange::ACTION_DELETE,
-      SyncData::CreateRemoteData(3, delete_specifics, base::Time(),
-                                 AttachmentIdList(),
-                                 AttachmentServiceProxyForTest::Create())));
+      SyncData::CreateRemoteData(3, delete_specifics, base::Time())));
 
   ASSERT_EQ(3U, change_list.size());
 
diff --git a/components/sync/model/sync_data.cc b/components/sync/model/sync_data.cc
index 46a6cdd..16186b1 100644
--- a/components/sync/model/sync_data.cc
+++ b/components/sync/model/sync_data.cc
@@ -15,24 +15,6 @@
 #include "components/sync/syncable/base_node.h"
 
 namespace syncer {
-namespace {
-
-sync_pb::AttachmentIdProto IdToProto(const AttachmentId& attachment_id) {
-  return attachment_id.GetProto();
-}
-
-AttachmentId ProtoToId(const sync_pb::AttachmentIdProto& proto) {
-  return AttachmentId::CreateFromProto(proto);
-}
-
-// Return true iff |attachment_ids| contains duplicates.
-bool ContainsDuplicateAttachments(const AttachmentIdList& attachment_ids) {
-  AttachmentIdSet id_set;
-  id_set.insert(attachment_ids.begin(), attachment_ids.end());
-  return id_set.size() != attachment_ids.size();
-}
-
-}  // namespace
 
 void SyncData::ImmutableSyncEntityTraits::InitializeWrapper(Wrapper* wrapper) {
   *wrapper = new sync_pb::SyncEntity();
@@ -61,12 +43,10 @@
 
 SyncData::SyncData(int64_t id,
                    sync_pb::SyncEntity* entity,
-                   const base::Time& remote_modification_time,
-                   const AttachmentServiceProxy& attachment_service)
+                   const base::Time& remote_modification_time)
     : id_(id),
       remote_modification_time_(remote_modification_time),
       immutable_entity_(entity),
-      attachment_service_(attachment_service),
       is_valid_(true) {}
 
 SyncData::SyncData(const SyncData& other) = default;
@@ -85,26 +65,11 @@
 SyncData SyncData::CreateLocalData(const std::string& sync_tag,
                                    const std::string& non_unique_title,
                                    const sync_pb::EntitySpecifics& specifics) {
-  AttachmentIdList attachment_ids;
-  return CreateLocalDataWithAttachments(sync_tag, non_unique_title, specifics,
-                                        attachment_ids);
-}
-
-// Static.
-SyncData SyncData::CreateLocalDataWithAttachments(
-    const std::string& sync_tag,
-    const std::string& non_unique_title,
-    const sync_pb::EntitySpecifics& specifics,
-    const AttachmentIdList& attachment_ids) {
-  DCHECK(!ContainsDuplicateAttachments(attachment_ids));
   sync_pb::SyncEntity entity;
   entity.set_client_defined_unique_tag(sync_tag);
   entity.set_non_unique_name(non_unique_title);
   entity.mutable_specifics()->CopyFrom(specifics);
-  std::transform(attachment_ids.begin(), attachment_ids.end(),
-                 RepeatedFieldBackInserter(entity.mutable_attachment_id()),
-                 IdToProto);
-  return SyncData(kInvalidId, &entity, base::Time(), AttachmentServiceProxy());
+  return SyncData(kInvalidId, &entity, base::Time());
 }
 
 // Static.
@@ -112,17 +77,12 @@
     int64_t id,
     const sync_pb::EntitySpecifics& specifics,
     const base::Time& modification_time,
-    const AttachmentIdList& attachment_ids,
-    const AttachmentServiceProxy& attachment_service,
     const std::string& client_tag_hash) {
   DCHECK_NE(id, kInvalidId);
   sync_pb::SyncEntity entity;
   entity.mutable_specifics()->CopyFrom(specifics);
   entity.set_client_defined_unique_tag(client_tag_hash);
-  std::transform(attachment_ids.begin(), attachment_ids.end(),
-                 RepeatedFieldBackInserter(entity.mutable_attachment_id()),
-                 IdToProto);
-  return SyncData(id, &entity, modification_time, attachment_service);
+  return SyncData(id, &entity, modification_time);
 }
 
 bool SyncData::IsValid() const {
@@ -174,14 +134,6 @@
   *os << sync_data.ToString();
 }
 
-AttachmentIdList SyncData::GetAttachmentIds() const {
-  AttachmentIdList result;
-  const sync_pb::SyncEntity& entity = immutable_entity_.Get();
-  std::transform(entity.attachment_id().begin(), entity.attachment_id().end(),
-                 std::back_inserter(result), ProtoToId);
-  return result;
-}
-
 SyncDataLocal::SyncDataLocal(const SyncData& sync_data) : SyncData(sync_data) {
   DCHECK(sync_data.IsLocal());
 }
@@ -219,10 +171,4 @@
   return immutable_entity_.Get().client_defined_unique_tag();
 }
 
-void SyncDataRemote::GetOrDownloadAttachments(
-    const AttachmentIdList& attachment_ids,
-    const AttachmentService::GetOrDownloadCallback& callback) {
-  attachment_service_.GetOrDownloadAttachments(attachment_ids, callback);
-}
-
 }  // namespace syncer
diff --git a/components/sync/model/sync_data.h b/components/sync/model/sync_data.h
index 84b1dc6..1628c2e 100644
--- a/components/sync/model/sync_data.h
+++ b/components/sync/model/sync_data.h
@@ -17,8 +17,6 @@
 #include "components/sync/base/immutable.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/base/weak_handle.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy.h"
 
 namespace sync_pb {
 class EntitySpecifics;
@@ -27,7 +25,6 @@
 
 namespace syncer {
 
-class AttachmentService;
 class SyncDataLocal;
 class SyncDataRemote;
 
@@ -54,26 +51,17 @@
   // the same as |sync_tag|) must be specfied.  Note: |non_unique_title| is
   // primarily for debug purposes, and will be overwritten if the datatype is
   // encrypted.
-  //
-  // For data with attachments: |attachment_ids| must not contain duplicates.
   static SyncData CreateLocalDelete(const std::string& sync_tag,
                                     ModelType datatype);
   static SyncData CreateLocalData(const std::string& sync_tag,
                                   const std::string& non_unique_title,
                                   const sync_pb::EntitySpecifics& specifics);
-  static SyncData CreateLocalDataWithAttachments(
-      const std::string& sync_tag,
-      const std::string& non_unique_title,
-      const sync_pb::EntitySpecifics& specifics,
-      const AttachmentIdList& attachment_ids);
 
   // Helper method for creating SyncData objects originating from the syncer.
   static SyncData CreateRemoteData(
       int64_t id,
       const sync_pb::EntitySpecifics& specifics,
       const base::Time& last_modified_time,
-      const AttachmentIdList& attachment_ids,
-      const AttachmentServiceProxy& attachment_service,
       const std::string& client_tag_hash = std::string());
 
   // Whether this SyncData holds valid data. The only way to have a SyncData
@@ -96,11 +84,6 @@
 
   std::string ToString() const;
 
-  // Return a list of this SyncData's attachment ids.
-  //
-  // The attachments may or may not be present on this device.
-  AttachmentIdList GetAttachmentIds() const;
-
   // TODO(zea): Query methods for other sync properties: parent, successor, etc.
 
  protected:
@@ -135,17 +118,14 @@
   // The actual shared sync entity being held.
   ImmutableSyncEntity immutable_entity_;
 
-  AttachmentServiceProxy attachment_service_;
-
  private:
   // Whether this SyncData holds valid data.
   bool is_valid_;
 
-  // Clears |entity| and |attachments|.
+  // Clears |entity|.
   SyncData(int64_t id,
            sync_pb::SyncEntity* entity,
-           const base::Time& remote_modification_time,
-           const AttachmentServiceProxy& attachment_service);
+           const base::Time& remote_modification_time);
 };
 
 // A SyncData going to the syncer.
@@ -180,19 +160,6 @@
   // Returns the tag hash value. May not always be present, in which case an
   // empty string will be returned.
   const std::string& GetClientTagHash() const;
-
-  // Retrieve the attachments indentified by |attachment_ids|. Invoke
-  // |callback| with the requested attachments.
-  //
-  // |callback| will be invoked when the operation is complete (successfully
-  // or otherwise).
-  //
-  // Retrieving the requested attachments may require reading local storage or
-  // requesting the attachments from the network.
-  //
-  void GetOrDownloadAttachments(
-      const AttachmentIdList& attachment_ids,
-      const AttachmentService::GetOrDownloadCallback& callback);
 };
 
 // gmock printer helper.
diff --git a/components/sync/model/sync_data_unittest.cc b/components/sync/model/sync_data_unittest.cc
index 30286196..e793bf34 100644
--- a/components/sync/model/sync_data_unittest.cc
+++ b/components/sync/model/sync_data_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/memory/ref_counted_memory.h"
 #include "base/message_loop/message_loop.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "components/sync/model/attachments/attachment_service.h"
 #include "components/sync/protocol/sync.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -27,17 +26,9 @@
 
 class SyncDataTest : public testing::Test {
  protected:
-  SyncDataTest()
-      : attachment_service(AttachmentService::CreateForTest()),
-        attachment_service_weak_ptr_factory(attachment_service.get()),
-        attachment_service_proxy(
-            base::ThreadTaskRunnerHandle::Get(),
-            attachment_service_weak_ptr_factory.GetWeakPtr()) {}
+  SyncDataTest() = default;
   base::MessageLoop loop;
   sync_pb::EntitySpecifics specifics;
-  std::unique_ptr<AttachmentService> attachment_service;
-  base::WeakPtrFactory<AttachmentService> attachment_service_weak_ptr_factory;
-  AttachmentServiceProxy attachment_service_proxy;
 };
 
 TEST_F(SyncDataTest, NoArgCtor) {
@@ -65,55 +56,16 @@
   EXPECT_TRUE(data.GetSpecifics().has_preference());
 }
 
-TEST_F(SyncDataTest, CreateLocalDataWithAttachments) {
-  specifics.mutable_preference();
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-
-  SyncData data = SyncData::CreateLocalDataWithAttachments(
-      kSyncTag, kNonUniqueTitle, specifics, attachment_ids);
-  EXPECT_TRUE(data.IsValid());
-  EXPECT_TRUE(data.IsLocal());
-  EXPECT_EQ(kSyncTag, SyncDataLocal(data).GetTag());
-  EXPECT_EQ(kDatatype, data.GetDataType());
-  EXPECT_EQ(kNonUniqueTitle, data.GetTitle());
-  EXPECT_TRUE(data.GetSpecifics().has_preference());
-  attachment_ids = data.GetAttachmentIds();
-  EXPECT_EQ(3U, attachment_ids.size());
-}
-
-TEST_F(SyncDataTest, CreateLocalDataWithAttachments_EmptyListOfAttachments) {
-  specifics.mutable_preference();
-  AttachmentIdList attachment_ids;
-  SyncData data = SyncData::CreateLocalDataWithAttachments(
-      kSyncTag, kNonUniqueTitle, specifics, attachment_ids);
-  EXPECT_TRUE(data.IsValid());
-  EXPECT_TRUE(data.IsLocal());
-  EXPECT_EQ(kSyncTag, SyncDataLocal(data).GetTag());
-  EXPECT_EQ(kDatatype, data.GetDataType());
-  EXPECT_EQ(kNonUniqueTitle, data.GetTitle());
-  EXPECT_TRUE(data.GetSpecifics().has_preference());
-  EXPECT_TRUE(data.GetAttachmentIds().empty());
-}
-
 TEST_F(SyncDataTest, CreateRemoteData) {
   specifics.mutable_preference();
-  SyncData data =
-      SyncData::CreateRemoteData(kId, specifics, kLastModifiedTime,
-                                 AttachmentIdList(), attachment_service_proxy);
+  SyncData data = SyncData::CreateRemoteData(kId, specifics, kLastModifiedTime);
   EXPECT_TRUE(data.IsValid());
   EXPECT_FALSE(data.IsLocal());
   EXPECT_EQ(kId, SyncDataRemote(data).GetId());
   EXPECT_EQ(kLastModifiedTime, SyncDataRemote(data).GetModifiedTime());
   EXPECT_TRUE(data.GetSpecifics().has_preference());
-  EXPECT_TRUE(data.GetAttachmentIds().empty());
 }
 
-// TODO(maniscalco): Add test cases that verify GetLocalAttachmentsForUpload
-// calls are passed through to the underlying AttachmentService.
-
 }  // namespace
 
 }  // namespace syncer
diff --git a/components/sync/model/syncable_service.cc b/components/sync/model/syncable_service.cc
index ae0c797c..4fbbc10 100644
--- a/components/sync/model/syncable_service.cc
+++ b/components/sync/model/syncable_service.cc
@@ -8,12 +8,4 @@
 
 SyncableService::~SyncableService() {}
 
-std::unique_ptr<AttachmentStoreForSync>
-SyncableService::GetAttachmentStoreForSync() {
-  return std::unique_ptr<AttachmentStoreForSync>();
-}
-
-void SyncableService::SetAttachmentService(
-    std::unique_ptr<AttachmentService> attachment_service) {}
-
 }  // namespace syncer
diff --git a/components/sync/model/syncable_service.h b/components/sync/model/syncable_service.h
index d68e989..0f8ef9b 100644
--- a/components/sync/model/syncable_service.h
+++ b/components/sync/model/syncable_service.h
@@ -12,7 +12,6 @@
 #include "base/compiler_specific.h"
 #include "base/memory/weak_ptr.h"
 #include "components/sync/base/model_type.h"
-#include "components/sync/model/attachments/attachment_store.h"
 #include "components/sync/model/sync_change_processor.h"
 #include "components/sync/model/sync_data.h"
 #include "components/sync/model/sync_error.h"
@@ -20,7 +19,6 @@
 
 namespace syncer {
 
-class AttachmentService;
 class SyncErrorFactory;
 
 // TODO(zea): remove SupportsWeakPtr in favor of having all SyncableService
@@ -69,28 +67,6 @@
   SyncError ProcessSyncChanges(const base::Location& from_here,
                                const SyncChangeList& change_list) override = 0;
 
-  // Returns AttachmentStore for use by sync when uploading or downloading
-  // attachments.
-  // GetAttachmentStoreForSync is called right before MergeDataAndStartSyncing.
-  // If at that time GetAttachmentStoreForSync returns null then datatype is
-  // considered not using attachments and all attempts to upload/download
-  // attachments will fail. Default implementation returns null. Datatype that
-  // uses sync attachments should create attachment store, implement
-  // GetAttachmentStoreForSync to return result of
-  // AttachmentStore::CreateAttachmentStoreForSync() from attachment store
-  // object.
-  virtual std::unique_ptr<AttachmentStoreForSync> GetAttachmentStoreForSync();
-
-  // Called by sync to provide AttachmentService to be used to download
-  // attachments.
-  // SetAttachmentService is called after GetAttachmentStore and right before
-  // MergeDataAndStartSyncing and only if GetAttachmentStore has returned a
-  // non-null store instance. Default implementation does nothing.
-  // Datatype that uses attachments must take ownerhip of the provided
-  // AttachmentService instance.
-  virtual void SetAttachmentService(
-      std::unique_ptr<AttachmentService> attachment_service);
-
  protected:
   ~SyncableService() override;
 };
diff --git a/components/sync/model_impl/attachments/DEPS b/components/sync/model_impl/attachments/DEPS
deleted file mode 100644
index 8fa9d48..0000000
--- a/components/sync/model_impl/attachments/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
-  "+net",
-]
diff --git a/components/sync/model_impl/attachments/attachment_service_impl.cc b/components/sync/model_impl/attachments/attachment_service_impl.cc
deleted file mode 100644
index a1656ae..0000000
--- a/components/sync/model_impl/attachments/attachment_service_impl.cc
+++ /dev/null
@@ -1,313 +0,0 @@
-// Copyright 2014 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/sync/model_impl/attachments/attachment_service_impl.h"
-
-#include <iterator>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "components/sync/engine/attachments/fake_attachment_downloader.h"
-#include "components/sync/engine/attachments/fake_attachment_uploader.h"
-#include "components/sync/model/attachments/attachment.h"
-
-namespace syncer {
-
-// GetOrDownloadAttachments starts multiple parallel DownloadAttachment calls.
-// GetOrDownloadState tracks completion of these calls and posts callback for
-// consumer once all attachments are either retrieved or reported unavailable.
-class AttachmentServiceImpl::GetOrDownloadState
-    : public base::RefCounted<GetOrDownloadState> {
- public:
-  // GetOrDownloadState gets parameter from values passed to
-  // AttachmentService::GetOrDownloadAttachments.
-  // |attachment_ids| is a list of attachmens to retrieve.
-  // |callback| will be posted on current thread when all attachments retrieved
-  // or confirmed unavailable.
-  GetOrDownloadState(const AttachmentIdList& attachment_ids,
-                     const GetOrDownloadCallback& callback);
-
-  // Attachment was just retrieved. Add it to retrieved attachments.
-  void AddAttachment(const Attachment& attachment);
-
-  // Both reading from local store and downloading attachment failed.
-  // Add it to unavailable set.
-  void AddUnavailableAttachmentId(const AttachmentId& attachment_id);
-
- private:
-  friend class base::RefCounted<GetOrDownloadState>;
-  virtual ~GetOrDownloadState();
-
-  // If all attachment requests completed then post callback to consumer with
-  // results.
-  void PostResultIfAllRequestsCompleted();
-
-  GetOrDownloadCallback callback_;
-
-  // Requests for these attachments are still in progress.
-  AttachmentIdSet in_progress_attachments_;
-
-  AttachmentIdSet unavailable_attachments_;
-  std::unique_ptr<AttachmentMap> retrieved_attachments_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(GetOrDownloadState);
-};
-
-AttachmentServiceImpl::GetOrDownloadState::GetOrDownloadState(
-    const AttachmentIdList& attachment_ids,
-    const GetOrDownloadCallback& callback)
-    : callback_(callback), retrieved_attachments_(new AttachmentMap()) {
-  std::copy(
-      attachment_ids.begin(), attachment_ids.end(),
-      std::inserter(in_progress_attachments_, in_progress_attachments_.end()));
-  PostResultIfAllRequestsCompleted();
-}
-
-AttachmentServiceImpl::GetOrDownloadState::~GetOrDownloadState() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-void AttachmentServiceImpl::GetOrDownloadState::AddAttachment(
-    const Attachment& attachment) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(retrieved_attachments_->find(attachment.GetId()) ==
-         retrieved_attachments_->end());
-  retrieved_attachments_->insert(
-      std::make_pair(attachment.GetId(), attachment));
-  DCHECK(in_progress_attachments_.find(attachment.GetId()) !=
-         in_progress_attachments_.end());
-  in_progress_attachments_.erase(attachment.GetId());
-  PostResultIfAllRequestsCompleted();
-}
-
-void AttachmentServiceImpl::GetOrDownloadState::AddUnavailableAttachmentId(
-    const AttachmentId& attachment_id) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(unavailable_attachments_.find(attachment_id) ==
-         unavailable_attachments_.end());
-  unavailable_attachments_.insert(attachment_id);
-  DCHECK(in_progress_attachments_.find(attachment_id) !=
-         in_progress_attachments_.end());
-  in_progress_attachments_.erase(attachment_id);
-  PostResultIfAllRequestsCompleted();
-}
-
-void AttachmentServiceImpl::GetOrDownloadState::
-    PostResultIfAllRequestsCompleted() {
-  if (in_progress_attachments_.empty()) {
-    // All requests completed. Let's notify consumer.
-    GetOrDownloadResult result =
-        unavailable_attachments_.empty() ? GET_SUCCESS : GET_UNSPECIFIED_ERROR;
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::Bind(callback_, result, base::Passed(&retrieved_attachments_)));
-  }
-}
-
-AttachmentServiceImpl::AttachmentServiceImpl(
-    std::unique_ptr<AttachmentStoreForSync> attachment_store,
-    std::unique_ptr<AttachmentUploader> attachment_uploader,
-    std::unique_ptr<AttachmentDownloader> attachment_downloader,
-    Delegate* delegate,
-    const base::TimeDelta& initial_backoff_delay,
-    const base::TimeDelta& max_backoff_delay)
-    : attachment_store_(std::move(attachment_store)),
-      attachment_uploader_(std::move(attachment_uploader)),
-      attachment_downloader_(std::move(attachment_downloader)),
-      delegate_(delegate),
-      weak_ptr_factory_(this) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(attachment_store_.get());
-
-  // TODO(maniscalco): Observe network connectivity change events.  When the
-  // network becomes disconnected, consider suspending queue dispatch.  When
-  // connectivity is restored, consider clearing any dispatch backoff (bug
-  // 411981).
-  upload_task_queue_ = std::make_unique<TaskQueue<AttachmentId>>(
-      base::Bind(&AttachmentServiceImpl::BeginUpload,
-                 weak_ptr_factory_.GetWeakPtr()),
-      initial_backoff_delay, max_backoff_delay);
-
-  net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
-}
-
-AttachmentServiceImpl::~AttachmentServiceImpl() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
-}
-
-void AttachmentServiceImpl::GetOrDownloadAttachments(
-    const AttachmentIdList& attachment_ids,
-    const GetOrDownloadCallback& callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  scoped_refptr<GetOrDownloadState> state(
-      new GetOrDownloadState(attachment_ids, callback));
-  // SetModelTypeReference() makes attachments visible for model type.
-  // Needed when attachment doesn't have model type reference, but still
-  // available in local store.
-  attachment_store_->SetModelTypeReference(attachment_ids);
-  attachment_store_->Read(attachment_ids,
-                          base::Bind(&AttachmentServiceImpl::ReadDone,
-                                     weak_ptr_factory_.GetWeakPtr(), state));
-}
-
-void AttachmentServiceImpl::ReadDone(
-    const scoped_refptr<GetOrDownloadState>& state,
-    const AttachmentStore::Result& result,
-    std::unique_ptr<AttachmentMap> attachments,
-    std::unique_ptr<AttachmentIdList> unavailable_attachment_ids) {
-  // Add read attachments to result.
-  for (AttachmentMap::const_iterator iter = attachments->begin();
-       iter != attachments->end(); ++iter) {
-    state->AddAttachment(iter->second);
-  }
-
-  AttachmentIdList::const_iterator iter = unavailable_attachment_ids->begin();
-  AttachmentIdList::const_iterator end = unavailable_attachment_ids->end();
-  if (result != AttachmentStore::STORE_INITIALIZATION_FAILED &&
-      attachment_downloader_.get()) {
-    // Try to download locally unavailable attachments.
-    for (; iter != end; ++iter) {
-      attachment_downloader_->DownloadAttachment(
-          *iter, base::Bind(&AttachmentServiceImpl::DownloadDone,
-                            weak_ptr_factory_.GetWeakPtr(), state, *iter));
-    }
-  } else {
-    // No downloader so all locally unavailable attachments are unavailable.
-    for (; iter != end; ++iter) {
-      state->AddUnavailableAttachmentId(*iter);
-    }
-  }
-}
-
-void AttachmentServiceImpl::WriteDone(
-    const scoped_refptr<GetOrDownloadState>& state,
-    const Attachment& attachment,
-    const AttachmentStore::Result& result) {
-  switch (result) {
-    case AttachmentStore::SUCCESS:
-      state->AddAttachment(attachment);
-      break;
-    case AttachmentStore::UNSPECIFIED_ERROR:
-    case AttachmentStore::STORE_INITIALIZATION_FAILED:
-      state->AddUnavailableAttachmentId(attachment.GetId());
-      break;
-  }
-}
-
-void AttachmentServiceImpl::UploadDone(
-    const AttachmentUploader::UploadResult& result,
-    const AttachmentId& attachment_id) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AttachmentIdList ids;
-  ids.push_back(attachment_id);
-  switch (result) {
-    case AttachmentUploader::UPLOAD_SUCCESS:
-      attachment_store_->DropSyncReference(ids);
-      upload_task_queue_->MarkAsSucceeded(attachment_id);
-      if (delegate_) {
-        delegate_->OnAttachmentUploaded(attachment_id);
-      }
-      break;
-    case AttachmentUploader::UPLOAD_TRANSIENT_ERROR:
-      upload_task_queue_->MarkAsFailed(attachment_id);
-      upload_task_queue_->AddToQueue(attachment_id);
-      break;
-    case AttachmentUploader::UPLOAD_UNSPECIFIED_ERROR:
-      // TODO(pavely): crbug/372622: Deal with UploadAttachment failures.
-      attachment_store_->DropSyncReference(ids);
-      upload_task_queue_->MarkAsFailed(attachment_id);
-      break;
-  }
-}
-
-void AttachmentServiceImpl::DownloadDone(
-    const scoped_refptr<GetOrDownloadState>& state,
-    const AttachmentId& attachment_id,
-    const AttachmentDownloader::DownloadResult& result,
-    std::unique_ptr<Attachment> attachment) {
-  switch (result) {
-    case AttachmentDownloader::DOWNLOAD_SUCCESS: {
-      AttachmentList attachment_list;
-      attachment_list.push_back(*attachment.get());
-      attachment_store_->Write(
-          attachment_list,
-          base::Bind(&AttachmentServiceImpl::WriteDone,
-                     weak_ptr_factory_.GetWeakPtr(), state, *attachment.get()));
-      break;
-    }
-    case AttachmentDownloader::DOWNLOAD_TRANSIENT_ERROR:
-    case AttachmentDownloader::DOWNLOAD_UNSPECIFIED_ERROR:
-      state->AddUnavailableAttachmentId(attachment_id);
-      break;
-  }
-}
-
-void AttachmentServiceImpl::BeginUpload(const AttachmentId& attachment_id) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(attachment_id);
-  attachment_store_->Read(attachment_ids,
-                          base::Bind(&AttachmentServiceImpl::ReadDoneNowUpload,
-                                     weak_ptr_factory_.GetWeakPtr()));
-}
-
-void AttachmentServiceImpl::UploadAttachments(
-    const AttachmentIdList& attachment_ids) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (!attachment_uploader_.get()) {
-    return;
-  }
-  attachment_store_->SetSyncReference(attachment_ids);
-
-  for (auto iter = attachment_ids.begin(); iter != attachment_ids.end();
-       ++iter) {
-    upload_task_queue_->AddToQueue(*iter);
-  }
-}
-
-void AttachmentServiceImpl::OnNetworkChanged(
-    net::NetworkChangeNotifier::ConnectionType type) {
-  if (type != net::NetworkChangeNotifier::CONNECTION_NONE) {
-    upload_task_queue_->ResetBackoff();
-  }
-}
-
-void AttachmentServiceImpl::ReadDoneNowUpload(
-    const AttachmentStore::Result& result,
-    std::unique_ptr<AttachmentMap> attachments,
-    std::unique_ptr<AttachmentIdList> unavailable_attachment_ids) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (!unavailable_attachment_ids->empty()) {
-    // TODO(maniscalco): We failed to read some attachments. What should we do
-    // now?
-    AttachmentIdList::const_iterator iter = unavailable_attachment_ids->begin();
-    AttachmentIdList::const_iterator end = unavailable_attachment_ids->end();
-    for (; iter != end; ++iter) {
-      upload_task_queue_->Cancel(*iter);
-    }
-    attachment_store_->DropSyncReference(*unavailable_attachment_ids);
-  }
-
-  AttachmentMap::const_iterator iter = attachments->begin();
-  AttachmentMap::const_iterator end = attachments->end();
-  for (; iter != end; ++iter) {
-    attachment_uploader_->UploadAttachment(
-        iter->second, base::Bind(&AttachmentServiceImpl::UploadDone,
-                                 weak_ptr_factory_.GetWeakPtr()));
-  }
-}
-
-void AttachmentServiceImpl::SetTimerForTest(
-    std::unique_ptr<base::Timer> timer) {
-  upload_task_queue_->SetTimerForTest(std::move(timer));
-}
-
-}  // namespace syncer
diff --git a/components/sync/model_impl/attachments/attachment_service_impl.h b/components/sync/model_impl/attachments/attachment_service_impl.h
deleted file mode 100644
index 1a602d1ae..0000000
--- a/components/sync/model_impl/attachments/attachment_service_impl.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2014 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_SYNC_MODEL_IMPL_ATTACHMENTS_ATTACHMENT_SERVICE_IMPL_H_
-#define COMPONENTS_SYNC_MODEL_IMPL_ATTACHMENTS_ATTACHMENT_SERVICE_IMPL_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequence_checker.h"
-#include "components/sync/engine/attachments/attachment_downloader.h"
-#include "components/sync/engine/attachments/attachment_uploader.h"
-#include "components/sync/model/attachments/attachment_service.h"
-#include "components/sync/model/attachments/attachment_service_proxy.h"
-#include "components/sync/model/attachments/attachment_store.h"
-#include "components/sync/model_impl/attachments/task_queue.h"
-#include "net/base/network_change_notifier.h"
-
-namespace syncer {
-
-// Implementation of AttachmentService.
-class AttachmentServiceImpl
-    : public AttachmentService,
-      public net::NetworkChangeNotifier::NetworkChangeObserver {
- public:
-  // |attachment_store| is required. UploadAttachments reads attachment data
-  // from it. Downloaded attachments will be written into it.
-  //
-  // |attachment_uploader| is optional. If null, attachments will never be
-  // uploaded to the sync server and |delegate|'s OnAttachmentUploaded will
-  // never be invoked.
-  //
-  // |attachment_downloader| is optional. If null, attachments will never be
-  // downloaded. Only attachments in |attachment_store| will be returned from
-  // GetOrDownloadAttachments.
-  //
-  // |delegate| is optional delegate for AttachmentService to notify about
-  // asynchronous events (AttachmentUploaded). Pass null if delegate is not
-  // provided. AttachmentService doesn't take ownership of delegate, the pointer
-  // must be valid throughout AttachmentService lifetime.
-  //
-  // |initial_backoff_delay| the initial delay between upload attempts.  This
-  // class automatically retries failed uploads.  After the first failure, it
-  // will wait this amount of time until it tries again.  After each failure,
-  // the delay is doubled until the |max_backoff_delay| is reached.  A
-  // successful upload clears the delay.
-  //
-  // |max_backoff_delay| the maxmium delay between upload attempts when backed
-  // off.
-  AttachmentServiceImpl(
-      std::unique_ptr<AttachmentStoreForSync> attachment_store,
-      std::unique_ptr<AttachmentUploader> attachment_uploader,
-      std::unique_ptr<AttachmentDownloader> attachment_downloader,
-      Delegate* delegate,
-      const base::TimeDelta& initial_backoff_delay,
-      const base::TimeDelta& max_backoff_delay);
-  ~AttachmentServiceImpl() override;
-
-  // AttachmentService implementation.
-  void GetOrDownloadAttachments(const AttachmentIdList& attachment_ids,
-                                const GetOrDownloadCallback& callback) override;
-  void UploadAttachments(const AttachmentIdList& attachment_ids) override;
-
-  // NetworkChangeObserver implementation.
-  void OnNetworkChanged(
-      net::NetworkChangeNotifier::ConnectionType type) override;
-
-  // Use |timer| in the underlying TaskQueue.
-  //
-  // Used in tests.  See also MockTimer.
-  void SetTimerForTest(std::unique_ptr<base::Timer> timer);
-
- private:
-  class GetOrDownloadState;
-
-  void ReadDone(const scoped_refptr<GetOrDownloadState>& state,
-                const AttachmentStore::Result& result,
-                std::unique_ptr<AttachmentMap> attachments,
-                std::unique_ptr<AttachmentIdList> unavailable_attachment_ids);
-  void WriteDone(const scoped_refptr<GetOrDownloadState>& state,
-                 const Attachment& attachment,
-                 const AttachmentStore::Result& result);
-  void UploadDone(const AttachmentUploader::UploadResult& result,
-                  const AttachmentId& attachment_id);
-  void DownloadDone(const scoped_refptr<GetOrDownloadState>& state,
-                    const AttachmentId& attachment_id,
-                    const AttachmentDownloader::DownloadResult& result,
-                    std::unique_ptr<Attachment> attachment);
-  void BeginUpload(const AttachmentId& attachment_id);
-  void ReadDoneNowUpload(
-      const AttachmentStore::Result& result,
-      std::unique_ptr<AttachmentMap> attachments,
-      std::unique_ptr<AttachmentIdList> unavailable_attachment_ids);
-
-  std::unique_ptr<AttachmentStoreForSync> attachment_store_;
-
-  // May be null.
-  const std::unique_ptr<AttachmentUploader> attachment_uploader_;
-
-  // May be null.
-  const std::unique_ptr<AttachmentDownloader> attachment_downloader_;
-
-  // May be null.
-  Delegate* delegate_;
-
-  std::unique_ptr<TaskQueue<AttachmentId>> upload_task_queue_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  // Must be last data member.
-  base::WeakPtrFactory<AttachmentServiceImpl> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(AttachmentServiceImpl);
-};
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_MODEL_IMPL_ATTACHMENTS_ATTACHMENT_SERVICE_IMPL_H_
diff --git a/components/sync/model_impl/attachments/attachment_service_impl_unittest.cc b/components/sync/model_impl/attachments/attachment_service_impl_unittest.cc
deleted file mode 100644
index d590343..0000000
--- a/components/sync/model_impl/attachments/attachment_service_impl_unittest.cc
+++ /dev/null
@@ -1,637 +0,0 @@
-// Copyright 2014 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/sync/model_impl/attachments/attachment_service_impl.h"
-
-#include <algorithm>
-#include <map>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/timer/mock_timer.h"
-#include "components/sync/engine/attachments/attachment_store_backend.h"
-#include "components/sync/engine/attachments/attachment_util.h"
-#include "components/sync/engine/attachments/fake_attachment_downloader.h"
-#include "components/sync/engine/attachments/fake_attachment_uploader.h"
-#include "testing/gmock/include/gmock/gmock-matchers.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace syncer {
-
-namespace {
-
-class MockAttachmentStoreBackend
-    : public AttachmentStoreBackend,
-      public base::SupportsWeakPtr<MockAttachmentStoreBackend> {
- public:
-  MockAttachmentStoreBackend(
-      const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner)
-      : AttachmentStoreBackend(callback_task_runner) {}
-
-  ~MockAttachmentStoreBackend() override {}
-
-  void Init(const AttachmentStore::InitCallback& callback) override {}
-
-  void Read(AttachmentStore::Component component,
-            const AttachmentIdList& ids,
-            const AttachmentStore::ReadCallback& callback) override {
-    read_ids.push_back(ids);
-    read_callbacks.push_back(callback);
-  }
-
-  void Write(AttachmentStore::Component component,
-             const AttachmentList& attachments,
-             const AttachmentStore::WriteCallback& callback) override {
-    write_attachments.push_back(attachments);
-    write_callbacks.push_back(callback);
-  }
-
-  void SetReference(AttachmentStore::Component component,
-                    const AttachmentIdList& ids) override {
-    set_reference_ids.push_back(std::make_pair(component, ids));
-  }
-
-  void DropReference(AttachmentStore::Component component,
-                     const AttachmentIdList& ids,
-                     const AttachmentStore::DropCallback& callback) override {
-    ASSERT_EQ(AttachmentStore::SYNC, component);
-    drop_ids.push_back(ids);
-  }
-
-  void ReadMetadataById(
-      AttachmentStore::Component component,
-      const AttachmentIdList& ids,
-      const AttachmentStore::ReadMetadataCallback& callback) override {
-    NOTREACHED();
-  }
-
-  void ReadMetadata(
-      AttachmentStore::Component component,
-      const AttachmentStore::ReadMetadataCallback& callback) override {
-    NOTREACHED();
-  }
-
-  // Respond to Read request. Attachments found in local_attachments should be
-  // returned, everything else should be reported unavailable.
-  void RespondToRead(const AttachmentIdSet& local_attachments) {
-    scoped_refptr<base::RefCountedString> data = new base::RefCountedString();
-    AttachmentStore::ReadCallback callback = read_callbacks.back();
-    AttachmentIdList ids = read_ids.back();
-    read_callbacks.pop_back();
-    read_ids.pop_back();
-
-    std::unique_ptr<AttachmentMap> attachments(new AttachmentMap());
-    std::unique_ptr<AttachmentIdList> unavailable_attachments(
-        new AttachmentIdList());
-    for (AttachmentIdList::const_iterator iter = ids.begin(); iter != ids.end();
-         ++iter) {
-      if (local_attachments.find(*iter) != local_attachments.end()) {
-        Attachment attachment = Attachment::CreateFromParts(*iter, data);
-        attachments->insert(std::make_pair(*iter, attachment));
-      } else {
-        unavailable_attachments->push_back(*iter);
-      }
-    }
-    AttachmentStore::Result result = unavailable_attachments->empty()
-                                         ? AttachmentStore::SUCCESS
-                                         : AttachmentStore::UNSPECIFIED_ERROR;
-
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(callback, result, base::Passed(&attachments),
-                              base::Passed(&unavailable_attachments)));
-  }
-
-  // Respond to Write request with |result|.
-  void RespondToWrite(const AttachmentStore::Result& result) {
-    AttachmentStore::WriteCallback callback = write_callbacks.back();
-    write_callbacks.pop_back();
-    write_attachments.pop_back();
-    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-                                                  base::Bind(callback, result));
-  }
-
-  std::vector<AttachmentIdList> read_ids;
-  std::vector<AttachmentStore::ReadCallback> read_callbacks;
-  std::vector<AttachmentList> write_attachments;
-  std::vector<AttachmentStore::WriteCallback> write_callbacks;
-  std::vector<std::pair<AttachmentStore::Component, AttachmentIdList>>
-      set_reference_ids;
-  std::vector<AttachmentIdList> drop_ids;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockAttachmentStoreBackend);
-};
-
-class MockAttachmentDownloader
-    : public AttachmentDownloader,
-      public base::SupportsWeakPtr<MockAttachmentDownloader> {
- public:
-  MockAttachmentDownloader() {}
-
-  void DownloadAttachment(const AttachmentId& id,
-                          const DownloadCallback& callback) override {
-    ASSERT_TRUE(download_requests.find(id) == download_requests.end());
-    download_requests.insert(std::make_pair(id, callback));
-  }
-
-  // Multiple requests to download will be active at the same time.
-  // RespondToDownload should respond to only one of them.
-  void RespondToDownload(const AttachmentId& id, const DownloadResult& result) {
-    ASSERT_TRUE(download_requests.find(id) != download_requests.end());
-    std::unique_ptr<Attachment> attachment;
-    if (result == DOWNLOAD_SUCCESS) {
-      scoped_refptr<base::RefCountedString> data = new base::RefCountedString();
-      attachment =
-          std::make_unique<Attachment>(Attachment::CreateFromParts(id, data));
-    }
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::Bind(download_requests[id], result, base::Passed(&attachment)));
-
-    download_requests.erase(id);
-  }
-
-  std::map<AttachmentId, DownloadCallback> download_requests;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockAttachmentDownloader);
-};
-
-class MockAttachmentUploader
-    : public AttachmentUploader,
-      public base::SupportsWeakPtr<MockAttachmentUploader> {
- public:
-  MockAttachmentUploader() {}
-
-  // AttachmentUploader implementation.
-  void UploadAttachment(const Attachment& attachment,
-                        const UploadCallback& callback) override {
-    const AttachmentId id = attachment.GetId();
-    ASSERT_TRUE(upload_requests.find(id) == upload_requests.end());
-    upload_requests.insert(std::make_pair(id, callback));
-  }
-
-  void RespondToUpload(const AttachmentId& id, const UploadResult& result) {
-    ASSERT_TRUE(upload_requests.find(id) != upload_requests.end());
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::Bind(upload_requests[id], result, id));
-    upload_requests.erase(id);
-  }
-
-  std::map<AttachmentId, UploadCallback> upload_requests;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockAttachmentUploader);
-};
-
-}  // namespace
-
-class AttachmentServiceImplTest : public testing::Test,
-                                  public AttachmentService::Delegate {
- protected:
-  AttachmentServiceImplTest() {}
-
-  void SetUp() override {
-    network_change_notifier_.reset(net::NetworkChangeNotifier::CreateMock());
-    InitializeAttachmentService(std::make_unique<MockAttachmentUploader>(),
-                                std::make_unique<MockAttachmentDownloader>(),
-                                this);
-  }
-
-  void TearDown() override {
-    attachment_service_.reset();
-    RunLoop();
-    ASSERT_FALSE(attachment_store_backend_);
-    ASSERT_FALSE(attachment_uploader_);
-    ASSERT_FALSE(attachment_downloader_);
-  }
-
-  // AttachmentService::Delegate implementation.
-  void OnAttachmentUploaded(const AttachmentId& attachment_id) override {
-    on_attachment_uploaded_list_.push_back(attachment_id);
-  }
-
-  void InitializeAttachmentService(
-      std::unique_ptr<MockAttachmentUploader> uploader,
-      std::unique_ptr<MockAttachmentDownloader> downloader,
-      AttachmentService::Delegate* delegate) {
-    // Initialize mock attachment store
-    scoped_refptr<base::SingleThreadTaskRunner> runner =
-        base::ThreadTaskRunnerHandle::Get();
-    std::unique_ptr<MockAttachmentStoreBackend> attachment_store_backend(
-        new MockAttachmentStoreBackend(runner));
-    attachment_store_backend_ = attachment_store_backend->AsWeakPtr();
-    std::unique_ptr<AttachmentStore> attachment_store =
-        AttachmentStore::CreateMockStoreForTest(
-            std::move(attachment_store_backend));
-
-    if (uploader.get()) {
-      attachment_uploader_ = uploader->AsWeakPtr();
-    }
-    if (downloader.get()) {
-      attachment_downloader_ = downloader->AsWeakPtr();
-    }
-    attachment_service_ = std::make_unique<AttachmentServiceImpl>(
-        attachment_store->CreateAttachmentStoreForSync(), std::move(uploader),
-        std::move(downloader), delegate, base::TimeDelta::FromMinutes(1),
-        base::TimeDelta::FromMinutes(8));
-
-    std::unique_ptr<base::MockTimer> timer_to_pass(
-        new base::MockTimer(false, false));
-    mock_timer_ = timer_to_pass.get();
-    attachment_service_->SetTimerForTest(std::move(timer_to_pass));
-  }
-
-  AttachmentService* attachment_service() { return attachment_service_.get(); }
-
-  base::MockTimer* mock_timer() { return mock_timer_; }
-
-  AttachmentService::GetOrDownloadCallback download_callback() {
-    return base::Bind(&AttachmentServiceImplTest::DownloadDone,
-                      base::Unretained(this));
-  }
-
-  void DownloadDone(const AttachmentService::GetOrDownloadResult& result,
-                    std::unique_ptr<AttachmentMap> attachments) {
-    download_results_.push_back(result);
-    last_download_attachments_ = std::move(attachments);
-  }
-
-  void RunLoop() {
-    base::RunLoop run_loop;
-    run_loop.RunUntilIdle();
-  }
-
-  void RunLoopAndFireTimer() {
-    RunLoop();
-    if (mock_timer()->IsRunning()) {
-      mock_timer()->Fire();
-      RunLoop();
-    }
-  }
-
-  static AttachmentIdSet AttachmentIdSetFromList(
-      const AttachmentIdList& id_list) {
-    AttachmentIdSet id_set;
-    std::copy(id_list.begin(), id_list.end(),
-              std::inserter(id_set, id_set.end()));
-    return id_set;
-  }
-
-  const std::vector<AttachmentService::GetOrDownloadResult>& download_results()
-      const {
-    return download_results_;
-  }
-
-  const AttachmentMap& last_download_attachments() const {
-    return *last_download_attachments_.get();
-  }
-
-  net::NetworkChangeNotifier* network_change_notifier() {
-    return network_change_notifier_.get();
-  }
-
-  MockAttachmentStoreBackend* store() {
-    return attachment_store_backend_.get();
-  }
-
-  MockAttachmentDownloader* downloader() {
-    return attachment_downloader_.get();
-  }
-
-  MockAttachmentUploader* uploader() { return attachment_uploader_.get(); }
-
-  const std::vector<AttachmentId>& on_attachment_uploaded_list() const {
-    return on_attachment_uploaded_list_;
-  }
-
- private:
-  base::MessageLoop message_loop_;
-  std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
-  base::WeakPtr<MockAttachmentStoreBackend> attachment_store_backend_;
-  base::WeakPtr<MockAttachmentDownloader> attachment_downloader_;
-  base::WeakPtr<MockAttachmentUploader> attachment_uploader_;
-  std::unique_ptr<AttachmentServiceImpl> attachment_service_;
-  base::MockTimer* mock_timer_;  // not owned
-
-  std::vector<AttachmentService::GetOrDownloadResult> download_results_;
-  std::unique_ptr<AttachmentMap> last_download_attachments_;
-  std::vector<AttachmentId> on_attachment_uploaded_list_;
-};
-
-TEST_F(AttachmentServiceImplTest, GetOrDownload_EmptyAttachmentList) {
-  AttachmentIdList attachment_ids;
-  attachment_service()->GetOrDownloadAttachments(attachment_ids,
-                                                 download_callback());
-  RunLoop();
-  store()->RespondToRead(AttachmentIdSet());
-
-  RunLoop();
-  EXPECT_EQ(1U, download_results().size());
-  EXPECT_EQ(0U, last_download_attachments().size());
-}
-
-TEST_F(AttachmentServiceImplTest, GetOrDownload_Local) {
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_service()->GetOrDownloadAttachments(attachment_ids,
-                                                 download_callback());
-  AttachmentIdSet local_attachments;
-  local_attachments.insert(attachment_ids[0]);
-  RunLoop();
-  EXPECT_EQ(1U, store()->set_reference_ids.size());
-  EXPECT_EQ(AttachmentStore::MODEL_TYPE, store()->set_reference_ids[0].first);
-  store()->RespondToRead(local_attachments);
-
-  RunLoop();
-  EXPECT_EQ(1U, download_results().size());
-  EXPECT_EQ(1U, last_download_attachments().size());
-  EXPECT_TRUE(last_download_attachments().find(attachment_ids[0]) !=
-              last_download_attachments().end());
-}
-
-TEST_F(AttachmentServiceImplTest, GetOrDownload_LocalRemoteUnavailable) {
-  // Create attachment list with 4 ids.
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  // Call attachment service.
-  attachment_service()->GetOrDownloadAttachments(attachment_ids,
-                                                 download_callback());
-  RunLoop();
-  // Ensure AttachmentStore is called.
-  EXPECT_FALSE(store()->read_ids.empty());
-
-  // Make AttachmentStore return only attachment 0.
-  AttachmentIdSet local_attachments;
-  local_attachments.insert(attachment_ids[0]);
-  store()->RespondToRead(local_attachments);
-  RunLoop();
-  // Ensure Downloader called with right attachment ids
-  EXPECT_EQ(3U, downloader()->download_requests.size());
-
-  // Make downloader return attachment 1.
-  downloader()->RespondToDownload(attachment_ids[1],
-                                  AttachmentDownloader::DOWNLOAD_SUCCESS);
-  RunLoop();
-  // Ensure consumer callback is not called.
-  EXPECT_TRUE(download_results().empty());
-  // Make AttachmentStore acknowledge writing attachment 1.
-  store()->RespondToWrite(AttachmentStore::SUCCESS);
-  RunLoop();
-  // Ensure consumer callback is not called.
-  EXPECT_TRUE(download_results().empty());
-
-  // Make downloader return attachment 2.
-  downloader()->RespondToDownload(attachment_ids[2],
-                                  AttachmentDownloader::DOWNLOAD_SUCCESS);
-  RunLoop();
-  // Ensure consumer callback is not called.
-  EXPECT_TRUE(download_results().empty());
-  // Make AttachmentStore fail writing attachment 2.
-  store()->RespondToWrite(AttachmentStore::UNSPECIFIED_ERROR);
-  RunLoop();
-  // Ensure consumer callback is not called.
-  EXPECT_TRUE(download_results().empty());
-
-  // Make downloader fail attachment 3.
-  downloader()->RespondToDownload(
-      attachment_ids[3], AttachmentDownloader::DOWNLOAD_UNSPECIFIED_ERROR);
-  RunLoop();
-
-  // Ensure callback is called
-  EXPECT_FALSE(download_results().empty());
-  // There should be only two attachments returned, 0 and 1.
-  EXPECT_EQ(2U, last_download_attachments().size());
-  EXPECT_TRUE(last_download_attachments().find(attachment_ids[0]) !=
-              last_download_attachments().end());
-  EXPECT_TRUE(last_download_attachments().find(attachment_ids[1]) !=
-              last_download_attachments().end());
-  EXPECT_TRUE(last_download_attachments().find(attachment_ids[2]) ==
-              last_download_attachments().end());
-  EXPECT_TRUE(last_download_attachments().find(attachment_ids[3]) ==
-              last_download_attachments().end());
-}
-
-TEST_F(AttachmentServiceImplTest, GetOrDownload_NoDownloader) {
-  // No downloader.
-  InitializeAttachmentService(
-      base::WrapUnique<MockAttachmentUploader>(new MockAttachmentUploader()),
-      base::WrapUnique<MockAttachmentDownloader>(nullptr), this);
-
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_service()->GetOrDownloadAttachments(attachment_ids,
-                                                 download_callback());
-  RunLoop();
-  EXPECT_FALSE(store()->read_ids.empty());
-
-  AttachmentIdSet local_attachments;
-  store()->RespondToRead(local_attachments);
-  RunLoop();
-  ASSERT_EQ(1U, download_results().size());
-  EXPECT_EQ(AttachmentService::GET_UNSPECIFIED_ERROR, download_results()[0]);
-  EXPECT_TRUE(last_download_attachments().empty());
-}
-
-TEST_F(AttachmentServiceImplTest, UploadAttachments_Success) {
-  AttachmentIdList attachment_ids;
-  const unsigned num_attachments = 3;
-  for (unsigned i = 0; i < num_attachments; ++i) {
-    attachment_ids.push_back(AttachmentId::Create(0, 0));
-  }
-  attachment_service()->UploadAttachments(attachment_ids);
-  RunLoop();
-  ASSERT_EQ(1U, store()->set_reference_ids.size());
-  EXPECT_EQ(AttachmentStore::SYNC, store()->set_reference_ids[0].first);
-  for (unsigned i = 0; i < num_attachments; ++i) {
-    RunLoopAndFireTimer();
-    // See that the service has issued a read for at least one of the
-    // attachments.
-    ASSERT_GE(store()->read_ids.size(), 1U);
-    store()->RespondToRead(AttachmentIdSetFromList(attachment_ids));
-    RunLoop();
-    ASSERT_GE(uploader()->upload_requests.size(), 1U);
-    uploader()->RespondToUpload(uploader()->upload_requests.begin()->first,
-                                AttachmentUploader::UPLOAD_SUCCESS);
-  }
-  RunLoop();
-  ASSERT_EQ(0U, store()->read_ids.size());
-  ASSERT_EQ(0U, uploader()->upload_requests.size());
-
-  // See that all the attachments were uploaded.
-  ASSERT_EQ(attachment_ids.size(), on_attachment_uploaded_list().size());
-  for (auto iter = attachment_ids.begin(); iter != attachment_ids.end();
-       ++iter) {
-    EXPECT_THAT(on_attachment_uploaded_list(), testing::Contains(*iter));
-  }
-  EXPECT_EQ(num_attachments, store()->drop_ids.size());
-}
-
-TEST_F(AttachmentServiceImplTest, UploadAttachments_Success_NoDelegate) {
-  InitializeAttachmentService(std::make_unique<MockAttachmentUploader>(),
-                              std::make_unique<MockAttachmentDownloader>(),
-                              nullptr);  // No delegate.
-
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_service()->UploadAttachments(attachment_ids);
-  RunLoopAndFireTimer();
-  ASSERT_EQ(1U, store()->read_ids.size());
-  ASSERT_EQ(0U, uploader()->upload_requests.size());
-  store()->RespondToRead(AttachmentIdSetFromList(attachment_ids));
-  RunLoop();
-  ASSERT_EQ(0U, store()->read_ids.size());
-  ASSERT_EQ(1U, uploader()->upload_requests.size());
-  uploader()->RespondToUpload(*attachment_ids.begin(),
-                              AttachmentUploader::UPLOAD_SUCCESS);
-  RunLoop();
-  ASSERT_TRUE(on_attachment_uploaded_list().empty());
-}
-
-TEST_F(AttachmentServiceImplTest, UploadAttachments_SomeMissingFromStore) {
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_service()->UploadAttachments(attachment_ids);
-  RunLoopAndFireTimer();
-  ASSERT_GE(store()->read_ids.size(), 1U);
-
-  ASSERT_EQ(0U, uploader()->upload_requests.size());
-  store()->RespondToRead(AttachmentIdSetFromList(attachment_ids));
-  RunLoop();
-  ASSERT_EQ(1U, uploader()->upload_requests.size());
-
-  uploader()->RespondToUpload(uploader()->upload_requests.begin()->first,
-                              AttachmentUploader::UPLOAD_SUCCESS);
-  RunLoopAndFireTimer();
-  ASSERT_EQ(1U, on_attachment_uploaded_list().size());
-  ASSERT_GE(store()->read_ids.size(), 1U);
-  // Not found!
-  store()->RespondToRead(AttachmentIdSet());
-  RunLoop();
-  // No upload requests since the read failed.
-  ASSERT_EQ(0U, uploader()->upload_requests.size());
-  EXPECT_EQ(attachment_ids.size(), store()->drop_ids.size());
-}
-
-TEST_F(AttachmentServiceImplTest, UploadAttachments_AllMissingFromStore) {
-  AttachmentIdList attachment_ids;
-  const unsigned num_attachments = 2;
-  for (unsigned i = 0; i < num_attachments; ++i) {
-    attachment_ids.push_back(AttachmentId::Create(0, 0));
-  }
-  attachment_service()->UploadAttachments(attachment_ids);
-
-  for (unsigned i = 0; i < num_attachments; ++i) {
-    RunLoopAndFireTimer();
-    ASSERT_GE(store()->read_ids.size(), 1U);
-    // None found!
-    store()->RespondToRead(AttachmentIdSet());
-  }
-  RunLoop();
-
-  // Nothing uploaded.
-  EXPECT_EQ(0U, uploader()->upload_requests.size());
-  // See that the delegate was never called.
-  ASSERT_EQ(0U, on_attachment_uploaded_list().size());
-  EXPECT_EQ(num_attachments, store()->drop_ids.size());
-}
-
-TEST_F(AttachmentServiceImplTest, UploadAttachments_NoUploader) {
-  InitializeAttachmentService(base::WrapUnique<MockAttachmentUploader>(nullptr),
-                              std::make_unique<MockAttachmentDownloader>(),
-                              this);
-
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_service()->UploadAttachments(attachment_ids);
-  RunLoop();
-  EXPECT_EQ(0U, store()->read_ids.size());
-  ASSERT_EQ(0U, on_attachment_uploaded_list().size());
-  EXPECT_EQ(0U, store()->drop_ids.size());
-}
-
-// Upload three attachments.  For one of them, server responds with error.
-TEST_F(AttachmentServiceImplTest, UploadAttachments_OneUploadFails) {
-  AttachmentIdList attachment_ids;
-  const unsigned num_attachments = 3;
-  for (unsigned i = 0; i < num_attachments; ++i) {
-    attachment_ids.push_back(AttachmentId::Create(0, 0));
-  }
-  attachment_service()->UploadAttachments(attachment_ids);
-
-  for (unsigned i = 0; i < 3; ++i) {
-    RunLoopAndFireTimer();
-    ASSERT_GE(store()->read_ids.size(), 1U);
-    store()->RespondToRead(AttachmentIdSetFromList(attachment_ids));
-    RunLoop();
-    ASSERT_EQ(1U, uploader()->upload_requests.size());
-    AttachmentUploader::UploadResult result =
-        AttachmentUploader::UPLOAD_SUCCESS;
-    // Fail the 2nd one.
-    if (i == 2U) {
-      result = AttachmentUploader::UPLOAD_UNSPECIFIED_ERROR;
-    } else {
-      result = AttachmentUploader::UPLOAD_SUCCESS;
-    }
-    uploader()->RespondToUpload(uploader()->upload_requests.begin()->first,
-                                result);
-    RunLoop();
-  }
-  ASSERT_EQ(2U, on_attachment_uploaded_list().size());
-  EXPECT_EQ(num_attachments, store()->drop_ids.size());
-}
-
-// Attempt an upload, respond with transient error to trigger backoff, issue
-// network disconnect/connect events and see that backoff is cleared.
-TEST_F(AttachmentServiceImplTest,
-       UploadAttachments_ResetBackoffAfterNetworkChange) {
-  AttachmentIdList attachment_ids;
-  attachment_ids.push_back(AttachmentId::Create(0, 0));
-  attachment_service()->UploadAttachments(attachment_ids);
-
-  RunLoopAndFireTimer();
-  ASSERT_EQ(1U, store()->read_ids.size());
-  store()->RespondToRead(AttachmentIdSetFromList(attachment_ids));
-  RunLoop();
-  ASSERT_EQ(1U, uploader()->upload_requests.size());
-
-  uploader()->RespondToUpload(uploader()->upload_requests.begin()->first,
-                              AttachmentUploader::UPLOAD_TRANSIENT_ERROR);
-  RunLoop();
-
-  // See that we are in backoff.
-  ASSERT_TRUE(mock_timer()->IsRunning());
-  ASSERT_GT(mock_timer()->GetCurrentDelay(), base::TimeDelta());
-
-  // Issue a network disconnect event.
-  network_change_notifier()->NotifyObserversOfNetworkChangeForTests(
-      net::NetworkChangeNotifier::CONNECTION_NONE);
-  RunLoop();
-
-  // Still in backoff.
-  ASSERT_TRUE(mock_timer()->IsRunning());
-  ASSERT_GT(mock_timer()->GetCurrentDelay(), base::TimeDelta());
-
-  // Issue a network connect event.
-  net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
-      net::NetworkChangeNotifier::CONNECTION_WIFI);
-  RunLoop();
-
-  // No longer in backoff.
-  ASSERT_TRUE(mock_timer()->IsRunning());
-  ASSERT_EQ(base::TimeDelta(), mock_timer()->GetCurrentDelay());
-}
-
-}  // namespace syncer
diff --git a/components/sync/model_impl/attachments/task_queue.h b/components/sync/model_impl/attachments/task_queue.h
deleted file mode 100644
index 05ea9495..0000000
--- a/components/sync/model_impl/attachments/task_queue.h
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright 2014 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_SYNC_MODEL_IMPL_ATTACHMENTS_TASK_QUEUE_H_
-#define COMPONENTS_SYNC_MODEL_IMPL_ATTACHMENTS_TASK_QUEUE_H_
-
-#include <stddef.h>
-
-#include <memory>
-#include <set>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/containers/circular_deque.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequence_checker.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "base/timer/timer.h"
-#include "net/base/backoff_entry.h"
-
-namespace syncer {
-
-// A queue that dispatches tasks, ignores duplicates, and provides backoff
-// semantics.
-//
-// |T| is the task type.
-//
-// For each task added to the queue, the HandleTaskCallback will eventually be
-// invoked.  For each invocation, the user of TaskQueue must call exactly one of
-// |MarkAsSucceeded|, |MarkAsFailed|, or |Cancel|.
-//
-// To retry a failed task, call MarkAsFailed(task) then AddToQueue(task).
-//
-// Example usage:
-//
-// void Handle(const Foo& foo);
-// ...
-// TaskQueue<Foo> queue(base::Bind(&Handle),
-//                      base::TimeDelta::FromSeconds(1),
-//                      base::TimeDelta::FromMinutes(1));
-// ...
-// {
-//   Foo foo;
-//   // Add foo to the queue.  At some point, Handle will be invoked in this
-//   // message loop.
-//   queue.AddToQueue(foo);
-// }
-// ...
-// void Handle(const Foo& foo) {
-//   DoSomethingWith(foo);
-//   // We must call one of the three methods to tell the queue how we're
-//   // dealing with foo.  Of course, we are free to call in the the context of
-//   // this HandleTaskCallback or outside the context if we so choose.
-//   if (SuccessfullyHandled(foo)) {
-//     queue.MarkAsSucceeded(foo);
-//   } else if (Failed(foo)) {
-//     queue.MarkAsFailed(foo);
-//     if (ShouldRetry(foo)) {
-//       queue.AddToQueue(foo);
-//     }
-//   } else {
-//     Cancel(foo);
-//   }
-// }
-//
-template <typename T>
-class TaskQueue {
- public:
-  // A callback provided by users of the TaskQueue to handle tasks.
-  //
-  // This callback is invoked by the queue with a task to be handled.  The
-  // callee is expected to (eventually) call |MarkAsSucceeded|, |MarkAsFailed|,
-  // or |Cancel| to signify completion of the task.
-  using HandleTaskCallback = base::Callback<void(const T&)>;
-
-  // Construct a TaskQueue.
-  //
-  // |callback| the callback to be invoked for handling tasks.
-  //
-  // |initial_backoff_delay| the initial amount of time the queue will wait
-  // before dispatching tasks after a failed task (see |MarkAsFailed|).  May be
-  // zero.  Subsequent failures will increase the delay up to
-  // |max_backoff_delay|.
-  //
-  // |max_backoff_delay| the maximum amount of time the queue will wait before
-  // dispatching tasks.  May be zero.  Must be greater than or equal to
-  // |initial_backoff_delay|.
-  TaskQueue(const HandleTaskCallback& callback,
-            const base::TimeDelta& initial_backoff_delay,
-            const base::TimeDelta& max_backoff_delay);
-
-  ~TaskQueue();
-
-  // Add |task| to the end of the queue.
-  //
-  // If |task| is already present (as determined by operator==) it is not added.
-  void AddToQueue(const T& task);
-
-  // Mark |task| as completing successfully.
-  //
-  // Marking a task as completing successfully will reduce or eliminate any
-  // backoff delay in effect.
-  //
-  // May only be called after the HandleTaskCallback has been invoked with
-  // |task|.
-  void MarkAsSucceeded(const T& task);
-
-  // Mark |task| as failed.
-  //
-  // Marking a task as failed will cause a backoff, i.e. a delay in dispatching
-  // of subsequent tasks.  Repeated failures will increase the delay.
-  //
-  // May only be called after the HandleTaskCallback has been invoked with
-  // |task|.
-  void MarkAsFailed(const T& task);
-
-  // Cancel |task|.
-  //
-  // |task| is removed from the queue and will not be retried.  Does not affect
-  // the backoff delay.
-  //
-  // May only be called after the HandleTaskCallback has been invoked with
-  // |task|.
-  void Cancel(const T& task);
-
-  // Reset any backoff delay and resume dispatching of tasks.
-  //
-  // Useful for when you know the cause of previous failures has been resolved
-  // and you want don't want to wait for the accumulated backoff delay to
-  // elapse.
-  void ResetBackoff();
-
-  // Use |timer| for scheduled events.
-  //
-  // Used in tests.  See also MockTimer.
-  void SetTimerForTest(std::unique_ptr<base::Timer> timer);
-
- private:
-  void FinishTask(const T& task);
-  void ScheduleDispatch();
-  void Dispatch();
-  // Return true if we should dispatch tasks.
-  bool ShouldDispatch();
-
-  const HandleTaskCallback process_callback_;
-  net::BackoffEntry::Policy backoff_policy_;
-  std::unique_ptr<net::BackoffEntry> backoff_entry_;
-  // The number of tasks currently being handled.
-  int num_in_progress_;
-  base::circular_deque<T> queue_;
-  // The set of tasks in queue_ or currently being handled.
-  std::set<T> tasks_;
-  base::Closure dispatch_closure_;
-  std::unique_ptr<base::Timer> backoff_timer_;
-  base::TimeDelta delay_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  // Must be last data member.
-  base::WeakPtrFactory<TaskQueue> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(TaskQueue);
-};
-
-// The maximum number of tasks that may be concurrently executed.  Think
-// carefully before changing this value.  The desired behavior of backoff may
-// not be obvious when there is more than one concurrent task
-const int kMaxConcurrentTasks = 1;
-
-template <typename T>
-TaskQueue<T>::TaskQueue(const HandleTaskCallback& callback,
-                        const base::TimeDelta& initial_backoff_delay,
-                        const base::TimeDelta& max_backoff_delay)
-    : process_callback_(callback),
-      backoff_policy_({}),
-      num_in_progress_(0),
-      weak_ptr_factory_(this) {
-  DCHECK_LE(initial_backoff_delay.InMicroseconds(),
-            max_backoff_delay.InMicroseconds());
-  backoff_policy_.initial_delay_ms = initial_backoff_delay.InMilliseconds();
-  backoff_policy_.multiply_factor = 2.0;
-  backoff_policy_.jitter_factor = 0.1;
-  backoff_policy_.maximum_backoff_ms = max_backoff_delay.InMilliseconds();
-  backoff_policy_.entry_lifetime_ms = -1;
-  backoff_policy_.always_use_initial_delay = false;
-  backoff_entry_ = std::make_unique<net::BackoffEntry>(&backoff_policy_);
-  dispatch_closure_ =
-      base::Bind(&TaskQueue::Dispatch, weak_ptr_factory_.GetWeakPtr());
-  backoff_timer_ = std::make_unique<base::Timer>(false, false);
-}
-
-template <typename T>
-TaskQueue<T>::~TaskQueue() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-template <typename T>
-void TaskQueue<T>::AddToQueue(const T& task) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // Ignore duplicates.
-  if (tasks_.find(task) == tasks_.end()) {
-    queue_.push_back(task);
-    tasks_.insert(task);
-  }
-  ScheduleDispatch();
-}
-
-template <typename T>
-void TaskQueue<T>::MarkAsSucceeded(const T& task) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  FinishTask(task);
-  // The task succeeded.  Stop any pending timer, reset (clear) the backoff, and
-  // reschedule a dispatch.
-  backoff_timer_->Stop();
-  backoff_entry_->Reset();
-  ScheduleDispatch();
-}
-
-template <typename T>
-void TaskQueue<T>::MarkAsFailed(const T& task) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  FinishTask(task);
-  backoff_entry_->InformOfRequest(false);
-  ScheduleDispatch();
-}
-
-template <typename T>
-void TaskQueue<T>::Cancel(const T& task) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  FinishTask(task);
-  ScheduleDispatch();
-}
-
-template <typename T>
-void TaskQueue<T>::ResetBackoff() {
-  backoff_timer_->Stop();
-  backoff_entry_->Reset();
-  ScheduleDispatch();
-}
-
-template <typename T>
-void TaskQueue<T>::SetTimerForTest(std::unique_ptr<base::Timer> timer) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(timer.get());
-  backoff_timer_ = std::move(timer);
-}
-
-template <typename T>
-void TaskQueue<T>::FinishTask(const T& task) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK_GE(num_in_progress_, 1);
-  --num_in_progress_;
-  const size_t num_erased = tasks_.erase(task);
-  DCHECK_EQ(1U, num_erased);
-}
-
-template <typename T>
-void TaskQueue<T>::ScheduleDispatch() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (backoff_timer_->IsRunning() || !ShouldDispatch()) {
-    return;
-  }
-
-  backoff_timer_->Start(FROM_HERE, backoff_entry_->GetTimeUntilRelease(),
-                        dispatch_closure_);
-}
-
-template <typename T>
-void TaskQueue<T>::Dispatch() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (!ShouldDispatch()) {
-    return;
-  }
-
-  DCHECK(!queue_.empty());
-  const T& task = queue_.front();
-  ++num_in_progress_;
-  DCHECK_LE(num_in_progress_, kMaxConcurrentTasks);
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE, base::Bind(process_callback_, task));
-  queue_.pop_front();
-}
-
-template <typename T>
-bool TaskQueue<T>::ShouldDispatch() {
-  return num_in_progress_ < kMaxConcurrentTasks && !queue_.empty();
-}
-
-}  // namespace syncer
-
-#endif  // COMPONENTS_SYNC_MODEL_IMPL_ATTACHMENTS_TASK_QUEUE_H_
diff --git a/components/sync/model_impl/attachments/task_queue_unittest.cc b/components/sync/model_impl/attachments/task_queue_unittest.cc
deleted file mode 100644
index 1119d83..0000000
--- a/components/sync/model_impl/attachments/task_queue_unittest.cc
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2014 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/sync/model_impl/attachments/task_queue.h"
-
-#include <vector>
-
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/timer/mock_timer.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using base::TimeDelta;
-
-namespace syncer {
-
-namespace {
-
-const TimeDelta kZero;
-
-}  // namespace
-
-class TaskQueueTest : public testing::Test {
- protected:
-  TaskQueueTest() : weak_ptr_factory_(this) {
-    queue_ = std::make_unique<TaskQueue<int>>(
-        base::Bind(&TaskQueueTest::Process, weak_ptr_factory_.GetWeakPtr()),
-        TimeDelta::FromMinutes(1), TimeDelta::FromMinutes(8));
-  }
-
-  void RunLoop() {
-    base::RunLoop run_loop;
-    run_loop.RunUntilIdle();
-  }
-
-  void Process(const int& task) { dispatched_.push_back(task); }
-
-  base::MessageLoop message_loop_;
-  std::unique_ptr<TaskQueue<int>> queue_;
-  std::vector<int> dispatched_;
-  base::WeakPtrFactory<TaskQueueTest> weak_ptr_factory_;
-};
-
-// See that at most one task is dispatched at a time.
-TEST_F(TaskQueueTest, AddToQueue_NoConcurrentTasks) {
-  queue_->AddToQueue(1);
-  queue_->AddToQueue(2);
-  RunLoop();
-
-  // Only one has been dispatched.
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(1, dispatched_.front());
-  RunLoop();
-
-  // Still only one.
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(1, dispatched_.front());
-  dispatched_.clear();
-  queue_->MarkAsSucceeded(1);
-  RunLoop();
-
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(2, dispatched_.front());
-  dispatched_.clear();
-  queue_->MarkAsSucceeded(2);
-  RunLoop();
-
-  ASSERT_TRUE(dispatched_.empty());
-}
-
-// See that that the queue ignores duplicate adds.
-TEST_F(TaskQueueTest, AddToQueue_NoDuplicates) {
-  queue_->AddToQueue(1);
-  queue_->AddToQueue(1);
-  queue_->AddToQueue(2);
-  queue_->AddToQueue(1);
-  ASSERT_TRUE(dispatched_.empty());
-  RunLoop();
-
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(1, dispatched_.front());
-  dispatched_.clear();
-  queue_->MarkAsSucceeded(1);
-  RunLoop();
-
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(2, dispatched_.front());
-  dispatched_.clear();
-  queue_->MarkAsSucceeded(2);
-  RunLoop();
-
-  ASSERT_TRUE(dispatched_.empty());
-}
-
-// See that Retry works as expected.
-TEST_F(TaskQueueTest, Retry) {
-  std::unique_ptr<base::MockTimer> timer_to_pass(
-      new base::MockTimer(false, false));
-  base::MockTimer* mock_timer = timer_to_pass.get();
-  queue_->SetTimerForTest(std::move(timer_to_pass));
-
-  // 1st attempt.
-  queue_->AddToQueue(1);
-  ASSERT_TRUE(mock_timer->IsRunning());
-  ASSERT_EQ(kZero, mock_timer->GetCurrentDelay());
-  TimeDelta last_delay = mock_timer->GetCurrentDelay();
-  mock_timer->Fire();
-  RunLoop();
-
-  // 2nd attempt.
-  ASSERT_FALSE(mock_timer->IsRunning());
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(1, dispatched_.front());
-  dispatched_.clear();
-  queue_->MarkAsFailed(1);
-  queue_->AddToQueue(1);
-  ASSERT_TRUE(mock_timer->IsRunning());
-  EXPECT_GT(mock_timer->GetCurrentDelay(), last_delay);
-  EXPECT_LE(mock_timer->GetCurrentDelay(), TimeDelta::FromMinutes(1));
-  last_delay = mock_timer->GetCurrentDelay();
-  mock_timer->Fire();
-  RunLoop();
-
-  // 3rd attempt.
-  ASSERT_FALSE(mock_timer->IsRunning());
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(1, dispatched_.front());
-  dispatched_.clear();
-  queue_->MarkAsFailed(1);
-  queue_->AddToQueue(1);
-  ASSERT_TRUE(mock_timer->IsRunning());
-  EXPECT_GT(mock_timer->GetCurrentDelay(), last_delay);
-  last_delay = mock_timer->GetCurrentDelay();
-  mock_timer->Fire();
-  RunLoop();
-
-  // Give up.
-  ASSERT_FALSE(mock_timer->IsRunning());
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(1, dispatched_.front());
-  dispatched_.clear();
-  queue_->Cancel(1);
-  ASSERT_FALSE(mock_timer->IsRunning());
-
-  // Try a different task.  See the timer remains unchanged because the previous
-  // task was cancelled.
-  ASSERT_TRUE(dispatched_.empty());
-  queue_->AddToQueue(2);
-  ASSERT_TRUE(mock_timer->IsRunning());
-  EXPECT_GE(last_delay, mock_timer->GetCurrentDelay());
-  last_delay = mock_timer->GetCurrentDelay();
-  mock_timer->Fire();
-  RunLoop();
-
-  // Mark this one as succeeding, which will clear the backoff delay.
-  ASSERT_FALSE(mock_timer->IsRunning());
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(2, dispatched_.front());
-  dispatched_.clear();
-  queue_->MarkAsSucceeded(2);
-  ASSERT_FALSE(mock_timer->IsRunning());
-
-  // Add one last task and see that it's dispatched without delay because the
-  // previous one succeeded.
-  ASSERT_TRUE(dispatched_.empty());
-  queue_->AddToQueue(3);
-  ASSERT_TRUE(mock_timer->IsRunning());
-  EXPECT_LT(mock_timer->GetCurrentDelay(), last_delay);
-  last_delay = mock_timer->GetCurrentDelay();
-  mock_timer->Fire();
-  RunLoop();
-
-  // Clean up.
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(3, dispatched_.front());
-  dispatched_.clear();
-  queue_->MarkAsSucceeded(3);
-  ASSERT_FALSE(mock_timer->IsRunning());
-}
-
-TEST_F(TaskQueueTest, Cancel) {
-  queue_->AddToQueue(1);
-  RunLoop();
-
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(1, dispatched_.front());
-  dispatched_.clear();
-  queue_->Cancel(1);
-  RunLoop();
-
-  ASSERT_TRUE(dispatched_.empty());
-}
-
-// See that ResetBackoff resets the backoff delay.
-TEST_F(TaskQueueTest, ResetBackoff) {
-  std::unique_ptr<base::MockTimer> timer_to_pass(
-      new base::MockTimer(false, false));
-  base::MockTimer* mock_timer = timer_to_pass.get();
-  queue_->SetTimerForTest(std::move(timer_to_pass));
-
-  // Add an item, mark it as failed, re-add it and see that we now have a
-  // backoff delay.
-  queue_->AddToQueue(1);
-  ASSERT_TRUE(mock_timer->IsRunning());
-  ASSERT_EQ(kZero, mock_timer->GetCurrentDelay());
-  mock_timer->Fire();
-  RunLoop();
-  ASSERT_FALSE(mock_timer->IsRunning());
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(1, dispatched_.front());
-  dispatched_.clear();
-  queue_->MarkAsFailed(1);
-  queue_->AddToQueue(1);
-  ASSERT_TRUE(mock_timer->IsRunning());
-  EXPECT_GT(mock_timer->GetCurrentDelay(), kZero);
-  EXPECT_LE(mock_timer->GetCurrentDelay(), TimeDelta::FromMinutes(1));
-
-  // Call ResetBackoff and see that there is no longer a delay.
-  queue_->ResetBackoff();
-  ASSERT_TRUE(mock_timer->IsRunning());
-  ASSERT_EQ(kZero, mock_timer->GetCurrentDelay());
-  mock_timer->Fire();
-  RunLoop();
-  ASSERT_FALSE(mock_timer->IsRunning());
-  ASSERT_EQ(1U, dispatched_.size());
-  EXPECT_EQ(1, dispatched_.front());
-  dispatched_.clear();
-  queue_->MarkAsSucceeded(1);
-}
-
-}  // namespace syncer
diff --git a/components/sync/syncable/base_node.cc b/components/sync/syncable/base_node.cc
index e69125f..c6521ac0 100644
--- a/components/sync/syncable/base_node.cc
+++ b/components/sync/syncable/base_node.cc
@@ -260,16 +260,6 @@
   return GetEntry()->GetModelType();
 }
 
-const AttachmentIdList BaseNode::GetAttachmentIds() const {
-  AttachmentIdList result;
-  const sync_pb::AttachmentMetadata& metadata =
-      GetEntry()->GetAttachmentMetadata();
-  for (int i = 0; i < metadata.record_size(); ++i) {
-    result.push_back(AttachmentId::CreateFromProto(metadata.record(i).id()));
-  }
-  return result;
-}
-
 void BaseNode::SetUnencryptedSpecifics(
     const sync_pb::EntitySpecifics& specifics) {
   ModelType type = GetModelTypeFromSpecifics(specifics);
diff --git a/components/sync/syncable/base_node.h b/components/sync/syncable/base_node.h
index fc3a765..7c70ead 100644
--- a/components/sync/syncable/base_node.h
+++ b/components/sync/syncable/base_node.h
@@ -16,7 +16,6 @@
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "components/sync/base/model_type.h"
-#include "components/sync/model/attachments/attachment.h"
 #include "components/sync/protocol/sync.pb.h"
 #include "url/gurl.h"
 
@@ -166,9 +165,6 @@
   // (ie. non-bookmarks).
   int GetPositionIndex() const;
 
-  // Returns this item's attachment ids.
-  const AttachmentIdList GetAttachmentIds() const;
-
   // Returns a base::DictionaryValue serialization of this node.
   std::unique_ptr<base::DictionaryValue> ToValue() const;
 
diff --git a/components/sync/syncable/directory.cc b/components/sync/syncable/directory.cc
index 37852d30..30e56b0 100644
--- a/components/sync/syncable/directory.cc
+++ b/components/sync/syncable/directory.cc
@@ -21,7 +21,6 @@
 #include "base/trace_event/memory_usage_estimator.h"
 #include "base/trace_event/process_memory_dump.h"
 #include "base/trace_event/trace_event.h"
-#include "components/sync/base/attachment_id_proto.h"
 #include "components/sync/base/unique_position.h"
 #include "components/sync/base/unrecoverable_error_handler.h"
 #include "components/sync/protocol/proto_memory_estimations.h"
@@ -174,7 +173,6 @@
         << "Unexpected duplicate use of ID";
     kernel_->ids_map[entry->ref(ID).value()] = entry;
     DCHECK(!entry->is_dirty());
-    AddToAttachmentIndex(lock, metahandle, entry->ref(ATTACHMENT_METADATA));
   }
 }
 
@@ -385,8 +383,6 @@
       return false;
     }
   }
-  AddToAttachmentIndex(lock, entry_ptr->ref(META_HANDLE),
-                       entry_ptr->ref(ATTACHMENT_METADATA));
 
   // Should NEVER be created with a client tag or server tag.
   if (!SyncAssert(entry_ptr->ref(UNIQUE_SERVER_TAG).empty(), FROM_HERE,
@@ -450,67 +446,6 @@
   }
 }
 
-void Directory::RemoveFromAttachmentIndex(
-    const ScopedKernelLock& lock,
-    const int64_t metahandle,
-    const sync_pb::AttachmentMetadata& attachment_metadata) {
-  for (int i = 0; i < attachment_metadata.record_size(); ++i) {
-    AttachmentIdUniqueId unique_id =
-        attachment_metadata.record(i).id().unique_id();
-    IndexByAttachmentId::iterator iter =
-        kernel_->index_by_attachment_id.find(unique_id);
-    if (iter != kernel_->index_by_attachment_id.end()) {
-      iter->second.erase(metahandle);
-      if (iter->second.empty()) {
-        kernel_->index_by_attachment_id.erase(iter);
-      }
-    }
-  }
-}
-
-void Directory::AddToAttachmentIndex(
-    const ScopedKernelLock& lock,
-    const int64_t metahandle,
-    const sync_pb::AttachmentMetadata& attachment_metadata) {
-  for (int i = 0; i < attachment_metadata.record_size(); ++i) {
-    AttachmentIdUniqueId unique_id =
-        attachment_metadata.record(i).id().unique_id();
-    IndexByAttachmentId::iterator iter =
-        kernel_->index_by_attachment_id.find(unique_id);
-    if (iter == kernel_->index_by_attachment_id.end()) {
-      iter = kernel_->index_by_attachment_id
-                 .insert(std::make_pair(unique_id, MetahandleSet()))
-                 .first;
-    }
-    iter->second.insert(metahandle);
-  }
-}
-
-void Directory::UpdateAttachmentIndex(
-    const int64_t metahandle,
-    const sync_pb::AttachmentMetadata& old_metadata,
-    const sync_pb::AttachmentMetadata& new_metadata) {
-  ScopedKernelLock lock(this);
-  RemoveFromAttachmentIndex(lock, metahandle, old_metadata);
-  AddToAttachmentIndex(lock, metahandle, new_metadata);
-}
-
-void Directory::GetMetahandlesByAttachmentId(
-    BaseTransaction* trans,
-    const sync_pb::AttachmentIdProto& attachment_id_proto,
-    Metahandles* result) {
-  DCHECK(result);
-  result->clear();
-  ScopedKernelLock lock(this);
-  IndexByAttachmentId::const_iterator index_iter =
-      kernel_->index_by_attachment_id.find(attachment_id_proto.unique_id());
-  if (index_iter == kernel_->index_by_attachment_id.end())
-    return;
-  const MetahandleSet& metahandle_set = index_iter->second;
-  std::copy(metahandle_set.begin(), metahandle_set.end(),
-            back_inserter(*result));
-}
-
 bool Directory::unrecoverable_error_set(const BaseTransaction* trans) const {
   DCHECK(trans != nullptr);
   return unrecoverable_error_set_;
@@ -639,8 +574,6 @@
       if (!SyncAssert(!kernel_->parent_child_index.Contains(entry.get()),
                       FROM_HERE, "Deleted entry still present", (&trans)))
         return false;
-      RemoveFromAttachmentIndex(lock, entry->ref(META_HANDLE),
-                                entry->ref(ATTACHMENT_METADATA));
     }
     if (trans.unrecoverable_error_set())
       return false;
@@ -738,7 +671,6 @@
     num_erased = kernel_->server_tags_map.erase(entry->ref(UNIQUE_SERVER_TAG));
     DCHECK_EQ(1u, num_erased);
   }
-  RemoveFromAttachmentIndex(lock, handle, entry->ref(ATTACHMENT_METADATA));
 
   if (save_to_journal) {
     entries_to_journal->insert(std::move(entry));
@@ -852,17 +784,6 @@
   return true;
 }
 
-bool Directory::IsAttachmentLinked(
-    const sync_pb::AttachmentIdProto& attachment_id_proto) const {
-  ScopedKernelLock lock(this);
-  IndexByAttachmentId::const_iterator iter =
-      kernel_->index_by_attachment_id.find(attachment_id_proto.unique_id());
-  if (iter != kernel_->index_by_attachment_id.end() && !iter->second.empty()) {
-    return true;
-  }
-  return false;
-}
-
 void Directory::HandleSaveChangesFailure(const SaveChangesSnapshot& snapshot) {
   WriteTransaction trans(FROM_HERE, HANDLE_SAVE_FAILURE, this);
   ScopedKernelLock lock(this);
@@ -929,7 +850,6 @@
         EstimateMemoryUsage(kernel_->server_tags_map) +
         EstimateMemoryUsage(kernel_->client_tags_map) +
         EstimateMemoryUsage(kernel_->parent_child_index) +
-        EstimateMemoryUsage(kernel_->index_by_attachment_id) +
         EstimateMemoryUsage(kernel_->unapplied_update_metahandles) +
         EstimateMemoryUsage(kernel_->unsynced_metahandles) +
         EstimateMemoryUsage(kernel_->dirty_metahandles) +
@@ -1603,58 +1523,6 @@
   entry->kernel_->clear_dirty(&kernel_->dirty_metahandles);
 }
 
-void Directory::GetAttachmentIdsToUpload(BaseTransaction* trans,
-                                         ModelType type,
-                                         AttachmentIdList* ids) {
-  // TODO(maniscalco): Maintain an index by ModelType and rewrite this method to
-  // use it.  The approach below is likely very expensive because it iterates
-  // all entries (bug 415199).
-  DCHECK(trans);
-  DCHECK(ids);
-  ids->clear();
-  AttachmentIdSet on_server_id_set;
-  AttachmentIdSet not_on_server_id_set;
-  std::vector<int64_t> metahandles;
-  {
-    ScopedKernelLock lock(this);
-    GetMetaHandlesOfType(lock, trans, type, &metahandles);
-    std::vector<int64_t>::const_iterator iter = metahandles.begin();
-    const std::vector<int64_t>::const_iterator end = metahandles.end();
-    // For all of this type's entries...
-    for (; iter != end; ++iter) {
-      EntryKernel* entry = GetEntryByHandle(lock, *iter);
-      DCHECK(entry);
-      const sync_pb::AttachmentMetadata metadata =
-          entry->ref(ATTACHMENT_METADATA);
-      // for each of this entry's attachments...
-      for (int i = 0; i < metadata.record_size(); ++i) {
-        AttachmentId id =
-            AttachmentId::CreateFromProto(metadata.record(i).id());
-        // if this attachment is known to be on the server, remember it for
-        // later,
-        if (metadata.record(i).is_on_server()) {
-          on_server_id_set.insert(id);
-        } else {
-          // otherwise, add it to id_set.
-          not_on_server_id_set.insert(id);
-        }
-      }
-    }
-  }
-  // Why did we bother keeping a set of ids known to be on the server?  The
-  // is_on_server flag is stored denormalized so we can end up with two entries
-  // with the same attachment id where one says it's on the server and the other
-  // says it's not.  When this happens, we trust the one that says it's on the
-  // server.  To avoid re-uploading the same attachment mulitple times, we
-  // remove any ids known to be on the server from the id_set we are about to
-  // return.
-  //
-  // TODO(maniscalco): Eliminate redundant metadata storage (bug 415203).
-  std::set_difference(not_on_server_id_set.begin(), not_on_server_id_set.end(),
-                      on_server_id_set.begin(), on_server_id_set.end(),
-                      std::back_inserter(*ids));
-}
-
 void Directory::OnCatastrophicError() {
   UMA_HISTOGRAM_BOOLEAN("Sync.DirectoryCatastrophicError", true);
   ReadTransaction trans(FROM_HERE, this);
diff --git a/components/sync/syncable/directory.h b/components/sync/syncable/directory.h
index e8e6f4c..71b783f9 100644
--- a/components/sync/syncable/directory.h
+++ b/components/sync/syncable/directory.h
@@ -22,7 +22,6 @@
 #include "base/macros.h"
 #include "base/values.h"
 #include "components/sync/base/weak_handle.h"
-#include "components/sync/model/attachments/attachment_id.h"
 #include "components/sync/syncable/dir_open_result.h"
 #include "components/sync/syncable/entry.h"
 #include "components/sync/syncable/entry_kernel.h"
@@ -73,9 +72,6 @@
       std::unordered_map<int64_t, std::unique_ptr<EntryKernel>>;
   using IdsMap = std::unordered_map<std::string, EntryKernel*>;
   using TagsMap = std::unordered_map<std::string, EntryKernel*>;
-  using AttachmentIdUniqueId = std::string;
-  using IndexByAttachmentId =
-      std::unordered_map<AttachmentIdUniqueId, MetahandleSet>;
 
   static const base::FilePath::CharType kSyncDatabaseFilename[];
 
@@ -200,17 +196,6 @@
     // within parent.  Protected by the ScopedKernelLock.
     ParentChildIndex parent_child_index;
 
-    // This index keeps track of which metahandles refer to a given attachment.
-    // Think of it as the inverse of EntryKernel's AttachmentMetadata Records.
-    //
-    // Because entries can be undeleted (e.g. PutIsDel(false)), entries should
-    // not removed from the index until they are actually deleted from memory.
-    //
-    // All access should go through IsAttachmentLinked,
-    // RemoveFromAttachmentIndex, AddToAttachmentIndex, and
-    // UpdateAttachmentIndex methods to avoid iterator invalidation errors.
-    IndexByAttachmentId index_by_attachment_id;
-
     // 3 in-memory indices on bits used extremely frequently by the syncer.
     // |unapplied_update_metahandles| is keyed by the server model type.
     MetahandleSet unapplied_update_metahandles[MODEL_TYPE_COUNT];
@@ -477,42 +462,15 @@
   // WARNING! This can be slow, as it iterates over all entries for a type.
   bool ResetVersionsForType(BaseWriteTransaction* trans, ModelType type);
 
-  // Returns true iff the attachment identified by |attachment_id_proto| is
-  // linked to an entry.
-  //
-  // An attachment linked to a deleted entry is still considered linked if the
-  // entry hasn't yet been purged.
-  bool IsAttachmentLinked(
-      const sync_pb::AttachmentIdProto& attachment_id_proto) const;
-
-  // Given attachment id return metahandles to all entries that reference this
-  // attachment.
-  void GetMetahandlesByAttachmentId(
-      BaseTransaction* trans,
-      const sync_pb::AttachmentIdProto& attachment_id_proto,
-      Metahandles* result);
-
   // Change entry to not dirty. Used in special case when we don't want to
   // persist modified entry on disk. e.g. SyncBackupManager uses this to
   // preserve sync preferences in DB on disk.
   void UnmarkDirtyEntry(WriteTransaction* trans, Entry* entry);
 
-  // Clears |ids| and fills it with the ids of attachments that need to be
-  // uploaded to the sync server.
-  void GetAttachmentIdsToUpload(BaseTransaction* trans,
-                                ModelType type,
-                                AttachmentIdList* ids);
-
   // For new entry creation only.
   bool InsertEntry(BaseWriteTransaction* trans,
                    std::unique_ptr<EntryKernel> entry);
 
-  // Update the attachment index for |metahandle| removing it from the index
-  // under |old_metadata| entries and add it under |new_metadata| entries.
-  void UpdateAttachmentIndex(const int64_t metahandle,
-                             const sync_pb::AttachmentMetadata& old_metadata,
-                             const sync_pb::AttachmentMetadata& new_metadata);
-
   virtual EntryKernel* GetEntryById(const Id& id);
   virtual EntryKernel* GetEntryByClientTag(const std::string& tag);
   EntryKernel* GetEntryByServerTag(const std::string& tag);
@@ -564,18 +522,6 @@
                    BaseWriteTransaction* trans,
                    std::unique_ptr<EntryKernel> entry);
 
-  // Remove each of |metahandle|'s attachment ids from index_by_attachment_id.
-  void RemoveFromAttachmentIndex(
-      const ScopedKernelLock& lock,
-      const int64_t metahandle,
-      const sync_pb::AttachmentMetadata& attachment_metadata);
-
-  // Add each of |metahandle|'s attachment ids to the index_by_attachment_id.
-  void AddToAttachmentIndex(
-      const ScopedKernelLock& lock,
-      const int64_t metahandle,
-      const sync_pb::AttachmentMetadata& attachment_metadata);
-
   void ClearDirtyMetahandles(const ScopedKernelLock& lock);
 
   DirOpenResult OpenImpl(
diff --git a/components/sync/syncable/directory_unittest.cc b/components/sync/syncable/directory_unittest.cc
index 53ed39d..46f76e85 100644
--- a/components/sync/syncable/directory_unittest.cc
+++ b/components/sync/syncable/directory_unittest.cc
@@ -13,7 +13,6 @@
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/values_test_util.h"
-#include "components/sync/base/attachment_id_proto.h"
 #include "components/sync/base/mock_unrecoverable_error_handler.h"
 #include "components/sync/syncable/syncable_proto_util.h"
 #include "components/sync/syncable/syncable_util.h"
@@ -107,20 +106,10 @@
 void SyncableDirectoryTest::CreateEntry(const ModelType& model_type,
                                         const std::string& entryname,
                                         const Id& id) {
-  CreateEntryWithAttachmentMetadata(model_type, entryname, id,
-                                    sync_pb::AttachmentMetadata());
-}
-
-void SyncableDirectoryTest::CreateEntryWithAttachmentMetadata(
-    const ModelType& model_type,
-    const std::string& entryname,
-    const Id& id,
-    const sync_pb::AttachmentMetadata& attachment_metadata) {
   WriteTransaction wtrans(FROM_HERE, UNITTEST, dir_.get());
   MutableEntry me(&wtrans, CREATE, model_type, wtrans.root_id(), entryname);
   ASSERT_TRUE(me.good());
   me.PutId(id);
-  me.PutAttachmentMetadata(attachment_metadata);
   me.PutIsUnsynced(true);
 }
 
@@ -1705,198 +1694,6 @@
   }
 }
 
-// Verify that Directory is notifed when a MutableEntry's AttachmentMetadata
-// changes.
-TEST_F(SyncableDirectoryTest, MutableEntry_PutAttachmentMetadata) {
-  sync_pb::AttachmentMetadata attachment_metadata;
-  sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
-  sync_pb::AttachmentIdProto attachment_id_proto =
-      CreateAttachmentIdProto(0, 0);
-  *record->mutable_id() = attachment_id_proto;
-  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
-  {
-    WriteTransaction trans(FROM_HERE, UNITTEST, dir().get());
-
-    // Create an entry with attachment metadata and see that the attachment id
-    // is not linked.
-    MutableEntry entry(&trans, CREATE, PREFERENCES, trans.root_id(),
-                       "some entry");
-    entry.PutId(TestIdFactory::FromNumber(-1));
-    entry.PutIsUnsynced(true);
-
-    Directory::Metahandles metahandles;
-    ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
-    dir()->GetMetahandlesByAttachmentId(&trans, attachment_id_proto,
-                                        &metahandles);
-    ASSERT_TRUE(metahandles.empty());
-
-    // Now add the attachment metadata and see that Directory believes it is
-    // linked.
-    entry.PutAttachmentMetadata(attachment_metadata);
-    ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
-    dir()->GetMetahandlesByAttachmentId(&trans, attachment_id_proto,
-                                        &metahandles);
-    ASSERT_FALSE(metahandles.empty());
-    ASSERT_EQ(metahandles[0], entry.GetMetahandle());
-
-    // Clear out the attachment metadata and see that it's no longer linked.
-    sync_pb::AttachmentMetadata empty_attachment_metadata;
-    entry.PutAttachmentMetadata(empty_attachment_metadata);
-    ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
-    dir()->GetMetahandlesByAttachmentId(&trans, attachment_id_proto,
-                                        &metahandles);
-    ASSERT_TRUE(metahandles.empty());
-  }
-  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
-}
-
-// Verify that UpdateAttachmentId updates attachment_id and is_on_server flag.
-TEST_F(SyncableDirectoryTest, MutableEntry_UpdateAttachmentId) {
-  sync_pb::AttachmentMetadata attachment_metadata;
-  sync_pb::AttachmentMetadataRecord* r1 = attachment_metadata.add_record();
-  sync_pb::AttachmentMetadataRecord* r2 = attachment_metadata.add_record();
-  *r1->mutable_id() = CreateAttachmentIdProto(0, 0);
-  *r2->mutable_id() = CreateAttachmentIdProto(0, 0);
-  sync_pb::AttachmentIdProto attachment_id_proto = r1->id();
-
-  WriteTransaction trans(FROM_HERE, UNITTEST, dir().get());
-
-  MutableEntry entry(&trans, CREATE, PREFERENCES, trans.root_id(),
-                     "some entry");
-  entry.PutId(TestIdFactory::FromNumber(-1));
-  entry.PutAttachmentMetadata(attachment_metadata);
-
-  {
-    const sync_pb::AttachmentMetadata& entry_metadata =
-        entry.GetAttachmentMetadata();
-    ASSERT_EQ(2, entry_metadata.record_size());
-    ASSERT_FALSE(entry_metadata.record(0).is_on_server());
-    ASSERT_FALSE(entry_metadata.record(1).is_on_server());
-    ASSERT_FALSE(entry.GetIsUnsynced());
-  }
-
-  entry.MarkAttachmentAsOnServer(attachment_id_proto);
-
-  {
-    // Re-get entry_metadata because it is immutable in the directory and
-    // entry_metadata reference has been made invalid by
-    // MarkAttachmentAsOnServer call above.
-    const sync_pb::AttachmentMetadata& entry_metadata =
-        entry.GetAttachmentMetadata();
-    ASSERT_TRUE(entry_metadata.record(0).is_on_server());
-    ASSERT_FALSE(entry_metadata.record(1).is_on_server());
-    ASSERT_TRUE(entry.GetIsUnsynced());
-  }
-}
-
-// Verify that deleted entries with attachments will retain the attachments.
-TEST_F(SyncableDirectoryTest, Directory_DeleteDoesNotUnlinkAttachments) {
-  sync_pb::AttachmentMetadata attachment_metadata;
-  sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
-  sync_pb::AttachmentIdProto attachment_id_proto =
-      CreateAttachmentIdProto(0, 0);
-  *record->mutable_id() = attachment_id_proto;
-  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
-  const Id id = TestIdFactory::FromNumber(-1);
-
-  // Create an entry with attachment metadata and see that the attachment id
-  // is linked.
-  CreateEntryWithAttachmentMetadata(PREFERENCES, "some entry", id,
-                                    attachment_metadata);
-  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
-
-  // Delete the entry and see that it's still linked because the entry hasn't
-  // yet been purged.
-  DeleteEntry(id);
-  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
-
-  // Reload the Directory, purging the deleted entry, and see that the
-  // attachment is no longer linked.
-  SimulateSaveAndReloadDir();
-  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
-}
-
-// Verify that a given attachment can be referenced by multiple entries and that
-// any one of the references is sufficient to ensure it remains linked.
-TEST_F(SyncableDirectoryTest, Directory_LastReferenceUnlinksAttachments) {
-  // Create one attachment.
-  sync_pb::AttachmentMetadata attachment_metadata;
-  sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
-  sync_pb::AttachmentIdProto attachment_id_proto =
-      CreateAttachmentIdProto(0, 0);
-  *record->mutable_id() = attachment_id_proto;
-
-  // Create two entries, each referencing the attachment.
-  const Id id1 = TestIdFactory::FromNumber(-1);
-  const Id id2 = TestIdFactory::FromNumber(-2);
-  CreateEntryWithAttachmentMetadata(PREFERENCES, "some entry", id1,
-                                    attachment_metadata);
-  CreateEntryWithAttachmentMetadata(PREFERENCES, "some other entry", id2,
-                                    attachment_metadata);
-
-  // See that the attachment is considered linked.
-  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
-
-  // Delete the first entry, reload the Directory, see that the attachment is
-  // still linked.
-  DeleteEntry(id1);
-  SimulateSaveAndReloadDir();
-  ASSERT_TRUE(dir()->IsAttachmentLinked(attachment_id_proto));
-
-  // Delete the second entry, reload the Directory, see that the attachment is
-  // no loner linked.
-  DeleteEntry(id2);
-  SimulateSaveAndReloadDir();
-  ASSERT_FALSE(dir()->IsAttachmentLinked(attachment_id_proto));
-}
-
-TEST_F(SyncableDirectoryTest, Directory_GetAttachmentIdsToUpload) {
-  // Create one attachment, referenced by two entries.
-  AttachmentId attachment_id = AttachmentId::Create(0, 0);
-  sync_pb::AttachmentIdProto attachment_id_proto = attachment_id.GetProto();
-  sync_pb::AttachmentMetadata attachment_metadata;
-  sync_pb::AttachmentMetadataRecord* record = attachment_metadata.add_record();
-  *record->mutable_id() = attachment_id_proto;
-  const Id id1 = TestIdFactory::FromNumber(-1);
-  const Id id2 = TestIdFactory::FromNumber(-2);
-  CreateEntryWithAttachmentMetadata(PREFERENCES, "some entry", id1,
-                                    attachment_metadata);
-  CreateEntryWithAttachmentMetadata(PREFERENCES, "some other entry", id2,
-                                    attachment_metadata);
-
-  // See that Directory reports that this attachment is not on the server.
-  AttachmentIdList ids;
-  {
-    ReadTransaction trans(FROM_HERE, dir().get());
-    dir()->GetAttachmentIdsToUpload(&trans, PREFERENCES, &ids);
-  }
-  ASSERT_EQ(1U, ids.size());
-  ASSERT_EQ(attachment_id, *ids.begin());
-
-  // Call again, but this time with a ModelType for which there are no entries.
-  // See that Directory correctly reports that there are none.
-  {
-    ReadTransaction trans(FROM_HERE, dir().get());
-    dir()->GetAttachmentIdsToUpload(&trans, PASSWORDS, &ids);
-  }
-  ASSERT_TRUE(ids.empty());
-
-  // Now, mark the attachment as "on the server" via entry_1.
-  {
-    WriteTransaction trans(FROM_HERE, UNITTEST, dir().get());
-    MutableEntry entry_1(&trans, GET_BY_ID, id1);
-    entry_1.MarkAttachmentAsOnServer(attachment_id_proto);
-  }
-
-  // See that Directory no longer reports that this attachment is not on the
-  // server.
-  {
-    ReadTransaction trans(FROM_HERE, dir().get());
-    dir()->GetAttachmentIdsToUpload(&trans, PREFERENCES, &ids);
-  }
-  ASSERT_TRUE(ids.empty());
-}
-
 // Verify that the directory accepts entries with unset parent ID.
 TEST_F(SyncableDirectoryTest, MutableEntry_ImplicitParentId) {
   TestIdFactory id_factory;
diff --git a/components/sync/syncable/directory_unittest.h b/components/sync/syncable/directory_unittest.h
index d69d2ca..ef87668 100644
--- a/components/sync/syncable/directory_unittest.h
+++ b/components/sync/syncable/directory_unittest.h
@@ -58,12 +58,6 @@
                    const std::string& entryname,
                    const Id& id);
 
-  void CreateEntryWithAttachmentMetadata(
-      const ModelType& model_type,
-      const std::string& entryname,
-      const Id& id,
-      const sync_pb::AttachmentMetadata& attachment_metadata);
-
   void DeleteEntry(const Id& id);
 
   // When a directory is saved then loaded from disk, it will pass through
diff --git a/components/sync/syncable/model_neutral_mutable_entry.cc b/components/sync/syncable/model_neutral_mutable_entry.cc
index 8ad181f..808f65b 100644
--- a/components/sync/syncable/model_neutral_mutable_entry.cc
+++ b/components/sync/syncable/model_neutral_mutable_entry.cc
@@ -419,25 +419,6 @@
   }
 }
 
-void ModelNeutralMutableEntry::PutServerAttachmentMetadata(
-    const sync_pb::AttachmentMetadata& value) {
-  DCHECK(kernel_);
-  const std::string& serialized_value = value.SerializeAsString();
-  if (serialized_value !=
-      kernel_->ref(SERVER_ATTACHMENT_METADATA).SerializeAsString()) {
-    base_write_transaction_->TrackChangesTo(kernel_);
-    // Check for potential sharing - SERVER_ATTACHMENT_METADATA is often
-    // copied from ATTACHMENT_METADATA.
-    if (serialized_value ==
-        kernel_->ref(ATTACHMENT_METADATA).SerializeAsString()) {
-      kernel_->copy(ATTACHMENT_METADATA, SERVER_ATTACHMENT_METADATA);
-    } else {
-      kernel_->put(SERVER_ATTACHMENT_METADATA, value);
-    }
-    MarkDirty();
-  }
-}
-
 void ModelNeutralMutableEntry::PutSyncing(bool value) {
   kernel_->put(SYNCING, value);
 }
diff --git a/components/sync/syncable/model_neutral_mutable_entry.h b/components/sync/syncable/model_neutral_mutable_entry.h
index a844c0b..bf7bd51 100644
--- a/components/sync/syncable/model_neutral_mutable_entry.h
+++ b/components/sync/syncable/model_neutral_mutable_entry.h
@@ -78,7 +78,6 @@
   void PutServerSpecifics(const sync_pb::EntitySpecifics& value);
   void PutBaseServerSpecifics(const sync_pb::EntitySpecifics& value);
   void PutServerUniquePosition(const UniquePosition& value);
-  void PutServerAttachmentMetadata(const sync_pb::AttachmentMetadata& value);
   void PutSyncing(bool value);
   void PutDirtySync(bool value);
 
diff --git a/components/sync/syncable/mutable_entry.cc b/components/sync/syncable/mutable_entry.cc
index a599184..2d11626 100644
--- a/components/sync/syncable/mutable_entry.cc
+++ b/components/sync/syncable/mutable_entry.cc
@@ -233,46 +233,6 @@
   return true;
 }
 
-void MutableEntry::PutAttachmentMetadata(
-    const sync_pb::AttachmentMetadata& value) {
-  DCHECK(kernel_);
-  const std::string& serialized_value = value.SerializeAsString();
-  if (serialized_value !=
-      kernel_->ref(ATTACHMENT_METADATA).SerializeAsString()) {
-    write_transaction()->TrackChangesTo(kernel_);
-    dir()->UpdateAttachmentIndex(GetMetahandle(),
-                                 kernel_->ref(ATTACHMENT_METADATA), value);
-    // Check for potential sharing - ATTACHMENT_METADATA is often
-    // copied from SERVER_ATTACHMENT_METADATA.
-    if (serialized_value ==
-        kernel_->ref(SERVER_ATTACHMENT_METADATA).SerializeAsString()) {
-      kernel_->copy(SERVER_ATTACHMENT_METADATA, ATTACHMENT_METADATA);
-    } else {
-      kernel_->put(ATTACHMENT_METADATA, value);
-    }
-    MarkDirty();
-  }
-}
-
-void MutableEntry::MarkAttachmentAsOnServer(
-    const sync_pb::AttachmentIdProto& attachment_id) {
-  DCHECK(kernel_);
-  DCHECK(!attachment_id.unique_id().empty());
-  write_transaction()->TrackChangesTo(kernel_);
-  sync_pb::AttachmentMetadata attachment_metadata =
-      kernel_->ref(ATTACHMENT_METADATA);
-  for (int i = 0; i < attachment_metadata.record_size(); ++i) {
-    sync_pb::AttachmentMetadataRecord* record =
-        attachment_metadata.mutable_record(i);
-    if (record->id().unique_id() != attachment_id.unique_id())
-      continue;
-    record->set_is_on_server(true);
-  }
-  kernel_->put(ATTACHMENT_METADATA, attachment_metadata);
-  MarkDirty();
-  MarkForSyncing(this);
-}
-
 // static
 std::unique_ptr<EntryKernel> MutableEntry::CreateEntryKernel(
     WriteTransaction* trans,
diff --git a/components/sync/syncable/mutable_entry.h b/components/sync/syncable/mutable_entry.h
index 104b78c..7ad081b 100644
--- a/components/sync/syncable/mutable_entry.h
+++ b/components/sync/syncable/mutable_entry.h
@@ -65,13 +65,6 @@
   // ID to put the node in first position.
   bool PutPredecessor(const Id& predecessor_id);
 
-  void PutAttachmentMetadata(const sync_pb::AttachmentMetadata& value);
-
-  // Update attachment metadata for |attachment_id| to indicate that this
-  // attachment has been uploaded to the sync server.
-  void MarkAttachmentAsOnServer(
-      const sync_pb::AttachmentIdProto& attachment_id);
-
  private:
   static std::unique_ptr<EntryKernel> CreateEntryKernel(
       WriteTransaction* trans,
diff --git a/components/sync/syncable/read_transaction.cc b/components/sync/syncable/read_transaction.cc
index a31e623..0821979 100644
--- a/components/sync/syncable/read_transaction.cc
+++ b/components/sync/syncable/read_transaction.cc
@@ -43,12 +43,6 @@
                                                        context);
 }
 
-void ReadTransaction::GetAttachmentIdsToUpload(ModelType type,
-                                               AttachmentIdList* ids) const {
-  DCHECK(ids);
-  transaction_->directory()->GetAttachmentIdsToUpload(transaction_, type, ids);
-}
-
 std::string ReadTransaction::GetStoreBirthday() const {
   return transaction_->directory()->store_birthday();
 }
diff --git a/components/sync/syncable/read_transaction.h b/components/sync/syncable/read_transaction.h
index b169e4a9..6d0ba93 100644
--- a/components/sync/syncable/read_transaction.h
+++ b/components/sync/syncable/read_transaction.h
@@ -12,7 +12,6 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "components/sync/model/attachments/attachment_id.h"
 #include "components/sync/syncable/base_transaction.h"
 
 namespace base {
@@ -50,10 +49,6 @@
   void GetDataTypeContext(ModelType type,
                           sync_pb::DataTypeContext* context) const;
 
-  // Clear |ids| and fill it with the ids of attachments that need to be
-  // uploaded to the sync server.
-  void GetAttachmentIdsToUpload(ModelType type, AttachmentIdList* ids) const;
-
   // Return the current (opaque) store birthday.
   std::string GetStoreBirthday() const;
 
diff --git a/components/sync/syncable/write_node.cc b/components/sync/syncable/write_node.cc
index 1cda993..d9cd0fd 100644
--- a/components/sync/syncable/write_node.cc
+++ b/components/sync/syncable/write_node.cc
@@ -444,11 +444,6 @@
   return true;
 }
 
-void WriteNode::SetAttachmentMetadata(
-    const sync_pb::AttachmentMetadata& attachment_metadata) {
-  entry_->PutAttachmentMetadata(attachment_metadata);
-}
-
 const syncable::Entry* WriteNode::GetEntry() const {
   return entry_;
 }
diff --git a/components/sync/syncable/write_node.h b/components/sync/syncable/write_node.h
index 9a38887..9a2f6d0 100644
--- a/components/sync/syncable/write_node.h
+++ b/components/sync/syncable/write_node.h
@@ -139,10 +139,6 @@
   // Should only be called if GetModelType() == TYPED_URLS.
   void SetTypedUrlSpecifics(const sync_pb::TypedUrlSpecifics& specifics);
 
-  // Set the attachment metadata.
-  void SetAttachmentMetadata(
-      const sync_pb::AttachmentMetadata& attachment_metadata);
-
   // Implementation of BaseNode's abstract virtual accessors.
   const syncable::Entry* GetEntry() const override;
 
diff --git a/components/sync/syncable/write_transaction.cc b/components/sync/syncable/write_transaction.cc
index 4e130a7..00b248a 100644
--- a/components/sync/syncable/write_transaction.cc
+++ b/components/sync/syncable/write_transaction.cc
@@ -74,16 +74,4 @@
   // See crbug.com/360280
 }
 
-void WriteTransaction::UpdateEntriesMarkAttachmentAsOnServer(
-    const AttachmentId& attachment_id) {
-  syncable::Directory::Metahandles handles;
-  GetDirectory()->GetMetahandlesByAttachmentId(
-      transaction_, attachment_id.GetProto(), &handles);
-  for (syncable::Directory::Metahandles::iterator iter = handles.begin();
-       iter != handles.end(); ++iter) {
-    syncable::MutableEntry entry(transaction_, syncable::GET_BY_HANDLE, *iter);
-    entry.MarkAttachmentAsOnServer(attachment_id.GetProto());
-  }
-}
-
 }  // namespace syncer
diff --git a/components/sync/syncable/write_transaction.h b/components/sync/syncable/write_transaction.h
index 3653574..3d0a353 100644
--- a/components/sync/syncable/write_transaction.h
+++ b/components/sync/syncable/write_transaction.h
@@ -56,10 +56,6 @@
       SyncChangeProcessor::ContextRefreshStatus refresh_status,
       const std::string& context);
 
-  // Update all entries that refer to |attachment_id| indicating that
-  // |attachment_id| has been uploaded to the sync server.
-  void UpdateEntriesMarkAttachmentAsOnServer(const AttachmentId& attachment_id);
-
  protected:
   WriteTransaction() {}
 
diff --git a/components/sync_preferences/pref_service_syncable_unittest.cc b/components/sync_preferences/pref_service_syncable_unittest.cc
index 2da726b..5a1c94e 100644
--- a/components/sync_preferences/pref_service_syncable_unittest.cc
+++ b/components/sync_preferences/pref_service_syncable_unittest.cc
@@ -16,8 +16,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/scoped_user_pref_update.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/sync_change.h"
 #include "components/sync/model/sync_data.h"
 #include "components/sync/model/sync_error_factory_mock.h"
@@ -137,9 +135,7 @@
     pref_one->set_value(serialized);
     return syncer::SyncChange(
         FROM_HERE, type,
-        syncer::SyncData::CreateRemoteData(
-            id, entity, base::Time(), syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create()));
+        syncer::SyncData::CreateRemoteData(id, entity, base::Time()));
   }
 
   void AddToRemoteDataList(const std::string& name,
@@ -152,10 +148,8 @@
     sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference();
     pref_one->set_name(name);
     pref_one->set_value(serialized);
-    out->push_back(SyncData::CreateRemoteData(
-        ++next_pref_remote_sync_node_id_, one, base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    out->push_back(SyncData::CreateRemoteData(++next_pref_remote_sync_node_id_,
+                                              one, base::Time()));
   }
 
   void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data,
@@ -207,9 +201,6 @@
   PrefModelAssociator* pref_sync_service_;
   TestSyncProcessorStub* test_processor_;
 
-  // TODO(tim): Remove this by fixing AttachmentServiceProxyForTest.
-  base::MessageLoop loop_;
-
   int next_pref_remote_sync_node_id_;
 };
 
diff --git a/components/sync_sessions/favicon_cache_unittest.cc b/components/sync_sessions/favicon_cache_unittest.cc
index cde2376..8e910fa7 100644
--- a/components/sync_sessions/favicon_cache_unittest.cc
+++ b/components/sync_sessions/favicon_cache_unittest.cc
@@ -11,8 +11,6 @@
 #include "base/strings/stringprintf.h"
 #include "base/test/scoped_task_environment.h"
 #include "base/time/time.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/sync_change_processor_wrapper_for_test.h"
 #include "components/sync/model/sync_error_factory_mock.h"
 #include "components/sync/model/time.h"
@@ -617,20 +615,12 @@
     sync_pb::EntitySpecifics image_specifics, tracking_specifics;
     FillImageSpecifics(BuildFaviconData(i),
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
   }
 
   syncer::SyncMergeResult merge_result =
@@ -696,20 +686,12 @@
     FillImageSpecifics(test_data,
                        image_specifics.mutable_favicon_image());
 
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(test_data,
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
   }
 
   syncer::SyncMergeResult merge_result =
@@ -781,20 +763,12 @@
     FillImageSpecifics(test_data,
                        image_specifics.mutable_favicon_image());
 
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(test_data,
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
   }
 
   syncer::SyncMergeResult merge_result =
@@ -846,31 +820,17 @@
     sync_pb::EntitySpecifics image_specifics, tracking_specifics;
     FillImageSpecifics(BuildFaviconData(i),
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE);
     image_specifics.mutable_favicon_image()->clear_favicon_web();
     stale_changes.push_back(syncer::SyncChange(
-        FROM_HERE,
-        syncer::SyncChange::ACTION_UPDATE,
-        syncer::SyncData::CreateRemoteData(
-            1,
-            image_specifics,
-            base::Time(),
-            syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create())));
+        FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -899,32 +859,18 @@
     FillImageSpecifics(test_data,
                        image_specifics.mutable_favicon_image());
     new_changes.push_back(syncer::SyncChange(
-        FROM_HERE,
-        syncer::SyncChange::ACTION_UPDATE,
-        syncer::SyncData::CreateRemoteData(
-            1,
-            image_specifics,
-            base::Time(),
-            syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create())));
+        FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())));
     image_specifics.mutable_favicon_image()
         ->mutable_favicon_web()
         ->mutable_favicon()
         ->append("old");
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -947,28 +893,14 @@
     FillImageSpecifics(test_data,
                        image_specifics.mutable_favicon_image());
     same_changes.push_back(syncer::SyncChange(
-        FROM_HERE,
-        syncer::SyncChange::ACTION_UPDATE,
-        syncer::SyncData::CreateRemoteData(
-            1,
-            image_specifics,
-            base::Time(),
-            syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create())));
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -991,31 +923,18 @@
     sync_pb::EntitySpecifics image_specifics, tracking_specifics;
     FillImageSpecifics(BuildFaviconData(i),
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     expected_change_types.push_back(syncer::SyncChange::ACTION_UPDATE);
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
     tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(-1);
-    stale_changes.push_back(syncer::SyncChange(
-        FROM_HERE,
-        syncer::SyncChange::ACTION_UPDATE,
-        syncer::SyncData::CreateRemoteData(
-            1,
-            tracking_specifics,
-            base::Time(),
-            syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create())));
+    stale_changes.push_back(
+        syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+                           syncer::SyncData::CreateRemoteData(
+                               1, tracking_specifics, base::Time())));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1043,30 +962,17 @@
     sync_pb::EntitySpecifics image_specifics, tracking_specifics;
     FillImageSpecifics(BuildFaviconData(i),
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
-    new_changes.push_back(syncer::SyncChange(
-        FROM_HERE,
-        syncer::SyncChange::ACTION_UPDATE,
-        syncer::SyncData::CreateRemoteData(
-            1,
-            tracking_specifics,
-            base::Time(),
-            syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create())));
+    new_changes.push_back(
+        syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+                           syncer::SyncData::CreateRemoteData(
+                               1, tracking_specifics, base::Time())));
     tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(i-1);
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1088,29 +994,16 @@
     sync_pb::EntitySpecifics image_specifics, tracking_specifics;
     FillImageSpecifics(BuildFaviconData(i),
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
-    same_changes.push_back(syncer::SyncChange(
-        FROM_HERE,
-        syncer::SyncChange::ACTION_UPDATE,
-        syncer::SyncData::CreateRemoteData(
-            1,
-            tracking_specifics,
-            base::Time(),
-            syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create())));
+        1, tracking_specifics, base::Time()));
+    same_changes.push_back(
+        syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+                           syncer::SyncData::CreateRemoteData(
+                               1, tracking_specifics, base::Time())));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1129,38 +1022,19 @@
     sync_pb::EntitySpecifics image_specifics, tracking_specifics;
     FillImageSpecifics(BuildFaviconData(i),
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
-    tracking_deletions.push_back(syncer::SyncChange(
-        FROM_HERE,
-        syncer::SyncChange::ACTION_DELETE,
-        syncer::SyncData::CreateRemoteData(
-            1,
-            tracking_specifics,
-            base::Time(),
-            syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create())));
+        1, tracking_specifics, base::Time()));
+    tracking_deletions.push_back(
+        syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_DELETE,
+                           syncer::SyncData::CreateRemoteData(
+                               1, tracking_specifics, base::Time())));
     image_deletions.push_back(syncer::SyncChange(
-        FROM_HERE,
-        syncer::SyncChange::ACTION_DELETE,
-        syncer::SyncData::CreateRemoteData(
-            1,
-            image_specifics,
-            base::Time(),
-            syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create())));
+        FROM_HERE, syncer::SyncChange::ACTION_DELETE,
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1190,20 +1064,12 @@
     sync_pb::EntitySpecifics image_specifics, tracking_specifics;
     FillImageSpecifics(BuildFaviconData(i),
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
     expected_icons.push_back(i);
 
     TestFaviconData favicon = BuildFaviconData(i+kMaxSyncFavicons);
@@ -1261,44 +1127,25 @@
     sync_pb::EntitySpecifics image_specifics, tracking_specifics;
     FillImageSpecifics(BuildFaviconData(i),
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
     // Set up new tracking specifics for the icons received at change time.
     expected_icons.push_back(i + kMaxSyncFavicons);
     FillImageSpecifics(BuildFaviconData(i + kMaxSyncFavicons),
                        image_specifics.mutable_favicon_image());
     image_changes.push_back(syncer::SyncChange(
-        FROM_HERE,
-        syncer::SyncChange::ACTION_ADD,
-        syncer::SyncData::CreateRemoteData(
-            1,
-            image_specifics,
-            base::Time(),
-            syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create())));
+        FROM_HERE, syncer::SyncChange::ACTION_ADD,
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time())));
     FillTrackingSpecifics(BuildFaviconData(i + kMaxSyncFavicons),
                           tracking_specifics.mutable_favicon_tracking());
-    tracking_changes.push_back(syncer::SyncChange(
-        FROM_HERE,
-        syncer::SyncChange::ACTION_ADD,
-        syncer::SyncData::CreateRemoteData(
-            1,
-            tracking_specifics,
-            base::Time(),
-            syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create())));
+    tracking_changes.push_back(
+        syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD,
+                           syncer::SyncData::CreateRemoteData(
+                               1, tracking_specifics, base::Time())));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1451,20 +1298,12 @@
     sync_pb::EntitySpecifics image_specifics, tracking_specifics;
     FillImageSpecifics(test_data,
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1509,20 +1348,12 @@
     sync_pb::EntitySpecifics image_specifics, tracking_specifics;
     FillImageSpecifics(test_data,
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
   }
 
   SetUpInitialSync(initial_image_data, initial_tracking_data);
@@ -1632,28 +1463,18 @@
       sync_pb::EntitySpecifics image_specifics;
       FillImageSpecifics(BuildFaviconData(i),
                          image_specifics.mutable_favicon_image());
-      initial_image_changes.push_back(syncer::SyncChange(
-          FROM_HERE,
-          syncer::SyncChange::ACTION_ADD,
-          syncer::SyncData::CreateRemoteData(
-              1,
-              image_specifics,
-              base::Time(),
-              syncer::AttachmentIdList(),
-              syncer::AttachmentServiceProxyForTest::Create())));
+      initial_image_changes.push_back(
+          syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD,
+                             syncer::SyncData::CreateRemoteData(
+                                 1, image_specifics, base::Time())));
     } else {
       sync_pb::EntitySpecifics tracking_specifics;
       FillTrackingSpecifics(BuildFaviconData(i),
                             tracking_specifics.mutable_favicon_tracking());
-      initial_tracking_changes.push_back(syncer::SyncChange(
-          FROM_HERE,
-          syncer::SyncChange::ACTION_ADD,
-          syncer::SyncData::CreateRemoteData(
-              1,
-              tracking_specifics,
-              base::Time(),
-              syncer::AttachmentIdList(),
-              syncer::AttachmentServiceProxyForTest::Create())));
+      initial_tracking_changes.push_back(
+          syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD,
+                             syncer::SyncData::CreateRemoteData(
+                                 1, tracking_specifics, base::Time())));
     }
   }
 
@@ -1712,12 +1533,8 @@
     sync_pb::EntitySpecifics image_specifics;
     FillImageSpecifics(BuildFaviconData(i),
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     image_specifics.mutable_favicon_image()->clear_favicon_web();
   }
 
@@ -1739,22 +1556,14 @@
     sync_pb::EntitySpecifics image_specifics, tracking_specifics;
     FillImageSpecifics(BuildFaviconData(i),
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     tracking_specifics.mutable_favicon_tracking()->set_last_visit_time_ms(
         syncer::TimeToProtoTime(base::Time()));
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
   }
 
   cache()->MergeDataAndStartSyncing(syncer::FAVICON_IMAGES,
@@ -1809,20 +1618,12 @@
             base::Time::Now() + base::TimeDelta::FromMinutes(kClockSkew));
     FillImageSpecifics(test_data,
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
     FillTrackingSpecifics(test_data,
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
   }
   SetUpInitialSync(initial_image_data, initial_tracking_data);
 
@@ -1872,22 +1673,14 @@
     // Push the images forward by 5, to match the unsynced favicons.
     FillImageSpecifics(BuildFaviconData(i + 5),
                        image_specifics.mutable_favicon_image());
-    initial_image_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        image_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+    initial_image_data.push_back(
+        syncer::SyncData::CreateRemoteData(1, image_specifics, base::Time()));
 
     sync_pb::EntitySpecifics tracking_specifics;
     FillTrackingSpecifics(BuildFaviconData(i),
                           tracking_specifics.mutable_favicon_tracking());
     initial_tracking_data.push_back(syncer::SyncData::CreateRemoteData(
-        1,
-        tracking_specifics,
-        base::Time(),
-        syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create()));
+        1, tracking_specifics, base::Time()));
   }
   SetUpInitialSync(initial_image_data, initial_tracking_data);
 
diff --git a/components/sync_sessions/lost_navigations_recorder_unittest.cc b/components/sync_sessions/lost_navigations_recorder_unittest.cc
index b984b927..8516236 100644
--- a/components/sync_sessions/lost_navigations_recorder_unittest.cc
+++ b/components/sync_sessions/lost_navigations_recorder_unittest.cc
@@ -9,7 +9,6 @@
 
 #include "base/message_loop/message_loop.h"
 #include "base/test/histogram_tester.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/syncable/entry.h"
 #include "components/sync/syncable/mutable_entry.h"
 #include "components/sync/syncable/syncable_base_transaction.h"
diff --git a/components/sync_sessions/sessions_sync_manager_unittest.cc b/components/sync_sessions/sessions_sync_manager_unittest.cc
index ad466db..cdaa2447 100644
--- a/components/sync_sessions/sessions_sync_manager_unittest.cc
+++ b/components/sync_sessions/sessions_sync_manager_unittest.cc
@@ -15,8 +15,6 @@
 #include "components/sync/device_info/local_device_info_provider_mock.h"
 #include "components/sync/driver/fake_sync_client.h"
 #include "components/sync/driver/sync_api_component_factory.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/sync_error_factory_mock.h"
 #include "components/sync_sessions/fake_sync_sessions_client.h"
 #include "components/sync_sessions/session_sync_test_helper.h"
@@ -675,8 +673,7 @@
                             base::Time mtime = base::Time()) const {
     // The server ID is never relevant to these tests, so just use 1.
     return SyncData::CreateRemoteData(
-        1, entity, mtime, syncer::AttachmentIdList(),
-        syncer::AttachmentServiceProxyForTest::Create(),
+        1, entity, mtime,
         SessionsSyncManager::TagHashFromSpecifics(entity.session()));
   }
 
@@ -1882,9 +1879,8 @@
   sync_pb::SessionSpecifics bad_header(
       helper()->BuildForeignSession(bad_header_tag, empty_ids, &empty_tabs));
   entity.mutable_session()->CopyFrom(bad_header);
-  foreign_data.push_back(SyncData::CreateRemoteData(
-      1, entity, base::Time(), syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create(), "bad_header_tag_hash"));
+  foreign_data.push_back(SyncData::CreateRemoteData(1, entity, base::Time(),
+                                                    "bad_header_tag_hash"));
 
   const std::string good_tag_tab = "good_tag_tab";
   sync_pb::SessionSpecifics good_tab;
@@ -1895,9 +1891,8 @@
   sync_pb::SessionSpecifics bad_tab;
   helper()->BuildTabSpecifics(bad_tab_tag, 0, 2, &bad_tab);
   entity.mutable_session()->CopyFrom(bad_tab);
-  foreign_data.push_back(SyncData::CreateRemoteData(
-      1, entity, base::Time(), syncer::AttachmentIdList(),
-      syncer::AttachmentServiceProxyForTest::Create(), "bad_tab_tag_hash"));
+  foreign_data.push_back(
+      SyncData::CreateRemoteData(1, entity, base::Time(), "bad_tab_tag_hash"));
 
   SyncChangeList output;
   InitWithSyncDataTakeOutput(foreign_data, &output);
diff --git a/components/sync_wifi/wifi_credential_syncable_service_unittest.cc b/components/sync_wifi/wifi_credential_syncable_service_unittest.cc
index 197d517..f3b71761 100644
--- a/components/sync_wifi/wifi_credential_syncable_service_unittest.cc
+++ b/components/sync_wifi/wifi_credential_syncable_service_unittest.cc
@@ -14,8 +14,6 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/time/time.h"
-#include "components/sync/model/attachments/attachment_id.h"
-#include "components/sync/model/attachments/attachment_service_proxy_for_test.h"
 #include "components/sync/model/fake_sync_change_processor.h"
 #include "components/sync/model/sync_change.h"
 #include "components/sync/model/sync_data.h"
@@ -135,8 +133,7 @@
         syncer::SyncData::CreateRemoteData(
             sync_item_id,
             MakeWifiCredentialSpecifics(ssid, security_class, passphrase),
-            base::Time(), syncer::AttachmentIdList(),
-            syncer::AttachmentServiceProxyForTest::Create()));
+            base::Time()));
   }
 
   void StartSyncing() {
diff --git a/components/viz/common/quads/compositor_frame.cc b/components/viz/common/quads/compositor_frame.cc
index 17e748a..4bd8cd0 100644
--- a/components/viz/common/quads/compositor_frame.cc
+++ b/components/viz/common/quads/compositor_frame.cc
@@ -4,6 +4,8 @@
 
 #include "components/viz/common/quads/compositor_frame.h"
 
+#include "base/containers/adapters.h"
+
 namespace viz {
 
 CompositorFrame::CompositorFrame() = default;
@@ -14,4 +16,15 @@
 
 CompositorFrame& CompositorFrame::operator=(CompositorFrame&& other) = default;
 
+bool CompositorFrame::HasCopyOutputRequests() const {
+  // Iterate the RenderPasses back-to-front, because CopyOutputRequests tend to
+  // be made on the later passes.
+  for (const auto& pass : base::Reversed(render_pass_list)) {
+    if (!pass->copy_requests.empty()) {
+      return true;
+    }
+  }
+  return false;
+}
+
 }  // namespace viz
diff --git a/components/viz/common/quads/compositor_frame.h b/components/viz/common/quads/compositor_frame.h
index de77425..b4d6397 100644
--- a/components/viz/common/quads/compositor_frame.h
+++ b/components/viz/common/quads/compositor_frame.h
@@ -37,6 +37,8 @@
     return render_pass_list.back()->output_rect.size();
   }
 
+  bool HasCopyOutputRequests() const;
+
   CompositorFrameMetadata metadata;
   std::vector<TransferableResource> resource_list;
   // This list is in the order that each RenderPass will be drawn. The last one
diff --git a/components/viz/common/quads/render_pass.h b/components/viz/common/quads/render_pass.h
index 1edfee6..6da9e23 100644
--- a/components/viz/common/quads/render_pass.h
+++ b/components/viz/common/quads/render_pass.h
@@ -144,8 +144,7 @@
 
   // If non-empty, the renderer should produce a copy of the render pass'
   // contents as a bitmap, and give a copy of the bitmap to each callback in
-  // this list. This property should not be serialized between compositors, as
-  // it only makes sense in the root compositor.
+  // this list.
   std::vector<std::unique_ptr<CopyOutputRequest>> copy_requests;
 
   QuadList quad_list;
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc
index 2395ee22..59b15508 100644
--- a/components/viz/service/display/surface_aggregator_unittest.cc
+++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -331,7 +331,10 @@
             &manager_,
             kArbitraryReservedFrameSinkId,
             kChildIsRoot,
-            kNeedsSyncPoints)) {}
+            kNeedsSyncPoints)) {
+    child_support_->set_allow_copy_output_requests_for_testing();
+  }
+
   SurfaceAggregatorValidSurfaceTest()
       : SurfaceAggregatorValidSurfaceTest(false) {}
 
@@ -3075,6 +3078,7 @@
       nullptr, &manager_, FrameSinkId(1, 1), kChildIsRoot, kNeedsSyncPoints);
   auto support2 = std::make_unique<CompositorFrameSinkSupport>(
       nullptr, &manager_, FrameSinkId(2, 2), kChildIsRoot, kNeedsSyncPoints);
+  support2->set_allow_copy_output_requests_for_testing();
   LocalSurfaceId local_frame1_id(7u, base::UnguessableToken::Create());
   SurfaceId surface1_id(support1->frame_sink_id(), local_frame1_id);
 
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc
index 64d6a0449..f921ee5 100644
--- a/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_impl.cc
@@ -43,15 +43,18 @@
     CompositorFrame frame,
     mojom::HitTestRegionListPtr hit_test_region_list,
     uint64_t submit_time) {
-  bool success;
-  support_->SubmitCompositorFrame(local_surface_id, std::move(frame),
-                                  std::move(hit_test_region_list), &success);
-  if (!success) {
-    DLOG(ERROR) << "SubmitCompositorFrame failed for " << local_surface_id;
-    compositor_frame_sink_binding_.CloseWithReason(
-        1, "Surface invariants violation");
-    OnClientConnectionLost();
-  }
+  const auto result = support_->MaybeSubmitCompositorFrame(
+      local_surface_id, std::move(frame), std::move(hit_test_region_list));
+  if (result == CompositorFrameSinkSupport::ACCEPTED)
+    return;
+
+  const char* reason =
+      CompositorFrameSinkSupport::GetSubmitResultAsString(result);
+  DLOG(ERROR) << "SubmitCompositorFrame failed for " << local_surface_id
+              << " because " << reason;
+  compositor_frame_sink_binding_.CloseWithReason(static_cast<uint32_t>(result),
+                                                 reason);
+  OnClientConnectionLost();
 }
 
 void CompositorFrameSinkImpl::DidNotProduceFrame(
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
index fb51b481..bfa74f4 100644
--- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -30,6 +30,7 @@
       surface_resource_holder_(this),
       is_root_(is_root),
       needs_sync_tokens_(needs_sync_tokens),
+      allow_copy_output_requests_(is_root),
       weak_factory_(this) {
   // This may result in SetBeginFrameSource() being called.
   frame_sink_manager_->RegisterCompositorFrameSinkSupport(frame_sink_id_, this);
@@ -177,24 +178,28 @@
     CompositorFrame frame,
     mojom::HitTestRegionListPtr hit_test_region_list,
     uint64_t submit_time) {
-  bool success;
-  SubmitCompositorFrame(local_surface_id, std::move(frame),
-                        std::move(hit_test_region_list), &success);
-  DCHECK(success);
+  const auto result = MaybeSubmitCompositorFrame(
+      local_surface_id, std::move(frame), std::move(hit_test_region_list));
+  DCHECK_EQ(result, ACCEPTED);
 }
 
-void CompositorFrameSinkSupport::SubmitCompositorFrame(
+CompositorFrameSinkSupport::SubmitResult
+CompositorFrameSinkSupport::MaybeSubmitCompositorFrame(
     const LocalSurfaceId& local_surface_id,
     CompositorFrame frame,
-    mojom::HitTestRegionListPtr hit_test_region_list,
-    bool* success) {
-  TRACE_EVENT1("viz", "CompositorFrameSinkSupport::SubmitCompositorFrame",
+    mojom::HitTestRegionListPtr hit_test_region_list) {
+  TRACE_EVENT1("viz", "CompositorFrameSinkSupport::MaybeSubmitCompositorFrame",
                "FrameSinkId", frame_sink_id_.ToString());
   DCHECK(local_surface_id.is_valid());
   DCHECK(!frame.render_pass_list.empty());
   DCHECK(!frame.size_in_pixels().IsEmpty());
-  DCHECK(success);
-  *success = true;
+
+  // Ensure no CopyOutputRequests have been submitted if they are banned.
+  if (!allow_copy_output_requests_ && frame.HasCopyOutputRequests()) {
+    TRACE_EVENT_INSTANT0("viz", "CopyOutputRequests not allowed",
+                         TRACE_EVENT_SCOPE_THREAD);
+    return COPY_OUTPUT_REQUESTS_NOT_ALLOWED;
+  }
 
   uint64_t frame_index = ++last_frame_index_;
   ++ack_pending_count_;
@@ -253,8 +258,7 @@
         DidPresentCompositorFrame(frame.metadata.presentation_token,
                                   base::TimeTicks(), base::TimeDelta(), 0);
       }
-      *success = false;
-      return;
+      return SURFACE_INVARIANTS_VIOLATION;
     }
 
     current_surface = CreateSurface(surface_info);
@@ -280,9 +284,9 @@
                 weak_factory_.GetWeakPtr(), frame.metadata.presentation_token)
           : Surface::PresentedCallback());
   if (!result) {
+    TRACE_EVENT_INSTANT0("viz", "QueueFrame failed", TRACE_EVENT_SCOPE_THREAD);
     EvictCurrentSurface();
-    *success = false;
-    return;
+    return SURFACE_INVARIANTS_VIOLATION;
   }
 
   if (prev_surface && prev_surface != current_surface) {
@@ -292,6 +296,8 @@
 
   if (begin_frame_source_)
     begin_frame_source_->DidFinishFrame(this);
+
+  return ACCEPTED;
 }
 
 void CompositorFrameSinkSupport::UpdateSurfaceReferences(
@@ -460,6 +466,21 @@
   return surface_manager_->GetSurfaceForId(current_surface_id_);
 }
 
+// static
+const char* CompositorFrameSinkSupport::GetSubmitResultAsString(
+    SubmitResult result) {
+  switch (result) {
+    case CompositorFrameSinkSupport::ACCEPTED:
+      return "Accepted";
+    case CompositorFrameSinkSupport::COPY_OUTPUT_REQUESTS_NOT_ALLOWED:
+      return "CopyOutputRequests not allowed";
+    case CompositorFrameSinkSupport::SURFACE_INVARIANTS_VIOLATION:
+      return "Surface invariants violation";
+  }
+  NOTREACHED();
+  return nullptr;
+}
+
 void CompositorFrameSinkSupport::OnAggregatedDamage(
     const LocalSurfaceId& local_surface_id,
     const gfx::Rect& damage_rect,
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.h b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
index 02ecf59..a0b8cb7 100644
--- a/components/viz/service/frame_sinks/compositor_frame_sink_support.h
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
@@ -37,6 +37,13 @@
       public CapturableFrameSink,
       public mojom::CompositorFrameSink {
  public:
+  // Possible outcomes of MaybeSubmitCompositorFrame().
+  enum SubmitResult {
+    ACCEPTED,
+    COPY_OUTPUT_REQUESTS_NOT_ALLOWED,
+    SURFACE_INVARIANTS_VIOLATION,
+  };
+
   using AggregatedDamageCallback =
       base::RepeatingCallback<void(const LocalSurfaceId& local_surface_id,
                                    const gfx::Rect& damage_rect)>;
@@ -95,16 +102,18 @@
 
   void EvictCurrentSurface();
 
-  // Submits a new CompositorFrame to |local_surface_id|. If |local_surface_id|
-  // hasn't been submitted to before then a new Surface will be created for it.
-  // Sets |success| to false if |frame| was rejected due to invalid data.
-  // SubmitCompositorFrame() that is inherited from mojom::CompositorFrameSink
-  // calls this one and DCHECK's |success|. Callers should prefer to call the
-  // other one unless they really want to check the value of |success|.
-  void SubmitCompositorFrame(const LocalSurfaceId& local_surface_id,
-                             CompositorFrame frame,
-                             mojom::HitTestRegionListPtr hit_test_region_list,
-                             bool* success);
+  // Attempts to submit a new CompositorFrame to |local_surface_id| and returns
+  // whether the frame was accepted or the reason why it was rejected. If
+  // |local_surface_id| hasn't been submitted before then a new Surface will be
+  // created for it.
+  //
+  // This is called by SubmitCompositorFrame(), which DCHECK-fails on a
+  // non-accepted result. Prefer calling SubmitCompositorFrame() instead of this
+  // method unless the result value affects what the caller will do next.
+  SubmitResult MaybeSubmitCompositorFrame(
+      const LocalSurfaceId& local_surface_id,
+      CompositorFrame frame,
+      mojom::HitTestRegionListPtr hit_test_region_list);
 
   // CapturableFrameSink implementation.
   void AttachCaptureClient(CapturableFrameSink::Client* client) override;
@@ -115,8 +124,18 @@
 
   HitTestAggregator* GetHitTestAggregator();
 
+  // Permits submitted CompositorFrames to contain CopyOutputRequests, for
+  // special-case testing purposes only.
+  void set_allow_copy_output_requests_for_testing() {
+    allow_copy_output_requests_ = true;
+  }
+
   Surface* GetCurrentSurfaceForTesting();
 
+  // Maps the |result| from MaybeSubmitCompositorFrame() to a human-readable
+  // string.
+  static const char* GetSubmitResultAsString(SubmitResult result);
+
  private:
   friend class FrameSinkManagerTest;
 
@@ -190,6 +209,12 @@
   const bool is_root_;
   const bool needs_sync_tokens_;
 
+  // By default, this is equivalent to |is_root_|, but may be overridden for
+  // testing. Generally, for non-roots, there must not be any CopyOutputRequests
+  // contained within submitted CompositorFrames. Otherwise, unprivileged
+  // clients would be able to capture content for which they are not authorized.
+  bool allow_copy_output_requests_;
+
   // A callback that will be run at the start of the destructor if set.
   base::OnceClosure destruction_callback_;
 
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
index ca4277e..80d02f2 100644
--- a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
@@ -93,6 +93,26 @@
               local_surface_id_);
   }
 
+  bool SubmitCompositorFrameWithCopyRequest(
+      std::unique_ptr<CopyOutputRequest> request) {
+    auto frame = MakeDefaultCompositorFrame();
+    frame.render_pass_list.back()->copy_requests.push_back(std::move(request));
+    const auto result = support_->MaybeSubmitCompositorFrame(
+        local_surface_id_, std::move(frame), nullptr);
+    switch (result) {
+      case CompositorFrameSinkSupport::ACCEPTED:
+        return true;
+      case CompositorFrameSinkSupport::COPY_OUTPUT_REQUESTS_NOT_ALLOWED:
+        return false;
+      default:
+        ADD_FAILURE()
+            << "Test broken; fail result not related to copy requests: "
+            << CompositorFrameSinkSupport::GetSubmitResultAsString(result);
+        break;
+    }
+    return false;
+  }
+
   void UnrefResources(ResourceId* ids_to_unref,
                       int* counts_to_unref,
                       size_t num_ids_to_unref) {
@@ -494,25 +514,50 @@
   LocalSurfaceId local_surface_id4(5, 3, kArbitraryToken);
   LocalSurfaceId local_surface_id5(8, 1, kArbitraryToken);
   LocalSurfaceId local_surface_id6(9, 3, kArbitraryToken);
-  bool success;
-  support->SubmitCompositorFrame(
-      local_surface_id1, MakeDefaultCompositorFrame(), nullptr, &success);
-  EXPECT_TRUE(success);
-  support->SubmitCompositorFrame(
-      local_surface_id2, MakeDefaultCompositorFrame(), nullptr, &success);
-  EXPECT_TRUE(success);
-  support->SubmitCompositorFrame(
-      local_surface_id3, MakeDefaultCompositorFrame(), nullptr, &success);
-  EXPECT_TRUE(success);
-  support->SubmitCompositorFrame(
-      local_surface_id4, MakeDefaultCompositorFrame(), nullptr, &success);
-  EXPECT_FALSE(success);
-  support->SubmitCompositorFrame(
-      local_surface_id5, MakeDefaultCompositorFrame(), nullptr, &success);
-  EXPECT_FALSE(success);
-  support->SubmitCompositorFrame(
-      local_surface_id6, MakeDefaultCompositorFrame(), nullptr, &success);
-  EXPECT_TRUE(success);
+  auto result = support->MaybeSubmitCompositorFrame(
+      local_surface_id1, MakeDefaultCompositorFrame(), nullptr);
+  EXPECT_EQ(CompositorFrameSinkSupport::ACCEPTED, result);
+  result = support->MaybeSubmitCompositorFrame(
+      local_surface_id2, MakeDefaultCompositorFrame(), nullptr);
+  EXPECT_EQ(CompositorFrameSinkSupport::ACCEPTED, result);
+  result = support->MaybeSubmitCompositorFrame(
+      local_surface_id3, MakeDefaultCompositorFrame(), nullptr);
+  EXPECT_EQ(CompositorFrameSinkSupport::ACCEPTED, result);
+  result = support->MaybeSubmitCompositorFrame(
+      local_surface_id4, MakeDefaultCompositorFrame(), nullptr);
+  EXPECT_EQ(CompositorFrameSinkSupport::SURFACE_INVARIANTS_VIOLATION, result);
+  result = support->MaybeSubmitCompositorFrame(
+      local_surface_id5, MakeDefaultCompositorFrame(), nullptr);
+  EXPECT_EQ(CompositorFrameSinkSupport::SURFACE_INVARIANTS_VIOLATION, result);
+  result = support->MaybeSubmitCompositorFrame(
+      local_surface_id6, MakeDefaultCompositorFrame(), nullptr);
+  EXPECT_EQ(CompositorFrameSinkSupport::ACCEPTED, result);
+
+  support->EvictCurrentSurface();
+  manager_.InvalidateFrameSinkId(kAnotherArbitraryFrameSinkId);
+}
+
+// Verifies that CopyOutputRequests submitted by unprivileged clients are
+// rejected.
+TEST_F(CompositorFrameSinkSupportTest, ProhibitsUnprivilegedCopyRequests) {
+  manager_.RegisterFrameSinkId(kAnotherArbitraryFrameSinkId);
+  manager_.SetFrameSinkDebugLabel(kAnotherArbitraryFrameSinkId,
+                                  "kAnotherArbitraryFrameSinkId");
+  MockCompositorFrameSinkClient mock_client;
+  auto support = std::make_unique<CompositorFrameSinkSupport>(
+      &mock_client, &manager_, kAnotherArbitraryFrameSinkId,
+      false /* not root frame sink */, kNeedsSyncPoints);
+
+  bool did_receive_aborted_copy_result = false;
+  auto request = std::make_unique<CopyOutputRequest>(
+      CopyOutputRequest::ResultFormat::RGBA_BITMAP,
+      base::BindOnce(
+          [](bool* got_nothing, std::unique_ptr<CopyOutputResult> result) {
+            *got_nothing = result->IsEmpty();
+          },
+          &did_receive_aborted_copy_result));
+  EXPECT_FALSE(SubmitCompositorFrameWithCopyRequest(std::move(request)));
+  EXPECT_TRUE(did_receive_aborted_copy_result);
 
   support->EvictCurrentSurface();
   manager_.InvalidateFrameSinkId(kAnotherArbitraryFrameSinkId);
@@ -664,10 +709,9 @@
                    .AddDefaultRenderPass()
                    .SetDeviceScaleFactor(0.f)
                    .Build();
-  bool success;
-  support_->SubmitCompositorFrame(local_surface_id_, std::move(frame), nullptr,
-                                  &success);
-  EXPECT_FALSE(success);
+  const auto result = support_->MaybeSubmitCompositorFrame(
+      local_surface_id_, std::move(frame), nullptr);
+  EXPECT_EQ(CompositorFrameSinkSupport::SURFACE_INVARIANTS_VIOLATION, result);
   EXPECT_FALSE(GetSurfaceForId(id));
 }
 
@@ -680,10 +724,9 @@
   auto frame = CompositorFrameBuilder()
                    .AddRenderPass(gfx::Rect(5, 5), gfx::Rect())
                    .Build();
-  bool success;
-  support_->SubmitCompositorFrame(local_surface_id_, std::move(frame), nullptr,
-                                  &success);
-  EXPECT_TRUE(success);
+  auto result = support_->MaybeSubmitCompositorFrame(local_surface_id_,
+                                                     std::move(frame), nullptr);
+  EXPECT_EQ(CompositorFrameSinkSupport::ACCEPTED, result);
   EXPECT_TRUE(GetSurfaceForId(id));
 
   // Submit a frame with size (5,4). This frame should be rejected and the
@@ -691,9 +734,9 @@
   frame = CompositorFrameBuilder()
               .AddRenderPass(gfx::Rect(5, 4), gfx::Rect())
               .Build();
-  support_->SubmitCompositorFrame(local_surface_id_, std::move(frame), nullptr,
-                                  &success);
-  EXPECT_FALSE(success);
+  result = support_->MaybeSubmitCompositorFrame(local_surface_id_,
+                                                std::move(frame), nullptr);
+  EXPECT_EQ(CompositorFrameSinkSupport::SURFACE_INVARIANTS_VIOLATION, result);
   manager_.surface_manager()->GarbageCollectSurfaces();
   EXPECT_FALSE(GetSurfaceForId(id));
 }
@@ -709,10 +752,9 @@
                    .AddDefaultRenderPass()
                    .SetDeviceScaleFactor(0.5f)
                    .Build();
-  bool success;
-  support_->SubmitCompositorFrame(local_surface_id_, std::move(frame), nullptr,
-                                  &success);
-  EXPECT_TRUE(success);
+  auto result = support_->MaybeSubmitCompositorFrame(local_surface_id_,
+                                                     std::move(frame), nullptr);
+  EXPECT_EQ(CompositorFrameSinkSupport::ACCEPTED, result);
   EXPECT_TRUE(GetSurfaceForId(id));
 
   // Submit a frame with device scale factor of 0.4. This frame should be
@@ -721,9 +763,9 @@
               .AddDefaultRenderPass()
               .SetDeviceScaleFactor(0.4f)
               .Build();
-  support_->SubmitCompositorFrame(local_surface_id_, std::move(frame), nullptr,
-                                  &success);
-  EXPECT_FALSE(success);
+  result = support_->MaybeSubmitCompositorFrame(local_surface_id_,
+                                                std::move(frame), nullptr);
+  EXPECT_EQ(CompositorFrameSinkSupport::SURFACE_INVARIANTS_VIOLATION, result);
   manager_.surface_manager()->GarbageCollectSurfaces();
   EXPECT_FALSE(GetSurfaceForId(id));
 }
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
index 7aaa35e74..6f9d2ff 100644
--- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
+++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -104,14 +104,18 @@
     display_->SetLocalSurfaceId(local_surface_id, frame.device_scale_factor());
   }
 
-  bool success;
-  support_->SubmitCompositorFrame(local_surface_id, std::move(frame),
-                                  std::move(hit_test_region_list), &success);
-  if (!success) {
-    DLOG(ERROR) << "SubmitCompositorFrame failed for " << local_surface_id;
-    compositor_frame_sink_binding_.Close();
-    OnClientConnectionLost();
-  }
+  const auto result = support_->MaybeSubmitCompositorFrame(
+      local_surface_id, std::move(frame), std::move(hit_test_region_list));
+  if (result == CompositorFrameSinkSupport::ACCEPTED)
+    return;
+
+  const char* reason =
+      CompositorFrameSinkSupport::GetSubmitResultAsString(result);
+  DLOG(ERROR) << "SubmitCompositorFrame failed for " << local_surface_id
+              << " because " << reason;
+  compositor_frame_sink_binding_.CloseWithReason(static_cast<uint32_t>(result),
+                                                 reason);
+  OnClientConnectionLost();
 }
 
 void RootCompositorFrameSinkImpl::DidNotProduceFrame(
diff --git a/components/viz/test/test_layer_tree_frame_sink.cc b/components/viz/test/test_layer_tree_frame_sink.cc
index 8d559dc..b3f77d2 100644
--- a/components/viz/test/test_layer_tree_frame_sink.cc
+++ b/components/viz/test/test_layer_tree_frame_sink.cc
@@ -106,7 +106,7 @@
       std::move(display_output_surface), std::move(scheduler),
       compositor_task_runner_);
 
-  constexpr bool is_root = false;
+  constexpr bool is_root = true;
   constexpr bool needs_sync_points = true;
   support_ = std::make_unique<CompositorFrameSinkSupport>(
       this, frame_sink_manager_.get(), frame_sink_id_, is_root,
diff --git a/content/browser/DEPS b/content/browser/DEPS
index 029cf8a0..3abc053b 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -65,7 +65,6 @@
   # header-only types, and some selected common code.
   "-third_party/WebKit",
   "+third_party/WebKit/common/feature_policy/feature_policy.h",
-  "+third_party/WebKit/common/feature_policy/feature_policy_feature.h",
   "+third_party/WebKit/public/platform/WebAddressSpace.h",
   "+third_party/WebKit/public/platform/WebContentSecurityPolicy.h",
   "+third_party/WebKit/public/platform/WebCursorInfo.h",
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h
index 4bf76a8..f455604 100644
--- a/content/browser/bad_message.h
+++ b/content/browser/bad_message.h
@@ -221,6 +221,7 @@
   WCI_NEW_WIDGET_PROCESS_MISMATCH = 194,
   AUTH_INVALID_EFFECTIVE_DOMAIN = 195,
   AUTH_INVALID_RELYING_PARTY = 196,
+  RWH_COPY_REQUEST_ATTEMPT = 197,
 
   // Please add new elements here. The naming convention is abbreviated class
   // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc b/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc
index 74d963f..234bc099 100644
--- a/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc
@@ -10,7 +10,7 @@
 #include "content/public/test/test_renderer_host.h"
 #include "content/test/test_render_frame_host.h"
 #include "third_party/WebKit/common/feature_policy/feature_policy.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 #include "third_party/WebKit/common/frame_policy.h"
 #include "third_party/WebKit/common/sandbox_flags.h"
 #include "url/gurl.h"
@@ -30,10 +30,10 @@
   static constexpr const char* kOrigin3 = "https://example.com";
   static constexpr const char* kOrigin4 = "https://test.com";
 
-  static const blink::FeaturePolicyFeature kDefaultEnabledFeature =
-      blink::FeaturePolicyFeature::kDocumentWrite;
-  static const blink::FeaturePolicyFeature kDefaultSelfFeature =
-      blink::FeaturePolicyFeature::kGeolocation;
+  static const blink::mojom::FeaturePolicyFeature kDefaultEnabledFeature =
+      blink::mojom::FeaturePolicyFeature::kDocumentWrite;
+  static const blink::mojom::FeaturePolicyFeature kDefaultSelfFeature =
+      blink::mojom::FeaturePolicyFeature::kGeolocation;
 
   RenderFrameHost* GetMainRFH(const char* origin) {
     RenderFrameHost* result = web_contents()->GetMainFrame();
@@ -53,7 +53,7 @@
   // The header policy should only be set once on page load, so we refresh the
   // page to simulate that.
   void RefreshPageAndSetHeaderPolicy(RenderFrameHost** rfh,
-                                     blink::FeaturePolicyFeature feature,
+                                     blink::mojom::FeaturePolicyFeature feature,
                                      const std::vector<std::string>& origins) {
     RenderFrameHost* current = *rfh;
     SimulateNavigation(&current, current->GetLastCommittedURL());
@@ -64,7 +64,7 @@
 
   void SetContainerPolicy(RenderFrameHost* parent,
                           RenderFrameHost* child,
-                          blink::FeaturePolicyFeature feature,
+                          blink::mojom::FeaturePolicyFeature feature,
                           const std::vector<std::string>& origins) {
     static_cast<TestRenderFrameHost*>(parent)->OnDidChangeFramePolicy(
         child->GetRoutingID(),
@@ -80,7 +80,7 @@
 
  private:
   blink::ParsedFeaturePolicy CreateFPHeader(
-      blink::FeaturePolicyFeature feature,
+      blink::mojom::FeaturePolicyFeature feature,
       const std::vector<std::string>& origins) {
     blink::ParsedFeaturePolicy result(1);
     result[0].feature = feature;
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index ff2575f..96a3e02 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2191,7 +2191,7 @@
 }
 
 bool RenderFrameHostImpl::IsFeatureEnabled(
-    blink::FeaturePolicyFeature feature) {
+    blink::mojom::FeaturePolicyFeature feature) {
   return feature_policy_ && feature_policy_->IsFeatureEnabledForOrigin(
                                 feature, GetLastCommittedOrigin());
 }
@@ -3473,7 +3473,6 @@
       FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type);
 
   std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories;
-  mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info;
   if (base::FeatureList::IsEnabled(network::features::kNetworkService) &&
       (!is_same_document || is_first_navigation)) {
     subresource_loader_factories =
@@ -3552,12 +3551,13 @@
       subresource_loader_factories->factories_info().emplace(
           factory.first, std::move(factory_proxy_info));
     }
+  }
 
-    // Pass the controller service worker info if we have one.
-    if (subresource_loader_params) {
-      controller_service_worker_info =
-          std::move(subresource_loader_params->controller_service_worker_info);
-    }
+  // Pass the controller service worker info if we have one.
+  mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info;
+  if (subresource_loader_params) {
+    controller_service_worker_info =
+        std::move(subresource_loader_params->controller_service_worker_info);
   }
 
   // It is imperative that cross-document navigations always provide a set of
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index d70485f..1b8d378 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -238,7 +238,7 @@
   bool IsBeforeUnloadHangMonitorDisabledForTesting() override;
   bool GetSuddenTerminationDisablerState(
       blink::WebSuddenTerminationDisablerType disabler_type) override;
-  bool IsFeatureEnabled(blink::FeaturePolicyFeature feature) override;
+  bool IsFeatureEnabled(blink::mojom::FeaturePolicyFeature feature) override;
   void ViewSource() override;
 
   // IPC::Sender
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 695831e8..cb7200d 100644
--- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -501,6 +501,13 @@
 
 // After a navigation, the StreamHandle must be released.
 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, StreamHandleReleased) {
+  if (IsNavigationMojoResponseEnabled() ||
+      base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+    // This test is specific to the delivery of the main resource in a blob url.
+    // This mechanism is not sued when NavigationMojoResponse or NetworkService
+    // are enabled.
+    return;
+  }
   EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl("", "title1.html")));
   WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
   RenderFrameHostImpl* main_frame =
diff --git a/content/browser/generic_sensor/sensor_provider_proxy_impl.cc b/content/browser/generic_sensor/sensor_provider_proxy_impl.cc
index a728e107..6e40657 100644
--- a/content/browser/generic_sensor/sensor_provider_proxy_impl.cc
+++ b/content/browser/generic_sensor/sensor_provider_proxy_impl.cc
@@ -17,7 +17,7 @@
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "services/device/public/interfaces/constants.mojom.h"
 #include "services/service_manager/public/cpp/connector.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 
 using device::mojom::SensorType;
 
@@ -82,27 +82,27 @@
 
 namespace {
 
-std::vector<blink::FeaturePolicyFeature> SensorTypeToFeaturePolicyFeatures(
-    SensorType type) {
+std::vector<blink::mojom::FeaturePolicyFeature>
+SensorTypeToFeaturePolicyFeatures(SensorType type) {
   switch (type) {
     case SensorType::AMBIENT_LIGHT:
-      return {blink::FeaturePolicyFeature::kAmbientLightSensor};
+      return {blink::mojom::FeaturePolicyFeature::kAmbientLightSensor};
     case SensorType::ACCELEROMETER:
     case SensorType::LINEAR_ACCELERATION:
-      return {blink::FeaturePolicyFeature::kAccelerometer};
+      return {blink::mojom::FeaturePolicyFeature::kAccelerometer};
     case SensorType::GYROSCOPE:
-      return {blink::FeaturePolicyFeature::kGyroscope};
+      return {blink::mojom::FeaturePolicyFeature::kGyroscope};
     case SensorType::MAGNETOMETER:
-      return {blink::FeaturePolicyFeature::kMagnetometer};
+      return {blink::mojom::FeaturePolicyFeature::kMagnetometer};
     case SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES:
     case SensorType::ABSOLUTE_ORIENTATION_QUATERNION:
-      return {blink::FeaturePolicyFeature::kAccelerometer,
-              blink::FeaturePolicyFeature::kGyroscope,
-              blink::FeaturePolicyFeature::kMagnetometer};
+      return {blink::mojom::FeaturePolicyFeature::kAccelerometer,
+              blink::mojom::FeaturePolicyFeature::kGyroscope,
+              blink::mojom::FeaturePolicyFeature::kMagnetometer};
     case SensorType::RELATIVE_ORIENTATION_EULER_ANGLES:
     case SensorType::RELATIVE_ORIENTATION_QUATERNION:
-      return {blink::FeaturePolicyFeature::kAccelerometer,
-              blink::FeaturePolicyFeature::kGyroscope};
+      return {blink::mojom::FeaturePolicyFeature::kAccelerometer,
+              blink::mojom::FeaturePolicyFeature::kGyroscope};
     default:
       NOTREACHED() << "Unknown sensor type " << type;
       return {};
@@ -112,10 +112,10 @@
 }  // namespace
 
 bool SensorProviderProxyImpl::CheckFeaturePolicies(SensorType type) const {
-  const std::vector<blink::FeaturePolicyFeature>& features =
+  const std::vector<blink::mojom::FeaturePolicyFeature>& features =
       SensorTypeToFeaturePolicyFeatures(type);
   return std::all_of(features.begin(), features.end(),
-                     [this](blink::FeaturePolicyFeature feature) {
+                     [this](blink::mojom::FeaturePolicyFeature feature) {
                        return render_frame_host_->IsFeatureEnabled(feature);
                      });
 }
diff --git a/content/browser/geolocation/geolocation_service_impl.cc b/content/browser/geolocation/geolocation_service_impl.cc
index 98ccff4..31a8620 100644
--- a/content/browser/geolocation/geolocation_service_impl.cc
+++ b/content/browser/geolocation/geolocation_service_impl.cc
@@ -8,7 +8,7 @@
 #include "content/public/browser/permission_type.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/common/content_features.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 
 namespace content {
 
@@ -75,7 +75,7 @@
   if (base::FeatureList::IsEnabled(features::kFeaturePolicy) &&
       base::FeatureList::IsEnabled(features::kUseFeaturePolicyForPermissions) &&
       !render_frame_host_->IsFeatureEnabled(
-          blink::FeaturePolicyFeature::kGeolocation)) {
+          blink::mojom::FeaturePolicyFeature::kGeolocation)) {
     return;
   }
 
diff --git a/content/browser/geolocation/geolocation_service_impl_unittest.cc b/content/browser/geolocation/geolocation_service_impl_unittest.cc
index 65341e81..9e2006f 100644
--- a/content/browser/geolocation/geolocation_service_impl_unittest.cc
+++ b/content/browser/geolocation/geolocation_service_impl_unittest.cc
@@ -17,7 +17,7 @@
 #include "services/device/public/interfaces/geoposition.mojom.h"
 #include "services/service_manager/public/cpp/bind_source_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 
 using base::test::ScopedFeatureList;
 using blink::mojom::PermissionStatus;
@@ -83,7 +83,7 @@
     if (allow_via_feature_policy) {
       RenderFrameHostTester::For(main_rfh())
           ->SimulateFeaturePolicyHeader(
-              blink::FeaturePolicyFeature::kGeolocation,
+              blink::mojom::FeaturePolicyFeature::kGeolocation,
               std::vector<url::Origin>{url::Origin::Create(kEmbeddedUrl)});
     }
     RenderFrameHost* embedded_rfh =
diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc
index b55bda4..2552153 100644
--- a/content/browser/gpu/gpu_data_manager_impl.cc
+++ b/content/browser/gpu/gpu_data_manager_impl.cc
@@ -105,6 +105,12 @@
   private_->SetGpuInfo(gpu_info);
 }
 
+void GpuDataManagerImpl::GetDisabledWebGLExtensions(
+    std::string* disabled_webgl_extensions) const {
+  base::AutoLock auto_lock(lock_);
+  private_->GetDisabledWebGLExtensions(disabled_webgl_extensions);
+}
+
 void GpuDataManagerImpl::Initialize() {
   base::AutoLock auto_lock(lock_);
   private_->Initialize();
diff --git a/content/browser/gpu/gpu_data_manager_impl.h b/content/browser/gpu/gpu_data_manager_impl.h
index b32d07c0..30a14dd 100644
--- a/content/browser/gpu/gpu_data_manager_impl.h
+++ b/content/browser/gpu/gpu_data_manager_impl.h
@@ -85,6 +85,8 @@
   void GetDisabledExtensions(std::string* disabled_extensions) const override;
   void SetGpuInfo(const gpu::GPUInfo& gpu_info) override;
 
+  void GetDisabledWebGLExtensions(std::string* disabled_webgl_extensions) const;
+
   bool IsGpuFeatureInfoAvailable() const;
   gpu::GpuFeatureStatus GetFeatureStatus(gpu::GpuFeatureType feature) const;
 
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc
index 5bdd40c..4256701 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -741,6 +741,12 @@
   *disabled_extensions = gpu_feature_info_.disabled_extensions;
 }
 
+void GpuDataManagerImplPrivate::GetDisabledWebGLExtensions(
+    std::string* disabled_webgl_extensions) const {
+  DCHECK(disabled_webgl_extensions);
+  *disabled_webgl_extensions = gpu_feature_info_.disabled_webgl_extensions;
+}
+
 void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIs(
     const GURL& url, GpuDataManagerImpl::DomainGuilt guilt) {
   BlockDomainFrom3DAPIsAtTime(url, guilt, base::Time::Now());
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.h b/content/browser/gpu/gpu_data_manager_impl_private.h
index 51d86d0..ea833f0 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.h
+++ b/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -84,6 +84,7 @@
   void HandleGpuSwitch();
 
   void GetDisabledExtensions(std::string* disabled_extensions) const;
+  void GetDisabledWebGLExtensions(std::string* disabled_webgl_extensions) const;
 
   void BlockDomainFrom3DAPIs(
       const GURL& url, GpuDataManagerImpl::DomainGuilt guilt);
diff --git a/content/browser/gpu/gpu_data_manager_testing_autogen.cc b/content/browser/gpu/gpu_data_manager_testing_autogen.cc
index 6d36db8c..43b1d39 100644
--- a/content/browser/gpu/gpu_data_manager_testing_autogen.cc
+++ b/content/browser/gpu/gpu_data_manager_testing_autogen.cc
@@ -23,6 +23,8 @@
         kFeatureListForEntry1,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -49,6 +51,8 @@
         kFeatureListForEntry2,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -75,6 +79,8 @@
         kFeatureListForEntry3,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -101,6 +107,8 @@
         kFeatureListForEntry4,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -127,6 +135,8 @@
         kFeatureListForEntry5,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -153,6 +163,8 @@
         kFeatureListForEntry6,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -179,6 +191,8 @@
         kFeatureListForEntry7,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc
index e2a6c8b..67dc866 100644
--- a/content/browser/gpu/gpu_internals_ui.cc
+++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -183,6 +183,10 @@
   GpuDataManagerImpl::GetInstance()->GetDisabledExtensions(
       &disabled_extensions);
 
+  std::string disabled_webgl_extensions;
+  GpuDataManagerImpl::GetInstance()->GetDisabledWebGLExtensions(
+      &disabled_webgl_extensions);
+
   basic_info->Append(
       NewDescriptionValuePair("Driver vendor", gpu_info.driver_vendor));
   basic_info->Append(NewDescriptionValuePair("Driver version",
@@ -209,6 +213,8 @@
                                              gpu_info.gl_extensions));
   basic_info->Append(NewDescriptionValuePair("Disabled Extensions",
                                              disabled_extensions));
+  basic_info->Append(NewDescriptionValuePair("Disabled WebGL Extensions",
+                                             disabled_webgl_extensions));
   basic_info->Append(NewDescriptionValuePair("Window system binding vendor",
                                              gpu_info.gl_ws_vendor));
   basic_info->Append(NewDescriptionValuePair("Window system binding version",
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc
index 49a0ce4..92d3ee3 100644
--- a/content/browser/loader/navigation_url_loader_network_service.cc
+++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -656,6 +656,26 @@
         if (navigation_data)
           cloned_navigation_data = navigation_data->Clone();
       }
+
+      // This is similar to what is done in
+      // ServiceWorkerControlleeHandler::MaybeCreateSubresourceLoaderParams().
+      // It takes the matching ControllerServiceWorkerInfo (if any) associated
+      // with the request. It will be sent to the renderer process and used to
+      // intercept requests.
+      // TODO(arthursonzogni): This is needed only for the non-S13nServiceWorker
+      // case. The S13nServiceWorker case is still not supported without the
+      // NetworkService. This block needs to be updated once support for it will
+      // be added.
+      ServiceWorkerProviderHost* sw_provider_host =
+          ServiceWorkerRequestHandler::GetProviderHost(url_request);
+      if (sw_provider_host && sw_provider_host->controller()) {
+        subresource_loader_params_ = SubresourceLoaderParams();
+        subresource_loader_params_->controller_service_worker_info =
+            mojom::ControllerServiceWorkerInfo::New();
+        subresource_loader_params_->controller_service_worker_info
+            ->object_info = sw_provider_host->GetOrCreateServiceWorkerHandle(
+            sw_provider_host->controller());
+      }
     }
 
     // Make a copy of the ResourceResponse before it is passed to another
diff --git a/content/browser/loader/prefetch_browsertest.cc b/content/browser/loader/prefetch_browsertest.cc
new file mode 100644
index 0000000..a88011f
--- /dev/null
+++ b/content/browser/loader/prefetch_browsertest.cc
@@ -0,0 +1,103 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <map>
+#include <string>
+
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "services/network/public/cpp/features.h"
+
+namespace content {
+
+class PrefetchBrowserTest : public ContentBrowserTest,
+                            public testing::WithParamInterface<bool> {
+ public:
+  PrefetchBrowserTest() = default;
+  ~PrefetchBrowserTest() = default;
+
+  void SetUp() override {
+    if (GetParam())
+      feature_list_.InitWithFeatures({network::features::kNetworkService}, {});
+    ContentBrowserTest::SetUp();
+  }
+
+  void RegisterResponse(const std::string& url, const std::string& content) {
+    response_map_[url] = content;
+  }
+
+  std::unique_ptr<net::test_server::HttpResponse> ServeResponses(
+      const net::test_server::HttpRequest& request) {
+    auto found = response_map_.find(request.relative_url);
+    if (found != response_map_.end()) {
+      auto response = std::make_unique<net::test_server::BasicHttpResponse>();
+      response->set_code(net::HTTP_OK);
+      response->set_content(found->second);
+      return std::move(response);
+    }
+    return nullptr;
+  }
+
+  void WatchURLAndRunClosure(const std::string& relative_url,
+                             int* visit_count,
+                             base::OnceClosure closure,
+                             const net::test_server::HttpRequest& request) {
+    if (request.relative_url == relative_url) {
+      (*visit_count)++;
+      std::move(closure).Run();
+    }
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+  std::map<std::string, std::string> response_map_;
+
+  DISALLOW_COPY_AND_ASSIGN(PrefetchBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_P(PrefetchBrowserTest, Simple) {
+  int target_fetch_count = 0;
+  const std::string prefetch_url = "/prefetch.html";
+  const std::string target_url = "/target.html";
+  RegisterResponse(prefetch_url,
+                   "<body><link rel='prefetch' href='/target.html'></body>");
+  RegisterResponse(target_url, "<head><title>Prefetch Target</title></head>");
+
+  base::RunLoop prefetch_waiter;
+  embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
+      &PrefetchBrowserTest::WatchURLAndRunClosure, base::Unretained(this),
+      target_url, &target_fetch_count, prefetch_waiter.QuitClosure()));
+  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
+      &PrefetchBrowserTest::ServeResponses, base::Unretained(this)));
+  ASSERT_TRUE(embedded_test_server()->Start());
+  EXPECT_EQ(0, target_fetch_count);
+
+  // Loading a page that prefetches the target URL would increment the
+  // |target_fetch_count|.
+  NavigateToURL(shell(), embedded_test_server()->GetURL(prefetch_url));
+  prefetch_waiter.Run();
+  EXPECT_EQ(1, target_fetch_count);
+
+  // Subsequent navigation to the target URL wouldn't hit the network for
+  // the target URL (therefore not increment |target_fetch_count|.
+  // The target content should still be read correctly.
+  base::string16 title = base::ASCIIToUTF16("Prefetch Target");
+  TitleWatcher title_watcher(shell()->web_contents(), title);
+  NavigateToURL(shell(), embedded_test_server()->GetURL(target_url));
+  EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
+  EXPECT_EQ(1, target_fetch_count);
+}
+
+INSTANTIATE_TEST_CASE_P(PrefetchBrowserTest,
+                        PrefetchBrowserTest,
+                        testing::Bool());
+
+}  // namespace content
diff --git a/content/browser/loader/source_stream_to_data_pipe.cc b/content/browser/loader/source_stream_to_data_pipe.cc
index 3f062ba5b..01f4b33 100644
--- a/content/browser/loader/source_stream_to_data_pipe.cc
+++ b/content/browser/loader/source_stream_to_data_pipe.cc
@@ -18,14 +18,7 @@
       completion_callback_(std::move(completion_callback)),
       writable_handle_watcher_(FROM_HERE,
                                mojo::SimpleWatcher::ArmingPolicy::MANUAL),
-      peer_closed_handle_watcher_(FROM_HERE,
-                                  mojo::SimpleWatcher::ArmingPolicy::MANUAL),
       weak_factory_(this) {
-  peer_closed_handle_watcher_.Watch(
-      dest_.get(), MOJO_HANDLE_SIGNAL_PEER_CLOSED,
-      base::BindRepeating(&SourceStreamToDataPipe::OnDataPipeClosed,
-                          base::Unretained(this)));
-  peer_closed_handle_watcher_.ArmOrNotify();
   writable_handle_watcher_.Watch(
       dest_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
       base::BindRepeating(&SourceStreamToDataPipe::OnDataPipeWritable,
@@ -48,6 +41,10 @@
     // The pipe is full.  We need to wait for it to have more space.
     writable_handle_watcher_.ArmOrNotify();
     return;
+  } else if (mojo_result == MOJO_RESULT_FAILED_PRECONDITION) {
+    // The data pipe consumer handle has been closed.
+    OnComplete(net::ERR_ABORTED);
+    return;
   } else if (mojo_result != MOJO_RESULT_OK) {
     // The body stream is in a bad state. Bail out.
     OnComplete(net::ERR_UNEXPECTED);
@@ -95,15 +92,10 @@
   ReadMore();
 }
 
-void SourceStreamToDataPipe::OnDataPipeClosed(MojoResult result) {
-  OnComplete(net::ERR_ABORTED);
-}
-
 void SourceStreamToDataPipe::OnComplete(int result) {
   // Resets the watchers, pipes and the exchange handler, so that
   // we will never be called back.
   writable_handle_watcher_.Cancel();
-  peer_closed_handle_watcher_.Cancel();
   pending_write_ = nullptr;  // Closes the data pipe if this was holding it.
   dest_.reset();
 
diff --git a/content/browser/loader/source_stream_to_data_pipe.h b/content/browser/loader/source_stream_to_data_pipe.h
index 6a7bcb5..7acd75e 100644
--- a/content/browser/loader/source_stream_to_data_pipe.h
+++ b/content/browser/loader/source_stream_to_data_pipe.h
@@ -7,6 +7,7 @@
 
 #include "base/callback_forward.h"
 #include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "mojo/public/cpp/system/simple_watcher.h"
 #include "services/network/public/cpp/net_adapters.h"
@@ -19,7 +20,7 @@
 
 // A convenient adapter class to read out data from net::SourceStream
 // and write them into a data pipe.
-class SourceStreamToDataPipe {
+class CONTENT_EXPORT SourceStreamToDataPipe {
  public:
   // Reads out the data from |source| and write into |dest|.
   SourceStreamToDataPipe(std::unique_ptr<net::SourceStream> source,
@@ -44,7 +45,6 @@
 
   scoped_refptr<network::NetToMojoPendingBuffer> pending_write_;
   mojo::SimpleWatcher writable_handle_watcher_;
-  mojo::SimpleWatcher peer_closed_handle_watcher_;
 
   base::WeakPtrFactory<SourceStreamToDataPipe> weak_factory_;
 };
diff --git a/content/browser/loader/source_stream_to_data_pipe_unittest.cc b/content/browser/loader/source_stream_to_data_pipe_unittest.cc
new file mode 100644
index 0000000..29e851f
--- /dev/null
+++ b/content/browser/loader/source_stream_to_data_pipe_unittest.cc
@@ -0,0 +1,194 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/source_stream_to_data_pipe.h"
+#include "base/optional.h"
+#include "base/test/scoped_task_environment.h"
+#include "net/filter/mock_source_stream.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+const int kBigPipeCapacity = 4096;
+const int kSmallPipeCapacity = 1;
+
+enum class ReadResultType {
+  // Each call to AddReadResult is a separate read from the lower layer
+  // SourceStream. This doesn't work with kSmallPipeCapacity, because
+  // MockSourceStream expects that IOBuffer size is not smaller than the data
+  // chunk passed to AddReadResult.
+  EVERYTHING_AT_ONCE,
+  // Whenever AddReadResult is called, each byte is actually a separate read
+  // result.
+  ONE_BYTE_AT_A_TIME,
+};
+
+struct SourceStreamToDataPipeTestParam {
+  SourceStreamToDataPipeTestParam(uint32_t pipe_capacity,
+                                  net::MockSourceStream::Mode read_mode,
+                                  ReadResultType read_result_type)
+      : pipe_capacity(pipe_capacity),
+        mode(read_mode),
+        read_result_type(read_result_type) {}
+
+  const uint32_t pipe_capacity;
+  const net::MockSourceStream::Mode mode;
+  const ReadResultType read_result_type;
+};
+
+}  // namespace
+
+class SourceStreamToDataPipeTest
+    : public ::testing::TestWithParam<SourceStreamToDataPipeTestParam> {
+ protected:
+  SourceStreamToDataPipeTest() {}
+
+  void Init() {
+    std::unique_ptr<net::MockSourceStream> source(new net::MockSourceStream());
+    if (GetParam().read_result_type == ReadResultType::ONE_BYTE_AT_A_TIME)
+      source->set_read_one_byte_at_a_time(true);
+    source_ = source.get();
+
+    const MojoCreateDataPipeOptions data_pipe_options{
+        sizeof(MojoCreateDataPipeOptions),
+        MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, 1, GetParam().pipe_capacity};
+    mojo::ScopedDataPipeProducerHandle producer_end;
+    CHECK_EQ(MOJO_RESULT_OK,
+             mojo::CreateDataPipe(&data_pipe_options, &producer_end,
+                                  &consumer_end_));
+
+    adapter_ = std::make_unique<SourceStreamToDataPipe>(
+        std::move(source), std::move(producer_end),
+        base::BindOnce(&SourceStreamToDataPipeTest::FinishedReading,
+                       base::Unretained(this)));
+  }
+
+  void CompleteReadsIfAsync() {
+    if (GetParam().mode == net::MockSourceStream::ASYNC) {
+      while (source()->awaiting_completion())
+        source()->CompleteNextRead();
+    }
+  }
+
+  // Reads from |consumer_end_| until an error occurs or the producer end is
+  // closed. Returns the value passed to the completion callback.
+  int ReadPipe(std::string* output) {
+    MojoResult result = MOJO_RESULT_OK;
+    while (result == MOJO_RESULT_OK || result == MOJO_RESULT_SHOULD_WAIT) {
+      char buffer[16];
+      uint32_t read_size = sizeof(buffer);
+      MojoResult result =
+          consumer_end().ReadData(buffer, &read_size, MOJO_READ_DATA_FLAG_NONE);
+      if (result == MOJO_RESULT_FAILED_PRECONDITION)
+        break;
+      if (result == MOJO_RESULT_SHOULD_WAIT) {
+        RunUntilIdle();
+        CompleteReadsIfAsync();
+      } else {
+        EXPECT_EQ(result, MOJO_RESULT_OK);
+        output->append(buffer, read_size);
+      }
+    }
+    EXPECT_TRUE(CallbackResult().has_value());
+    return *CallbackResult();
+  }
+
+  SourceStreamToDataPipe* adapter() { return adapter_.get(); }
+  net::MockSourceStream* source() { return source_; }
+  mojo::DataPipeConsumerHandle consumer_end() { return consumer_end_.get(); }
+
+  void CloseConsumerHandle() { consumer_end_.reset(); }
+  void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); }
+  base::Optional<int> CallbackResult() { return callback_result_; }
+
+ private:
+  void FinishedReading(int result) { callback_result_ = result; }
+
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
+  net::MockSourceStream* source_;
+  std::unique_ptr<SourceStreamToDataPipe> adapter_;
+  mojo::ScopedDataPipeConsumerHandle consumer_end_;
+  base::Optional<int> callback_result_;
+};
+
+INSTANTIATE_TEST_CASE_P(
+    SourceStreamToDataPipeTests,
+    SourceStreamToDataPipeTest,
+    ::testing::Values(
+        SourceStreamToDataPipeTestParam(kBigPipeCapacity,
+                                        net::MockSourceStream::SYNC,
+                                        ReadResultType::EVERYTHING_AT_ONCE),
+        SourceStreamToDataPipeTestParam(kBigPipeCapacity,
+                                        net::MockSourceStream::ASYNC,
+                                        ReadResultType::EVERYTHING_AT_ONCE),
+        SourceStreamToDataPipeTestParam(kBigPipeCapacity,
+                                        net::MockSourceStream::SYNC,
+                                        ReadResultType::ONE_BYTE_AT_A_TIME),
+        SourceStreamToDataPipeTestParam(kSmallPipeCapacity,
+                                        net::MockSourceStream::SYNC,
+                                        ReadResultType::ONE_BYTE_AT_A_TIME),
+        SourceStreamToDataPipeTestParam(kBigPipeCapacity,
+                                        net::MockSourceStream::ASYNC,
+                                        ReadResultType::ONE_BYTE_AT_A_TIME),
+        SourceStreamToDataPipeTestParam(kSmallPipeCapacity,
+                                        net::MockSourceStream::ASYNC,
+                                        ReadResultType::ONE_BYTE_AT_A_TIME)));
+
+TEST_P(SourceStreamToDataPipeTest, EmptyStream) {
+  Init();
+  source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
+  adapter()->Start();
+
+  std::string output;
+  EXPECT_EQ(ReadPipe(&output), net::OK);
+  EXPECT_TRUE(output.empty());
+}
+
+TEST_P(SourceStreamToDataPipeTest, Simple) {
+  const char message[] = "Hello, world!";
+
+  Init();
+  source()->AddReadResult(message, sizeof(message) - 1, net::OK,
+                          GetParam().mode);
+  source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
+  adapter()->Start();
+
+  std::string output;
+  EXPECT_EQ(ReadPipe(&output), net::OK);
+  EXPECT_EQ(output, message);
+}
+
+TEST_P(SourceStreamToDataPipeTest, Error) {
+  const char message[] = "Hello, world!";
+
+  Init();
+  source()->AddReadResult(message, sizeof(message) - 1, net::OK,
+                          GetParam().mode);
+  source()->AddReadResult(nullptr, 0, net::ERR_FAILED, GetParam().mode);
+  adapter()->Start();
+
+  std::string output;
+  EXPECT_EQ(ReadPipe(&output), net::ERR_FAILED);
+  EXPECT_EQ(output, message);
+}
+
+TEST_P(SourceStreamToDataPipeTest, ConsumerClosed) {
+  const char message[] = "a";
+
+  Init();
+  source()->AddReadResult(message, sizeof(message) - 1, net::OK,
+                          GetParam().mode);
+  adapter()->Start();
+
+  CloseConsumerHandle();
+  CompleteReadsIfAsync();
+  RunUntilIdle();
+
+  ASSERT_TRUE(CallbackResult().has_value());
+  EXPECT_EQ(*CallbackResult(), net::ERR_ABORTED);
+}
+
+}  // namespace content
diff --git a/content/browser/loader/web_package_request_handler_browsertest.cc b/content/browser/loader/web_package_request_handler_browsertest.cc
new file mode 100644
index 0000000..3ccba2b
--- /dev/null
+++ b/content/browser/loader/web_package_request_handler_browsertest.cc
@@ -0,0 +1,57 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
+#include "content/public/common/content_features.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "services/network/public/cpp/features.h"
+
+namespace content {
+
+class WebPackageRequestHandlerBrowserTest
+    : public ContentBrowserTest,
+      public testing::WithParamInterface<bool> {
+ public:
+  WebPackageRequestHandlerBrowserTest() = default;
+  ~WebPackageRequestHandlerBrowserTest() = default;
+
+  void SetUp() override {
+    if (is_network_service_enabled()) {
+      feature_list_.InitWithFeatures(
+          {features::kSignedHTTPExchange, network::features::kNetworkService},
+          {});
+    } else {
+      feature_list_.InitWithFeatures({features::kSignedHTTPExchange}, {});
+    }
+    ContentBrowserTest::SetUp();
+  }
+
+ private:
+  bool is_network_service_enabled() const { return GetParam(); }
+
+  base::test::ScopedFeatureList feature_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebPackageRequestHandlerBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_P(WebPackageRequestHandlerBrowserTest, Simple) {
+  embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL url =
+      embedded_test_server()->GetURL("/htxg/origin-signed-response.html");
+  base::string16 title = base::ASCIIToUTF16("https://example.com/test.html");
+  TitleWatcher title_watcher(shell()->web_contents(), title);
+  NavigateToURL(shell(), url);
+  EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
+}
+
+INSTANTIATE_TEST_CASE_P(WebPackageRequestHandlerBrowserTest,
+                        WebPackageRequestHandlerBrowserTest,
+                        testing::Bool());
+
+}  // namespace content
diff --git a/content/browser/media/media_devices_permission_checker.cc b/content/browser/media/media_devices_permission_checker.cc
index ba1971a..c3c25457 100644
--- a/content/browser/media/media_devices_permission_checker.cc
+++ b/content/browser/media/media_devices_permission_checker.cc
@@ -44,10 +44,10 @@
   bool mic_feature_policy = true;
   bool camera_feature_policy = true;
   if (base::FeatureList::IsEnabled(features::kUseFeaturePolicyForPermissions)) {
-    mic_feature_policy =
-        frame_host->IsFeatureEnabled(blink::FeaturePolicyFeature::kMicrophone);
-    camera_feature_policy =
-        frame_host->IsFeatureEnabled(blink::FeaturePolicyFeature::kCamera);
+    mic_feature_policy = frame_host->IsFeatureEnabled(
+        blink::mojom::FeaturePolicyFeature::kMicrophone);
+    camera_feature_policy = frame_host->IsFeatureEnabled(
+        blink::mojom::FeaturePolicyFeature::kCamera);
   }
 
   MediaDevicesManager::BoolDeviceTypes result;
diff --git a/content/browser/media/media_devices_permission_checker_unittest.cc b/content/browser/media/media_devices_permission_checker_unittest.cc
index ee97526..cfcf1a9 100644
--- a/content/browser/media/media_devices_permission_checker_unittest.cc
+++ b/content/browser/media/media_devices_permission_checker_unittest.cc
@@ -51,7 +51,7 @@
  protected:
   // The header policy should only be set once on page load, so we refresh the
   // page to simulate that.
-  void RefreshPageAndSetHeaderPolicy(blink::FeaturePolicyFeature feature,
+  void RefreshPageAndSetHeaderPolicy(blink::mojom::FeaturePolicyFeature feature,
                                      bool enabled) {
     NavigateAndCommit(origin_.GetURL());
     std::vector<url::Origin> whitelist;
@@ -108,12 +108,12 @@
   EXPECT_TRUE(CheckPermission(MEDIA_DEVICE_TYPE_AUDIO_INPUT));
   EXPECT_TRUE(CheckPermission(MEDIA_DEVICE_TYPE_VIDEO_INPUT));
 
-  RefreshPageAndSetHeaderPolicy(blink::FeaturePolicyFeature::kMicrophone,
+  RefreshPageAndSetHeaderPolicy(blink::mojom::FeaturePolicyFeature::kMicrophone,
                                 /*enabled=*/false);
   EXPECT_FALSE(CheckPermission(MEDIA_DEVICE_TYPE_AUDIO_INPUT));
   EXPECT_TRUE(CheckPermission(MEDIA_DEVICE_TYPE_VIDEO_INPUT));
 
-  RefreshPageAndSetHeaderPolicy(blink::FeaturePolicyFeature::kCamera,
+  RefreshPageAndSetHeaderPolicy(blink::mojom::FeaturePolicyFeature::kCamera,
                                 /*enabled=*/false);
   EXPECT_TRUE(CheckPermission(MEDIA_DEVICE_TYPE_AUDIO_INPUT));
   EXPECT_FALSE(CheckPermission(MEDIA_DEVICE_TYPE_VIDEO_INPUT));
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/content/browser/renderer_host/browser_compositor_view_mac.mm
index e4d6d2f9..e219c6c 100644
--- a/content/browser/renderer_host/browser_compositor_view_mac.mm
+++ b/content/browser/renderer_host/browser_compositor_view_mac.mm
@@ -284,6 +284,10 @@
     return;
   }
 
+  // Suspend the ui::Compositor until we get a renderer frame of the new size.
+  if (recyclable_compositor_)
+    recyclable_compositor_->Suspend();
+
   delegated_frame_host_surface_id_ =
       parent_local_surface_id_allocator_.GenerateId();
   delegated_frame_host_size_dip_ = size_dip;
@@ -346,14 +350,9 @@
     GetViewProperties(nullptr, nullptr, &color_space);
     recyclable_compositor_->compositor()->SetDisplayColorSpace(color_space);
 
-    // Unsuspend the browser compositor after showing the delegated frame host.
-    // If there is not a saved delegated frame, then the delegated frame host
-    // will keep the compositor locked until a delegated frame is swapped.
-    recyclable_compositor_->Unsuspend();
-
-    // If there exists a saved frame ready to display, resize the compositor to
-    // be ready to display that frame (if not, the compositor will be resized
-    // on first surface activation).
+    // If there exists a saved frame ready to display, unsuspend the compositor
+    // now (if one is not ready, the compositor will unsuspend on first surface
+    // activation).
     if (delegated_frame_host_->HasSavedFrame()) {
       if (compositor_scale_factor_ != delegated_frame_host_scale_factor_ ||
           compositor_size_pixels_ != delegated_frame_host_size_pixels_) {
@@ -367,6 +366,7 @@
             compositor_scale_factor_, compositor_size_pixels_,
             compositor_surface_id_);
       }
+      recyclable_compositor_->Unsuspend();
     }
 
     state_ = HasAttachedCompositor;
@@ -441,7 +441,7 @@
 }
 
 bool BrowserCompositorMac::DelegatedFrameHostIsVisible() const {
-  return state_ == HasAttachedCompositor;
+  return state_ == HasAttachedCompositor || state_ == HasDetachedCompositor;
 }
 
 SkColor BrowserCompositorMac::DelegatedFrameHostGetGutterColor() const {
@@ -463,6 +463,9 @@
     const viz::SurfaceInfo& surface_info) {
   if (!recyclable_compositor_)
     return;
+
+  recyclable_compositor_->Unsuspend();
+
   // Resize the compositor to match the current frame size, if needed.
   if (compositor_size_pixels_ == surface_info.size_in_pixels() &&
       compositor_scale_factor_ == surface_info.device_scale_factor()) {
@@ -480,10 +483,10 @@
   // Disable screen updates until the frame of the new size appears (because the
   // content is drawn in the GPU process, it may change before we want it to).
   if (repaint_state_ == RepaintState::Paused) {
-    gfx::Size compositor_size_dip = gfx::ConvertSizeToDIP(
-        compositor_scale_factor_, compositor_size_pixels_);
-    if (compositor_size_dip == delegated_frame_host_size_pixels_ ||
-        repaint_auto_resize_enabled_) {
+    bool compositor_is_nsview_size =
+        compositor_size_pixels_ == delegated_frame_host_size_pixels_ &&
+        compositor_scale_factor_ == delegated_frame_host_scale_factor_;
+    if (compositor_is_nsview_size || repaint_auto_resize_enabled_) {
       NSDisableScreenUpdates();
       repaint_state_ = RepaintState::ScreenUpdatesDisabled;
     }
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc
index 332ec6d7..5de1bcc8 100644
--- a/content/browser/renderer_host/delegated_frame_host.cc
+++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -130,30 +130,55 @@
     const gfx::Size& output_size,
     const ReadbackRequestCallback& callback,
     const SkColorType preferred_color_type) {
-  // Only ARGB888 and RGB565 supported as of now.
-  bool format_support = ((preferred_color_type == kAlpha_8_SkColorType) ||
-                         (preferred_color_type == kRGB_565_SkColorType) ||
-                         (preferred_color_type == kN32_SkColorType));
-  DCHECK(format_support);
-  if (!CanCopyFromCompositingSurface()) {
+  // TODO(crbug/759310): Only NavigationEntryScreenshotManager needs grayscale.
+  // Move that transformation to there; and then remove |preferred_color_type|
+  // from this API and the end-to-end code path.
+  DCHECK(preferred_color_type == kN32_SkColorType ||
+         preferred_color_type == kAlpha_8_SkColorType);
+
+  if (!CanCopyFromCompositingSurface() ||
+      current_frame_size_in_dip_.IsEmpty()) {
     callback.Run(SkBitmap(), content::READBACK_SURFACE_UNAVAILABLE);
     return;
   }
 
   std::unique_ptr<viz::CopyOutputRequest> request =
       std::make_unique<viz::CopyOutputRequest>(
-          viz::CopyOutputRequest::ResultFormat::RGBA_TEXTURE,
-          base::BindOnce(&CopyFromCompositingSurfaceHasResult, output_size,
+          viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
+          base::BindOnce(&CopyFromCompositingSurfaceHasResult, gfx::Size(),
                          preferred_color_type, callback));
-  if (!src_subrect.IsEmpty()) {
-    request->set_area(
-        gfx::ScaleToRoundedRect(src_subrect, active_device_scale_factor_));
+
+  if (src_subrect.IsEmpty()) {
+    request->set_area(gfx::Rect(current_frame_size_in_dip_));
+  } else {
+    request->set_area(src_subrect);
   }
-  support_->RequestCopyOfSurface(std::move(request));
+
+  // If VIZ display compositing is disabled, the request will be issued directly
+  // to CompositorFrameSinkSupport, which requires Surface pixel coordinates.
+  if (!enable_viz_) {
+    request->set_area(
+        gfx::ScaleToRoundedRect(request->area(), active_device_scale_factor_));
+  }
+
+  if (!output_size.IsEmpty()) {
+    request->set_result_selection(gfx::Rect(output_size));
+    request->SetScaleRatio(
+        gfx::Vector2d(request->area().width(), request->area().height()),
+        gfx::Vector2d(output_size.width(), output_size.height()));
+  }
+
+  if (enable_viz_) {
+    client_->DelegatedFrameHostGetLayer()->RequestCopyOfOutput(
+        std::move(request));
+  } else {
+    support_->RequestCopyOfSurface(std::move(request));
+  }
 }
 
 bool DelegatedFrameHost::CanCopyFromCompositingSurface() const {
-  return support_ && HasFallbackSurface() && active_device_scale_factor_ != 0.f;
+  return (enable_viz_ || support_) && HasFallbackSurface() &&
+         active_device_scale_factor_ != 0.f;
 }
 
 viz::FrameSinkId DelegatedFrameHost::GetFrameSinkId() {
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy.cc b/content/browser/renderer_host/media/media_stream_ui_proxy.cc
index 0e4fff2..16f7c23 100644
--- a/content/browser/renderer_host/media/media_stream_ui_proxy.cc
+++ b/content/browser/renderer_host/media/media_stream_ui_proxy.cc
@@ -16,7 +16,7 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "media/capture/video/fake_video_capture_device.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -24,7 +24,7 @@
 
 bool IsFeatureEnabled(RenderFrameHost* rfh,
                       bool tests_use_fake_render_frame_hosts,
-                      blink::FeaturePolicyFeature feature) {
+                      blink::mojom::FeaturePolicyFeature feature) {
   if (!base::FeatureList::IsEnabled(features::kUseFeaturePolicyForPermissions))
     return true;
 
@@ -152,13 +152,13 @@
   for (const MediaStreamDevice& device : devices) {
     if (device.type == MEDIA_DEVICE_AUDIO_CAPTURE &&
         !IsFeatureEnabled(host, tests_use_fake_render_frame_hosts_,
-                          blink::FeaturePolicyFeature::kMicrophone)) {
+                          blink::mojom::FeaturePolicyFeature::kMicrophone)) {
       continue;
     }
 
     if (device.type == MEDIA_DEVICE_VIDEO_CAPTURE &&
         !IsFeatureEnabled(host, tests_use_fake_render_frame_hosts_,
-                          blink::FeaturePolicyFeature::kCamera)) {
+                          blink::mojom::FeaturePolicyFeature::kCamera)) {
       continue;
     }
 
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc b/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
index 4e3e6eb1..8504a813 100644
--- a/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
@@ -277,7 +277,7 @@
   // The header policy should only be set once on page load, so we refresh the
   // page to simulate that.
   void RefreshPageAndSetHeaderPolicy(RenderFrameHost* rfh,
-                                     blink::FeaturePolicyFeature feature,
+                                     blink::mojom::FeaturePolicyFeature feature,
                                      bool enabled) {
     NavigateAndCommit(rfh->GetLastCommittedURL());
     std::vector<url::Origin> whitelist;
@@ -387,7 +387,7 @@
 
   // Mic disabled.
   RefreshPageAndSetHeaderPolicy(main_rfh(),
-                                blink::FeaturePolicyFeature::kMicrophone,
+                                blink::mojom::FeaturePolicyFeature::kMicrophone,
                                 /*enabled=*/false);
   GetResultForRequest(CreateRequest(main_rfh(), MEDIA_DEVICE_AUDIO_CAPTURE,
                                     MEDIA_DEVICE_VIDEO_CAPTURE),
@@ -398,7 +398,7 @@
 
   // Camera disabled.
   RefreshPageAndSetHeaderPolicy(main_rfh(),
-                                blink::FeaturePolicyFeature::kCamera,
+                                blink::mojom::FeaturePolicyFeature::kCamera,
                                 /*enabled=*/false);
   GetResultForRequest(CreateRequest(main_rfh(), MEDIA_DEVICE_AUDIO_CAPTURE,
                                     MEDIA_DEVICE_VIDEO_CAPTURE),
@@ -409,7 +409,7 @@
 
   // Camera disabled resulting in no devices being returned.
   RefreshPageAndSetHeaderPolicy(main_rfh(),
-                                blink::FeaturePolicyFeature::kCamera,
+                                blink::mojom::FeaturePolicyFeature::kCamera,
                                 /*enabled=*/false);
   GetResultForRequest(
       CreateRequest(main_rfh(), MEDIA_NO_SERVICE, MEDIA_DEVICE_VIDEO_CAPTURE),
diff --git a/content/browser/renderer_host/media/peer_connection_tracker_host.cc b/content/browser/renderer_host/media/peer_connection_tracker_host.cc
index 5d427b1..33d5906 100644
--- a/content/browser/renderer_host/media/peer_connection_tracker_host.cc
+++ b/content/browser/renderer_host/media/peer_connection_tracker_host.cc
@@ -90,6 +90,12 @@
 
 void PeerConnectionTrackerHost::OnUpdatePeerConnection(
     int lid, const std::string& type, const std::string& value) {
+  // TODO(eladalon): Get rid of magic value. https://crbug.com/810383
+  if (type == "stop") {
+    auto* manager = WebRtcEventLogManager::GetInstance();
+    manager->PeerConnectionStopped(render_process_id_, lid);
+  }
+
   WebRTCInternals* webrtc_internals = WebRTCInternals::GetInstance();
   if (webrtc_internals) {
     webrtc_internals->OnUpdatePeerConnection(peer_pid(), lid, type, value);
diff --git a/content/browser/renderer_host/render_widget_host_browsertest.cc b/content/browser/renderer_host/render_widget_host_browsertest.cc
new file mode 100644
index 0000000..6b225e8
--- /dev/null
+++ b/content/browser/renderer_host/render_widget_host_browsertest.cc
@@ -0,0 +1,97 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/optional.h"
+#include "base/run_loop.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
+#include "components/viz/common/features.h"
+#include "components/viz/common/frame_sinks/copy_output_request.h"
+#include "components/viz/common/frame_sinks/copy_output_result.h"
+#include "components/viz/common/quads/compositor_frame.h"
+#include "components/viz/common/quads/render_pass.h"
+#include "components/viz/common/surfaces/local_surface_id.h"
+#include "content/browser/bad_message.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace content {
+
+class RenderWidgetHostBrowserTest : public ContentBrowserTest {};
+
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostBrowserTest,
+                       ProhibitsCopyRequestsFromRenderer) {
+  NavigateToURL(shell(), GURL("data:text/html,<!doctype html>"
+                              "<body style='background-color: red;'></body>"));
+
+  // Wait for the view's surface to become available.
+  auto* const view = static_cast<RenderWidgetHostViewBase*>(
+      shell()->web_contents()->GetRenderWidgetHostView());
+  while (!view->IsSurfaceAvailableForCopy()) {
+    base::RunLoop run_loop;
+    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+        FROM_HERE, run_loop.QuitClosure(),
+        base::TimeDelta::FromMilliseconds(250));
+    run_loop.Run();
+  }
+
+  // The browser process should be allowed to make a CopyOutputRequest.
+  bool did_receive_copy_result = false;
+  base::RunLoop run_loop;
+  view->CopyFromSurface(
+      gfx::Rect(), gfx::Size(),
+      // TODO(crbug/759310): This should be a OnceCallback.
+      base::BindRepeating(
+          [](bool* success, base::OnceClosure quit_closure,
+             const SkBitmap& bitmap, ReadbackResponse response) {
+            *success = (response == READBACK_SUCCESS && bitmap.readyToDraw());
+            std::move(quit_closure).Run();
+          },
+          &did_receive_copy_result, run_loop.QuitClosure()),
+      kN32_SkColorType);
+  run_loop.Run();
+  ASSERT_TRUE(did_receive_copy_result);
+
+  // Create a simulated-from-renderer CompositorFrame with a CopyOutputRequest.
+  viz::CompositorFrame frame;
+  std::unique_ptr<viz::RenderPass> pass = viz::RenderPass::Create();
+  const gfx::Rect& output_rect = gfx::Rect(view->GetPhysicalBackingSize());
+  pass->SetNew(1 /* render pass id */, output_rect, output_rect,
+               gfx::Transform());
+  bool did_receive_aborted_copy_result = false;
+  pass->copy_requests.push_back(std::make_unique<viz::CopyOutputRequest>(
+      viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
+      base::BindOnce(
+          [](bool* got_nothing, std::unique_ptr<viz::CopyOutputResult> result) {
+            *got_nothing = result->IsEmpty();
+          },
+          &did_receive_aborted_copy_result)));
+  frame.render_pass_list.push_back(std::move(pass));
+
+  // Submit the frame and expect the renderer to be instantly killed.
+  auto* const host = RenderWidgetHostImpl::From(view->GetRenderWidgetHost());
+  RenderProcessHostKillWaiter waiter(host->GetProcess());
+  host->SubmitCompositorFrame(viz::LocalSurfaceId(), std::move(frame), nullptr,
+                              0);
+  base::Optional<bad_message::BadMessageReason> result = waiter.Wait();
+  ASSERT_TRUE(result.has_value());
+  EXPECT_EQ(bad_message::RWH_COPY_REQUEST_ATTEMPT, *result);
+
+  // Check that the copy request result callback received an empty result. In a
+  // normal browser, the requestor (in the render process) might never see a
+  // response to the copy request before the process is killed. Nevertheless,
+  // ensure the result is empty, just in case there is a race.
+  EXPECT_TRUE(did_receive_aborted_copy_result);
+}
+
+}  // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index e148651..f0a1cbd 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -2697,6 +2697,17 @@
   // TODO(gklassen): Route hit-test data to appropriate HitTestAggregator.
   TRACE_EVENT_FLOW_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
                         "SubmitCompositorFrame", local_surface_id.hash());
+
+  // Ensure there are no CopyOutputRequests stowed-away in the CompositorFrame.
+  // For security/privacy reasons, renderers are not allowed to make copy
+  // requests because they could use this to gain access to content from another
+  // domain (e.g., in a child frame).
+  if (frame.HasCopyOutputRequests()) {
+    bad_message::ReceivedBadMessage(GetProcess(),
+                                    bad_message::RWH_COPY_REQUEST_ATTEMPT);
+    return;
+  }
+
   bool tracing_enabled;
   TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
                                      &tracing_enabled);
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
index 36ecff7..dc04069d 100644
--- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -32,6 +32,7 @@
 #include "content/test/did_commit_provisional_load_interceptor.h"
 #include "net/base/filename_util.h"
 #include "net/dns/mock_host_resolver.h"
+#include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/layout.h"
 #include "ui/display/display_switches.h"
@@ -117,34 +118,6 @@
       quit_closure.Run();
   }
 
-  // Copy one frame using the CopyFromSurface API.
-  void RunBasicCopyFromSurfaceTest() {
-    SET_UP_SURFACE_OR_PASS_TEST(nullptr);
-
-    // Repeatedly call CopyFromBackingStore() since, on some platforms (e.g.,
-    // Windows), the operation will fail until the first "present" has been
-    // made.
-    int count_attempts = 0;
-    while (true) {
-      ++count_attempts;
-      base::RunLoop run_loop;
-      GetRenderWidgetHostView()->CopyFromSurface(
-          gfx::Rect(), frame_size(),
-          base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromSurface,
-                     base::Unretained(this), run_loop.QuitClosure()),
-          kN32_SkColorType);
-      run_loop.Run();
-
-      if (frames_captured())
-        break;
-      else
-        GiveItSomeTime();
-    }
-
-    EXPECT_EQ(count_attempts, callback_invoke_count());
-    EXPECT_EQ(1, frames_captured());
-  }
-
  protected:
   // Waits until the source is available for copying.
   void WaitForCopySourceReady() {
@@ -158,7 +131,7 @@
     base::RunLoop run_loop;
     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
         FROM_HERE, run_loop.QuitClosure(),
-        base::TimeDelta::FromMilliseconds(10));
+        base::TimeDelta::FromMilliseconds(250));
     run_loop.Run();
   }
 
@@ -258,6 +231,7 @@
   void SetUp() override {
     if (compositing_mode_ == SOFTWARE_COMPOSITING)
       UseSoftwareCompositing();
+    EnablePixelOutput();
     RenderWidgetHostViewBrowserTest::SetUp();
   }
 
@@ -295,13 +269,43 @@
 // enabled.
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
                        CopyFromSurface) {
-  RunBasicCopyFromSurfaceTest();
+  SET_UP_SURFACE_OR_PASS_TEST(nullptr);
+
+  // Repeatedly call CopyFromSurface() since, on some platforms (e.g., Windows),
+  // the operation will fail until the first "present" has been made.
+  int count_attempts = 0;
+  while (true) {
+    ++count_attempts;
+    base::RunLoop run_loop;
+    GetRenderWidgetHostView()->CopyFromSurface(
+        gfx::Rect(), frame_size(),
+        // TODO(crbug/759310): This should be a OnceCallback.
+        base::BindRepeating(
+            &RenderWidgetHostViewBrowserTest::FinishCopyFromSurface,
+            base::Unretained(this), run_loop.QuitClosure()),
+        kN32_SkColorType);
+    run_loop.Run();
+
+    if (frames_captured())
+      break;
+    else
+      GiveItSomeTime();
+  }
+
+  EXPECT_EQ(count_attempts, callback_invoke_count());
+  EXPECT_EQ(1, frames_captured());
 }
 
 // Tests that the callback passed to CopyFromSurface is always called, even
 // when the RenderWidgetHostView is deleting in the middle of an async copy.
+//
+// TODO(miu): On some bots (e.g., ChromeOS and Cast Shell), this test fails
+// because the RunLoop quits before its QuitClosure() is run. This is because
+// the call to WebContents::Close() leads to something that makes the current
+// thread's RunLoop::Delegate constantly report "should quit." We'll need to
+// find a better way of testing this functionality.
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
-                       CopyFromSurface_CallbackDespiteDelete) {
+                       DISABLED_CopyFromSurface_CallbackDespiteDelete) {
   SET_UP_SURFACE_OR_PASS_TEST(nullptr);
 
   base::RunLoop run_loop;
@@ -310,6 +314,7 @@
       base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromSurface,
                  base::Unretained(this), run_loop.QuitClosure()),
       kN32_SkColorType);
+  shell()->web_contents()->Close();
   run_loop.Run();
 
   EXPECT_EQ(1, callback_invoke_count());
@@ -323,11 +328,6 @@
         allowable_error_(0),
         test_url_("data:text/html,<!doctype html>") {}
 
-  void SetUp() override {
-    EnablePixelOutput();
-    CompositingRenderWidgetHostViewBrowserTest::SetUp();
-  }
-
   void ReadbackRequestCallbackTest(base::Closure quit_callback,
                                    const SkBitmap& bitmap,
                                    ReadbackResponse response) {
@@ -374,6 +374,12 @@
         expected_copy_from_compositing_surface_bitmap_;
     EXPECT_EQ(expected_bitmap.width(), bitmap.width());
     EXPECT_EQ(expected_bitmap.height(), bitmap.height());
+    if (expected_bitmap.width() != bitmap.width() ||
+        expected_bitmap.height() != bitmap.height()) {
+      readback_response_ = READBACK_INCORRECT_RESULT_SIZE;
+      quit_callback.Run();
+      return;
+    }
     EXPECT_EQ(expected_bitmap.colorType(), bitmap.colorType());
     int fails = 0;
     for (int i = 0; i < bitmap.width() && fails < 10; ++i) {
@@ -484,14 +490,13 @@
     //      is allowed to transiently fail.  The purpose of these tests is to
     //      confirm correct cropping/scaling behavior; and not that every
     //      readback must succeed.  http://crbug.com/444237
-    uint32_t last_frame_number = 0;
+    int attempt_count = 0;
     do {
-      // Wait for renderer to provide the next frame.
-      while (!GetRenderWidgetHost()->ScheduleComposite())
+      // Wait a little before retrying again. This gives the most up-to-date
+      // frame a chance to propagate from the renderer to the compositor.
+      if (attempt_count > 0)
         GiveItSomeTime();
-      while (rwhv->RendererFrameNumber() == last_frame_number)
-        GiveItSomeTime();
-      last_frame_number = rwhv->RendererFrameNumber();
+      ++attempt_count;
 
       // Request readback.  The callbacks will examine the pixels in the
       // SkBitmap result if readback was successful.
@@ -515,24 +520,28 @@
       // If the readback operation did not provide a frame, log the reason
       // to aid in future debugging.  This information will also help determine
       // whether the implementation is broken, or a test bot is in a bad state.
-      #define CASE_LOG_READBACK_WARNING(enum_value) \
-        case enum_value: \
-          LOG(WARNING) << "Readback attempt failed (render frame #" \
-                       << last_frame_number << ").  Reason: " #enum_value; \
-          break
+      // clang-format off
       switch (readback_response_) {
         case READBACK_SUCCESS:
           break;
+        #define CASE_LOG_READBACK_WARNING(enum_value)                    \
+          case enum_value:                                               \
+            LOG(WARNING) << "Readback attempt failed (attempt #"         \
+                         << attempt_count << ").  Reason: " #enum_value; \
+            break
         CASE_LOG_READBACK_WARNING(READBACK_FAILED);
         CASE_LOG_READBACK_WARNING(READBACK_SURFACE_UNAVAILABLE);
         CASE_LOG_READBACK_WARNING(READBACK_BITMAP_ALLOCATION_FAILURE);
         CASE_LOG_READBACK_WARNING(READBACK_NO_TEST_COLORS);
+        CASE_LOG_READBACK_WARNING(READBACK_INCORRECT_RESULT_SIZE);
         default:
           LOG(ERROR)
               << "Invalid readback response value: " << readback_response_;
           NOTREACHED();
       }
-    } while (readback_response_ != READBACK_SUCCESS);
+      // clang-format on
+    } while (readback_response_ != READBACK_SUCCESS &&
+             !testing::Test::HasFailure());
   }
 
   // Sets up |bitmap| to have size |copy_size|. It floods the left half with
@@ -556,6 +565,7 @@
   enum ExtraReadbackResponsesForTest {
     READBACK_NO_RESPONSE = -1337,
     READBACK_NO_TEST_COLORS,
+    READBACK_INCORRECT_RESULT_SIZE,
   };
 
   virtual bool ShouldContinueAfterTestURLLoad() {
diff --git a/content/browser/service_worker/service_worker_handle.cc b/content/browser/service_worker/service_worker_handle.cc
index 40003a3..9164ce2 100644
--- a/content/browser/service_worker/service_worker_handle.cc
+++ b/content/browser/service_worker/service_worker_handle.cc
@@ -12,6 +12,7 @@
 #include "content/common/service_worker/service_worker_messages.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/common/browser_side_navigation_policy.h"
 #include "content/public/common/service_worker_modes.h"
 
 namespace content {
@@ -78,7 +79,8 @@
 
 void ServiceWorkerHandle::RegisterIntoDispatcherHost(
     ServiceWorkerDispatcherHost* dispatcher_host) {
-  DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+  DCHECK(ServiceWorkerUtils::IsServicificationEnabled() ||
+         IsNavigationMojoResponseEnabled());
   DCHECK(!dispatcher_host_);
   dispatcher_host_ = dispatcher_host;
   dispatcher_host_->RegisterServiceWorkerHandle(base::WrapUnique(this));
@@ -95,7 +97,8 @@
   // S13nServiceWorker: This handle may have been precreated before registering
   // to a dispatcher host. Just self-destruct since we're no longer needed.
   if (!dispatcher_host_) {
-    DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+    DCHECK(ServiceWorkerUtils::IsServicificationEnabled() ||
+           IsNavigationMojoResponseEnabled());
     delete this;
     return;
   }
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc
index 885f2c8..409aa62 100644
--- a/content/browser/service_worker/service_worker_provider_host.cc
+++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -509,7 +509,8 @@
   if (!context_ || !version)
     return nullptr;
   if (!dispatcher_host_) {
-    DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+    DCHECK(ServiceWorkerUtils::IsServicificationEnabled() ||
+           IsNavigationMojoResponseEnabled());
     blink::mojom::ServiceWorkerObjectInfoPtr info;
     // This is called before the dispatcher host is created.
     // |precreated_controller_handle_| instance's lifetime is controlled by its
@@ -608,7 +609,8 @@
   if (!controller_)
     return;
 
-  if (ServiceWorkerUtils::IsServicificationEnabled() &&
+  if ((ServiceWorkerUtils::IsServicificationEnabled() ||
+       IsNavigationMojoResponseEnabled()) &&
       precreated_controller_handle_) {
     // S13nServiceWorker: register the pre-created handle for the controller
     // service worker with the dispatcher host, now that it exists.
@@ -619,10 +621,12 @@
     precreated_controller_handle_ = nullptr;
   }
 
-  // In S13nServiceWorker case the controller is already sent in navigation
-  // commit, but we still need this for S13nServiceWorker case for setting the
-  // use counter correctly.
-  // TODO(kinuko): Stop doing this in S13nServiceWorker case.
+  // In S13nServiceWorker/NavigationMojoResponse case the controller is already
+  // sent in navigation commit, but we still need this for
+  // S13nServiceWorker/NavigationMojoResponse case for setting the use counter
+  // correctly.
+  // TODO(kinuko): Stop doing this in S13nServiceWorker/NavigationMojoResponse
+  // case.
   SendSetControllerServiceWorker(false /* notify_controllerchange */);
 }
 
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h
index 064855f..28a80da 100644
--- a/content/browser/service_worker/service_worker_provider_host.h
+++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -572,7 +572,7 @@
 
   std::vector<base::Closure> queued_events_;
 
-  // S13nServiceWorker:
+  // S13nServiceWorker/NavigationMojoResponse:
   // A service worker handle for the controller service worker that is
   // pre-created before the renderer process (and therefore the dispatcher host)
   // is created.
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index aadc91b..a5d4fc7 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -649,8 +649,9 @@
         "FeaturePolicy,FeaturePolicyExperimentalFeatures");
   }
 
-  blink::ParsedFeaturePolicy CreateFPHeader(blink::FeaturePolicyFeature feature,
-                                            const std::vector<GURL>& origins) {
+  blink::ParsedFeaturePolicy CreateFPHeader(
+      blink::mojom::FeaturePolicyFeature feature,
+      const std::vector<GURL>& origins) {
     blink::ParsedFeaturePolicy result(1);
     result[0].feature = feature;
     result[0].matches_all_origins = false;
@@ -661,7 +662,7 @@
   }
 
   blink::ParsedFeaturePolicy CreateFPHeaderMatchesAll(
-      blink::FeaturePolicyFeature feature) {
+      blink::mojom::FeaturePolicyFeature feature) {
     blink::ParsedFeaturePolicy result(1);
     result[0].feature = feature;
     result[0].matches_all_origins = true;
@@ -8196,15 +8197,16 @@
   EXPECT_TRUE(NavigateToURL(shell(), start_url));
 
   FrameTreeNode* root = web_contents()->GetFrameTree()->root();
-  EXPECT_EQ(CreateFPHeader(blink::FeaturePolicyFeature::kVibrate,
+  EXPECT_EQ(CreateFPHeader(blink::mojom::FeaturePolicyFeature::kVibrate,
                            {start_url.GetOrigin()}),
             root->current_replication_state().feature_policy_header);
 
   // When the main frame navigates to a page with a new policy, it should
   // overwrite the old one.
   EXPECT_TRUE(NavigateToURL(shell(), first_nav_url));
-  EXPECT_EQ(CreateFPHeaderMatchesAll(blink::FeaturePolicyFeature::kVibrate),
-            root->current_replication_state().feature_policy_header);
+  EXPECT_EQ(
+      CreateFPHeaderMatchesAll(blink::mojom::FeaturePolicyFeature::kVibrate),
+      root->current_replication_state().feature_policy_header);
 
   // When the main frame navigates to a page without a policy, the replicated
   // policy header should be cleared.
@@ -8223,15 +8225,16 @@
   EXPECT_TRUE(NavigateToURL(shell(), start_url));
 
   FrameTreeNode* root = web_contents()->GetFrameTree()->root();
-  EXPECT_EQ(CreateFPHeader(blink::FeaturePolicyFeature::kVibrate,
+  EXPECT_EQ(CreateFPHeader(blink::mojom::FeaturePolicyFeature::kVibrate,
                            {start_url.GetOrigin()}),
             root->current_replication_state().feature_policy_header);
 
   // When the main frame navigates to a page with a new policy, it should
   // overwrite the old one.
   EXPECT_TRUE(NavigateToURL(shell(), first_nav_url));
-  EXPECT_EQ(CreateFPHeaderMatchesAll(blink::FeaturePolicyFeature::kVibrate),
-            root->current_replication_state().feature_policy_header);
+  EXPECT_EQ(
+      CreateFPHeaderMatchesAll(blink::mojom::FeaturePolicyFeature::kVibrate),
+      root->current_replication_state().feature_policy_header);
 
   // When the main frame navigates to a page without a policy, the replicated
   // policy header should be cleared.
@@ -8252,19 +8255,19 @@
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
 
   FrameTreeNode* root = web_contents()->GetFrameTree()->root();
-  EXPECT_EQ(CreateFPHeader(blink::FeaturePolicyFeature::kVibrate,
+  EXPECT_EQ(CreateFPHeader(blink::mojom::FeaturePolicyFeature::kVibrate,
                            {main_url.GetOrigin(), GURL("http://example.com/")}),
             root->current_replication_state().feature_policy_header);
   EXPECT_EQ(1UL, root->child_count());
   EXPECT_EQ(
-      CreateFPHeader(blink::FeaturePolicyFeature::kVibrate,
+      CreateFPHeader(blink::mojom::FeaturePolicyFeature::kVibrate,
                      {main_url.GetOrigin()}),
       root->child_at(0)->current_replication_state().feature_policy_header);
 
   // Navigate the iframe cross-site.
   NavigateFrameToURL(root->child_at(0), first_nav_url);
   EXPECT_EQ(
-      CreateFPHeaderMatchesAll(blink::FeaturePolicyFeature::kVibrate),
+      CreateFPHeaderMatchesAll(blink::mojom::FeaturePolicyFeature::kVibrate),
       root->child_at(0)->current_replication_state().feature_policy_header);
 
   // Navigate the iframe to another location, this one with no policy header
@@ -8276,7 +8279,7 @@
   // Navigate the iframe back to a page with a policy
   NavigateFrameToURL(root->child_at(0), first_nav_url);
   EXPECT_EQ(
-      CreateFPHeaderMatchesAll(blink::FeaturePolicyFeature::kVibrate),
+      CreateFPHeaderMatchesAll(blink::mojom::FeaturePolicyFeature::kVibrate),
       root->child_at(0)->current_replication_state().feature_policy_header);
 }
 
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index 2d82c0d..3596ae22 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -1080,8 +1080,6 @@
 void WebContentsViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
                                           const gfx::Rect& new_bounds) {
   SizeChangedCommon(new_bounds.size());
-  if (delegate_)
-    delegate_->SizeChanged(new_bounds.size());
 
   // Constrained web dialogs, need to be kept centered over our content area.
   for (size_t i = 0; i < window_->children().size(); i++) {
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm
index 2c5dd9e9..97016f03 100644
--- a/content/browser/web_contents/web_contents_view_mac.mm
+++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -708,9 +708,6 @@
 - (void)setFrameSize:(NSSize)newSize {
   [super setFrameSize:newSize];
 
-  if (webContentsView_ && webContentsView_->delegate())
-    webContentsView_->delegate()->SizeChanged(gfx::Size(newSize));
-
   // Perform manual layout of subviews, e.g., when the window size changes.
   for (NSView* subview in [self subviews])
     [subview setFrame:[self bounds]];
diff --git a/content/browser/webrtc/webrtc_browsertest.cc b/content/browser/webrtc/webrtc_browsertest.cc
index ba8df2a1..faa28c8 100644
--- a/content/browser/webrtc/webrtc_browsertest.cc
+++ b/content/browser/webrtc/webrtc_browsertest.cc
@@ -177,7 +177,13 @@
 
 // This test will modify the SDP offer to use no encryption, which should
 // cause SetLocalDescription to fail.
-IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, NegotiateNonCryptoCall) {
+// Flaky on MAC: http://crbug/810321.
+#if defined(OS_MACOSX)
+#define MAYBE_NegotiateNonCryptoCall DISABLED_NegotiateNonCryptoCall
+#else
+#define MAYBE_NegotiateNonCryptoCall NegotiateNonCryptoCall
+#endif
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, MAYBE_NegotiateNonCryptoCall) {
   MakeTypicalPeerConnectionCall("negotiateNonCryptoCall();");
 }
 
diff --git a/content/browser/webrtc/webrtc_event_log_manager.cc b/content/browser/webrtc/webrtc_event_log_manager.cc
index 358d1f7..91cf5f88 100644
--- a/content/browser/webrtc/webrtc_event_log_manager.cc
+++ b/content/browser/webrtc/webrtc_event_log_manager.cc
@@ -81,14 +81,18 @@
 }
 
 WebRtcEventLogManager::WebRtcEventLogManager()
+    : WebRtcEventLogManager(base::CreateSequencedTaskRunnerWithTraits(
+          {base::MayBlock(), base::TaskPriority::BACKGROUND,
+           base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {}
+
+WebRtcEventLogManager::WebRtcEventLogManager(
+    const scoped_refptr<base::SequencedTaskRunner>& task_runner)
     : local_logs_observer_(nullptr),
       remote_logs_observer_(nullptr),
       local_logs_manager_(this),
       remote_logs_manager_(this),
       pc_tracker_proxy_(new PeerConnectionTrackerProxyImpl),
-      task_runner_(base::CreateSequencedTaskRunnerWithTraits(
-          {base::MayBlock(), base::TaskPriority::BACKGROUND,
-           base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {
+      task_runner_(task_runner) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(!g_webrtc_event_log_manager);
   g_webrtc_event_log_manager = this;
@@ -182,6 +186,13 @@
                      GetBrowserContextId(browser_context), std::move(reply)));
 }
 
+void WebRtcEventLogManager::PeerConnectionStopped(
+    int render_process_id,
+    int lid,
+    base::OnceCallback<void(bool)> reply) {
+  return PeerConnectionRemoved(render_process_id, lid, std::move(reply));
+}
+
 void WebRtcEventLogManager::EnableLocalLogging(
     const base::FilePath& base_path,
     size_t max_file_size_bytes,
@@ -266,15 +277,9 @@
                      base::Unretained(this), observer, std::move(reply)));
 }
 
-void WebRtcEventLogManager::SetTaskRunnerForTesting(
-    const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
-  // Testing function only - threading left for the caller's discretion.
-  task_runner_ = task_runner;
-}
-
 scoped_refptr<base::SequencedTaskRunner>&
 WebRtcEventLogManager::GetTaskRunnerForTesting() {
-  // Testing function only - threading left for the caller's discretion.
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   return task_runner_;
 }
 
@@ -533,22 +538,65 @@
   }
 }
 
-void WebRtcEventLogManager::SetClockForTesting(base::Clock* clock) {
-  // Testing function only - threading left for the caller's discretion.
-  local_logs_manager_.SetClockForTesting(clock);
+void WebRtcEventLogManager::SetClockForTesting(base::Clock* clock,
+                                               base::OnceClosure reply) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  auto task = [](WebRtcEventLogManager* manager, base::Clock* clock,
+                 base::OnceClosure reply) {
+    manager->local_logs_manager_.SetClockForTesting(clock);
+    if (reply) {
+      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(reply));
+    }
+  };
+
+  // Posting to task queue owned by the unretained object - unretained is safe.
+  task_runner_->PostTask(FROM_HERE, base::BindOnce(task, base::Unretained(this),
+                                                   clock, std::move(reply)));
 }
 
 void WebRtcEventLogManager::SetPeerConnectionTrackerProxyForTesting(
-    std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy) {
-  // Testing function only - threading left for the caller's discretion.
-  pc_tracker_proxy_ = std::move(pc_tracker_proxy);
+    std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy,
+    base::OnceClosure reply) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  auto task = [](WebRtcEventLogManager* manager,
+                 std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy,
+                 base::OnceClosure reply) {
+    manager->pc_tracker_proxy_ = std::move(pc_tracker_proxy);
+    if (reply) {
+      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(reply));
+    }
+  };
+
+  // Posting to task queue owned by the unretained object - unretained is safe.
+  task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(task, base::Unretained(this),
+                                std::move(pc_tracker_proxy), std::move(reply)));
 }
 
 void WebRtcEventLogManager::SetWebRtcEventLogUploaderFactoryForTesting(
-    std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory) {
-  // Testing function only - threading left for the caller's discretion.
-  remote_logs_manager_.SetWebRtcEventLogUploaderFactoryForTesting(
-      std::move(uploader_factory));
+    std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory,
+    base::OnceClosure reply) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  auto task =
+      [](WebRtcEventLogManager* manager,
+         std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory,
+         base::OnceClosure reply) {
+        auto& remote_logs_manager = manager->remote_logs_manager_;
+        remote_logs_manager.SetWebRtcEventLogUploaderFactoryForTesting(
+            std::move(uploader_factory));
+        if (reply) {
+          BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+                                  std::move(reply));
+        }
+      };
+
+  // Posting to task queue owned by the unretained object - unretained is safe.
+  task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(task, base::Unretained(this),
+                                std::move(uploader_factory), std::move(reply)));
 }
 
 }  // namespace content
diff --git a/content/browser/webrtc/webrtc_event_log_manager.h b/content/browser/webrtc/webrtc_event_log_manager.h
index 93ca39c..8f8d21a 100644
--- a/content/browser/webrtc/webrtc_event_log_manager.h
+++ b/content/browser/webrtc/webrtc_event_log_manager.h
@@ -33,7 +33,9 @@
 // as well as of writing the logs to files which were manually indicated by the
 // user from the WebRTCIntenals. (A log may simulatenously be written to both,
 // either, or none.)
-class CONTENT_EXPORT WebRtcEventLogManager
+// This needs to be final, so that posting |base::Unretained(this)| to the
+// internal task runner would not be a problem during destruction.
+class CONTENT_EXPORT WebRtcEventLogManager final
     : public RenderProcessHostObserver,
       public WebRtcLocalEventLogsObserver,
       public WebRtcRemoteEventLogsObserver {
@@ -109,6 +111,18 @@
       int lid,  // Renderer-local PeerConnection ID.
       base::OnceCallback<void(bool)> reply = base::OnceCallback<void(bool)>());
 
+  // Call this to let the manager know when a PeerConnection was stopped.
+  // Closing of a peer connection is an irreversible action. Its distinction
+  // from the removal event is that it may happen before the peer connection has
+  // be garbage collected. From WebRtcEventLogManager's perspective, we treat
+  // stopping a peer connection the same as we do its removal. Should a stopped
+  // peer connection be later removed, the removal callback will assume the
+  // value |false|.
+  void PeerConnectionStopped(
+      int render_process_id,
+      int lid,  // Renderer-local PeerConnection ID.
+      base::OnceCallback<void(bool)> reply = base::OnceCallback<void(bool)>());
+
   // Enable local logging of RTC events.
   // Local logging is distinguished from remote logging, in that local logs are
   // kept in response to explicit user input, are saved to a specific location,
@@ -187,11 +201,11 @@
 
  protected:
   friend class WebRtcEventLogManagerTest;  // Unit tests inject a frozen clock.
+  friend class WebRTCInternalsForTest;     // Unit tests inject a task runner.
 
   WebRtcEventLogManager();
-
   // This can be used by unit tests to ensure that they would run synchronously.
-  void SetTaskRunnerForTesting(
+  explicit WebRtcEventLogManager(
       const scoped_refptr<base::SequencedTaskRunner>& task_runner);
 
   // This allows unit tests that do not wish to change the task runner to still
@@ -278,14 +292,24 @@
   void SetRemoteLogsObserverInternal(WebRtcRemoteEventLogsObserver* observer,
                                      base::OnceClosure reply);
 
-  // Methods for injecting testing utilities in place of actual implementations.
-  // Because these are only intended for testing, we perform these changes
-  // asynchronously, trusting the unit tests to do so carefully enough.
-  void SetClockForTesting(base::Clock* clock);
+  // Injects a fake clock, to be used by tests. For example, this could be
+  // used to inject a frozen clock, thereby allowing unit tests to know what a
+  // local log's filename would end up being.
+  void SetClockForTesting(base::Clock* clock,
+                          base::OnceClosure reply = base::OnceClosure());
+
+  // Injects a PeerConnectionTrackerProxy for testing. The normal tracker proxy
+  // is used to communicate back to WebRTC whether event logging is desired for
+  // a given peer connection. Using this function, those indications can be
+  // intercepted by a unit test.
   void SetPeerConnectionTrackerProxyForTesting(
-      std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy);
+      std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy,
+      base::OnceClosure reply = base::OnceClosure());
+
+  // Injects a fake uploader, to be used by unit tests.
   void SetWebRtcEventLogUploaderFactoryForTesting(
-      std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory);
+      std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory,
+      base::OnceClosure reply = base::OnceClosure());
 
   // Observer which will be informed whenever a local log file is started or
   // stopped. Its callbacks are called synchronously from |task_runner_|,
diff --git a/content/browser/webrtc/webrtc_event_log_manager_unittest.cc b/content/browser/webrtc/webrtc_event_log_manager_unittest.cc
index 181c8e3..24655768a6 100644
--- a/content/browser/webrtc/webrtc_event_log_manager_unittest.cc
+++ b/content/browser/webrtc/webrtc_event_log_manager_unittest.cc
@@ -237,7 +237,9 @@
 
   void SetWebRtcEventLogUploaderFactoryForTesting(
       std::unique_ptr<WebRtcEventLogUploader::Factory> factory) {
-    manager_->SetWebRtcEventLogUploaderFactoryForTesting(std::move(factory));
+    manager_->SetWebRtcEventLogUploaderFactoryForTesting(std::move(factory),
+                                                         VoidReplyClosure());
+    WaitForReply();
   }
 
   std::pair<bool, bool> OnWebRtcEventLogWrite(int render_process_id,
@@ -255,7 +257,8 @@
     ASSERT_TRUE(
         base::Time::FromLocalExploded(frozen_time_exploded, &frozen_time));
     frozen_clock_.SetNow(frozen_time);
-    manager_->SetClockForTesting(&frozen_clock_);
+    manager_->SetClockForTesting(&frozen_clock_, VoidReplyClosure());
+    WaitForReply();
   }
 
   void SetWebRtcEventLoggingState(PeerConnectionKey key,
@@ -277,7 +280,8 @@
       std::unique_ptr<WebRtcEventLogManager::PeerConnectionTrackerProxy>
           pc_tracker_proxy) {
     manager_->SetPeerConnectionTrackerProxyForTesting(
-        std::move(pc_tracker_proxy));
+        std::move(pc_tracker_proxy), VoidReplyClosure());
+    WaitForReply();
   }
 
   std::unique_ptr<TestBrowserContext> CreateBrowserContext(
diff --git a/content/browser/webrtc/webrtc_internals_unittest.cc b/content/browser/webrtc/webrtc_internals_unittest.cc
index 4dec2cf..22bec44c 100644
--- a/content/browser/webrtc/webrtc_internals_unittest.cc
+++ b/content/browser/webrtc/webrtc_internals_unittest.cc
@@ -73,14 +73,6 @@
 
 }  // namespace
 
-class WebRtcEventLogManagerForTesting : public WebRtcEventLogManager {
- public:
-  WebRtcEventLogManagerForTesting() {
-    SetTaskRunnerForTesting(base::ThreadTaskRunnerHandle::Get());
-  }
-  ~WebRtcEventLogManagerForTesting() override = default;
-};
-
 // Derived class for testing only.  Allows the tests to have their own instance
 // for testing and control the period for which WebRTCInternals will bulk up
 // updates (changes down from 500ms to 1ms).
@@ -88,7 +80,9 @@
  public:
   WebRTCInternalsForTest()
       : WebRTCInternals(1, true),
-        mock_wake_lock_(mojo::MakeRequest(&wake_lock_)) {}
+        mock_wake_lock_(mojo::MakeRequest(&wake_lock_)),
+        synchronous_webrtc_event_log_manager_(
+            base::ThreadTaskRunnerHandle::Get()) {}
 
   ~WebRTCInternalsForTest() override {}
 
@@ -96,7 +90,7 @@
 
  private:
   MockWakeLock mock_wake_lock_;
-  WebRtcEventLogManagerForTesting synchronous_webrtc_event_log_manager_;
+  WebRtcEventLogManager synchronous_webrtc_event_log_manager_;
 };
 
 class WebRtcInternalsTest : public testing::Test {
diff --git a/content/browser/webrtc/webrtc_local_event_log_manager.cc b/content/browser/webrtc/webrtc_local_event_log_manager.cc
index 7590d0c..3b94fe51 100644
--- a/content/browser/webrtc/webrtc_local_event_log_manager.cc
+++ b/content/browser/webrtc/webrtc_local_event_log_manager.cc
@@ -8,6 +8,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "build/build_config.h"
+#include "content/public/browser/browser_thread.h"
 
 #if defined(OS_WIN)
 #define IntToStringType base::IntToString16
@@ -29,14 +30,19 @@
     WebRtcLocalEventLogsObserver* observer)
     : observer_(observer),
       clock_for_testing_(nullptr),
-      max_log_file_size_bytes_(kDefaultMaxLocalLogFileSizeBytes) {}
+      max_log_file_size_bytes_(kDefaultMaxLocalLogFileSizeBytes) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DETACH_FROM_SEQUENCE(io_task_sequence_checker_);
+}
 
 WebRtcLocalEventLogManager::~WebRtcLocalEventLogManager() {
-  // This should never actually run, except in unit tests.
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 }
 
 bool WebRtcLocalEventLogManager::PeerConnectionAdded(int render_process_id,
                                                      int lid) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   const auto result = active_peer_connections_.emplace(render_process_id, lid);
 
   if (!result.second) {  // PeerConnection already registered.
@@ -55,6 +61,8 @@
 
 bool WebRtcLocalEventLogManager::PeerConnectionRemoved(int render_process_id,
                                                        int lid) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   const PeerConnectionKey key = PeerConnectionKey(render_process_id, lid);
   auto peer_connection = active_peer_connections_.find(key);
 
@@ -77,6 +85,8 @@
 
 bool WebRtcLocalEventLogManager::EnableLogging(const base::FilePath& base_path,
                                                size_t max_file_size_bytes) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   if (!base_path_.empty()) {
     return false;
   }
@@ -97,6 +107,8 @@
 }
 
 bool WebRtcLocalEventLogManager::DisableLogging() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   if (base_path_.empty()) {
     return false;
   }
@@ -114,6 +126,7 @@
 bool WebRtcLocalEventLogManager::EventLogWrite(int render_process_id,
                                                int lid,
                                                const std::string& message) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
   auto it = log_files_.find(PeerConnectionKey(render_process_id, lid));
   if (it == log_files_.end()) {
     return false;
@@ -123,6 +136,8 @@
 
 void WebRtcLocalEventLogManager::RenderProcessHostExitedDestroyed(
     int render_process_id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   // Remove all of the peer connections associated with this render process.
   auto pc_it = active_peer_connections_.begin();
   while (pc_it != active_peer_connections_.end()) {
@@ -146,10 +161,13 @@
 }
 
 void WebRtcLocalEventLogManager::SetClockForTesting(base::Clock* clock) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
   clock_for_testing_ = clock;
 }
 
 void WebRtcLocalEventLogManager::StartLogFile(int render_process_id, int lid) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   // Add some information to the name given by the caller.
   base::FilePath file_path = GetFilePath(base_path_, render_process_id, lid);
   CHECK(!file_path.empty()) << "Couldn't set path for local WebRTC log file.";
@@ -193,6 +211,8 @@
 
 WebRtcLocalEventLogManager::LogFilesMap::iterator
 WebRtcLocalEventLogManager::CloseLogFile(LogFilesMap::iterator it) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   const PeerConnectionKey peer_connection = it->first;
 
   it->second.file.Flush();
@@ -209,6 +229,8 @@
     const base::FilePath& base_path,
     int render_process_id,
     int lid) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   base::Time::Exploded now;
   if (clock_for_testing_) {
     clock_for_testing_->Now().LocalExplode(&now);
diff --git a/content/browser/webrtc/webrtc_local_event_log_manager.h b/content/browser/webrtc/webrtc_local_event_log_manager.h
index a8d05f3..1ca73cd 100644
--- a/content/browser/webrtc/webrtc_local_event_log_manager.h
+++ b/content/browser/webrtc/webrtc_local_event_log_manager.h
@@ -11,6 +11,7 @@
 
 #include "base/files/file.h"
 #include "base/files/file_path.h"
+#include "base/sequence_checker.h"
 #include "base/time/clock.h"
 #include "content/browser/webrtc/webrtc_event_log_manager_common.h"
 
@@ -53,6 +54,10 @@
                              int render_process_id,
                              int lid);
 
+  // This object is expected to be created and destroyed on the UI thread,
+  // but live on its owner's internal, IO-capable task queue.
+  SEQUENCE_CHECKER(io_task_sequence_checker_);
+
   // Observer which will be informed whenever a local log file is started or
   // stopped. Through this, the owning WebRtcEventLogManager can be informed,
   // and decide whether it wants to turn notifications from WebRTC on/off.
diff --git a/content/browser/webrtc/webrtc_remote_event_log_manager.cc b/content/browser/webrtc/webrtc_remote_event_log_manager.cc
index a3530d99..02a811a 100644
--- a/content/browser/webrtc/webrtc_remote_event_log_manager.cc
+++ b/content/browser/webrtc/webrtc_remote_event_log_manager.cc
@@ -12,6 +12,7 @@
 #include "base/logging.h"
 #include "base/rand_util.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "content/public/browser/browser_thread.h"
 
 namespace content {
 
@@ -38,9 +39,13 @@
 WebRtcRemoteEventLogManager::WebRtcRemoteEventLogManager(
     WebRtcRemoteEventLogsObserver* observer)
     : observer_(observer),
-      uploader_factory_(new WebRtcEventLogUploaderImpl::Factory) {}
+      uploader_factory_(new WebRtcEventLogUploaderImpl::Factory) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DETACH_FROM_SEQUENCE(io_task_sequence_checker_);
+}
 
 WebRtcRemoteEventLogManager::~WebRtcRemoteEventLogManager() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // TODO(eladalon): Purge from disk files which were being uploaded  while
   // destruction took place, thereby avoiding endless attempts to upload
   // the same file. https://crbug.com/775415
@@ -49,6 +54,7 @@
 void WebRtcRemoteEventLogManager::EnableForBrowserContext(
     BrowserContextId browser_context,
     const base::FilePath& browser_context_dir) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
   const base::FilePath remote_bound_logs_dir =
       GetLogsDirectoryPath(browser_context_dir);
   if (!MaybeCreateLogsDirectory(remote_bound_logs_dir)) {
@@ -61,6 +67,7 @@
 
 void WebRtcRemoteEventLogManager::DisableForBrowserContext(
     BrowserContextId browser_context) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
   auto active_it = active_logs_counts_.find(browser_context);
   if (active_it != active_logs_counts_.end()) {
     active_logs_counts_.erase(active_it);
@@ -73,6 +80,7 @@
 
 bool WebRtcRemoteEventLogManager::PeerConnectionAdded(int render_process_id,
                                                       int lid) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
   PrunePendingLogs();  // Infrequent event - good opportunity to prune.
   const auto result = active_peer_connections_.emplace(render_process_id, lid);
   return result.second;
@@ -82,6 +90,8 @@
     int render_process_id,
     int lid,
     BrowserContextId browser_context) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   PrunePendingLogs();  // Infrequent event - good opportunity to prune.
 
   const PeerConnectionKey key = PeerConnectionKey(render_process_id, lid);
@@ -106,6 +116,8 @@
     BrowserContextId browser_context,
     const base::FilePath& browser_context_dir,
     size_t max_file_size_bytes) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   // TODO(eladalon): Set a tighter limit (following discussion with rschriebman
   // and manj). https://crbug.com/775415
   if (max_file_size_bytes == kWebRtcEventLogManagerUnlimitedFileSize) {
@@ -151,6 +163,8 @@
 bool WebRtcRemoteEventLogManager::EventLogWrite(int render_process_id,
                                                 int lid,
                                                 const std::string& message) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   auto it = active_logs_.find(PeerConnectionKey(render_process_id, lid));
   if (it == active_logs_.end()) {
     return false;
@@ -160,6 +174,8 @@
 
 void WebRtcRemoteEventLogManager::RenderProcessHostExitedDestroyed(
     int render_process_id) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   // Closing files will call MaybeStartUploading(). Avoid letting that upload
   // any recently expired files.
   PrunePendingLogs();
@@ -196,6 +212,8 @@
 void WebRtcRemoteEventLogManager::OnWebRtcEventLogUploadComplete(
     const base::FilePath& file_path,
     bool upload_successful) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   // Post a task to deallocate the uploader (can't do this directly,
   // because this function is a callback from the uploader), potentially
   // starting a new upload for the next file.
@@ -211,11 +229,13 @@
 
 void WebRtcRemoteEventLogManager::SetWebRtcEventLogUploaderFactoryForTesting(
     std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   uploader_factory_ = std::move(uploader_factory);
 
   // Unit tests would initially set a null uploader factory, so that files would
   // be kept around. Some tests would later change to a different factory
-  // (e.g. one that always simulates upload failure); inthat case, we should
+  // (e.g. one that always simulates upload failure); in that case, we should
   // get rid of the null uploader, since it never terminates.
   uploader_.reset();
   MaybeStartUploading();
@@ -228,6 +248,8 @@
 
 WebRtcRemoteEventLogManager::LogFilesMap::iterator
 WebRtcRemoteEventLogManager::CloseLogFile(LogFilesMap::iterator it) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   const PeerConnectionKey peer_connection = it->first;
 
   it->second.file.Flush();
@@ -244,6 +266,8 @@
 
 bool WebRtcRemoteEventLogManager::MaybeCreateLogsDirectory(
     const base::FilePath& remote_bound_logs_dir) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   if (base::PathExists(remote_bound_logs_dir)) {
     if (!base::DirectoryExists(remote_bound_logs_dir)) {
       LOG(ERROR) << "Path for remote-bound logs is taken by a non-directory.";
@@ -262,6 +286,7 @@
 void WebRtcRemoteEventLogManager::AddPendingLogs(
     BrowserContextId browser_context,
     const base::FilePath& remote_bound_logs_dir) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
   DCHECK(active_logs_counts_.find(browser_context) ==
          active_logs_counts_.end());
   DCHECK(pending_logs_counts_.find(browser_context) ==
@@ -292,6 +317,8 @@
     BrowserContextId browser_context,
     const base::FilePath& browser_context_dir,
     size_t max_file_size_bytes) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   // Randomize a new filename. In the highly unlikely event that this filename
   // is already taken, it will be treated the same way as any other failure
   // to start the log file.
@@ -328,6 +355,8 @@
     int render_process_id,
     int lid,
     BrowserContextId browser_context) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   const PeerConnectionKey key(render_process_id, lid);
   const auto it = active_logs_.find(key);
 
@@ -354,6 +383,7 @@
 }
 
 void WebRtcRemoteEventLogManager::PrunePendingLogs() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
   const base::Time oldest_non_expired_timestamp =
       base::Time::Now() - kRemoteBoundWebRtcEventLogsMaxRetention;
   for (auto it = pending_logs_.begin(); it != pending_logs_.end();) {
@@ -370,10 +400,13 @@
 }
 
 bool WebRtcRemoteEventLogManager::UploadingAllowed() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
   return active_peer_connections_.empty();
 }
 
 void WebRtcRemoteEventLogManager::MaybeStartUploading() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
+
   PrunePendingLogs();  // Avoid uploading freshly expired files.
 
   if (uploader_) {
@@ -399,6 +432,7 @@
 }
 
 void WebRtcRemoteEventLogManager::OnWebRtcEventLogUploadCompleteInternal() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_);
   uploader_.reset();
   MaybeStartUploading();
 }
diff --git a/content/browser/webrtc/webrtc_remote_event_log_manager.h b/content/browser/webrtc/webrtc_remote_event_log_manager.h
index da4fbcb..c1c37657 100644
--- a/content/browser/webrtc/webrtc_remote_event_log_manager.h
+++ b/content/browser/webrtc/webrtc_remote_event_log_manager.h
@@ -9,6 +9,7 @@
 #include <set>
 #include <vector>
 
+#include "base/sequence_checker.h"
 #include "base/time/time.h"
 #include "content/browser/webrtc/webrtc_event_log_manager_common.h"
 #include "content/browser/webrtc/webrtc_event_log_uploader.h"
@@ -195,6 +196,10 @@
   // When an upload is complete, it might be time to upload the next file.
   void OnWebRtcEventLogUploadCompleteInternal();
 
+  // This object is expected to be created and destroyed on the UI thread,
+  // but live on its owner's internal, IO-capable task queue.
+  SEQUENCE_CHECKER(io_task_sequence_checker_);
+
   // This is used to inform WebRtcEventLogManager when remote-bound logging
   // of a peer connection starts/stops, which allows WebRtcEventLogManager to
   // decide when to ask WebRTC to start/stop sending event logs.
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc
index 8dfdad7..0afea274 100644
--- a/content/child/child_thread_impl.cc
+++ b/content/child/child_thread_impl.cc
@@ -795,7 +795,7 @@
 
 void ChildThreadImpl::EnsureConnected() {
   VLOG(0) << "ChildThreadImpl::EnsureConnected()";
-  base::Process::Current().Terminate(0, false);
+  base::Process::TerminateCurrentProcessImmediately(0);
 }
 
 void ChildThreadImpl::GetRoute(
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index 84ab38b..934cda9e 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -63,9 +63,10 @@
   // also be provided by the browser as a a means for the renderer to load
   // subresources where applicable.
   //
-  // When S13nServiceWorker is enabled, |controller_service_worker_info| may
-  // also be provided by the browser if the frame that is being navigated
-  // is supposed to be controlled by a Service Worker.
+  // When S13nServiceWorker/NavigationMojoResponse is enabled,
+  // |controller_service_worker_info| may also be provided by the browser if the
+  // frame that is being navigated is supposed to be controlled by a Service
+  // Worker.
   //
   // For automation driver-initiated navigations over the devtools protocol,
   // |devtools_navigation_token_| is used to tag the navigation. This navigation
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index 3274b0fe..90a528a 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -130,8 +130,8 @@
                           content::FileChooserParams::Save)
 IPC_ENUM_TRAITS_MAX_VALUE(content::CSPDirective::Name,
                           content::CSPDirective::NameLast)
-IPC_ENUM_TRAITS_MAX_VALUE(blink::FeaturePolicyFeature,
-                          blink::FeaturePolicyFeature::LAST_FEATURE)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::FeaturePolicyFeature,
+                          blink::mojom::FeaturePolicyFeature::kLastFeature)
 IPC_ENUM_TRAITS_MAX_VALUE(content::CSPDisposition,
                           content::CSPDisposition::LAST)
 IPC_ENUM_TRAITS_MAX_VALUE(blink::WebTriggeringEventInfo,
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h
index bb3ae9b..5bd2881 100644
--- a/content/public/browser/render_frame_host.h
+++ b/content/public/browser/render_frame_host.h
@@ -24,8 +24,10 @@
 
 namespace blink {
 class AssociatedInterfaceProvider;
+namespace mojom {
 enum class FeaturePolicyFeature;
-}
+}  // namespace mojom
+}  // namespace blink
 
 namespace base {
 class UnguessableToken;
@@ -299,7 +301,7 @@
   // Returns true if the given Feature Policy |feature| is enabled for this
   // RenderFrameHost and is allowed to be used by it. Use this in the browser
   // process to determine whether access to a feature is allowed.
-  virtual bool IsFeatureEnabled(blink::FeaturePolicyFeature feature) = 0;
+  virtual bool IsFeatureEnabled(blink::mojom::FeaturePolicyFeature feature) = 0;
 
   // Opens view-source tab for the document last committed in this
   // RenderFrameHost.
diff --git a/content/public/browser/web_contents_view_delegate.cc b/content/public/browser/web_contents_view_delegate.cc
index 3d0a1bf..5d86aae 100644
--- a/content/public/browser/web_contents_view_delegate.cc
+++ b/content/public/browser/web_contents_view_delegate.cc
@@ -41,9 +41,6 @@
   return false;
 }
 
-void WebContentsViewDelegate::SizeChanged(const gfx::Size& size) {
-}
-
 void WebContentsViewDelegate::OverrideDisplayColorSpace(
     gfx::ColorSpace* color_space) {}
 
diff --git a/content/public/browser/web_contents_view_delegate.h b/content/public/browser/web_contents_view_delegate.h
index b7a1112..6b29450 100644
--- a/content/public/browser/web_contents_view_delegate.h
+++ b/content/public/browser/web_contents_view_delegate.h
@@ -19,7 +19,6 @@
 
 namespace gfx {
 class ColorSpace;
-class Size;
 }
 
 namespace content {
@@ -61,9 +60,6 @@
   // Advance focus to the view that follows or precedes the WebContents.
   virtual bool TakeFocus(bool reverse);
 
-  // Allows the delegate to update bounds for a special views.
-  virtual void SizeChanged(const gfx::Size& size);
-
   // This method allows the embedder to specify the display color space (instead
   // of using the color space specified by display::Display) and write it in
   // |*color_space|. The default behavior is to leave |*color_space| unchanged.
diff --git a/content/public/test/network_service_test_helper.cc b/content/public/test/network_service_test_helper.cc
index b3778079..db82b99 100644
--- a/content/public/test/network_service_test_helper.cc
+++ b/content/public/test/network_service_test_helper.cc
@@ -69,11 +69,11 @@
   }
 
   void SimulateCrash() override {
-    LOG(ERROR) << "Intentionally issuing kill signal to current process to"
-               << " simulate NetworkService crash for testing.";
-    // Use |Process::Terminate()| instead of |CHECK()| to avoid 'Fatal error'
-    // dialog on Windows debug.
-    base::Process::Current().Terminate(1, false);
+    LOG(ERROR) << "Intentionally terminating current process to simulate"
+                  " NetworkService crash for testing.";
+    // Use |TerminateCurrentProcessImmediately()| instead of |CHECK()| to avoid
+    // 'Fatal error' dialog on Windows debug.
+    base::Process::TerminateCurrentProcessImmediately(1);
   }
 
   void MockCertVerifierSetDefaultResult(
diff --git a/content/public/test/test_renderer_host.h b/content/public/test/test_renderer_host.h
index b5066ca..5e899b2b 100644
--- a/content/public/test/test_renderer_host.h
+++ b/content/public/test/test_renderer_host.h
@@ -122,7 +122,7 @@
   // can be generalized as needed. Setting a header policy should only be done
   // once per navigation of the RFH.
   virtual void SimulateFeaturePolicyHeader(
-      blink::FeaturePolicyFeature feature,
+      blink::mojom::FeaturePolicyFeature feature,
       const std::vector<url::Origin>& whitelist) = 0;
 
   // Gets all the console messages requested via
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index 423605b..89bf4804 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -63,7 +63,6 @@
 #include "media/base/media_switches.h"
 #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
 #include "third_party/WebKit/public/platform/WebCompositeAndReadbackAsyncCallback.h"
-#include "third_party/WebKit/public/platform/WebCompositorMutatorClient.h"
 #include "third_party/WebKit/public/platform/WebLayoutAndPaintAsyncCallback.h"
 #include "third_party/WebKit/public/platform/WebRuntimeFeatures.h"
 #include "third_party/WebKit/public/platform/WebSize.h"
@@ -910,7 +909,7 @@
 }
 
 void RenderWidgetCompositor::SetMutatorClient(
-    std::unique_ptr<blink::WebCompositorMutatorClient> client) {
+    std::unique_ptr<cc::LayerTreeMutator> client) {
   TRACE_EVENT0("cc", "RenderWidgetCompositor::setMutatorClient");
   layer_tree_host_->SetLayerTreeMutator(std::move(client));
 }
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h
index e81f46f3..f95eed7 100644
--- a/content/renderer/gpu/render_widget_compositor.h
+++ b/content/renderer/gpu/render_widget_compositor.h
@@ -160,8 +160,7 @@
   void ClearViewportLayers() override;
   void RegisterSelection(const blink::WebSelection& selection) override;
   void ClearSelection() override;
-  void SetMutatorClient(
-      std::unique_ptr<blink::WebCompositorMutatorClient>) override;
+  void SetMutatorClient(std::unique_ptr<cc::LayerTreeMutator>) override;
   void ForceRecalculateRasterScales() override;
   void SetEventListenerProperties(
       blink::WebEventListenerClass eventClass,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index e002ab8..d2c948f 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -875,9 +875,10 @@
     // of base::debug::DumpWithoutCrashing for more details.
     base::debug::DumpWithoutCrashing();
   } else if (url == kChromeUIKillURL) {
-    LOG(ERROR) << "Intentionally issuing kill signal to current process"
-               << " because user navigated to " << url.spec();
-    base::Process::Current().Terminate(1, false);
+    LOG(ERROR) << "Intentionally terminating current process because user"
+                  " navigated to "
+               << url.spec();
+    base::Process::TerminateCurrentProcessImmediately(1);
   } else if (url == kChromeUIHangURL) {
     LOG(ERROR) << "Intentionally hanging ourselves with sleep infinite loop"
                << " because user navigated to " << url.spec();
diff --git a/content/renderer/service_worker/service_worker_provider_context.cc b/content/renderer/service_worker/service_worker_provider_context.cc
index 191c194..92a616b 100644
--- a/content/renderer/service_worker/service_worker_provider_context.cc
+++ b/content/renderer/service_worker/service_worker_provider_context.cc
@@ -15,6 +15,7 @@
 #include "content/child/child_thread_impl.h"
 #include "content/child/thread_safe_sender.h"
 #include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/common/browser_side_navigation_policy.h"
 #include "content/public/common/service_names.mojom.h"
 #include "content/public/common/shared_url_loader_factory.h"
 #include "content/renderer/service_worker/controller_service_worker_connector.h"
@@ -109,13 +110,16 @@
   state_for_client_ = std::make_unique<ProviderStateForClient>(
       std::move(default_loader_factory));
 
-  if (!CanCreateSubresourceLoaderFactory())
+  if (!CanCreateSubresourceLoaderFactory() &&
+      !IsNavigationMojoResponseEnabled()) {
     return;
+  }
 
-  // S13nServiceWorker:
+  // S13nServiceWorker/NavigationMojoResponse:
   // Set up the URL loader factory for sending subresource requests to
   // the controller.
-  DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+  DCHECK(ServiceWorkerUtils::IsServicificationEnabled() ||
+         IsNavigationMojoResponseEnabled());
   if (controller_info) {
     SetController(std::move(controller_info),
                   std::vector<blink::mojom::WebFeature>(),
diff --git a/content/renderer/service_worker/service_worker_provider_context.h b/content/renderer/service_worker/service_worker_provider_context.h
index 0714346..412ad0ff6 100644
--- a/content/renderer/service_worker/service_worker_provider_context.h
+++ b/content/renderer/service_worker/service_worker_provider_context.h
@@ -65,9 +65,11 @@
   // the content::ServiceWorkerProviderHost that notifies of changes to the
   // registration's and workers' status. |request| is bound with |binding_|.
   //
+  // For S13nServiceWorker/NavigationMojoResponse:
+  // |controller_info| contains the endpoint (which is non-null only when
+  // S13nServiceWorker is enabled) and object info that is needed to set up the
+  // controller service worker for the client.
   // For S13nServiceWorker:
-  // |controller_info| contains the endpoint and object info that is needed to
-  // set up the controller service worker for the client.
   // |default_loader_factory| is a default loader factory for network requests,
   // and is used when we create a subresource loader for controllees. This is
   // non-null only if the provider is created for controllees, and if the
diff --git a/content/shell/utility/shell_content_utility_client.cc b/content/shell/utility/shell_content_utility_client.cc
index a4f3d5c..73e2e856 100644
--- a/content/shell/utility/shell_content_utility_client.cc
+++ b/content/shell/utility/shell_content_utility_client.cc
@@ -41,7 +41,7 @@
   }
 
   void DoTerminateProcess(DoTerminateProcessCallback callback) override {
-    base::Process::Current().Terminate(0, false);
+    base::Process::TerminateCurrentProcessImmediately(0);
   }
 
   void CreateFolder(CreateFolderCallback callback) override {
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index f875359..c2ded32 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -738,9 +738,11 @@
     "../browser/isolated_origin_browsertest.cc",
     "../browser/loader/cross_site_document_blocking_browsertest.cc",
     "../browser/loader/cross_site_resource_handler_browsertest.cc",
+    "../browser/loader/prefetch_browsertest.cc",
     "../browser/loader/reload_cache_control_browsertest.cc",
     "../browser/loader/resource_dispatcher_host_browsertest.cc",
     "../browser/loader/resource_scheduler_browsertest.cc",
+    "../browser/loader/web_package_request_handler_browsertest.cc",
     "../browser/manifest/manifest_browsertest.cc",
     "../browser/media/encrypted_media_browsertest.cc",
     "../browser/media/media_browsertest.cc",
@@ -785,6 +787,7 @@
     "../browser/renderer_host/media/video_capture_browsertest.cc",
     "../browser/renderer_host/render_process_host_browsertest.cc",
     "../browser/renderer_host/render_view_host_browsertest.cc",
+    "../browser/renderer_host/render_widget_host_browsertest.cc",
     "../browser/renderer_host/render_widget_host_view_browsertest.cc",
     "../browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc",
     "../browser/resource_loading_browsertest.cc",
@@ -1163,6 +1166,10 @@
     check_includes = false
   }
 
+  if (is_android) {
+    enable_multidex = true
+  }
+
   defines = []
   sources = [
     "../browser/accessibility/browser_accessibility_mac_unittest.mm",
@@ -1320,6 +1327,7 @@
     "../browser/loader/signed_exchange_cert_fetcher_unittest.cc",
     "../browser/loader/signed_exchange_header_parser_unittest.cc",
     "../browser/loader/signed_exchange_signature_verifier_unittest.cc",
+    "../browser/loader/source_stream_to_data_pipe_unittest.cc",
     "../browser/loader/temporary_file_stream_unittest.cc",
     "../browser/loader/test_resource_handler.cc",
     "../browser/loader/test_resource_handler.h",
diff --git a/content/test/data/gpu/functional_webgl_disabled_extension.html b/content/test/data/gpu/functional_webgl_disabled_extension.html
new file mode 100644
index 0000000..f1222bcf
--- /dev/null
+++ b/content/test/data/gpu/functional_webgl_disabled_extension.html
@@ -0,0 +1,27 @@
+<html>
+<script type="text/javascript">
+function runTest() {
+  var canvas = document.getElementById("glcanvas");
+  var gl = canvas.getContext('webgl');
+  if (!gl) {
+    if (window.domAutomationController) {
+      window.domAutomationController.send("FAILED");
+    } else {
+      alert("Unable to initialize WebGL");
+    }
+    return;
+  }
+  // This extension is supposed to be disabled via a blacklist entry.
+  if (gl.getExtension('WEBGL_lose_context')) {
+    window.domAutomationController.send("FAILED");
+  } else {
+    window.domAutomationController.send("FINISHED");
+  }
+}
+</script>
+<body onload="runTest()">
+  <canvas id="glcanvas" width="640" height="480">
+    Your browser doesn't appear to support the HTML5 <code>&lt;canvas&gt;</code> element.
+  </canvas>
+</body>
+</html>
diff --git a/content/test/data/htxg/.gitattributes b/content/test/data/htxg/.gitattributes
new file mode 100644
index 0000000..2a4fcb3bc
--- /dev/null
+++ b/content/test/data/htxg/.gitattributes
@@ -0,0 +1 @@
+*.htxg binary
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/origin-signed-response-iframe.htxg b/content/test/data/htxg/origin-signed-response-iframe.htxg
similarity index 100%
rename from third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/origin-signed-response-iframe.htxg
rename to content/test/data/htxg/origin-signed-response-iframe.htxg
Binary files differ
diff --git a/content/test/data/htxg/origin-signed-response-iframe.htxg.mock-http-headers b/content/test/data/htxg/origin-signed-response-iframe.htxg.mock-http-headers
new file mode 100644
index 0000000..acfdd18
--- /dev/null
+++ b/content/test/data/htxg/origin-signed-response-iframe.htxg.mock-http-headers
@@ -0,0 +1,2 @@
+HTTP/1.1 200 OK
+Content-Type: application/http-exchange+cbor
diff --git a/content/test/data/htxg/origin-signed-response.html b/content/test/data/htxg/origin-signed-response.html
new file mode 100644
index 0000000..0d04b3f
--- /dev/null
+++ b/content/test/data/htxg/origin-signed-response.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<title>Location of origin-signed HTTP response</title>
+<body>
+<script>
+function with_iframe(url) {
+  return new Promise(function(resolve) {
+      const frame = document.createElement('iframe');
+      frame.src = url;
+      frame.onload = function() { resolve(frame); };
+      document.body.appendChild(frame);
+    });
+}
+
+const url = 'origin-signed-response-iframe.htxg';
+with_iframe(url)
+  .then((frame) => {
+    const channel = new MessageChannel();
+    const promise =
+        new Promise((resolve) => { channel.port1.onmessage = resolve; });
+    frame.contentWindow.postMessage(
+      {port: channel.port2}, '*', [channel.port2]);
+    return promise;
+  })
+  .then((event) => {
+    document.title = event.data.location;
+  });
+</script>
+</body>
+
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py
index 4b165ae..c78a5139 100755
--- a/content/test/gpu/generate_buildbot_json.py
+++ b/content/test/gpu/generate_buildbot_json.py
@@ -133,39 +133,6 @@
    },
 
   'testers': {
-    # TODO(kbr): rename Win7 bots to Win10 in tools/build workspace.
-    'Win7 Release (NVIDIA)': {
-      'swarming_dimensions': [
-        {
-          'gpu': WIN7_NVIDIA_QUADRO_P400_STABLE_DRIVER,
-          'os': 'Windows-2008ServerR2-SP1',
-          'pool': 'Chrome-GPU',
-        },
-      ],
-      'build_config': 'Release',
-      'swarming': True,
-      'os_type': 'win',
-      'use_gpu_trigger_script': True,
-      'alternate_swarming_dimensions': [
-        {
-          'gpu': WIN10_NVIDIA_QUADRO_P400_STABLE_DRIVER,
-          'os': WIN10_NVIDIA_QUADRO_P400_STABLE_OS,
-          'pool': 'Chrome-GPU',
-        },
-      ],
-    },
-    'Win7 Debug (NVIDIA)': {
-      'swarming_dimensions': [
-        {
-          'gpu': WIN10_NVIDIA_QUADRO_P400_STABLE_DRIVER,
-          'os': WIN10_NVIDIA_QUADRO_P400_STABLE_OS,
-          'pool': 'Chrome-GPU',
-        },
-      ],
-      'build_config': 'Debug',
-      'swarming': True,
-      'os_type': 'win',
-    },
     'Win10 Release (NVIDIA)': {
       'swarming_dimensions': [
         {
@@ -299,9 +266,6 @@
   },
 
   'testers': {
-    # TODO(kbr): switch over trybots to point to Win10 bots in
-    # tools/build workspace, and then switch Win7 bots back to running
-    # only on Win7.
     'Win7 Release (NVIDIA)': {
       'swarming_dimensions': [
         {
@@ -314,13 +278,6 @@
       'swarming': True,
       'os_type': 'win',
       'use_gpu_trigger_script': True,
-      'alternate_swarming_dimensions': [
-        {
-          'gpu': WIN10_NVIDIA_QUADRO_P400_STABLE_DRIVER,
-          'os': WIN10_NVIDIA_QUADRO_P400_STABLE_OS,
-          'pool': 'Chrome-GPU',
-        },
-      ],
     },
     'Win7 Debug (NVIDIA)': {
       'swarming_dimensions': [
@@ -334,22 +291,6 @@
       'swarming': True,
       'os_type': 'win',
     },
-    # TODO(kbr): rename Win7 dEQP bot to Win10 in tools/build and
-    # delete this one.
-    'Win7 dEQP Release (NVIDIA)': {
-      'swarming_dimensions': [
-        {
-          'gpu': WIN10_NVIDIA_QUADRO_P400_STABLE_DRIVER,
-          'os': WIN10_NVIDIA_QUADRO_P400_STABLE_OS,
-          'pool': 'Chrome-GPU',
-        },
-      ],
-      'build_config': 'Release',
-      'swarming': True,
-      'os_type': 'win',
-      'type': Types.DEQP,
-      'use_gpu_trigger_script': True,
-    },
     'Win10 dEQP Release (NVIDIA)': {
       'swarming_dimensions': [
         {
@@ -363,23 +304,6 @@
       'os_type': 'win',
       'type': Types.DEQP,
     },
-    # TODO(kbr): rename Win7 Experimental bot to Win10 in tools/build
-    # and delete this one.
-    'Win7 Experimental Release (NVIDIA)': {
-      'swarming_dimensions': [
-        {
-          'gpu': WIN10_NVIDIA_QUADRO_P400_EXPERIMENTAL_DRIVER,
-          'os': WIN10_NVIDIA_QUADRO_P400_EXPERIMENTAL_OS,
-          'pool': 'Chrome-GPU',
-        },
-      ],
-      'build_config': 'Release',
-      'swarming': True,
-      'os_type': 'win',
-      'type': Types.EXPERIMENTAL,
-      # This should match another config name specified in this file.
-      'stable_tester_name': 'Win10 Release (NVIDIA)',
-    },
     'Win10 Experimental Release (NVIDIA)': {
       'swarming_dimensions': [
         {
@@ -885,29 +809,6 @@
     # a completely different (redundant) bot specification to handle
     # this.
 
-    # TODO(kbr): change trybots in tools/build workspace to point to
-    # Optional Win10 bot, and delete this one.
-    'Optional Win7 Release (NVIDIA)': {
-      'swarming_dimensions': [
-        {
-          'gpu': WIN7_NVIDIA_QUADRO_P400_STABLE_DRIVER,
-          'os': 'Windows-2008ServerR2-SP1',
-          'pool': 'Chrome-GPU',
-        },
-      ],
-      'build_config': 'Release',
-      'swarming': True,
-      'os_type': 'win',
-      'type': Types.OPTIONAL,
-      'use_gpu_trigger_script': True,
-      'alternate_swarming_dimensions': [
-        {
-          'gpu': WIN10_NVIDIA_QUADRO_P400_STABLE_DRIVER,
-          'os': WIN10_NVIDIA_QUADRO_P400_STABLE_OS,
-          'pool': 'Chrome-GPU',
-        },
-      ],
-    },
     'Optional Win10 Release (NVIDIA)': {
       'swarming_dimensions': [
         {
@@ -1833,9 +1734,7 @@
         'names': [
           'Win7 Release (NVIDIA)',
           'Win7 Debug (NVIDIA)',
-          'Win7 dEQP Release (NVIDIA)',
           'Win10 dEQP Release (NVIDIA)',
-          'Win7 Experimental Release (NVIDIA)',
           'Win10 Experimental Release (NVIDIA)',
           'Win10 Debug (NVIDIA)',
           'Win7 Release (AMD)',
diff --git a/content/test/gpu/gpu_tests/gpu_process_integration_test.py b/content/test/gpu/gpu_tests/gpu_process_integration_test.py
index a29c73d..431a0af 100644
--- a/content/test/gpu/gpu_tests/gpu_process_integration_test.py
+++ b/content/test/gpu/gpu_tests/gpu_process_integration_test.py
@@ -15,8 +15,14 @@
 test_harness_script = r"""
   var domAutomationController = {};
   domAutomationController._finished = false;
+  domAutomationController._succeeded = false;
   domAutomationController.send = function(msg) {
     domAutomationController._finished = true;
+    if (msg.toLowerCase() == "finished") {
+      domAutomationController._succeeded = true;
+    } else {
+      domAutomationController._succeeded = false;
+    }
   }
 
   window.domAutomationController = domAutomationController;
@@ -78,7 +84,9 @@
              ('GpuProcess_disable_gpu_and_swiftshader',
               'gpu/functional_webgl.html'),
              ('GpuProcess_disabling_workarounds_works', 'chrome:gpu'),
-             ('GpuProcess_swiftshader_for_webgl', 'gpu/functional_webgl.html'))
+             ('GpuProcess_swiftshader_for_webgl', 'gpu/functional_webgl.html'),
+             ('GpuProcess_webgl_disabled_extension',
+              'gpu/functional_webgl_disabled_extension.html'))
 
     # The earlier has_transparent_visuals_gpu_process and
     # no_transparent_visuals_gpu_process tests became no-ops in
@@ -105,8 +113,11 @@
 
   def _NavigateAndWait(self, test_path):
     self._Navigate(test_path)
-    self.tab.action_runner.WaitForJavaScriptCondition(
+    tab = self.tab
+    tab.action_runner.WaitForJavaScriptCondition(
       'window.domAutomationController._finished', timeout=10)
+    if not tab.EvaluateJavaScript('window.domAutomationController._succeeded'):
+      self.fail('Test reported that it failed')
 
   def _VerifyGpuProcessPresent(self):
     tab = self.tab
@@ -398,6 +409,13 @@
         if tab.EvaluateJavaScript('!gl_context.getExtension("' + ext + '")'):
           self.fail("Expected " + ext + " support")
 
+  def _GpuProcess_webgl_disabled_extension(self, test_path):
+    # Hit exception from id 257 from kGpuDriverBugListEntries.
+    self.RestartBrowserIfNecessaryWithArgs([
+      '--gpu-driver-bug-list-test-group=2',
+    ])
+    self._NavigateAndWait(test_path)
+
 def load_tests(loader, tests, pattern):
   del loader, tests, pattern  # Unused.
   return gpu_integration_test.LoadAllTestsInModule(sys.modules[__name__])
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index c575988..13b6aea 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -32,6 +32,7 @@
         ['win', 'mac', 'linux'])
     self.Skip('WebglExtension_WEBGL_compressed_texture_s3tc_srgb',
         ['win', 'mac', 'linux'])
+    self.Skip('WebglExtension_EXT_disjoint_timer_query_webgl2', bug=808744)
 
     # ========================
     # Conformance expectations
@@ -891,8 +892,6 @@
     # Linux Intel
     self.Fail('conformance2/extensions/ext-color-buffer-float.html',
         ['linux', 'intel'], bug=640389)
-    self.Fail('WebglExtension_EXT_disjoint_timer_query_webgl2',
-        ['linux', 'intel'], bug=687210)
 
     # See https://bugs.freedesktop.org/show_bug.cgi?id=94477
     self.Skip('conformance/glsl/bugs/temp-expressions-should-not-crash.html',
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
index 6d7713b..8dff047 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -56,10 +56,9 @@
         ['win', 'mac', 'linux'])
     self.Skip('WebglExtension_WEBGL_compressed_texture_s3tc_srgb',
         ['win', 'mac', 'linux', 'android'])
+    self.Skip('WebglExtension_EXT_disjoint_timer_query', bug=808744)
 
     # Extensions not available under D3D9
-    self.Fail('WebglExtension_EXT_disjoint_timer_query',
-        ['win', 'd3d9'])
     self.Fail('WebglExtension_EXT_sRGB',
         ['win', 'd3d9'])
 
@@ -70,8 +69,6 @@
         ['win', 'd3d9'])
 
     # Android general
-    self.Fail('WebglExtension_EXT_disjoint_timer_query',
-        ['android'])
     self.Fail('WebglExtension_EXT_frag_depth',
         ['android'])
     self.Fail('WebglExtension_EXT_shader_texture_lod',
@@ -525,9 +522,6 @@
     self.Fail('conformance/rendering/clipping-wide-points.html',
         ['linux', 'intel'], bug=642822)
 
-    self.Fail('WebglExtension_EXT_disjoint_timer_query',
-        ['linux', 'intel'], bug=687210)
-
     # Linux Intel HD 630
     self.Fail('conformance/textures/misc/texture-size-limit.html',
         ['linux', ('intel', 0x5912)], bug=745888)
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc
index fcba52a..1bfdbda1 100644
--- a/content/test/test_render_frame_host.cc
+++ b/content/test/test_render_frame_host.cc
@@ -333,7 +333,7 @@
 }
 
 void TestRenderFrameHost::SimulateFeaturePolicyHeader(
-    blink::FeaturePolicyFeature feature,
+    blink::mojom::FeaturePolicyFeature feature,
     const std::vector<url::Origin>& whitelist) {
   blink::ParsedFeaturePolicy header(1);
   header[0].feature = feature;
diff --git a/content/test/test_render_frame_host.h b/content/test/test_render_frame_host.h
index 9f8b78c..46cffe622 100644
--- a/content/test/test_render_frame_host.h
+++ b/content/test/test_render_frame_host.h
@@ -79,7 +79,7 @@
   void NavigateAndCommitRendererInitiated(bool did_create_new_entry,
                                           const GURL& url) override;
   void SimulateFeaturePolicyHeader(
-      blink::FeaturePolicyFeature feature,
+      blink::mojom::FeaturePolicyFeature feature,
       const std::vector<url::Origin>& whitelist) override;
   const std::vector<std::string>& GetConsoleMessages() override;
 
diff --git a/device/BUILD.gn b/device/BUILD.gn
index 5e52e72..3fab0fd 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -299,6 +299,7 @@
   }
 
   android_library("bluetooth_test_java") {
+    testonly = true
     java_files = bluetooth_java_sources_needing_jni
     deps = [
       "//base:base_java",
@@ -307,6 +308,8 @@
       "//third_party/android_tools:android_support_annotations_java",
     ]
 
+    deps += android_extra_test_deps
+
     srcjar_deps = [ ":bluetooth_test_javagen" ]
   }
 
diff --git a/gpu/config/gpu_blacklist_unittest.cc b/gpu/config/gpu_blacklist_unittest.cc
index 45bfe72c..17f2bf80c 100644
--- a/gpu/config/gpu_blacklist_unittest.cc
+++ b/gpu/config/gpu_blacklist_unittest.cc
@@ -30,6 +30,8 @@
         kFeatureListForEntry1,  // features
         0,                      // DisabledExtensions size
         nullptr,                // DisabledExtensions
+        0,                      // DisabledWebGLExtensions size
+        nullptr,                // DisabledWebGLExtensions
         0,                      // CrBugs size
         nullptr,                // CrBugs
         {
diff --git a/gpu/config/gpu_control_list.cc b/gpu/config/gpu_control_list.cc
index a1a29a0..f93c1d2 100644
--- a/gpu/config/gpu_control_list.cc
+++ b/gpu/config/gpu_control_list.cc
@@ -605,6 +605,19 @@
                                   disabled_extensions.end());
 }
 
+std::vector<std::string> GpuControlList::GetDisabledWebGLExtensions() {
+  std::set<std::string> disabled_webgl_extensions;
+  for (auto index : active_entries_) {
+    DCHECK_LT(index, entry_count_);
+    const Entry& entry = entries_[index];
+    for (size_t ii = 0; ii < entry.disabled_webgl_extension_size; ++ii) {
+      disabled_webgl_extensions.insert(entry.disabled_webgl_extensions[ii]);
+    }
+  }
+  return std::vector<std::string>(disabled_webgl_extensions.begin(),
+                                  disabled_webgl_extensions.end());
+}
+
 void GpuControlList::GetReasons(base::ListValue* problem_list,
                                 const std::string& tag,
                                 const std::vector<uint32_t>& entries) const {
diff --git a/gpu/config/gpu_control_list.h b/gpu/config/gpu_control_list.h
index de98ea8..416386d7 100644
--- a/gpu/config/gpu_control_list.h
+++ b/gpu/config/gpu_control_list.h
@@ -191,6 +191,8 @@
     const int* features;
     size_t disabled_extension_size;
     const char* const* disabled_extensions;
+    size_t disabled_webgl_extension_size;
+    const char* const* disabled_webgl_extensions;
     size_t cr_bug_size;
     const uint32_t* cr_bugs;
     Conditions conditions;
@@ -243,6 +245,8 @@
 
   // Collects all disabled extensions.
   std::vector<std::string> GetDisabledExtensions();
+  // Collects all disabled WebGL extensions.
+  std::vector<std::string> GetDisabledWebGLExtensions();
 
   // Returns the description and bugs from active entries provided.
   // Each problems has:
diff --git a/gpu/config/gpu_control_list_testing_autogen.cc b/gpu/config/gpu_control_list_testing_autogen.cc
index 5525743..72408ae 100644
--- a/gpu/config/gpu_control_list_testing_autogen.cc
+++ b/gpu/config/gpu_control_list_testing_autogen.cc
@@ -23,8 +23,10 @@
         kFeatureListForEntry1,                    // features
         arraysize(kDisabledExtensionsForEntry1),  // DisabledExtensions size
         kDisabledExtensionsForEntry1,             // DisabledExtensions
-        arraysize(kCrBugsForEntry1),              // CrBugs size
-        kCrBugsForEntry1,                         // CrBugs
+        0,                            // DisabledWebGLExtensions size
+        nullptr,                      // DisabledWebGLExtensions
+        arraysize(kCrBugsForEntry1),  // CrBugs size
+        kCrBugsForEntry1,             // CrBugs
         {
             GpuControlList::kOsMacosx,  // os_type
             {GpuControlList::kEQ, GpuControlList::kVersionStyleNumerical,
@@ -49,6 +51,8 @@
         kFeatureListForEntry2,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -75,6 +79,8 @@
         kFeatureListForEntry3,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -101,6 +107,8 @@
         kFeatureListForEntry4,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -127,6 +135,8 @@
         kFeatureListForEntry5,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -153,6 +163,8 @@
         kFeatureListForEntry6,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -179,6 +191,8 @@
         kFeatureListForEntry7,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -205,6 +219,8 @@
         kFeatureListForEntry8,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -231,6 +247,8 @@
         kFeatureListForEntry9,             // features
         0,                                 // DisabledExtensions size
         nullptr,                           // DisabledExtensions
+        0,                                 // DisabledWebGLExtensions size
+        nullptr,                           // DisabledWebGLExtensions
         0,                                 // CrBugs size
         nullptr,                           // CrBugs
         {
@@ -257,6 +275,8 @@
         kFeatureListForEntry10,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -283,6 +303,8 @@
         kFeatureListForEntry11,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -309,6 +331,8 @@
         kFeatureListForEntry12,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -335,6 +359,8 @@
         kFeatureListForEntry13,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -361,6 +387,8 @@
         kFeatureListForEntry14,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -387,6 +415,8 @@
         kFeatureListForEntry15,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -413,6 +443,8 @@
         kFeatureListForEntry16,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -439,6 +471,8 @@
         kFeatureListForEntry17,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -465,6 +499,8 @@
         kFeatureListForEntry18,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -491,6 +527,8 @@
         kFeatureListForEntry19,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -517,6 +555,8 @@
         kFeatureListForEntry20,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -543,6 +583,8 @@
         kFeatureListForEntry21,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -569,6 +611,8 @@
         kFeatureListForEntry22,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -595,6 +639,8 @@
         kFeatureListForEntry23,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -621,6 +667,8 @@
         kFeatureListForEntry24,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -647,6 +695,8 @@
         kFeatureListForEntry25,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -673,6 +723,8 @@
         kFeatureListForEntry26,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -699,6 +751,8 @@
         kFeatureListForEntry27,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -725,6 +779,8 @@
         kFeatureListForEntry28,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -751,6 +807,8 @@
         kFeatureListForEntry29,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -777,6 +835,8 @@
         kFeatureListForEntry30,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -803,6 +863,8 @@
         kFeatureListForEntry31,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -829,6 +891,8 @@
         kFeatureListForEntry32,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -855,6 +919,8 @@
         kFeatureListForEntry33,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -881,6 +947,8 @@
         kFeatureListForEntry34,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -907,6 +975,8 @@
         kFeatureListForEntry35,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -933,6 +1003,8 @@
         kFeatureListForEntry36,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -959,6 +1031,8 @@
         kFeatureListForEntry37,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -985,6 +1059,8 @@
         kFeatureListForEntry38,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1011,6 +1087,8 @@
         kFeatureListForEntry39,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1037,6 +1115,8 @@
         kFeatureListForEntry40,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1063,6 +1143,8 @@
         kFeatureListForEntry41,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1089,6 +1171,8 @@
         kFeatureListForEntry42,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1115,6 +1199,8 @@
         kFeatureListForEntry43,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1141,6 +1227,8 @@
         kFeatureListForEntry44,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1167,6 +1255,8 @@
         kFeatureListForEntry45,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1193,6 +1283,8 @@
         kFeatureListForEntry46,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1220,6 +1312,8 @@
         kFeatureListForEntry47,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1247,6 +1341,8 @@
         kFeatureListForEntry48,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1273,6 +1369,8 @@
         kFeatureListForEntry49,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1299,6 +1397,8 @@
         kFeatureListForEntry50,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1325,6 +1425,8 @@
         kFeatureListForEntry51,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1351,6 +1453,8 @@
         kFeatureListForEntry52,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1377,6 +1481,8 @@
         kFeatureListForEntry53,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1403,6 +1509,8 @@
         kFeatureListForEntry54,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1429,8 +1537,10 @@
         nullptr,                                   // features
         arraysize(kDisabledExtensionsForEntry55),  // DisabledExtensions size
         kDisabledExtensionsForEntry55,             // DisabledExtensions
-        0,                                         // CrBugs size
-        nullptr,                                   // CrBugs
+        0,        // DisabledWebGLExtensions size
+        nullptr,  // DisabledWebGLExtensions
+        0,        // CrBugs size
+        nullptr,  // CrBugs
         {
             GpuControlList::kOsWin,  // os_type
             {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical,
@@ -1455,8 +1565,10 @@
         nullptr,                                   // features
         arraysize(kDisabledExtensionsForEntry56),  // DisabledExtensions size
         kDisabledExtensionsForEntry56,             // DisabledExtensions
-        0,                                         // CrBugs size
-        nullptr,                                   // CrBugs
+        0,        // DisabledWebGLExtensions size
+        nullptr,  // DisabledWebGLExtensions
+        0,        // CrBugs size
+        nullptr,  // CrBugs
         {
             GpuControlList::kOsWin,  // os_type
             {GpuControlList::kUnknown, GpuControlList::kVersionStyleNumerical,
@@ -1481,6 +1593,8 @@
         kFeatureListForEntry57,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1507,6 +1621,8 @@
         kFeatureListForEntry58,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1533,6 +1649,8 @@
         kFeatureListForEntry59,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
@@ -1559,6 +1677,8 @@
         kFeatureListForEntry60,             // features
         0,                                  // DisabledExtensions size
         nullptr,                            // DisabledExtensions
+        0,                                  // DisabledWebGLExtensions size
+        nullptr,                            // DisabledWebGLExtensions
         0,                                  // CrBugs size
         nullptr,                            // CrBugs
         {
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index 12895a5d..af2df0c 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -2810,6 +2810,24 @@
       "features": [
         "disable_av_sample_buffer_display_layer"
       ]
+    },
+    {
+      "id": 256,
+      "description": "Don't expose disjoint_timer_query extensions to WebGL",
+      "cr_bugs": [808744],
+      "disabled_webgl_extensions": [
+        "EXT_disjoint_timer_query",
+        "EXT_disjoint_timer_query_webgl2"
+      ]
+    },
+    {
+      "id": 257,
+      "description": "Fake entry for testing disabling of WebGL extensions",
+      "cr_bugs": [808744],
+      "test_group": 2,
+      "disabled_webgl_extensions": [
+        "WEBGL_lose_context"
+      ]
     }
   ]
 }
diff --git a/gpu/config/gpu_feature_info.h b/gpu/config/gpu_feature_info.h
index f26572d..51138ae 100644
--- a/gpu/config/gpu_feature_info.h
+++ b/gpu/config/gpu_feature_info.h
@@ -52,6 +52,8 @@
   std::vector<int32_t> enabled_gpu_driver_bug_workarounds;
   // Disabled extensions separated by whitespaces.
   std::string disabled_extensions;
+  // Disabled WebGL extensions separated by whitespaces.
+  std::string disabled_webgl_extensions;
   // Applied gpu blacklist entry indices.
   std::vector<uint32_t> applied_gpu_blacklist_entries;
   // Applied gpu driver bug list entry indices.
diff --git a/gpu/config/gpu_util.cc b/gpu/config/gpu_util.cc
index 3aa0383..affbd91 100644
--- a/gpu/config/gpu_util.cc
+++ b/gpu/config/gpu_util.cc
@@ -328,6 +328,16 @@
     driver_bug_disabled_extensions = list->GetDisabledExtensions();
     all_disabled_extensions.insert(driver_bug_disabled_extensions.begin(),
                                    driver_bug_disabled_extensions.end());
+
+    // Disabling WebGL extensions only occurs via the blacklist, so
+    // the logic is simpler.
+    gl::ExtensionSet disabled_webgl_extensions;
+    std::vector<std::string> disabled_webgl_extension_list =
+        list->GetDisabledWebGLExtensions();
+    disabled_webgl_extensions.insert(disabled_webgl_extension_list.begin(),
+                                     disabled_webgl_extension_list.end());
+    gpu_feature_info.disabled_webgl_extensions =
+        gl::MakeExtensionString(disabled_webgl_extensions);
   }
   gpu::GpuDriverBugList::AppendWorkaroundsFromCommandLine(
       &enabled_driver_bug_workarounds, *command_line);
diff --git a/gpu/config/process_json.py b/gpu/config/process_json.py
index bc67ce3..03910fc 100755
--- a/gpu/config/process_json.py
+++ b/gpu/config/process_json.py
@@ -127,9 +127,10 @@
   data_helper_file.write('};\n\n')
 
 
-def write_disabled_extension_list(entry_id, data, data_file, data_helper_file):
+def write_disabled_extension_list(entry_kind, entry_id, data, data_file,
+                                  data_helper_file):
   if data:
-    var_name = 'kDisabledExtensionsForEntry' + str(entry_id)
+    var_name = 'k%sForEntry%d' % (entry_kind, entry_id)
     # define the list
     data_helper_file.write(
         'const char* const %s[%d] = {\n' % (var_name, len(data)))
@@ -138,11 +139,11 @@
       data_helper_file.write(',\n')
     data_helper_file.write('};\n\n')
     # use the list
-    data_file.write('arraysize(%s),  // DisabledExtensions size\n' % var_name)
-    data_file.write('%s,  // DisabledExtensions\n' % var_name)
+    data_file.write('arraysize(%s),  // %s size\n' % (var_name, entry_kind))
+    data_file.write('%s,  // %s\n' % (var_name, entry_kind))
   else:
-    data_file.write('0,  // DisabledExtensions size\n')
-    data_file.write('nullptr,  // DisabledExtensions\n')
+    data_file.write('0,  // %s size\n' % entry_kind)
+    data_file.write('nullptr,  // %s\n' % entry_kind)
 
 
 def write_gl_strings(entry_id, is_exception, exception_id, data,
@@ -381,6 +382,9 @@
     elif key == 'disabled_extensions':
       assert not is_exception
       continue
+    elif key == 'disabled_webgl_extensions':
+      assert not is_exception
+      continue
     elif key == 'comment':
       continue
     elif key == 'webkit_bugs':
@@ -526,10 +530,12 @@
     data_file.write('0,  // feature size\n')
     data_file.write('nullptr,  // features\n')
   # Disabled extensions
-  disabled_extensions = None
-  if 'disabled_extensions' in entry:
-    disabled_extensions = entry['disabled_extensions']
-  write_disabled_extension_list(entry_id, disabled_extensions,
+  write_disabled_extension_list('DisabledExtensions', entry_id,
+                                entry.get('disabled_extensions', None),
+                                data_file, data_helper_file)
+  # Disabled WebGL extensions
+  write_disabled_extension_list('DisabledWebGLExtensions', entry_id,
+                                entry.get('disabled_webgl_extensions', None),
                                 data_file, data_helper_file)
   # webkit_bugs are skipped because there is only one entry that has it.
   # cr_bugs
diff --git a/gpu/ipc/common/gpu_feature_info.mojom b/gpu/ipc/common/gpu_feature_info.mojom
index 72fe153..01cf4e6 100644
--- a/gpu/ipc/common/gpu_feature_info.mojom
+++ b/gpu/ipc/common/gpu_feature_info.mojom
@@ -30,6 +30,9 @@
   // GL extensions disabled by GpuDriverBugWorkarounds, separated by ' '.
   string disabled_extensions;
 
+  // WebGL extensions disabled by GpuDriverBugWorkarounds, separated by ' '.
+  string disabled_webgl_extensions;
+
   // The array contains a list of gpu blacklist entry indices that apply in the
   // current platform. The entries are defined in
   // gpu/config/software_rendering_list.json.
diff --git a/gpu/ipc/common/gpu_feature_info_struct_traits.h b/gpu/ipc/common/gpu_feature_info_struct_traits.h
index 79f959c..c7b0a07b5 100644
--- a/gpu/ipc/common/gpu_feature_info_struct_traits.h
+++ b/gpu/ipc/common/gpu_feature_info_struct_traits.h
@@ -71,6 +71,7 @@
     return data.ReadEnabledGpuDriverBugWorkarounds(
                &out->enabled_gpu_driver_bug_workarounds) &&
            data.ReadDisabledExtensions(&out->disabled_extensions) &&
+           data.ReadDisabledWebglExtensions(&out->disabled_webgl_extensions) &&
            data.ReadAppliedGpuBlacklistEntries(
                &out->applied_gpu_blacklist_entries) &&
            gpu::GpuBlacklist::AreEntryIndicesValid(
@@ -97,6 +98,11 @@
     return info.disabled_extensions;
   }
 
+  static const std::string& disabled_webgl_extensions(
+      const gpu::GpuFeatureInfo& info) {
+    return info.disabled_webgl_extensions;
+  }
+
   static const std::vector<uint32_t>& applied_gpu_blacklist_entries(
       const gpu::GpuFeatureInfo& info) {
     return info.applied_gpu_blacklist_entries;
diff --git a/ios/chrome/browser/metrics/ukm_egtest.mm b/ios/chrome/browser/metrics/ukm_egtest.mm
index 150df3e9..e30bd38 100644
--- a/ios/chrome/browser/metrics/ukm_egtest.mm
+++ b/ios/chrome/browser/metrics/ukm_egtest.mm
@@ -290,6 +290,7 @@
   // Disable sync.
   SignOut();
   AssertSyncInitialized(false);
+  chrome_test_util::ClearSyncServerData();
 
   [super tearDown];
 }
@@ -452,7 +453,57 @@
 
 // testMultiDisableSync not needed, since there can't be multiple profiles.
 
-// TODO(crbug.com/793082): Implement testSecondaryPassphrase.
+// Make sure that UKM is disabled when a secondary passphrase is used.
+// TODO(crbug.com/806784): Re-enable this test on devices.
+#if TARGET_OS_SIMULATOR
+#define MAYBE_testSecondaryPassphrase testSecondaryPassphrase
+#else
+#define MAYBE_testSecondaryPassphrase FLAKY_testSecondaryPassphrase
+#endif
+- (void)MAYBE_testSecondaryPassphrase {
+  uint64_t original_client_id = metrics::UkmEGTestHelper::client_id();
+
+  [ChromeEarlGreyUI openSettingsMenu];
+  // Open accounts settings, then sync settings.
+  [[EarlGrey selectElementWithMatcher:SettingsAccountButton()]
+      performAction:grey_tap()];
+  [[EarlGrey selectElementWithMatcher:AccountsSyncButton()]
+      performAction:grey_tap()];
+  // Open sync encryption menu.
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"kSettingsSyncId")]
+      performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)];
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(
+                                          l10n_util::GetNSStringWithFixup(
+                                              IDS_IOS_SYNC_ENCRYPTION_TITLE))]
+      performAction:grey_tap()];
+  // Select passphrase encryption.
+  [[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabelId(
+                                          IDS_SYNC_FULL_ENCRYPTION_DATA)]
+      performAction:grey_tap()];
+  // Type and confirm passphrase, then submit.
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityValue(@"Passphrase")]
+      performAction:grey_typeText(@"mypassphrase")];
+  [[EarlGrey
+      selectElementWithMatcher:grey_accessibilityValue(@"Confirm passphrase")]
+      performAction:grey_typeText(@"mypassphrase")];
+  [[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabelId(
+                                          IDS_IOS_SYNC_DECRYPT_BUTTON)]
+      performAction:grey_tap()];
+
+  AssertUKMEnabled(false);
+  // Client ID should have been reset.
+  GREYAssert(original_client_id != metrics::UkmEGTestHelper::client_id(),
+             @"Client ID was not reset.");
+
+  [[EarlGrey selectElementWithMatcher:NavigationBarDoneButton()]
+      performAction:grey_tap()];
+
+  // Reset sync back to original state.
+  SignOut();
+  chrome_test_util::ClearSyncServerData();
+  SignInWithPromo();
+  AssertUKMEnabled(true);
+}
 
 // Make sure that UKM is disabled when sync is not enabled.
 // TODO(crbug.com/806784): Re-enable this test on devices.
diff --git a/media/base/audio_buffer.cc b/media/base/audio_buffer.cc
index 4c8a438..aa587f7 100644
--- a/media/base/audio_buffer.cc
+++ b/media/base/audio_buffer.cc
@@ -366,7 +366,8 @@
   CHECK_LE(frames_to_trim, adjusted_frame_count_);
 
   const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
-  const int frames_to_copy = adjusted_frame_count_ - end;
+  // Empty buffers do not have frames to copy backed by data_.
+  const int frames_to_copy = data_ ? adjusted_frame_count_ - end : 0;
   if (frames_to_copy > 0) {
     switch (sample_format_) {
       case kSampleFormatPlanarS16:
diff --git a/media/base/audio_buffer_unittest.cc b/media/base/audio_buffer_unittest.cc
index 245e572..d423e35 100644
--- a/media/base/audio_buffer_unittest.cc
+++ b/media/base/audio_buffer_unittest.cc
@@ -432,6 +432,37 @@
   VerifyBus(bus.get(), frames, 0, 0);
 }
 
+TEST(AudioBufferTest, TrimEmptyBuffer) {
+  const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
+  const int channels = ChannelLayoutToChannelCount(channel_layout);
+  const int frames = kSampleRate / 10;
+  const base::TimeDelta start_time;
+  const base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
+  scoped_refptr<AudioBuffer> buffer = AudioBuffer::CreateEmptyBuffer(
+      channel_layout, channels, kSampleRate, frames, start_time);
+  EXPECT_EQ(frames, buffer->frame_count());
+  EXPECT_EQ(start_time, buffer->timestamp());
+  EXPECT_EQ(duration, buffer->duration());
+  EXPECT_FALSE(buffer->end_of_stream());
+
+  // Read all frames from the buffer. All data should be 0.
+  std::unique_ptr<AudioBus> bus = AudioBus::Create(channels, frames);
+  buffer->ReadFrames(frames, 0, 0, bus.get());
+  VerifyBus(bus.get(), frames, 0, 0);
+
+  // Trim 10ms of frames from the middle of the buffer.
+  int trim_start = frames / 2;
+  const int trim_length = kSampleRate / 100;
+  const base::TimeDelta trim_duration = base::TimeDelta::FromMilliseconds(10);
+  buffer->TrimRange(trim_start, trim_start + trim_length);
+  EXPECT_EQ(frames - trim_length, buffer->frame_count());
+  EXPECT_EQ(start_time, buffer->timestamp());
+  EXPECT_EQ(duration - trim_duration, buffer->duration());
+  bus->Zero();
+  buffer->ReadFrames(buffer->frame_count(), 0, 0, bus.get());
+  VerifyBus(bus.get(), trim_start, 0, 0);
+}
+
 TEST(AudioBufferTest, Trim) {
   const ChannelLayout channel_layout = CHANNEL_LAYOUT_4_0;
   const int channels = ChannelLayoutToChannelCount(channel_layout);
diff --git a/net/BUILD.gn b/net/BUILD.gn
index dacee46..c063001 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -2152,6 +2152,8 @@
         "websockets/websocket_basic_handshake_stream.h",
         "websockets/websocket_basic_stream.cc",
         "websockets/websocket_basic_stream.h",
+        "websockets/websocket_basic_stream_adapters.cc",
+        "websockets/websocket_basic_stream_adapters.h",
         "websockets/websocket_channel.cc",
         "websockets/websocket_channel.h",
         "websockets/websocket_deflate_parameters.cc",
@@ -5521,6 +5523,7 @@
       "server/http_server_response_info_unittest.cc",
       "server/http_server_unittest.cc",
       "server/web_socket_encoder_unittest.cc",
+      "websockets/websocket_basic_stream_adapters_test.cc",
       "websockets/websocket_basic_stream_test.cc",
       "websockets/websocket_channel_test.cc",
       "websockets/websocket_deflate_parameters_test.cc",
diff --git a/net/android/java/src/org/chromium/net/ProxyChangeListener.java b/net/android/java/src/org/chromium/net/ProxyChangeListener.java
index 503e2eae..f2433a7d 100644
--- a/net/android/java/src/org/chromium/net/ProxyChangeListener.java
+++ b/net/android/java/src/org/chromium/net/ProxyChangeListener.java
@@ -250,7 +250,7 @@
     }
 
     /**
-     * See net/proxy/proxy_config_service_android.cc
+     * See net/proxy_resolution/proxy_config_service_android.cc
      */
     @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate")
     private native void nativeProxySettingsChangedTo(long nativePtr,
diff --git a/net/android/javatests/src/org/chromium/net/AndroidProxySelectorTest.java b/net/android/javatests/src/org/chromium/net/AndroidProxySelectorTest.java
index 8696220..2f310db6 100644
--- a/net/android/javatests/src/org/chromium/net/AndroidProxySelectorTest.java
+++ b/net/android/javatests/src/org/chromium/net/AndroidProxySelectorTest.java
@@ -5,11 +5,11 @@
 /**
  * Test suite for Android's default ProxySelector implementation. The purpose of these tests
  * is to check that the behaviour of the ProxySelector implementation matches what we have
- * implemented in net/proxy/proxy_config_service_android.cc.
+ * implemented in net/proxy_resolution/proxy_config_service_android.cc.
  *
  * IMPORTANT: These test cases are generated from net/android/tools/proxy_test_cases.py, so if any
  * of these tests fail, please be sure to edit that file and regenerate the test cases here and also
- * in net/proxy/proxy_config_service_android_unittests.cc if required.
+ * in net/proxy_resolution/proxy_config_service_android_unittests.cc if required.
  */
 
 package org.chromium.net;
diff --git a/net/disk_cache/disk_cache_perftest.cc b/net/disk_cache/disk_cache_perftest.cc
index 8df5c20..e34b510 100644
--- a/net/disk_cache/disk_cache_perftest.cc
+++ b/net/disk_cache/disk_cache_perftest.cc
@@ -21,6 +21,7 @@
 #include "base/test/scoped_task_environment.h"
 #include "base/test/test_file_util.h"
 #include "base/threading/thread.h"
+#include "build/build_config.h"
 #include "net/base/cache_type.h"
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
@@ -53,7 +54,7 @@
 const int kMaxParallelOperations = 10;
 
 void MaybeSetFdLimit(unsigned int max_descriptors) {
-#if defined(OS_POSIX)
+#if defined(OS_POSIX) && !defined(OS_FUCHSIA)
   base::SetFdLimit(max_descriptors);
 #endif
 }
diff --git a/net/disk_cache/simple/simple_backend_impl.cc b/net/disk_cache/simple/simple_backend_impl.cc
index e88db9ea..80813698 100644
--- a/net/disk_cache/simple/simple_backend_impl.cc
+++ b/net/disk_cache/simple/simple_backend_impl.cc
@@ -31,6 +31,7 @@
 #include "base/time/time.h"
 #include "base/trace_event/memory_usage_estimator.h"
 #include "base/trace_event/process_memory_dump.h"
+#include "build/build_config.h"
 #include "net/base/net_errors.h"
 #include "net/disk_cache/backend_cleanup_tracker.h"
 #include "net/disk_cache/cache_util.h"
@@ -85,7 +86,7 @@
   int soft_fd_limit = 0;
   int hard_fd_limit = 0;
 
-#if defined(OS_POSIX)
+#if defined(OS_POSIX) && !defined(OS_FUCHSIA)
   struct rlimit nofile;
   if (!getrlimit(RLIMIT_NOFILE, &nofile)) {
     soft_fd_limit = nofile.rlim_cur;
diff --git a/net/disk_cache/simple/simple_entry_impl.cc b/net/disk_cache/simple/simple_entry_impl.cc
index e653bbe..5b46036 100644
--- a/net/disk_cache/simple/simple_entry_impl.cc
+++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -949,7 +949,7 @@
       last_used_, last_modified_, data_size_, sparse_data_size_));
   Closure task = base::Bind(
       &SimpleSynchronousEntry::ReadData, base::Unretained(synchronous_entry_),
-      SimpleSynchronousEntry::EntryOperationData(stream_index, offset, buf_len),
+      SimpleSynchronousEntry::ReadRequest(stream_index, offset, buf_len),
       crc_request.get(), entry_stat.get(), base::RetainedRef(buf),
       result.get());
   Closure reply =
@@ -1053,8 +1053,8 @@
   // just work.
   Closure task = base::Bind(
       &SimpleSynchronousEntry::WriteData, base::Unretained(synchronous_entry_),
-      SimpleSynchronousEntry::EntryOperationData(
-          stream_index, offset, buf_len, truncate, doom_state_ != DOOM_NONE),
+      SimpleSynchronousEntry::WriteRequest(stream_index, offset, buf_len,
+                                           truncate, doom_state_ != DOOM_NONE),
       base::Unretained(buf), entry_stat.get(), result.get());
   Closure reply = base::Bind(&SimpleEntryImpl::WriteOperationComplete, this,
                              stream_index, callback, base::Passed(&entry_stat),
@@ -1095,11 +1095,11 @@
 
   std::unique_ptr<int> result(new int());
   std::unique_ptr<base::Time> last_used(new base::Time());
-  Closure task = base::Bind(
-      &SimpleSynchronousEntry::ReadSparseData,
-      base::Unretained(synchronous_entry_),
-      SimpleSynchronousEntry::EntryOperationData(sparse_offset, buf_len),
-      base::RetainedRef(buf), last_used.get(), result.get());
+  Closure task =
+      base::Bind(&SimpleSynchronousEntry::ReadSparseData,
+                 base::Unretained(synchronous_entry_),
+                 SimpleSynchronousEntry::SparseRequest(sparse_offset, buf_len),
+                 base::RetainedRef(buf), last_used.get(), result.get());
   Closure reply = base::Bind(&SimpleEntryImpl::ReadSparseOperationComplete,
                              this,
                              callback,
@@ -1151,12 +1151,12 @@
   last_used_ = last_modified_ = base::Time::Now();
 
   std::unique_ptr<int> result(new int());
-  Closure task = base::Bind(
-      &SimpleSynchronousEntry::WriteSparseData,
-      base::Unretained(synchronous_entry_),
-      SimpleSynchronousEntry::EntryOperationData(sparse_offset, buf_len),
-      base::RetainedRef(buf), max_sparse_data_size, entry_stat.get(),
-      result.get());
+  Closure task =
+      base::Bind(&SimpleSynchronousEntry::WriteSparseData,
+                 base::Unretained(synchronous_entry_),
+                 SimpleSynchronousEntry::SparseRequest(sparse_offset, buf_len),
+                 base::RetainedRef(buf), max_sparse_data_size, entry_stat.get(),
+                 result.get());
   Closure reply = base::Bind(&SimpleEntryImpl::WriteSparseOperationComplete,
                              this,
                              callback,
@@ -1186,12 +1186,11 @@
   state_ = STATE_IO_PENDING;
 
   std::unique_ptr<int> result(new int());
-  Closure task = base::Bind(&SimpleSynchronousEntry::GetAvailableRange,
-                            base::Unretained(synchronous_entry_),
-                            SimpleSynchronousEntry::EntryOperationData(
-                                sparse_offset, len),
-                            out_start,
-                            result.get());
+  Closure task =
+      base::Bind(&SimpleSynchronousEntry::GetAvailableRange,
+                 base::Unretained(synchronous_entry_),
+                 SimpleSynchronousEntry::SparseRequest(sparse_offset, len),
+                 out_start, result.get());
   Closure reply = base::Bind(
       &SimpleEntryImpl::GetAvailableRangeOperationComplete,
       this,
diff --git a/net/disk_cache/simple/simple_synchronous_entry.cc b/net/disk_cache/simple/simple_synchronous_entry.cc
index 9f1e6d2..f1660ca 100644
--- a/net/disk_cache/simple/simple_synchronous_entry.cc
+++ b/net/disk_cache/simple/simple_synchronous_entry.cc
@@ -211,27 +211,24 @@
                                              uint32_t data_crc32_p)
     : index(index_p), has_crc32(has_crc32_p), data_crc32(data_crc32_p) {}
 
-SimpleSynchronousEntry::EntryOperationData::EntryOperationData(int index_p,
-                                                               int offset_p,
-                                                               int buf_len_p)
-    : index(index_p),
-      offset(offset_p),
-      buf_len(buf_len_p) {}
+SimpleSynchronousEntry::ReadRequest::ReadRequest(int index_p,
+                                                 int offset_p,
+                                                 int buf_len_p)
+    : index(index_p), offset(offset_p), buf_len(buf_len_p) {}
 
-SimpleSynchronousEntry::EntryOperationData::EntryOperationData(int index_p,
-                                                               int offset_p,
-                                                               int buf_len_p,
-                                                               bool truncate_p,
-                                                               bool doomed_p)
+SimpleSynchronousEntry::WriteRequest::WriteRequest(int index_p,
+                                                   int offset_p,
+                                                   int buf_len_p,
+                                                   bool truncate_p,
+                                                   bool doomed_p)
     : index(index_p),
       offset(offset_p),
       buf_len(buf_len_p),
       truncate(truncate_p),
       doomed(doomed_p) {}
 
-SimpleSynchronousEntry::EntryOperationData::EntryOperationData(
-    int64_t sparse_offset_p,
-    int buf_len_p)
+SimpleSynchronousEntry::SparseRequest::SparseRequest(int64_t sparse_offset_p,
+                                                     int buf_len_p)
     : sparse_offset(sparse_offset_p), buf_len(buf_len_p) {}
 
 // static
@@ -369,7 +366,7 @@
   return (did_delete_count == key_hashes->size()) ? net::OK : net::ERR_FAILED;
 }
 
-void SimpleSynchronousEntry::ReadData(const EntryOperationData& in_entry_op,
+void SimpleSynchronousEntry::ReadData(const ReadRequest& in_entry_op,
                                       CRCRequest* crc_request,
                                       SimpleEntryStat* entry_stat,
                                       net::IOBuffer* out_buf,
@@ -425,7 +422,7 @@
   }
 }
 
-void SimpleSynchronousEntry::WriteData(const EntryOperationData& in_entry_op,
+void SimpleSynchronousEntry::WriteData(const WriteRequest& in_entry_op,
                                        net::IOBuffer* in_buf,
                                        SimpleEntryStat* out_entry_stat,
                                        int* out_result) {
@@ -533,11 +530,10 @@
   *out_result = buf_len;
 }
 
-void SimpleSynchronousEntry::ReadSparseData(
-    const EntryOperationData& in_entry_op,
-    net::IOBuffer* out_buf,
-    base::Time* out_last_used,
-    int* out_result) {
+void SimpleSynchronousEntry::ReadSparseData(const SparseRequest& in_entry_op,
+                                            net::IOBuffer* out_buf,
+                                            base::Time* out_last_used,
+                                            int* out_result) {
   DCHECK(initialized_);
   int64_t offset = in_entry_op.sparse_offset;
   int buf_len = in_entry_op.buf_len;
@@ -611,12 +607,11 @@
   *out_result = read_so_far;
 }
 
-void SimpleSynchronousEntry::WriteSparseData(
-    const EntryOperationData& in_entry_op,
-    net::IOBuffer* in_buf,
-    uint64_t max_sparse_data_size,
-    SimpleEntryStat* out_entry_stat,
-    int* out_result) {
+void SimpleSynchronousEntry::WriteSparseData(const SparseRequest& in_entry_op,
+                                             net::IOBuffer* in_buf,
+                                             uint64_t max_sparse_data_size,
+                                             SimpleEntryStat* out_entry_stat,
+                                             int* out_result) {
   DCHECK(initialized_);
   int64_t offset = in_entry_op.sparse_offset;
   int buf_len = in_entry_op.buf_len;
@@ -726,10 +721,9 @@
   *out_result = written_so_far;
 }
 
-void SimpleSynchronousEntry::GetAvailableRange(
-    const EntryOperationData& in_entry_op,
-    int64_t* out_start,
-    int* out_result) {
+void SimpleSynchronousEntry::GetAvailableRange(const SparseRequest& in_entry_op,
+                                               int64_t* out_start,
+                                               int* out_result) {
   DCHECK(initialized_);
   int64_t offset = in_entry_op.sparse_offset;
   int len = in_entry_op.buf_len;
diff --git a/net/disk_cache/simple/simple_synchronous_entry.h b/net/disk_cache/simple/simple_synchronous_entry.h
index 0539dd1..ad53650 100644
--- a/net/disk_cache/simple/simple_synchronous_entry.h
+++ b/net/disk_cache/simple/simple_synchronous_entry.h
@@ -136,23 +136,33 @@
     bool verify_ok;
   };
 
-  struct EntryOperationData {
-    EntryOperationData(int index_p, int offset_p, int buf_len_p);
-    EntryOperationData(int index_p,
-                       int offset_p,
-                       int buf_len_p,
-                       bool truncate_p,
-                       bool doomed_p);
-    EntryOperationData(int64_t sparse_offset_p, int buf_len_p);
-
+  struct ReadRequest {
+    ReadRequest(int index_p, int offset_p, int buf_len_p);
     int index;
     int offset;
-    int64_t sparse_offset;
+    int buf_len;
+  };
+
+  struct WriteRequest {
+    WriteRequest(int index_p,
+                 int offset_p,
+                 int buf_len_p,
+                 bool truncate_p,
+                 bool doomed_p);
+    int index;
+    int offset;
     int buf_len;
     bool truncate;
     bool doomed;
   };
 
+  struct SparseRequest {
+    SparseRequest(int64_t sparse_offset_p, int buf_len_p);
+
+    int64_t sparse_offset;
+    int buf_len;
+  };
+
   // Opens a disk cache entry on disk. The |key| parameter is optional, if empty
   // the operation may be slower. The |entry_hash| parameter is required.
   // |had_index| is provided only for histograms.
@@ -209,12 +219,12 @@
 
   // |crc_request| can be nullptr here, to denote that no CRC computation is
   // requested.
-  void ReadData(const EntryOperationData& in_entry_op,
+  void ReadData(const ReadRequest& in_entry_op,
                 CRCRequest* crc_request,
                 SimpleEntryStat* entry_stat,
                 net::IOBuffer* out_buf,
                 int* out_result);
-  void WriteData(const EntryOperationData& in_entry_op,
+  void WriteData(const WriteRequest& in_entry_op,
                  net::IOBuffer* in_buf,
                  SimpleEntryStat* out_entry_stat,
                  int* out_result);
@@ -223,16 +233,16 @@
                      const SimpleEntryStat& entry_stat,
                      uint32_t expected_crc32);
 
-  void ReadSparseData(const EntryOperationData& in_entry_op,
+  void ReadSparseData(const SparseRequest& in_entry_op,
                       net::IOBuffer* out_buf,
                       base::Time* out_last_used,
                       int* out_result);
-  void WriteSparseData(const EntryOperationData& in_entry_op,
+  void WriteSparseData(const SparseRequest& in_entry_op,
                        net::IOBuffer* in_buf,
                        uint64_t max_sparse_data_size,
                        SimpleEntryStat* out_entry_stat,
                        int* out_result);
-  void GetAvailableRange(const EntryOperationData& in_entry_op,
+  void GetAvailableRange(const SparseRequest& in_entry_op,
                          int64_t* out_start,
                          int* out_result);
 
diff --git a/net/socket/client_socket_pool_manager_impl.h b/net/socket/client_socket_pool_manager_impl.h
index d3a7af8..7946a4ed 100644
--- a/net/socket/client_socket_pool_manager_impl.h
+++ b/net/socket/client_socket_pool_manager_impl.h
@@ -14,6 +14,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/threading/thread_checker.h"
+#include "net/base/net_export.h"
 #include "net/cert/cert_database.h"
 #include "net/http/http_network_session.h"
 #include "net/socket/client_socket_pool_manager.h"
@@ -41,8 +42,9 @@
 class TransportClientSocketPool;
 class TransportSecurityState;
 
-class ClientSocketPoolManagerImpl : public ClientSocketPoolManager,
-                                    public CertDatabase::Observer {
+class NET_EXPORT_PRIVATE ClientSocketPoolManagerImpl
+    : public ClientSocketPoolManager,
+      public CertDatabase::Observer {
  public:
   ClientSocketPoolManagerImpl(
       NetLog* net_log,
diff --git a/net/tools/stress_cache/stress_cache.cc b/net/tools/stress_cache/stress_cache.cc
index 3d49fda..992370f 100644
--- a/net/tools/stress_cache/stress_cache.cc
+++ b/net/tools/stress_cache/stress_cache.cc
@@ -352,14 +352,9 @@
 
   if (rand() % 100 > 30) {
     printf("sweet death...\n");
-#if defined(OS_WIN)
-    // Windows does more work on _exit() than we would like.
-    base::Process::Current().Terminate(kExpectedCrash, false);
-#elif defined(OS_POSIX)
-    // On POSIX, _exit() will terminate the process with minimal cleanup,
-    // and it is cleaner than killing.
-    _exit(kExpectedCrash);
-#endif
+
+    // Terminate the current process without doing normal process-exit cleanup.
+    base::Process::TerminateCurrentProcessImmediately(kExpectedCrash);
   }
 }
 
diff --git a/net/traffic_annotation/network_traffic_annotation.h b/net/traffic_annotation/network_traffic_annotation.h
index 3069102f..da91a84 100644
--- a/net/traffic_annotation/network_traffic_annotation.h
+++ b/net/traffic_annotation/network_traffic_annotation.h
@@ -223,7 +223,7 @@
   }
 
   explicit operator NetworkTrafficAnnotationTag() const {
-    CHECK(is_valid());
+    DCHECK(is_valid());
     return NetworkTrafficAnnotationTag({unique_id_hash_code});
   }
 
@@ -247,7 +247,7 @@
   int32_t completing_id_hash_code;
 
   explicit operator PartialNetworkTrafficAnnotationTag() const {
-    CHECK(is_valid());
+    DCHECK(is_valid());
     return PartialNetworkTrafficAnnotationTag(
         {unique_id_hash_code, completing_id_hash_code});
   }
@@ -266,7 +266,6 @@
   int32_t unique_id_hash_code;
 
   explicit operator PartialNetworkTrafficAnnotationTag() const {
-    CHECK(is_valid());
     return PartialNetworkTrafficAnnotationTag({unique_id_hash_code});
   }
 
diff --git a/net/websockets/websocket_basic_handshake_stream.cc b/net/websockets/websocket_basic_handshake_stream.cc
index 47113a24..a32494e 100644
--- a/net/websockets/websocket_basic_handshake_stream.cc
+++ b/net/websockets/websocket_basic_handshake_stream.cc
@@ -37,6 +37,7 @@
 #include "net/socket/websocket_transport_client_socket_pool.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/websockets/websocket_basic_stream.h"
+#include "net/websockets/websocket_basic_stream_adapters.h"
 #include "net/websockets/websocket_deflate_parameters.h"
 #include "net/websockets/websocket_deflate_predictor.h"
 #include "net/websockets/websocket_deflate_predictor_impl.h"
@@ -485,9 +486,11 @@
   // sure it does not touch it again before it is destroyed.
   state_.DeleteParser();
   WebSocketTransportClientSocketPool::UnlockEndpoint(state_.connection());
-  std::unique_ptr<WebSocketStream> basic_stream(
-      new WebSocketBasicStream(state_.ReleaseConnection(), state_.read_buf(),
-                               sub_protocol_, extensions_));
+  std::unique_ptr<WebSocketStream> basic_stream =
+      std::make_unique<WebSocketBasicStream>(
+          std::make_unique<WebSocketClientSocketHandleAdapter>(
+              state_.ReleaseConnection()),
+          state_.read_buf(), sub_protocol_, extensions_);
   DCHECK(extension_params_.get());
   if (extension_params_->deflate_enabled) {
     UMA_HISTOGRAM_ENUMERATION(
diff --git a/net/websockets/websocket_basic_stream.cc b/net/websockets/websocket_basic_stream.cc
index d7bccc1..22d0c68 100644
--- a/net/websockets/websocket_basic_stream.cc
+++ b/net/websockets/websocket_basic_stream.cc
@@ -8,9 +8,7 @@
 #include <stdint.h>
 #include <algorithm>
 #include <limits>
-#include <string>
 #include <utility>
-#include <vector>
 
 #include "base/bind.h"
 #include "base/logging.h"
@@ -19,10 +17,9 @@
 #include "net/base/io_buffer.h"
 #include "net/base/net_errors.h"
 #include "net/socket/client_socket_handle.h"
-#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "net/websockets/websocket_basic_stream_adapters.h"
 #include "net/websockets/websocket_errors.h"
 #include "net/websockets/websocket_frame.h"
-#include "net/websockets/websocket_frame_parser.h"
 
 namespace net {
 
@@ -98,7 +95,7 @@
 }  // namespace
 
 WebSocketBasicStream::WebSocketBasicStream(
-    std::unique_ptr<ClientSocketHandle> connection,
+    std::unique_ptr<Adapter> connection,
     const scoped_refptr<GrowableIOBuffer>& http_read_buffer,
     const std::string& sub_protocol,
     const std::string& extensions)
@@ -147,13 +144,10 @@
     // call any callbacks after Disconnect(), which we call from the
     // destructor. The caller of ReadFrames() is required to keep |frames|
     // valid.
-    int result = connection_->socket()->Read(
-        read_buffer_.get(),
-        read_buffer_->size(),
+    int result = connection_->Read(
+        read_buffer_.get(), read_buffer_->size(),
         base::Bind(&WebSocketBasicStream::OnReadComplete,
-                   base::Unretained(this),
-                   base::Unretained(frames),
-                   callback));
+                   base::Unretained(this), base::Unretained(frames), callback));
     if (result == ERR_IO_PENDING)
       return result;
     result = HandleReadResult(result, frames);
@@ -206,7 +200,9 @@
   return WriteEverything(drainable_buffer, callback);
 }
 
-void WebSocketBasicStream::Close() { connection_->socket()->Disconnect(); }
+void WebSocketBasicStream::Close() {
+  connection_->Disconnect();
+}
 
 std::string WebSocketBasicStream::GetSubProtocol() const {
   return sub_protocol_;
@@ -222,8 +218,10 @@
     const std::string& sub_protocol,
     const std::string& extensions,
     WebSocketMaskingKeyGeneratorFunction key_generator_function) {
-  std::unique_ptr<WebSocketBasicStream> stream(new WebSocketBasicStream(
-      std::move(connection), http_read_buffer, sub_protocol, extensions));
+  auto stream = std::make_unique<WebSocketBasicStream>(
+      std::make_unique<WebSocketClientSocketHandleAdapter>(
+          std::move(connection)),
+      http_read_buffer, sub_protocol, extensions);
   stream->generate_websocket_masking_key_ = key_generator_function;
   return stream;
 }
@@ -234,11 +232,11 @@
   while (buffer->BytesRemaining() > 0) {
     // The use of base::Unretained() here is safe because on destruction we
     // disconnect the socket, preventing any further callbacks.
-    int result = connection_->socket()->Write(
-        buffer.get(), buffer->BytesRemaining(),
-        base::Bind(&WebSocketBasicStream::OnWriteComplete,
-                   base::Unretained(this), buffer, callback),
-        kTrafficAnnotation);
+    int result =
+        connection_->Write(buffer.get(), buffer->BytesRemaining(),
+                           base::Bind(&WebSocketBasicStream::OnWriteComplete,
+                                      base::Unretained(this), buffer, callback),
+                           kTrafficAnnotation);
     if (result > 0) {
       UMA_HISTOGRAM_COUNTS_100000("Net.WebSocket.DataUse.Upstream", result);
       buffer->DidConsume(result);
diff --git a/net/websockets/websocket_basic_stream.h b/net/websockets/websocket_basic_stream.h
index 490424b..e7fab4e 100644
--- a/net/websockets/websocket_basic_stream.h
+++ b/net/websockets/websocket_basic_stream.h
@@ -12,6 +12,7 @@
 #include "base/callback.h"
 #include "base/memory/ref_counted.h"
 #include "net/base/net_export.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/websockets/websocket_frame_parser.h"
 #include "net/websockets/websocket_stream.h"
 
@@ -35,10 +36,27 @@
  public:
   typedef WebSocketMaskingKey (*WebSocketMaskingKeyGeneratorFunction)();
 
+  // Adapter that allows WebSocketBasicStream to use
+  // either a TCP/IP or TLS socket, or an HTTP/2 stream.
+  class Adapter {
+   public:
+    virtual ~Adapter() = default;
+    virtual int Read(IOBuffer* buf,
+                     int buf_len,
+                     const CompletionCallback& callback) = 0;
+    virtual int Write(
+        IOBuffer* buf,
+        int buf_len,
+        const CompletionCallback& callback,
+        const NetworkTrafficAnnotationTag& traffic_annotation) = 0;
+    virtual void Disconnect() = 0;
+    virtual bool is_initialized() const = 0;
+  };
+
   // This class should not normally be constructed directly; see
   // WebSocketStream::CreateAndConnectStream() and
   // WebSocketBasicHandshakeStream::Upgrade().
-  WebSocketBasicStream(std::unique_ptr<ClientSocketHandle> connection,
+  WebSocketBasicStream(std::unique_ptr<Adapter> connection,
                        const scoped_refptr<GrowableIOBuffer>& http_read_buffer,
                        const std::string& sub_protocol,
                        const std::string& extensions);
@@ -132,7 +150,7 @@
 
   // The connection, wrapped in a ClientSocketHandle so that we can prevent it
   // from being returned to the pool.
-  std::unique_ptr<ClientSocketHandle> connection_;
+  std::unique_ptr<Adapter> connection_;
 
   // Frame header for the frame currently being received. Only non-NULL while we
   // are processing the frame. If the frame arrives in multiple chunks, it can
diff --git a/net/websockets/websocket_basic_stream_adapters.cc b/net/websockets/websocket_basic_stream_adapters.cc
new file mode 100644
index 0000000..fc50347
--- /dev/null
+++ b/net/websockets/websocket_basic_stream_adapters.cc
@@ -0,0 +1,47 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/websockets/websocket_basic_stream_adapters.h"
+
+#include <algorithm>
+#include <cstring>
+#include <utility>
+
+#include "net/base/io_buffer.h"
+#include "net/socket/client_socket_handle.h"
+#include "net/socket/socket.h"
+
+namespace net {
+
+WebSocketClientSocketHandleAdapter::WebSocketClientSocketHandleAdapter(
+    std::unique_ptr<ClientSocketHandle> connection)
+    : connection_(std::move(connection)) {}
+
+WebSocketClientSocketHandleAdapter::~WebSocketClientSocketHandleAdapter() {}
+
+int WebSocketClientSocketHandleAdapter::Read(
+    IOBuffer* buf,
+    int buf_len,
+    const CompletionCallback& callback) {
+  return connection_->socket()->Read(buf, buf_len, callback);
+}
+
+int WebSocketClientSocketHandleAdapter::Write(
+    IOBuffer* buf,
+    int buf_len,
+    const CompletionCallback& callback,
+    const NetworkTrafficAnnotationTag& traffic_annotation) {
+  return connection_->socket()->Write(buf, buf_len, callback,
+                                      traffic_annotation);
+}
+
+void WebSocketClientSocketHandleAdapter::Disconnect() {
+  connection_->socket()->Disconnect();
+}
+
+bool WebSocketClientSocketHandleAdapter::is_initialized() const {
+  return connection_->is_initialized();
+}
+
+}  // namespace net
diff --git a/net/websockets/websocket_basic_stream_adapters.h b/net/websockets/websocket_basic_stream_adapters.h
new file mode 100644
index 0000000..131b244
--- /dev/null
+++ b/net/websockets/websocket_basic_stream_adapters.h
@@ -0,0 +1,43 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_
+#define NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_
+
+#include <memory>
+
+#include "net/base/net_export.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "net/websockets/websocket_basic_stream.h"
+
+namespace net {
+
+class ClientSocketHandle;
+class IOBuffer;
+
+// Trivial adapter to make WebSocketBasicStream use an HTTP/1.1 connection.
+class NET_EXPORT_PRIVATE WebSocketClientSocketHandleAdapter
+    : public WebSocketBasicStream::Adapter {
+ public:
+  explicit WebSocketClientSocketHandleAdapter(
+      std::unique_ptr<ClientSocketHandle> connection);
+  ~WebSocketClientSocketHandleAdapter() override;
+
+  int Read(IOBuffer* buf,
+           int buf_len,
+           const CompletionCallback& callback) override;
+  int Write(IOBuffer* buf,
+            int buf_len,
+            const CompletionCallback& callback,
+            const NetworkTrafficAnnotationTag& traffic_annotation) override;
+  void Disconnect() override;
+  bool is_initialized() const override;
+
+ private:
+  std::unique_ptr<ClientSocketHandle> connection_;
+};
+
+}  // namespace net
+
+#endif  // NET_WEBSOCKETS_WEBSOCKET_BASIC_STREAM_ADAPTERS_H_
diff --git a/net/websockets/websocket_basic_stream_adapters_test.cc b/net/websockets/websocket_basic_stream_adapters_test.cc
new file mode 100644
index 0000000..964443a9
--- /dev/null
+++ b/net/websockets/websocket_basic_stream_adapters_test.cc
@@ -0,0 +1,268 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/websockets/websocket_basic_stream_adapters.h"
+
+#include <utility>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/strings/string_piece.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/io_buffer.h"
+#include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/http/http_network_session.h"
+#include "net/socket/client_socket_handle.h"
+#include "net/socket/client_socket_pool_manager_impl.h"
+#include "net/socket/socket_test_util.h"
+#include "net/socket/ssl_client_socket_pool.h"
+#include "net/socket/transport_client_socket_pool.h"
+#include "net/ssl/ssl_config.h"
+#include "net/test/gtest_util.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace test {
+
+const char* const kGroupName = "ssl/www.example.org:443";
+
+class WebSocketClientSocketHandleAdapterTest : public testing::Test {
+ protected:
+  WebSocketClientSocketHandleAdapterTest()
+      : host_port_pair_("www.example.org", 443),
+        socket_pool_manager_(std::make_unique<ClientSocketPoolManagerImpl>(
+            &net_log_,
+            &socket_factory_,
+            nullptr,
+            nullptr,
+            &host_resolver,
+            nullptr,
+            nullptr,
+            nullptr,
+            nullptr,
+            nullptr,
+            "test_shard",
+            nullptr,
+            HttpNetworkSession::NORMAL_SOCKET_POOL)),
+        transport_params_(base::MakeRefCounted<TransportSocketParams>(
+            host_port_pair_,
+            false,
+            OnHostResolutionCallback(),
+            TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)),
+        ssl_params_(base::MakeRefCounted<SSLSocketParams>(transport_params_,
+                                                          nullptr,
+                                                          nullptr,
+                                                          host_port_pair_,
+                                                          SSLConfig(),
+                                                          PRIVACY_MODE_DISABLED,
+                                                          0,
+                                                          false)) {}
+
+  bool InitClientSocketHandle(ClientSocketHandle* connection) {
+    TestCompletionCallback callback;
+    int rv = connection->Init(
+        kGroupName, ssl_params_, MEDIUM, SocketTag(),
+        ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
+        socket_pool_manager_->GetSSLSocketPool(), NetLogWithSource());
+    rv = callback.GetResult(rv);
+    return rv == OK;
+  }
+
+  const HostPortPair host_port_pair_;
+  NetLog net_log_;
+  MockClientSocketFactory socket_factory_;
+  MockHostResolver host_resolver;
+  std::unique_ptr<ClientSocketPoolManagerImpl> socket_pool_manager_;
+  scoped_refptr<TransportSocketParams> transport_params_;
+  scoped_refptr<SSLSocketParams> ssl_params_;
+};
+
+TEST_F(WebSocketClientSocketHandleAdapterTest, Uninitialized) {
+  auto connection = std::make_unique<ClientSocketHandle>();
+  WebSocketClientSocketHandleAdapter adapter(std::move(connection));
+  EXPECT_FALSE(adapter.is_initialized());
+}
+
+TEST_F(WebSocketClientSocketHandleAdapterTest, IsInitialized) {
+  StaticSocketDataProvider data(nullptr, 0, nullptr, 0);
+  socket_factory_.AddSocketDataProvider(&data);
+  SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
+
+  auto connection = std::make_unique<ClientSocketHandle>();
+  ClientSocketHandle* const connection_ptr = connection.get();
+
+  WebSocketClientSocketHandleAdapter adapter(std::move(connection));
+  EXPECT_FALSE(adapter.is_initialized());
+
+  EXPECT_TRUE(InitClientSocketHandle(connection_ptr));
+
+  EXPECT_TRUE(adapter.is_initialized());
+}
+
+TEST_F(WebSocketClientSocketHandleAdapterTest, Disconnect) {
+  StaticSocketDataProvider data(nullptr, 0, nullptr, 0);
+  socket_factory_.AddSocketDataProvider(&data);
+  SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
+
+  auto connection = std::make_unique<ClientSocketHandle>();
+  EXPECT_TRUE(InitClientSocketHandle(connection.get()));
+
+  StreamSocket* const socket = connection->socket();
+
+  WebSocketClientSocketHandleAdapter adapter(std::move(connection));
+  EXPECT_TRUE(adapter.is_initialized());
+
+  EXPECT_TRUE(socket->IsConnected());
+  adapter.Disconnect();
+  EXPECT_FALSE(socket->IsConnected());
+}
+
+TEST_F(WebSocketClientSocketHandleAdapterTest, Read) {
+  MockRead reads[] = {MockRead(SYNCHRONOUS, "foo"), MockRead("bar")};
+  StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
+  socket_factory_.AddSocketDataProvider(&data);
+  SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
+
+  auto connection = std::make_unique<ClientSocketHandle>();
+  EXPECT_TRUE(InitClientSocketHandle(connection.get()));
+
+  WebSocketClientSocketHandleAdapter adapter(std::move(connection));
+  EXPECT_TRUE(adapter.is_initialized());
+
+  // Buffer larger than each MockRead.
+  const int kReadBufSize = 1024;
+  auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
+  int rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionCallback());
+  ASSERT_EQ(3, rv);
+  EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
+
+  TestCompletionCallback callback;
+  rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
+  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+  rv = callback.WaitForResult();
+  ASSERT_EQ(3, rv);
+  EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
+
+  EXPECT_TRUE(data.AllReadDataConsumed());
+  EXPECT_TRUE(data.AllWriteDataConsumed());
+}
+
+TEST_F(WebSocketClientSocketHandleAdapterTest, ReadIntoSmallBuffer) {
+  MockRead reads[] = {MockRead(SYNCHRONOUS, "foo"), MockRead("bar")};
+  StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
+  socket_factory_.AddSocketDataProvider(&data);
+  SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
+
+  auto connection = std::make_unique<ClientSocketHandle>();
+  EXPECT_TRUE(InitClientSocketHandle(connection.get()));
+
+  WebSocketClientSocketHandleAdapter adapter(std::move(connection));
+  EXPECT_TRUE(adapter.is_initialized());
+
+  // Buffer smaller than each MockRead.
+  const int kReadBufSize = 2;
+  auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
+  int rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionCallback());
+  ASSERT_EQ(2, rv);
+  EXPECT_EQ("fo", base::StringPiece(read_buf->data(), rv));
+
+  rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionCallback());
+  ASSERT_EQ(1, rv);
+  EXPECT_EQ("o", base::StringPiece(read_buf->data(), rv));
+
+  TestCompletionCallback callback1;
+  rv = adapter.Read(read_buf.get(), kReadBufSize, callback1.callback());
+  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+  rv = callback1.WaitForResult();
+  ASSERT_EQ(2, rv);
+  EXPECT_EQ("ba", base::StringPiece(read_buf->data(), rv));
+
+  rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionCallback());
+  ASSERT_EQ(1, rv);
+  EXPECT_EQ("r", base::StringPiece(read_buf->data(), rv));
+
+  EXPECT_TRUE(data.AllReadDataConsumed());
+  EXPECT_TRUE(data.AllWriteDataConsumed());
+}
+
+TEST_F(WebSocketClientSocketHandleAdapterTest, Write) {
+  MockWrite writes[] = {MockWrite(SYNCHRONOUS, "foo"), MockWrite("bar")};
+  StaticSocketDataProvider data(nullptr, 0, writes, arraysize(writes));
+  socket_factory_.AddSocketDataProvider(&data);
+  SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
+
+  auto connection = std::make_unique<ClientSocketHandle>();
+  EXPECT_TRUE(InitClientSocketHandle(connection.get()));
+
+  WebSocketClientSocketHandleAdapter adapter(std::move(connection));
+  EXPECT_TRUE(adapter.is_initialized());
+
+  auto write_buf1 = base::MakeRefCounted<StringIOBuffer>("foo");
+  int rv = adapter.Write(write_buf1.get(), write_buf1->size(),
+                         CompletionCallback(), TRAFFIC_ANNOTATION_FOR_TESTS);
+  ASSERT_EQ(3, rv);
+
+  auto write_buf2 = base::MakeRefCounted<StringIOBuffer>("bar");
+  TestCompletionCallback callback;
+  rv = adapter.Write(write_buf2.get(), write_buf2->size(), callback.callback(),
+                     TRAFFIC_ANNOTATION_FOR_TESTS);
+  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+  rv = callback.WaitForResult();
+  ASSERT_EQ(3, rv);
+
+  EXPECT_TRUE(data.AllReadDataConsumed());
+  EXPECT_TRUE(data.AllWriteDataConsumed());
+}
+
+// Test that if both Read() and Write() returns asynchronously,
+// the two callbacks are handled correctly.
+TEST_F(WebSocketClientSocketHandleAdapterTest, AsyncReadAndWrite) {
+  MockRead reads[] = {MockRead("foobar")};
+  MockWrite writes[] = {MockWrite("baz")};
+  StaticSocketDataProvider data(reads, arraysize(reads), writes,
+                                arraysize(writes));
+  socket_factory_.AddSocketDataProvider(&data);
+  SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
+  socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
+
+  auto connection = std::make_unique<ClientSocketHandle>();
+  EXPECT_TRUE(InitClientSocketHandle(connection.get()));
+
+  WebSocketClientSocketHandleAdapter adapter(std::move(connection));
+  EXPECT_TRUE(adapter.is_initialized());
+
+  const int kReadBufSize = 1024;
+  auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
+  TestCompletionCallback read_callback;
+  int rv = adapter.Read(read_buf.get(), kReadBufSize, read_callback.callback());
+  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+  auto write_buf = base::MakeRefCounted<StringIOBuffer>("baz");
+  TestCompletionCallback write_callback;
+  rv = adapter.Write(write_buf.get(), write_buf->size(),
+                     write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
+  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
+
+  rv = read_callback.WaitForResult();
+  ASSERT_EQ(6, rv);
+  EXPECT_EQ("foobar", base::StringPiece(read_buf->data(), rv));
+
+  rv = write_callback.WaitForResult();
+  ASSERT_EQ(3, rv);
+
+  EXPECT_TRUE(data.AllReadDataConsumed());
+  EXPECT_TRUE(data.AllWriteDataConsumed());
+}
+
+}  // namespace test
+
+}  // namespace net
diff --git a/net/websockets/websocket_basic_stream_test.cc b/net/websockets/websocket_basic_stream_test.cc
index da8d228d..a1dea4a 100644
--- a/net/websockets/websocket_basic_stream_test.cc
+++ b/net/websockets/websocket_basic_stream_test.cc
@@ -11,9 +11,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <string.h>  // for memcpy() and memset().
-#include <string>
 #include <utility>
-#include <vector>
 
 #include "base/big_endian.h"
 #include "base/macros.h"
diff --git a/net/websockets/websocket_handshake_constants.cc b/net/websockets/websocket_handshake_constants.cc
index bb031e21..cb03efb33 100644
--- a/net/websockets/websocket_handshake_constants.cc
+++ b/net/websockets/websocket_handshake_constants.cc
@@ -22,13 +22,8 @@
 const char kUpgrade[] = "Upgrade";
 const char kWebSocketGuid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
 
-const char kSecWebSocketProtocolSpdy3[] = ":sec-websocket-protocol";
-const char kSecWebSocketExtensionsSpdy3[] = ":sec-websocket-extensions";
-
-const char* const kSecWebSocketProtocolLowercase =
-    kSecWebSocketProtocolSpdy3 + 1;
-const char* const kSecWebSocketExtensionsLowercase =
-    kSecWebSocketExtensionsSpdy3 + 1;
+const char kSecWebSocketProtocolLowercase[] = "sec-websocket-protocol";
+const char kSecWebSocketExtensionsLowercase[] = "sec-websocket-extensions";
 const char kSecWebSocketKeyLowercase[] = "sec-websocket-key";
 const char kSecWebSocketVersionLowercase[] = "sec-websocket-version";
 const char kUpgradeLowercase[] = "upgrade";
diff --git a/net/websockets/websocket_handshake_constants.h b/net/websockets/websocket_handshake_constants.h
index 6b17be0..f32b5f26 100644
--- a/net/websockets/websocket_handshake_constants.h
+++ b/net/websockets/websocket_handshake_constants.h
@@ -56,21 +56,13 @@
 // RFC6455.
 extern const char NET_EXPORT kWebSocketGuid[];
 
-// Colon-prefixed lowercase headers for SPDY3.
-
-// ":sec-websocket-protocol"
-extern const char kSecWebSocketProtocolSpdy3[];
-
-// ":sec-websocket-extensions"
-extern const char kSecWebSocketExtensionsSpdy3[];
-
 // Some parts of the code require lowercase versions of the header names in
-// order to do case-insensitive comparisons, or because of SPDY.
+// order to do case-insensitive comparisons, or because of HTTP/2.
 // "sec-websocket-protocol"
-extern const char* const kSecWebSocketProtocolLowercase;
+extern const char kSecWebSocketProtocolLowercase[];
 
 // "sec-websocket-extensions"
-extern const char* const kSecWebSocketExtensionsLowercase;
+extern const char kSecWebSocketExtensionsLowercase[];
 
 // "sec-webSocket-key"
 extern const char kSecWebSocketKeyLowercase[];
diff --git a/net/websockets/websocket_test_util.cc b/net/websockets/websocket_test_util.cc
index f7c3725..556ed74 100644
--- a/net/websockets/websocket_test_util.cc
+++ b/net/websockets/websocket_test_util.cc
@@ -7,7 +7,6 @@
 #include <stddef.h>
 #include <algorithm>
 #include <utility>
-#include <vector>
 
 #include "base/strings/stringprintf.h"
 #include "net/proxy_resolution/proxy_service.h"
diff --git a/net/websockets/websocket_test_util.h b/net/websockets/websocket_test_util.h
index efa2196..ef3674f0 100644
--- a/net/websockets/websocket_test_util.h
+++ b/net/websockets/websocket_test_util.h
@@ -9,6 +9,7 @@
 
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "base/macros.h"
 #include "net/http/http_basic_state.h"
diff --git a/sandbox/linux/services/credentials.cc b/sandbox/linux/services/credentials.cc
index 65b63ad..ad0714a7 100644
--- a/sandbox/linux/services/credentials.cc
+++ b/sandbox/linux/services/credentials.cc
@@ -6,6 +6,7 @@
 
 #include <errno.h>
 #include <limits.h>
+#include <sched.h>
 #include <signal.h>
 #include <stddef.h>
 #include <stdint.h>
diff --git a/services/network/network_context.h b/services/network/network_context.h
index a038301..1efcf8e 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -17,7 +17,6 @@
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/strong_binding_set.h"
 #include "services/network/cookie_manager.h"
-#include "services/network/keepalive_statistics_recorder.h"
 #include "services/network/public/interfaces/network_service.mojom.h"
 #include "services/network/public/interfaces/udp_socket.mojom.h"
 #include "services/network/public/interfaces/url_loader_factory.mojom.h"
@@ -81,10 +80,6 @@
 
   NetworkService* network_service() { return network_service_; }
 
-  KeepaliveStatisticsRecorder* keepalive_statistics_recorder() {
-    return &keepalive_statistics_recorder_;
-  }
-
   // mojom::NetworkContext implementation:
   void CreateURLLoaderFactory(mojom::URLLoaderFactoryRequest request,
                               uint32_t process_id) override;
@@ -146,8 +141,6 @@
   // NetworkServiceURLLoaderFactory instances.
   mojo::StrongBindingSet<mojom::URLLoaderFactory> loader_factory_bindings_;
 
-  KeepaliveStatisticsRecorder keepalive_statistics_recorder_;
-
   mojom::NetworkContextParamsPtr params_;
 
   mojo::Binding<mojom::NetworkContext> binding_;
diff --git a/services/network/network_service.h b/services/network/network_service.h
index 3020192..6734619 100644
--- a/services/network/network_service.h
+++ b/services/network/network_service.h
@@ -12,6 +12,7 @@
 #include "base/component_export.h"
 #include "base/macros.h"
 #include "mojo/public/cpp/bindings/binding.h"
+#include "services/network/keepalive_statistics_recorder.h"
 #include "services/network/network_change_manager.h"
 #include "services/network/network_service.h"
 #include "services/network/public/interfaces/network_change_manager.mojom.h"
@@ -96,6 +97,9 @@
 
   mojom::NetworkServiceClient* client() { return client_.get(); }
   net::NetLog* net_log() const;
+  KeepaliveStatisticsRecorder* keepalive_statistics_recorder() {
+    return &keepalive_statistics_recorder_;
+  }
 
  private:
   class MojoNetLog;
@@ -114,6 +118,8 @@
 
   mojom::NetworkServiceClientPtr client_;
 
+  KeepaliveStatisticsRecorder keepalive_statistics_recorder_;
+
   // Observer that logs network changes to the NetLog. Must be below the NetLog
   // and the NetworkChangeNotifier (Once this class creates it), so it's
   // destroyed before them.
diff --git a/services/network/network_service_url_loader_factory.cc b/services/network/network_service_url_loader_factory.cc
index 9afec4d..1e91f4ae 100644
--- a/services/network/network_service_url_loader_factory.cc
+++ b/services/network/network_service_url_loader_factory.cc
@@ -16,11 +16,17 @@
     NetworkContext* context,
     uint32_t process_id)
     : context_(context), process_id_(process_id) {
-  context->keepalive_statistics_recorder()->Register(process_id_);
+  if (context_->network_service()) {
+    context->network_service()->keepalive_statistics_recorder()->Register(
+        process_id_);
+  }
 }
 
 NetworkServiceURLLoaderFactory::~NetworkServiceURLLoaderFactory() {
-  context_->keepalive_statistics_recorder()->Unregister(process_id_);
+  if (context_->network_service()) {
+    context_->network_service()->keepalive_statistics_recorder()->Unregister(
+        process_id_);
+  }
 }
 
 void NetworkServiceURLLoaderFactory::CreateLoaderAndStart(
@@ -40,14 +46,19 @@
   }
 
   mojom::NetworkServiceClient* network_service_client = nullptr;
-  if (context_->network_service())
+  base::WeakPtr<KeepaliveStatisticsRecorder> keepalive_statistics_recorder;
+  if (context_->network_service()) {
     network_service_client = context_->network_service()->client();
+    keepalive_statistics_recorder = context_->network_service()
+                                        ->keepalive_statistics_recorder()
+                                        ->AsWeakPtr();
+  }
   new URLLoader(
       context_->url_request_context_getter(), network_service_client,
       std::move(request), options, url_request, report_raw_headers,
       std::move(client),
       static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation),
-      process_id_, context_->keepalive_statistics_recorder()->AsWeakPtr());
+      process_id_, std::move(keepalive_statistics_recorder));
 }
 
 void NetworkServiceURLLoaderFactory::Clone(
diff --git a/services/viz/public/cpp/compositing/copy_output_request_struct_traits.cc b/services/viz/public/cpp/compositing/copy_output_request_struct_traits.cc
index 9825cbf4..f5d8b2c 100644
--- a/services/viz/public/cpp/compositing/copy_output_request_struct_traits.cc
+++ b/services/viz/public/cpp/compositing/copy_output_request_struct_traits.cc
@@ -91,16 +91,13 @@
   }
   request->SetScaleRatio(scale_from, scale_to);
 
-  if (!data.ReadSource(&request->source_))
+  if (!data.ReadSource(&request->source_) || !data.ReadArea(&request->area_) ||
+      !data.ReadResultSelection(&request->result_selection_) ||
+      !data.ReadMailbox(&request->mailbox_) ||
+      !data.ReadSyncToken(&request->sync_token_)) {
     return false;
+  }
 
-  if (!data.ReadArea(&request->area_))
-    return false;
-
-  if (!data.ReadMailbox(&request->mailbox_))
-    return false;
-  if (!data.ReadSyncToken(&request->sync_token_))
-    return false;
   // Mailbox and SyncToken always come together.
   if (!request->mailbox_ != !request->sync_token_)
     return false;
diff --git a/services/viz/public/cpp/compositing/copy_output_request_struct_traits.h b/services/viz/public/cpp/compositing/copy_output_request_struct_traits.h
index 494c34f..9ddac49 100644
--- a/services/viz/public/cpp/compositing/copy_output_request_struct_traits.h
+++ b/services/viz/public/cpp/compositing/copy_output_request_struct_traits.h
@@ -7,6 +7,7 @@
 
 #include "components/viz/common/frame_sinks/copy_output_request.h"
 #include "mojo/common/common_custom_types_struct_traits.h"
+#include "services/viz/public/cpp/compositing/copy_output_result_struct_traits.h"
 #include "services/viz/public/interfaces/compositing/copy_output_request.mojom.h"
 #include "ui/gfx/geometry/mojo/geometry_struct_traits.h"
 
@@ -40,6 +41,11 @@
     return request->area_;
   }
 
+  static const base::Optional<gfx::Rect>& result_selection(
+      const std::unique_ptr<viz::CopyOutputRequest>& request) {
+    return request->result_selection_;
+  }
+
   static const base::Optional<gpu::Mailbox>& mailbox(
       const std::unique_ptr<viz::CopyOutputRequest>& request) {
     return request->mailbox_;
diff --git a/services/viz/public/cpp/compositing/render_pass_struct_traits.cc b/services/viz/public/cpp/compositing/render_pass_struct_traits.cc
index 5dda213..0ec7a9d 100644
--- a/services/viz/public/cpp/compositing/render_pass_struct_traits.cc
+++ b/services/viz/public/cpp/compositing/render_pass_struct_traits.cc
@@ -23,7 +23,8 @@
       !data.ReadTransformToRootTarget(&(*out)->transform_to_root_target) ||
       !data.ReadFilters(&(*out)->filters) ||
       !data.ReadBackgroundFilters(&(*out)->background_filters) ||
-      !data.ReadColorSpace(&(*out)->color_space)) {
+      !data.ReadColorSpace(&(*out)->color_space) ||
+      !data.ReadCopyRequests(&(*out)->copy_requests)) {
     return false;
   }
   (*out)->id = data.id();
diff --git a/services/viz/public/cpp/compositing/render_pass_struct_traits.h b/services/viz/public/cpp/compositing/render_pass_struct_traits.h
index 52d6b57..a7e871d 100644
--- a/services/viz/public/cpp/compositing/render_pass_struct_traits.h
+++ b/services/viz/public/cpp/compositing/render_pass_struct_traits.h
@@ -9,6 +9,7 @@
 
 #include "base/logging.h"
 #include "components/viz/common/quads/render_pass.h"
+#include "services/viz/public/cpp/compositing/copy_output_request_struct_traits.h"
 #include "services/viz/public/cpp/compositing/quads_struct_traits.h"
 #include "services/viz/public/interfaces/compositing/render_pass.mojom-shared.h"
 #include "ui/gfx/ipc/color/gfx_param_traits.h"
@@ -72,6 +73,11 @@
     return input->generate_mipmap;
   }
 
+  static const std::vector<std::unique_ptr<viz::CopyOutputRequest>>&
+  copy_requests(const std::unique_ptr<viz::RenderPass>& input) {
+    return input->copy_requests;
+  }
+
   static const viz::QuadList& quad_list(
       const std::unique_ptr<viz::RenderPass>& input) {
     return input->quad_list;
diff --git a/services/viz/public/cpp/compositing/struct_traits_unittest.cc b/services/viz/public/cpp/compositing/struct_traits_unittest.cc
index b984a39..73f8f33c 100644
--- a/services/viz/public/cpp/compositing/struct_traits_unittest.cc
+++ b/services/viz/public/cpp/compositing/struct_traits_unittest.cc
@@ -259,6 +259,7 @@
   EXPECT_EQ(scale_from, input->scale_from());
   EXPECT_EQ(scale_to, input->scale_to());
   input->set_area(area);
+  input->set_result_selection(result_rect);
   input->set_source(source);
   EXPECT_TRUE(input->is_scaled());
   std::unique_ptr<CopyOutputRequest> output;
@@ -272,6 +273,8 @@
   EXPECT_EQ(source, output->source());
   EXPECT_TRUE(output->has_area());
   EXPECT_EQ(area, output->area());
+  EXPECT_TRUE(output->has_result_selection());
+  EXPECT_EQ(result_rect, output->result_selection());
 
   SkBitmap bitmap;
   bitmap.allocN32Pixels(result_rect.width(), result_rect.height());
@@ -718,6 +721,9 @@
 }
 
 TEST_F(StructTraitsTest, RenderPass) {
+  // The CopyOutputRequest struct traits require a TaskRunner.
+  base::test::ScopedTaskEnvironment scoped_task_environment;
+
   const RenderPassId render_pass_id = 3u;
   const gfx::Rect output_rect(45, 22, 120, 13);
   const gfx::Transform transform_to_root =
@@ -740,6 +746,9 @@
                 filters, background_filters, color_space,
                 has_transparent_background, cache_render_pass,
                 has_damage_from_contributing_content, generate_mipmap);
+  input->copy_requests.push_back(CopyOutputRequest::CreateStubForTesting());
+  const gfx::Rect copy_output_area(24, 42, 75, 57);
+  input->copy_requests.back()->set_area(copy_output_area);
 
   SharedQuadState* shared_state_1 = input->CreateAndAppendSharedQuadState();
   shared_state_1->SetAll(
@@ -798,6 +807,8 @@
   EXPECT_EQ(has_damage_from_contributing_content,
             output->has_damage_from_contributing_content);
   EXPECT_EQ(generate_mipmap, output->generate_mipmap);
+  ASSERT_EQ(1u, output->copy_requests.size());
+  EXPECT_EQ(copy_output_area, output->copy_requests.front()->area());
 
   SharedQuadState* out_sqs1 = output->shared_quad_state_list.ElementAt(0);
   EXPECT_EQ(shared_state_1->quad_to_target_transform,
diff --git a/services/viz/public/interfaces/compositing/copy_output_request.mojom b/services/viz/public/interfaces/compositing/copy_output_request.mojom
index b3d9fc3..a292ac7 100644
--- a/services/viz/public/interfaces/compositing/copy_output_request.mojom
+++ b/services/viz/public/interfaces/compositing/copy_output_request.mojom
@@ -20,6 +20,7 @@
 
   mojo.common.mojom.UnguessableToken? source;
   gfx.mojom.Rect? area;
+  gfx.mojom.Rect? result_selection;
 
   // DEPRECATED: To be removed once tab capture is moved into VIZ.
   // http://crbug.com/754872
diff --git a/services/viz/public/interfaces/compositing/render_pass.mojom b/services/viz/public/interfaces/compositing/render_pass.mojom
index c0614701..af2b98c 100644
--- a/services/viz/public/interfaces/compositing/render_pass.mojom
+++ b/services/viz/public/interfaces/compositing/render_pass.mojom
@@ -4,6 +4,7 @@
 
 module viz.mojom;
 
+import "services/viz/public/interfaces/compositing/copy_output_request.mojom";
 import "services/viz/public/interfaces/compositing/filter_operations.mojom";
 import "services/viz/public/interfaces/compositing/quads.mojom";
 import "ui/gfx/geometry/mojo/geometry.mojom";
@@ -23,5 +24,7 @@
   bool cache_render_pass = false;
   bool has_damage_from_contributing_content = false;
   bool generate_mipmap = false;
+  // |copy_requests| are only allowed by privileged clients.
+  array<CopyOutputRequest> copy_requests;
   array<DrawQuad> quad_list;
 };
diff --git a/testing/android/reporter/BUILD.gn b/testing/android/reporter/BUILD.gn
index 4ff062fc..886569e 100644
--- a/testing/android/reporter/BUILD.gn
+++ b/testing/android/reporter/BUILD.gn
@@ -5,11 +5,15 @@
 import("//build/config/android/rules.gni")
 
 android_library("reporter_java") {
+  testonly = true
   chromium_code = true
 
   deps = [
     "//base:base_java",
   ]
+
+  deps += android_extra_test_deps
+
   java_files = [
     "java/src/org/chromium/test/reporter/TestStatusListener.java",
     "java/src/org/chromium/test/reporter/TestStatusReceiver.java",
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 30151f3..5249a48 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -11177,409 +11177,6 @@
       }
     ]
   },
-  "Optional Win7 Release (NVIDIA)": {
-    "gtest_tests": [
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--test-launcher-retry-limit=0"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "angle_end2end_tests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--test-launcher-retry-limit=0"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "angle_white_box_tests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--use-angle=d3d9"
-        ],
-        "name": "gles2_conform_d3d9_test",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "gles2_conform_test",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--use-angle=gl",
-          "--disable-gpu-sandbox"
-        ],
-        "name": "gles2_conform_gl_test",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "gles2_conform_test",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "gles2_conform_test",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "gpu_unittests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "swiftshader_unittests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      }
-    ],
-    "isolated_scripts": [
-      {
-        "args": [
-          "info_collection",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--expected-vendor-id",
-          "10de",
-          "--expected-device-id",
-          "1cb3"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "info_collection_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating",
-          "--webgl-conformance-version=2.0.1",
-          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl2_conformance_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 20
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d11 --use-cmd-decoder=passthrough"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_d3d11_passthrough_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 2
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9 --use-cmd-decoder=passthrough"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_d3d9_passthrough_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 2
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=d3d9 --use-cmd-decoder=validating"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_d3d9_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 2
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_gl_passthrough_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 2
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      }
-    ]
-  },
   "Win10 Debug (NVIDIA)": {
     "gtest_tests": [
       {
@@ -15565,36 +15162,6 @@
       }
     ]
   },
-  "Win7 Experimental Release (NVIDIA)": {
-    "gtest_tests": [],
-    "isolated_scripts": [
-      {
-        "args": [
-          "noop_sleep",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "noop_sleep_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        }
-      }
-    ]
-  },
   "Win7 Release (AMD)": {
     "gtest_tests": [
       {
@@ -16278,7 +15845,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16305,7 +15872,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16331,7 +15898,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16361,7 +15928,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16388,7 +15955,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16416,7 +15983,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16442,7 +16009,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16470,7 +16037,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16499,7 +16066,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16525,7 +16092,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16548,7 +16115,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16571,7 +16138,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16600,7 +16167,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16629,7 +16196,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16658,7 +16225,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16695,7 +16262,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16729,7 +16296,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16763,7 +16330,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16797,7 +16364,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16835,7 +16402,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16876,7 +16443,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16925,7 +16492,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16960,7 +16527,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -16994,7 +16561,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -17031,7 +16598,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -17066,7 +16633,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -17101,7 +16668,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -17136,7 +16703,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -17171,7 +16738,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -17206,7 +16773,7 @@
         "trigger_script": {
           "args": [
             "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
+            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}]",
             "--multiple-dimension-script-verbose",
             "True"
           ],
@@ -17260,183 +16827,6 @@
     ],
     "isolated_scripts": []
   },
-  "Win7 dEQP Release (NVIDIA)": {
-    "gtest_tests": [
-      {
-        "args": [
-          "--test-launcher-batch-limit=400"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 4
-        },
-        "test": "angle_deqp_egl_tests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--test-launcher-batch-limit=400",
-          "--deqp-egl-display-type=angle-d3d11"
-        ],
-        "name": "angle_deqp_gles2_d3d11_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 4
-        },
-        "test": "angle_deqp_gles2_tests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--test-launcher-batch-limit=400",
-          "--deqp-egl-display-type=angle-vulkan"
-        ],
-        "name": "angle_deqp_gles2_vulkan_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 4
-        },
-        "test": "angle_deqp_gles2_tests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--test-launcher-batch-limit=400",
-          "--deqp-egl-display-type=angle-d3d11"
-        ],
-        "name": "angle_deqp_gles31_d3d11_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 6
-        },
-        "test": "angle_deqp_gles31_tests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--test-launcher-batch-limit=400",
-          "--deqp-egl-display-type=angle-gl"
-        ],
-        "name": "angle_deqp_gles31_gl_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 6
-        },
-        "test": "angle_deqp_gles31_tests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--test-launcher-batch-limit=400",
-          "--deqp-egl-display-type=angle-d3d11"
-        ],
-        "name": "angle_deqp_gles3_d3d11_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 12
-        },
-        "test": "angle_deqp_gles3_tests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      }
-    ],
-    "isolated_scripts": []
-  },
   "Win7 x64 Debug (NVIDIA)": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/chromium.gpu.json b/testing/buildbot/chromium.gpu.json
index 7577f98..da2ba95 100644
--- a/testing/buildbot/chromium.gpu.json
+++ b/testing/buildbot/chromium.gpu.json
@@ -3329,922 +3329,5 @@
         }
       }
     ]
-  },
-  "Win7 Debug (NVIDIA)": {
-    "gtest_tests": [
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--test-launcher-retry-limit=0"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "angle_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--use-cmd-decoder=validating"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "gl_tests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--use-cmd-decoder=passthrough"
-        ],
-        "name": "gl_tests_passthrough",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "gl_tests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "gl_unittests",
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-angle=d3d11",
-          "--use-test-data-path",
-          "--test_video_data=test-25fps.h264:320:240:250:258:::1"
-        ],
-        "name": "video_decode_accelerator_d3d11_unittest",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "video_decode_accelerator_unittest",
-        "use_xvfb": false
-      }
-    ],
-    "isolated_scripts": [
-      {
-        "args": [
-          "context_lost",
-          "--show-stdout",
-          "--browser=debug",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "context_lost_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "depth_capture",
-          "--show-stdout",
-          "--browser=debug",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "depth_capture_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "gpu_process",
-          "--show-stdout",
-          "--browser=debug",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "gpu_process_launch_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "hardware_accelerated_feature",
-          "--show-stdout",
-          "--browser=debug",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "hardware_accelerated_feature_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "info_collection",
-          "--show-stdout",
-          "--browser=debug",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--expected-vendor-id",
-          "10de",
-          "--expected-device-id",
-          "1cb3"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "info_collection_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "maps",
-          "--show-stdout",
-          "--browser=debug",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--dont-restore-color-profile-after-test",
-          "--os-type",
-          "win",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "maps_pixel_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "pixel",
-          "--show-stdout",
-          "--browser=debug",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--dont-restore-color-profile-after-test",
-          "--refimg-cloud-storage-bucket",
-          "chromium-gpu-archive/reference-images",
-          "--os-type",
-          "win",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "pixel_test",
-        "non_precommit_args": [
-          "--upload-refimg-to-cloud-storage"
-        ],
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "precommit_args": [
-          "--download-refimg-from-cloud-storage"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "screenshot_sync",
-          "--show-stdout",
-          "--browser=debug",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--dont-restore-color-profile-after-test"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "screenshot_sync_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "trace_test",
-          "--show-stdout",
-          "--browser=debug",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "trace_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=debug",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8816",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 2
-        }
-      }
-    ]
-  },
-  "Win7 Release (NVIDIA)": {
-    "gtest_tests": [
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--test-launcher-retry-limit=0"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "angle_unittests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--enable-gpu",
-          "--test-launcher-bot-mode",
-          "--test-launcher-jobs=1",
-          "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*"
-        ],
-        "name": "tab_capture_end2end_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "browser_tests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--use-cmd-decoder=validating"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "gl_tests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
-          "--use-cmd-decoder=passthrough"
-        ],
-        "name": "gl_tests_passthrough",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "gl_tests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "gl_unittests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      },
-      {
-        "args": [
-          "--use-angle=d3d11",
-          "--use-test-data-path",
-          "--test_video_data=test-25fps.h264:320:240:250:258:::1"
-        ],
-        "name": "video_decode_accelerator_d3d11_unittest",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "video_decode_accelerator_unittest",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        },
-        "use_xvfb": false
-      }
-    ],
-    "isolated_scripts": [
-      {
-        "args": [
-          "context_lost",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "context_lost_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "depth_capture",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "depth_capture_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "gpu_process",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "gpu_process_launch_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "hardware_accelerated_feature",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "hardware_accelerated_feature_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "info_collection",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--expected-vendor-id",
-          "10de",
-          "--expected-device-id",
-          "1cb3"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "info_collection_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "maps",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--dont-restore-color-profile-after-test",
-          "--os-type",
-          "win",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "maps_pixel_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "pixel",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--dont-restore-color-profile-after-test",
-          "--refimg-cloud-storage-bucket",
-          "chromium-gpu-archive/reference-images",
-          "--os-type",
-          "win",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "pixel_test",
-        "non_precommit_args": [
-          "--upload-refimg-to-cloud-storage"
-        ],
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "precommit_args": [
-          "--download-refimg-from-cloud-storage"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "screenshot_sync",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--dont-restore-color-profile-after-test"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "screenshot_sync_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "trace_test",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "trace_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "--passthrough",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-23.21.13.8792",
-              "os": "Windows-2008ServerR2-SP1",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 2
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      }
-    ]
   }
 }
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json
index a9efab3d..d01a287f 100644
--- a/testing/buildbot/chromium.perf.json
+++ b/testing/buildbot/chromium.perf.json
@@ -34,7 +34,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65,7 +65,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -94,7 +94,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -125,7 +125,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -154,7 +154,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -185,7 +185,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -214,7 +214,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -245,7 +245,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -274,7 +274,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -305,7 +305,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -334,7 +334,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -365,7 +365,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -394,7 +394,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -425,7 +425,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -454,7 +454,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -485,7 +485,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -514,7 +514,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -545,7 +545,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -574,7 +574,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -605,7 +605,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -634,7 +634,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -665,7 +665,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -694,7 +694,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -725,7 +725,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -745,7 +745,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -774,7 +774,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -805,7 +805,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -834,7 +834,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -865,7 +865,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -894,7 +894,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -925,7 +925,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -954,7 +954,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -985,7 +985,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1005,7 +1005,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1094,7 +1094,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1125,7 +1125,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1154,7 +1154,7 @@
           "expiration": 36000,
           "hard_timeout": 16200,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1183,7 +1183,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1214,7 +1214,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1243,7 +1243,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1274,7 +1274,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1303,7 +1303,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1334,7 +1334,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1363,7 +1363,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1394,7 +1394,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1423,7 +1423,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1454,7 +1454,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1483,7 +1483,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1514,7 +1514,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1543,7 +1543,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1572,7 +1572,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1603,7 +1603,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1632,7 +1632,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1663,7 +1663,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1692,7 +1692,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1723,7 +1723,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1752,7 +1752,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1783,7 +1783,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1812,7 +1812,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1843,7 +1843,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1872,7 +1872,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1903,7 +1903,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1932,7 +1932,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1963,7 +1963,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -1992,7 +1992,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2023,7 +2023,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2052,7 +2052,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2083,7 +2083,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2112,7 +2112,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2143,7 +2143,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2172,7 +2172,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2203,7 +2203,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2232,7 +2232,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2263,7 +2263,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2292,7 +2292,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2323,7 +2323,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2352,7 +2352,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2383,7 +2383,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2412,7 +2412,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2443,7 +2443,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2472,7 +2472,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2503,7 +2503,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2532,7 +2532,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2563,7 +2563,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2592,7 +2592,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2623,7 +2623,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2652,7 +2652,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2683,7 +2683,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2712,7 +2712,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2743,7 +2743,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2772,7 +2772,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2803,7 +2803,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2832,7 +2832,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2863,7 +2863,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2892,7 +2892,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2923,7 +2923,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2952,7 +2952,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -2983,7 +2983,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3012,7 +3012,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3043,7 +3043,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3072,7 +3072,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3103,7 +3103,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3132,7 +3132,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3163,7 +3163,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3192,7 +3192,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3223,7 +3223,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3252,7 +3252,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3283,7 +3283,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3312,7 +3312,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3343,7 +3343,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3372,7 +3372,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3401,7 +3401,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3432,7 +3432,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3463,7 +3463,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3492,7 +3492,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3521,7 +3521,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3552,7 +3552,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3583,7 +3583,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3612,7 +3612,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3643,7 +3643,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3672,7 +3672,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3703,7 +3703,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3732,7 +3732,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3763,7 +3763,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3792,7 +3792,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3823,7 +3823,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3852,7 +3852,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3883,7 +3883,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3912,7 +3912,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3943,7 +3943,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -3972,7 +3972,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4003,7 +4003,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4032,7 +4032,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4063,7 +4063,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4092,7 +4092,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4123,7 +4123,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4152,7 +4152,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4183,7 +4183,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4212,7 +4212,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4243,7 +4243,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4272,7 +4272,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4303,7 +4303,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4332,7 +4332,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4363,7 +4363,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4383,7 +4383,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4412,7 +4412,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4441,7 +4441,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4472,7 +4472,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4503,7 +4503,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4532,7 +4532,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4563,7 +4563,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4592,7 +4592,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4621,7 +4621,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4652,7 +4652,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4681,7 +4681,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4712,7 +4712,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -4738,7 +4738,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4767,7 +4767,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4798,7 +4798,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4827,7 +4827,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4858,7 +4858,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4887,7 +4887,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4918,7 +4918,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4947,7 +4947,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -4978,7 +4978,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5007,7 +5007,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5038,7 +5038,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5067,7 +5067,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5098,7 +5098,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5127,7 +5127,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5158,7 +5158,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5187,7 +5187,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5218,7 +5218,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5247,7 +5247,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5278,7 +5278,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5307,7 +5307,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5338,7 +5338,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5367,7 +5367,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5398,7 +5398,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5427,7 +5427,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5458,7 +5458,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5487,7 +5487,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5518,7 +5518,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5547,7 +5547,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5578,7 +5578,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5607,7 +5607,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5638,7 +5638,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5667,7 +5667,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5698,7 +5698,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5718,7 +5718,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5807,7 +5807,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5838,7 +5838,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5867,7 +5867,7 @@
           "expiration": 36000,
           "hard_timeout": 16200,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5896,7 +5896,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5927,7 +5927,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5947,7 +5947,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -5976,7 +5976,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6007,7 +6007,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6036,7 +6036,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6067,7 +6067,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6096,7 +6096,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6127,7 +6127,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6156,7 +6156,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6187,7 +6187,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6216,7 +6216,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6247,7 +6247,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6276,7 +6276,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6305,7 +6305,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6336,7 +6336,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6365,7 +6365,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6396,7 +6396,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6425,7 +6425,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6456,7 +6456,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6485,7 +6485,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6516,7 +6516,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6545,7 +6545,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6576,7 +6576,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6605,7 +6605,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6636,7 +6636,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6665,7 +6665,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6696,7 +6696,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6725,7 +6725,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6756,7 +6756,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6785,7 +6785,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6816,7 +6816,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6845,7 +6845,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6876,7 +6876,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6905,7 +6905,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6936,7 +6936,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6965,7 +6965,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -6996,7 +6996,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7025,7 +7025,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7056,7 +7056,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7085,7 +7085,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7116,7 +7116,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7145,7 +7145,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7176,7 +7176,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7205,7 +7205,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7236,7 +7236,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7265,7 +7265,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7296,7 +7296,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7325,7 +7325,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7356,7 +7356,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7385,7 +7385,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7416,7 +7416,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7445,7 +7445,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7476,7 +7476,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7505,7 +7505,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7536,7 +7536,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7565,7 +7565,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7596,7 +7596,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7625,7 +7625,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7656,7 +7656,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7685,7 +7685,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7716,7 +7716,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7745,7 +7745,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7776,7 +7776,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7805,7 +7805,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7836,7 +7836,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7865,7 +7865,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7896,7 +7896,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7925,7 +7925,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7956,7 +7956,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -7985,7 +7985,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8016,7 +8016,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8045,7 +8045,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8076,7 +8076,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8105,7 +8105,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8134,7 +8134,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8165,7 +8165,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8196,7 +8196,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8225,7 +8225,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8254,7 +8254,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8285,7 +8285,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8316,7 +8316,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8345,7 +8345,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8376,7 +8376,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8405,7 +8405,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8436,7 +8436,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8465,7 +8465,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8496,7 +8496,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8525,7 +8525,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8556,7 +8556,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8585,7 +8585,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8616,7 +8616,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8645,7 +8645,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8676,7 +8676,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8705,7 +8705,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8736,7 +8736,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8765,7 +8765,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8796,7 +8796,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8825,7 +8825,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8856,7 +8856,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8885,7 +8885,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8916,7 +8916,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8945,7 +8945,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -8976,7 +8976,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9005,7 +9005,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9036,7 +9036,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9065,7 +9065,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9096,7 +9096,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9116,7 +9116,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9145,7 +9145,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9174,7 +9174,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9205,7 +9205,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9236,7 +9236,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9265,7 +9265,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9296,7 +9296,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9325,7 +9325,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9354,7 +9354,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9385,7 +9385,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9414,7 +9414,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9445,7 +9445,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -9479,7 +9479,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9509,7 +9509,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9539,7 +9539,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9569,7 +9569,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9599,7 +9599,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9629,7 +9629,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9659,7 +9659,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9689,7 +9689,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9719,7 +9719,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9749,7 +9749,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9779,7 +9779,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9809,7 +9809,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9839,7 +9839,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9869,7 +9869,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9899,7 +9899,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9929,7 +9929,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -9989,7 +9989,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10019,7 +10019,7 @@
           "expiration": 36000,
           "hard_timeout": 16200,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10049,7 +10049,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10079,7 +10079,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10109,7 +10109,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10139,7 +10139,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10169,7 +10169,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10199,7 +10199,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10229,7 +10229,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10259,7 +10259,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10289,7 +10289,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10319,7 +10319,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10349,7 +10349,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10379,7 +10379,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10409,7 +10409,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10439,7 +10439,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10469,7 +10469,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10499,7 +10499,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10529,7 +10529,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10559,7 +10559,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10589,7 +10589,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10619,7 +10619,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10649,7 +10649,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10679,7 +10679,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10709,7 +10709,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10739,7 +10739,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10769,7 +10769,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10799,7 +10799,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10829,7 +10829,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10859,7 +10859,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10889,7 +10889,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10919,7 +10919,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10949,7 +10949,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -10979,7 +10979,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11009,7 +11009,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11039,7 +11039,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11069,7 +11069,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11099,7 +11099,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11129,7 +11129,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11159,7 +11159,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11189,7 +11189,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11219,7 +11219,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11249,7 +11249,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11279,7 +11279,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11309,7 +11309,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11339,7 +11339,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11369,7 +11369,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11399,7 +11399,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11429,7 +11429,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11459,7 +11459,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11489,7 +11489,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11519,7 +11519,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11549,7 +11549,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11579,7 +11579,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11609,7 +11609,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11639,7 +11639,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11669,7 +11669,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11699,7 +11699,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11729,7 +11729,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -11762,7 +11762,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11793,7 +11793,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11822,7 +11822,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11853,7 +11853,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11882,7 +11882,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11913,7 +11913,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11942,7 +11942,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -11973,7 +11973,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12002,7 +12002,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12033,7 +12033,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12062,7 +12062,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12093,7 +12093,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12122,7 +12122,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12153,7 +12153,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12182,7 +12182,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12213,7 +12213,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12242,7 +12242,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12273,7 +12273,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12302,7 +12302,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12333,7 +12333,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12362,7 +12362,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12393,7 +12393,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12422,7 +12422,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12453,7 +12453,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12473,7 +12473,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12502,7 +12502,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12533,7 +12533,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12562,7 +12562,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12593,7 +12593,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12622,7 +12622,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12653,7 +12653,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12682,7 +12682,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12713,7 +12713,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12733,7 +12733,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12822,7 +12822,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12853,7 +12853,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12882,7 +12882,7 @@
           "expiration": 36000,
           "hard_timeout": 16200,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12911,7 +12911,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12942,7 +12942,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -12971,7 +12971,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13002,7 +13002,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13031,7 +13031,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13062,7 +13062,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13091,7 +13091,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13122,7 +13122,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13151,7 +13151,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13182,7 +13182,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13211,7 +13211,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13242,7 +13242,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13271,7 +13271,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13300,7 +13300,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13331,7 +13331,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13360,7 +13360,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13391,7 +13391,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13420,7 +13420,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13451,7 +13451,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13480,7 +13480,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13511,7 +13511,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13540,7 +13540,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13571,7 +13571,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13600,7 +13600,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13631,7 +13631,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13660,7 +13660,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13691,7 +13691,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13720,7 +13720,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13751,7 +13751,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13780,7 +13780,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13811,7 +13811,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13840,7 +13840,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13871,7 +13871,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13900,7 +13900,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13931,7 +13931,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13960,7 +13960,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -13991,7 +13991,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14020,7 +14020,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14051,7 +14051,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14080,7 +14080,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14111,7 +14111,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14140,7 +14140,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14171,7 +14171,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14200,7 +14200,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14231,7 +14231,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14260,7 +14260,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14291,7 +14291,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14320,7 +14320,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14351,7 +14351,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14380,7 +14380,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14411,7 +14411,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14440,7 +14440,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14471,7 +14471,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14500,7 +14500,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14531,7 +14531,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14560,7 +14560,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14591,7 +14591,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14620,7 +14620,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14651,7 +14651,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14680,7 +14680,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14711,7 +14711,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14740,7 +14740,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14771,7 +14771,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14800,7 +14800,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14831,7 +14831,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14860,7 +14860,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14891,7 +14891,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14920,7 +14920,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14951,7 +14951,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -14980,7 +14980,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15011,7 +15011,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15040,7 +15040,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15071,7 +15071,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15100,7 +15100,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15129,7 +15129,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15160,7 +15160,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15191,7 +15191,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15220,7 +15220,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15249,7 +15249,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15280,7 +15280,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15311,7 +15311,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15340,7 +15340,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15371,7 +15371,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15400,7 +15400,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15431,7 +15431,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15460,7 +15460,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15491,7 +15491,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15520,7 +15520,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15551,7 +15551,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15580,7 +15580,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15611,7 +15611,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15640,7 +15640,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15671,7 +15671,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15700,7 +15700,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15731,7 +15731,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15760,7 +15760,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15791,7 +15791,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15820,7 +15820,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15851,7 +15851,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15880,7 +15880,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15911,7 +15911,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15940,7 +15940,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -15971,7 +15971,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16000,7 +16000,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16031,7 +16031,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16060,7 +16060,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16091,7 +16091,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16111,7 +16111,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16140,7 +16140,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16169,7 +16169,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16200,7 +16200,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16231,7 +16231,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16260,7 +16260,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16291,7 +16291,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16320,7 +16320,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16349,7 +16349,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16380,7 +16380,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16409,7 +16409,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16440,7 +16440,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -16474,7 +16474,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16504,7 +16504,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16534,7 +16534,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16564,7 +16564,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16594,7 +16594,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16624,7 +16624,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16654,7 +16654,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16684,7 +16684,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16714,7 +16714,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16744,7 +16744,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16774,7 +16774,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16804,7 +16804,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16834,7 +16834,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16864,7 +16864,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16894,7 +16894,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16924,7 +16924,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -16984,7 +16984,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17014,7 +17014,7 @@
           "expiration": 36000,
           "hard_timeout": 16200,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17044,7 +17044,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17074,7 +17074,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17104,7 +17104,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17134,7 +17134,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17164,7 +17164,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17194,7 +17194,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17224,7 +17224,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17254,7 +17254,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17284,7 +17284,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17314,7 +17314,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17344,7 +17344,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17374,7 +17374,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17404,7 +17404,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17434,7 +17434,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17464,7 +17464,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17494,7 +17494,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17524,7 +17524,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17554,7 +17554,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17584,7 +17584,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17614,7 +17614,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17644,7 +17644,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17674,7 +17674,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17704,7 +17704,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17734,7 +17734,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17764,7 +17764,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17794,7 +17794,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17824,7 +17824,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17854,7 +17854,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17884,7 +17884,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17914,7 +17914,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17944,7 +17944,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -17974,7 +17974,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18004,7 +18004,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18034,7 +18034,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18064,7 +18064,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18094,7 +18094,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18124,7 +18124,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18154,7 +18154,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18184,7 +18184,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18214,7 +18214,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18244,7 +18244,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18274,7 +18274,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18304,7 +18304,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18334,7 +18334,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18364,7 +18364,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18394,7 +18394,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18424,7 +18424,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18454,7 +18454,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18484,7 +18484,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18514,7 +18514,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18544,7 +18544,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18574,7 +18574,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18604,7 +18604,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18634,7 +18634,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18664,7 +18664,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18694,7 +18694,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18724,7 +18724,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -18757,7 +18757,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18788,7 +18788,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18817,7 +18817,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18848,7 +18848,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18877,7 +18877,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18908,7 +18908,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18937,7 +18937,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18968,7 +18968,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -18997,7 +18997,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19028,7 +19028,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19057,7 +19057,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19088,7 +19088,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19117,7 +19117,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19148,7 +19148,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19177,7 +19177,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19208,7 +19208,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19237,7 +19237,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19268,7 +19268,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19297,7 +19297,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19328,7 +19328,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19357,7 +19357,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19388,7 +19388,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19417,7 +19417,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19448,7 +19448,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19468,7 +19468,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19497,7 +19497,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19528,7 +19528,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19557,7 +19557,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19588,7 +19588,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19617,7 +19617,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19648,7 +19648,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19677,7 +19677,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19708,7 +19708,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19728,7 +19728,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19817,7 +19817,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19848,7 +19848,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19877,7 +19877,7 @@
           "expiration": 36000,
           "hard_timeout": 16200,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19906,7 +19906,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19937,7 +19937,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19966,7 +19966,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -19997,7 +19997,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20026,7 +20026,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20057,7 +20057,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20086,7 +20086,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20117,7 +20117,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20146,7 +20146,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20177,7 +20177,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20206,7 +20206,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20237,7 +20237,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20266,7 +20266,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20295,7 +20295,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20326,7 +20326,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20355,7 +20355,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20386,7 +20386,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20415,7 +20415,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20446,7 +20446,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20475,7 +20475,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20506,7 +20506,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20535,7 +20535,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20566,7 +20566,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20595,7 +20595,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20626,7 +20626,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20655,7 +20655,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20686,7 +20686,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20715,7 +20715,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20746,7 +20746,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20775,7 +20775,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20806,7 +20806,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20835,7 +20835,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20866,7 +20866,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20895,7 +20895,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20926,7 +20926,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20955,7 +20955,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -20986,7 +20986,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21015,7 +21015,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21046,7 +21046,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21075,7 +21075,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21106,7 +21106,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21135,7 +21135,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21166,7 +21166,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21195,7 +21195,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21226,7 +21226,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21255,7 +21255,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21286,7 +21286,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21315,7 +21315,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21346,7 +21346,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21375,7 +21375,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21406,7 +21406,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21435,7 +21435,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21466,7 +21466,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21495,7 +21495,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21526,7 +21526,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21555,7 +21555,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21586,7 +21586,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21615,7 +21615,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21646,7 +21646,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21675,7 +21675,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21706,7 +21706,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21735,7 +21735,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21766,7 +21766,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21795,7 +21795,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21826,7 +21826,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21855,7 +21855,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21886,7 +21886,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21915,7 +21915,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21946,7 +21946,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -21975,7 +21975,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22006,7 +22006,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22035,7 +22035,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22066,7 +22066,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22095,7 +22095,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22124,7 +22124,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22155,7 +22155,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22186,7 +22186,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22215,7 +22215,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22244,7 +22244,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22275,7 +22275,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22306,7 +22306,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22335,7 +22335,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22366,7 +22366,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22395,7 +22395,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22426,7 +22426,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22455,7 +22455,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22486,7 +22486,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22515,7 +22515,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22546,7 +22546,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22575,7 +22575,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22606,7 +22606,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22635,7 +22635,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22666,7 +22666,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22695,7 +22695,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22726,7 +22726,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22755,7 +22755,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22786,7 +22786,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22815,7 +22815,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22846,7 +22846,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22875,7 +22875,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22906,7 +22906,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22935,7 +22935,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22966,7 +22966,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -22995,7 +22995,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23026,7 +23026,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23055,7 +23055,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23086,7 +23086,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23106,7 +23106,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23135,7 +23135,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23164,7 +23164,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23195,7 +23195,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23226,7 +23226,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23255,7 +23255,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23286,7 +23286,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23315,7 +23315,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23344,7 +23344,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23375,7 +23375,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23404,7 +23404,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23435,7 +23435,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -23468,7 +23468,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23499,7 +23499,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23528,7 +23528,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23559,7 +23559,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23588,7 +23588,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23619,7 +23619,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23648,7 +23648,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23679,7 +23679,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23708,7 +23708,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23739,7 +23739,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23768,7 +23768,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23799,7 +23799,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23828,7 +23828,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23859,7 +23859,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23888,7 +23888,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23919,7 +23919,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23948,7 +23948,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -23979,7 +23979,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24008,7 +24008,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24039,7 +24039,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24068,7 +24068,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24099,7 +24099,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24128,7 +24128,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24159,7 +24159,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24188,7 +24188,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24219,7 +24219,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24248,7 +24248,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24279,7 +24279,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24308,7 +24308,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24339,7 +24339,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24368,7 +24368,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24399,7 +24399,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24488,7 +24488,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24519,7 +24519,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24548,7 +24548,7 @@
           "expiration": 36000,
           "hard_timeout": 16200,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24577,7 +24577,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24608,7 +24608,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24637,7 +24637,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24668,7 +24668,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24697,7 +24697,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24728,7 +24728,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24757,7 +24757,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24788,7 +24788,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24817,7 +24817,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24848,7 +24848,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24877,7 +24877,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24908,7 +24908,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24937,7 +24937,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24966,7 +24966,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -24997,7 +24997,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25026,7 +25026,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25057,7 +25057,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25086,7 +25086,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25117,7 +25117,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25146,7 +25146,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25177,7 +25177,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25206,7 +25206,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25237,7 +25237,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25266,7 +25266,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25297,7 +25297,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25326,7 +25326,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25357,7 +25357,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25386,7 +25386,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25417,7 +25417,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25446,7 +25446,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25477,7 +25477,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25506,7 +25506,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25537,7 +25537,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25566,7 +25566,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25597,7 +25597,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25626,7 +25626,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25657,7 +25657,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25686,7 +25686,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25717,7 +25717,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25746,7 +25746,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25777,7 +25777,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25806,7 +25806,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25837,7 +25837,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25866,7 +25866,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25897,7 +25897,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25926,7 +25926,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25957,7 +25957,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -25986,7 +25986,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26017,7 +26017,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26046,7 +26046,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26077,7 +26077,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26106,7 +26106,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26137,7 +26137,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26166,7 +26166,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26197,7 +26197,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26226,7 +26226,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26257,7 +26257,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26286,7 +26286,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26317,7 +26317,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26346,7 +26346,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26377,7 +26377,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26406,7 +26406,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26437,7 +26437,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26466,7 +26466,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26497,7 +26497,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26526,7 +26526,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26557,7 +26557,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26586,7 +26586,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26617,7 +26617,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26646,7 +26646,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26677,7 +26677,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26706,7 +26706,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26737,7 +26737,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26766,7 +26766,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26795,7 +26795,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26826,7 +26826,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26857,7 +26857,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26886,7 +26886,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26915,7 +26915,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26946,7 +26946,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -26977,7 +26977,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27006,7 +27006,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27037,7 +27037,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27066,7 +27066,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27097,7 +27097,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27126,7 +27126,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27157,7 +27157,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27186,7 +27186,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27217,7 +27217,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27246,7 +27246,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27277,7 +27277,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27306,7 +27306,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27337,7 +27337,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27366,7 +27366,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27397,7 +27397,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27426,7 +27426,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27457,7 +27457,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27486,7 +27486,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27517,7 +27517,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27546,7 +27546,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27577,7 +27577,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27606,7 +27606,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27637,7 +27637,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27666,7 +27666,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27697,7 +27697,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27726,7 +27726,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27757,7 +27757,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27777,7 +27777,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27806,7 +27806,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27835,7 +27835,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27866,7 +27866,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27897,7 +27897,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27926,7 +27926,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27957,7 +27957,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -27986,7 +27986,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28015,7 +28015,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28046,7 +28046,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28075,7 +28075,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28106,7 +28106,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -28151,7 +28151,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28183,7 +28183,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28213,7 +28213,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28245,7 +28245,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28275,7 +28275,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28307,7 +28307,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28337,7 +28337,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28369,7 +28369,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28399,7 +28399,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28431,7 +28431,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28461,7 +28461,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28493,7 +28493,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28523,7 +28523,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28555,7 +28555,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28585,7 +28585,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28617,7 +28617,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28647,7 +28647,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28679,7 +28679,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28709,7 +28709,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28741,7 +28741,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28771,7 +28771,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28803,7 +28803,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28833,7 +28833,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28865,7 +28865,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28895,7 +28895,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28927,7 +28927,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28957,7 +28957,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -28989,7 +28989,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29019,7 +29019,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29051,7 +29051,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29081,7 +29081,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29113,7 +29113,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29205,7 +29205,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29237,7 +29237,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29258,7 +29258,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29288,7 +29288,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29318,7 +29318,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29350,7 +29350,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29371,7 +29371,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29401,7 +29401,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29433,7 +29433,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29463,7 +29463,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29495,7 +29495,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29525,7 +29525,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29557,7 +29557,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29578,7 +29578,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29608,7 +29608,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29640,7 +29640,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29670,7 +29670,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29702,7 +29702,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29732,7 +29732,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29762,7 +29762,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29794,7 +29794,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29824,7 +29824,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29856,7 +29856,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29886,7 +29886,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29918,7 +29918,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29948,7 +29948,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -29980,7 +29980,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30010,7 +30010,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30042,7 +30042,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30072,7 +30072,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30104,7 +30104,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30134,7 +30134,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30166,7 +30166,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30196,7 +30196,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30228,7 +30228,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30258,7 +30258,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30290,7 +30290,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30320,7 +30320,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30352,7 +30352,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30382,7 +30382,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30414,7 +30414,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30444,7 +30444,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30476,7 +30476,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30506,7 +30506,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30538,7 +30538,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30568,7 +30568,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30600,7 +30600,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30630,7 +30630,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30662,7 +30662,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30692,7 +30692,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30724,7 +30724,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30754,7 +30754,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30786,7 +30786,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30816,7 +30816,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30848,7 +30848,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30878,7 +30878,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30910,7 +30910,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30940,7 +30940,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -30972,7 +30972,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31002,7 +31002,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31034,7 +31034,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31064,7 +31064,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31096,7 +31096,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31126,7 +31126,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31156,7 +31156,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31188,7 +31188,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31220,7 +31220,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31250,7 +31250,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31280,7 +31280,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31312,7 +31312,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31344,7 +31344,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31374,7 +31374,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31406,7 +31406,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31436,7 +31436,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31468,7 +31468,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31498,7 +31498,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31530,7 +31530,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31560,7 +31560,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31592,7 +31592,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31622,7 +31622,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31654,7 +31654,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31684,7 +31684,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31716,7 +31716,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31746,7 +31746,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31778,7 +31778,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31799,7 +31799,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31829,7 +31829,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31859,7 +31859,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31891,7 +31891,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31923,7 +31923,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31953,7 +31953,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -31985,7 +31985,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32015,7 +32015,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32045,7 +32045,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32077,7 +32077,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32107,7 +32107,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32139,7 +32139,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -32173,7 +32173,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32205,7 +32205,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32235,7 +32235,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32267,7 +32267,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32297,7 +32297,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32329,7 +32329,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32359,7 +32359,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32391,7 +32391,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32421,7 +32421,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32453,7 +32453,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32483,7 +32483,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32515,7 +32515,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32545,7 +32545,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32577,7 +32577,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32607,7 +32607,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32639,7 +32639,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32669,7 +32669,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32701,7 +32701,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32731,7 +32731,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32763,7 +32763,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32793,7 +32793,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32825,7 +32825,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32855,7 +32855,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32887,7 +32887,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32917,7 +32917,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32949,7 +32949,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -32979,7 +32979,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33011,7 +33011,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33041,7 +33041,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33073,7 +33073,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33103,7 +33103,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33135,7 +33135,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33165,7 +33165,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33197,7 +33197,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33227,7 +33227,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33259,7 +33259,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33351,7 +33351,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33383,7 +33383,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33413,7 +33413,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33443,7 +33443,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33475,7 +33475,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33505,7 +33505,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33537,7 +33537,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33567,7 +33567,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33599,7 +33599,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33629,7 +33629,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33661,7 +33661,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33682,7 +33682,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33712,7 +33712,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33744,7 +33744,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33774,7 +33774,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33806,7 +33806,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33836,7 +33836,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33866,7 +33866,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33898,7 +33898,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33928,7 +33928,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33960,7 +33960,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -33990,7 +33990,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34022,7 +34022,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34052,7 +34052,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34084,7 +34084,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34114,7 +34114,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34146,7 +34146,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34176,7 +34176,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34208,7 +34208,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34238,7 +34238,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34270,7 +34270,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34300,7 +34300,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34332,7 +34332,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34362,7 +34362,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34394,7 +34394,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34424,7 +34424,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34456,7 +34456,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34486,7 +34486,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34518,7 +34518,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34548,7 +34548,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34580,7 +34580,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34610,7 +34610,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34642,7 +34642,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34672,7 +34672,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34704,7 +34704,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34734,7 +34734,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34766,7 +34766,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34796,7 +34796,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34828,7 +34828,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34858,7 +34858,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34890,7 +34890,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34920,7 +34920,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34952,7 +34952,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -34982,7 +34982,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35014,7 +35014,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35044,7 +35044,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35076,7 +35076,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35106,7 +35106,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35138,7 +35138,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35168,7 +35168,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35200,7 +35200,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35230,7 +35230,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35260,7 +35260,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35292,7 +35292,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35324,7 +35324,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35354,7 +35354,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35384,7 +35384,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35416,7 +35416,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35448,7 +35448,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35478,7 +35478,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35510,7 +35510,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35540,7 +35540,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35572,7 +35572,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35602,7 +35602,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35634,7 +35634,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35664,7 +35664,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35696,7 +35696,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35726,7 +35726,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35758,7 +35758,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35788,7 +35788,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35820,7 +35820,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35850,7 +35850,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35880,7 +35880,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35912,7 +35912,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35944,7 +35944,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -35974,7 +35974,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36006,7 +36006,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36036,7 +36036,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36066,7 +36066,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36098,7 +36098,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36128,7 +36128,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36160,7 +36160,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -36194,7 +36194,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36226,7 +36226,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36256,7 +36256,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36288,7 +36288,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36318,7 +36318,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36350,7 +36350,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36380,7 +36380,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36412,7 +36412,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36442,7 +36442,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36474,7 +36474,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36504,7 +36504,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36536,7 +36536,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36566,7 +36566,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36598,7 +36598,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36628,7 +36628,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36660,7 +36660,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36690,7 +36690,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36722,7 +36722,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36752,7 +36752,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36784,7 +36784,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36814,7 +36814,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36846,7 +36846,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36876,7 +36876,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36908,7 +36908,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36938,7 +36938,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -36970,7 +36970,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37000,7 +37000,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37032,7 +37032,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37062,7 +37062,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37094,7 +37094,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37124,7 +37124,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37156,7 +37156,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37186,7 +37186,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37218,7 +37218,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37248,7 +37248,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37280,7 +37280,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37372,7 +37372,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37404,7 +37404,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37434,7 +37434,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37464,7 +37464,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37496,7 +37496,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37526,7 +37526,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37558,7 +37558,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37588,7 +37588,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37620,7 +37620,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37650,7 +37650,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37682,7 +37682,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37712,7 +37712,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37744,7 +37744,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37774,7 +37774,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37806,7 +37806,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37827,7 +37827,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37857,7 +37857,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37887,7 +37887,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37919,7 +37919,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37949,7 +37949,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -37981,7 +37981,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38011,7 +38011,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38043,7 +38043,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38073,7 +38073,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38105,7 +38105,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38135,7 +38135,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38167,7 +38167,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38197,7 +38197,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38229,7 +38229,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38259,7 +38259,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38291,7 +38291,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38321,7 +38321,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38353,7 +38353,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38383,7 +38383,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38415,7 +38415,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38445,7 +38445,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38477,7 +38477,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38507,7 +38507,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38539,7 +38539,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38569,7 +38569,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38601,7 +38601,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38631,7 +38631,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38663,7 +38663,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38693,7 +38693,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38725,7 +38725,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38755,7 +38755,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38787,7 +38787,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38817,7 +38817,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38849,7 +38849,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38879,7 +38879,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38911,7 +38911,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38941,7 +38941,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -38973,7 +38973,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39003,7 +39003,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39035,7 +39035,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39065,7 +39065,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39097,7 +39097,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39127,7 +39127,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39159,7 +39159,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39189,7 +39189,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39221,7 +39221,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39251,7 +39251,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39281,7 +39281,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39313,7 +39313,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39345,7 +39345,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39375,7 +39375,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39405,7 +39405,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39437,7 +39437,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39469,7 +39469,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39499,7 +39499,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39531,7 +39531,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39561,7 +39561,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39593,7 +39593,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39623,7 +39623,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39655,7 +39655,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39685,7 +39685,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39717,7 +39717,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39747,7 +39747,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39779,7 +39779,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39809,7 +39809,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39841,7 +39841,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39871,7 +39871,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39901,7 +39901,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39933,7 +39933,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39965,7 +39965,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -39995,7 +39995,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40027,7 +40027,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40057,7 +40057,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40087,7 +40087,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40119,7 +40119,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40149,7 +40149,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40181,7 +40181,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -40220,7 +40220,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40252,7 +40252,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40282,7 +40282,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40314,7 +40314,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40344,7 +40344,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40376,7 +40376,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40406,7 +40406,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40438,7 +40438,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40468,7 +40468,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40500,7 +40500,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40530,7 +40530,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40562,7 +40562,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40592,7 +40592,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40624,7 +40624,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40654,7 +40654,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40686,7 +40686,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40716,7 +40716,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40748,7 +40748,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40778,7 +40778,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40810,7 +40810,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40840,7 +40840,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40872,7 +40872,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40902,7 +40902,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40934,7 +40934,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40964,7 +40964,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -40996,7 +40996,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41026,7 +41026,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41058,7 +41058,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41088,7 +41088,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41120,7 +41120,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41150,7 +41150,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41182,7 +41182,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41212,7 +41212,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41244,7 +41244,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41274,7 +41274,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41306,7 +41306,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41398,7 +41398,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41430,7 +41430,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41460,7 +41460,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41490,7 +41490,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41522,7 +41522,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41552,7 +41552,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41584,7 +41584,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41614,7 +41614,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41646,7 +41646,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41676,7 +41676,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41708,7 +41708,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41738,7 +41738,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41770,7 +41770,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41800,7 +41800,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41832,7 +41832,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41853,7 +41853,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41883,7 +41883,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41913,7 +41913,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41945,7 +41945,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -41975,7 +41975,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42007,7 +42007,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42037,7 +42037,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42069,7 +42069,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42099,7 +42099,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42131,7 +42131,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42161,7 +42161,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42193,7 +42193,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42223,7 +42223,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42255,7 +42255,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42285,7 +42285,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42317,7 +42317,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42347,7 +42347,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42379,7 +42379,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42409,7 +42409,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42441,7 +42441,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42471,7 +42471,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42503,7 +42503,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42533,7 +42533,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42565,7 +42565,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42595,7 +42595,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42627,7 +42627,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42657,7 +42657,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42689,7 +42689,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42719,7 +42719,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42751,7 +42751,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42781,7 +42781,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42813,7 +42813,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42843,7 +42843,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42875,7 +42875,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42905,7 +42905,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42937,7 +42937,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42967,7 +42967,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -42999,7 +42999,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43029,7 +43029,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43061,7 +43061,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43091,7 +43091,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43123,7 +43123,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43153,7 +43153,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43185,7 +43185,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43215,7 +43215,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43247,7 +43247,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43277,7 +43277,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43307,7 +43307,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43339,7 +43339,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43371,7 +43371,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43401,7 +43401,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43431,7 +43431,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43463,7 +43463,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43495,7 +43495,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43525,7 +43525,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43557,7 +43557,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43587,7 +43587,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43619,7 +43619,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43649,7 +43649,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43681,7 +43681,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43711,7 +43711,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43743,7 +43743,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43773,7 +43773,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43805,7 +43805,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43835,7 +43835,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43867,7 +43867,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43897,7 +43897,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43927,7 +43927,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43959,7 +43959,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -43991,7 +43991,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44021,7 +44021,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44053,7 +44053,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44083,7 +44083,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44113,7 +44113,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44145,7 +44145,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44175,7 +44175,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44207,7 +44207,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -44241,7 +44241,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44273,7 +44273,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44303,7 +44303,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44335,7 +44335,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44365,7 +44365,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44397,7 +44397,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44427,7 +44427,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44459,7 +44459,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44489,7 +44489,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44521,7 +44521,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44551,7 +44551,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44583,7 +44583,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44613,7 +44613,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44645,7 +44645,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44675,7 +44675,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44707,7 +44707,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44737,7 +44737,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44769,7 +44769,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44799,7 +44799,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44831,7 +44831,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44861,7 +44861,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44893,7 +44893,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44923,7 +44923,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44955,7 +44955,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -44985,7 +44985,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45017,7 +45017,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45047,7 +45047,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45079,7 +45079,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45109,7 +45109,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45141,7 +45141,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45171,7 +45171,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45203,7 +45203,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45295,7 +45295,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45327,7 +45327,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45357,7 +45357,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45387,7 +45387,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45419,7 +45419,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45449,7 +45449,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45481,7 +45481,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45511,7 +45511,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45543,7 +45543,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45573,7 +45573,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45605,7 +45605,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45635,7 +45635,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45667,7 +45667,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45697,7 +45697,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45729,7 +45729,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45759,7 +45759,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45789,7 +45789,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45821,7 +45821,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45851,7 +45851,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45883,7 +45883,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45913,7 +45913,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45945,7 +45945,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -45975,7 +45975,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46007,7 +46007,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46037,7 +46037,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46069,7 +46069,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46099,7 +46099,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46131,7 +46131,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46161,7 +46161,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46193,7 +46193,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46223,7 +46223,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46255,7 +46255,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46285,7 +46285,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46317,7 +46317,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46347,7 +46347,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46379,7 +46379,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46409,7 +46409,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46441,7 +46441,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46471,7 +46471,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46503,7 +46503,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46533,7 +46533,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46565,7 +46565,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46595,7 +46595,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46627,7 +46627,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46657,7 +46657,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46689,7 +46689,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46719,7 +46719,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46751,7 +46751,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46781,7 +46781,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46813,7 +46813,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46843,7 +46843,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46875,7 +46875,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46905,7 +46905,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46937,7 +46937,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46967,7 +46967,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -46999,7 +46999,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47029,7 +47029,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47061,7 +47061,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47091,7 +47091,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47123,7 +47123,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47153,7 +47153,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47183,7 +47183,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47215,7 +47215,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47247,7 +47247,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47277,7 +47277,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47307,7 +47307,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47339,7 +47339,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47371,7 +47371,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47401,7 +47401,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47433,7 +47433,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47463,7 +47463,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47495,7 +47495,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47525,7 +47525,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47557,7 +47557,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47587,7 +47587,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47619,7 +47619,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47649,7 +47649,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47681,7 +47681,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47711,7 +47711,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47743,7 +47743,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47773,7 +47773,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47803,7 +47803,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47835,7 +47835,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47867,7 +47867,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47897,7 +47897,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47929,7 +47929,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47959,7 +47959,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -47989,7 +47989,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48021,7 +48021,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48051,7 +48051,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48083,7 +48083,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -48117,7 +48117,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48149,7 +48149,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48179,7 +48179,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48211,7 +48211,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48241,7 +48241,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48273,7 +48273,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48303,7 +48303,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48335,7 +48335,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48365,7 +48365,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48397,7 +48397,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48427,7 +48427,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48459,7 +48459,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48489,7 +48489,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48521,7 +48521,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48551,7 +48551,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48583,7 +48583,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48613,7 +48613,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48645,7 +48645,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48675,7 +48675,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48707,7 +48707,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48737,7 +48737,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48769,7 +48769,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48799,7 +48799,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48831,7 +48831,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48861,7 +48861,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48893,7 +48893,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48923,7 +48923,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48955,7 +48955,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -48985,7 +48985,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49017,7 +49017,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49047,7 +49047,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49079,7 +49079,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49171,7 +49171,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49203,7 +49203,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49233,7 +49233,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49263,7 +49263,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49295,7 +49295,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49316,7 +49316,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49346,7 +49346,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49378,7 +49378,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49408,7 +49408,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49440,7 +49440,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49470,7 +49470,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49502,7 +49502,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49532,7 +49532,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49564,7 +49564,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49594,7 +49594,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49626,7 +49626,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49656,7 +49656,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49686,7 +49686,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49718,7 +49718,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49748,7 +49748,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49780,7 +49780,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49810,7 +49810,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49842,7 +49842,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49872,7 +49872,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49904,7 +49904,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49934,7 +49934,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49966,7 +49966,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -49996,7 +49996,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50028,7 +50028,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50058,7 +50058,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50090,7 +50090,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50120,7 +50120,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50152,7 +50152,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50182,7 +50182,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50214,7 +50214,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50244,7 +50244,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50276,7 +50276,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50306,7 +50306,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50338,7 +50338,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50368,7 +50368,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50400,7 +50400,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50430,7 +50430,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50462,7 +50462,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50492,7 +50492,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50524,7 +50524,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50554,7 +50554,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50586,7 +50586,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50616,7 +50616,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50648,7 +50648,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50678,7 +50678,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50710,7 +50710,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50740,7 +50740,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50772,7 +50772,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50802,7 +50802,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50834,7 +50834,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50864,7 +50864,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50896,7 +50896,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50926,7 +50926,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50958,7 +50958,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -50988,7 +50988,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51020,7 +51020,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51050,7 +51050,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51080,7 +51080,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51112,7 +51112,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51144,7 +51144,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51174,7 +51174,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51204,7 +51204,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51236,7 +51236,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51268,7 +51268,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51298,7 +51298,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51330,7 +51330,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51360,7 +51360,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51392,7 +51392,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51422,7 +51422,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51454,7 +51454,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51484,7 +51484,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51516,7 +51516,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51546,7 +51546,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51578,7 +51578,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51608,7 +51608,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51640,7 +51640,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51670,7 +51670,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51700,7 +51700,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51732,7 +51732,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51764,7 +51764,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51794,7 +51794,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51826,7 +51826,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51856,7 +51856,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51886,7 +51886,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51918,7 +51918,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51948,7 +51948,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -51980,7 +51980,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -52014,7 +52014,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52046,7 +52046,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52076,7 +52076,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52108,7 +52108,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52138,7 +52138,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52170,7 +52170,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52200,7 +52200,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52232,7 +52232,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52262,7 +52262,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52294,7 +52294,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52324,7 +52324,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52356,7 +52356,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52386,7 +52386,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52418,7 +52418,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52448,7 +52448,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52480,7 +52480,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52510,7 +52510,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52542,7 +52542,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52572,7 +52572,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52604,7 +52604,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52634,7 +52634,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52666,7 +52666,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52696,7 +52696,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52728,7 +52728,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52758,7 +52758,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52790,7 +52790,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52820,7 +52820,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52852,7 +52852,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52882,7 +52882,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52914,7 +52914,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52944,7 +52944,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -52976,7 +52976,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53068,7 +53068,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53100,7 +53100,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53121,7 +53121,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53151,7 +53151,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53181,7 +53181,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53213,7 +53213,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53234,7 +53234,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53264,7 +53264,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53296,7 +53296,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53326,7 +53326,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53358,7 +53358,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53388,7 +53388,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53420,7 +53420,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53450,7 +53450,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53482,7 +53482,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53512,7 +53512,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53544,7 +53544,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53565,7 +53565,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53595,7 +53595,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53625,7 +53625,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53657,7 +53657,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53687,7 +53687,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53719,7 +53719,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53749,7 +53749,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53781,7 +53781,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53811,7 +53811,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53843,7 +53843,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53873,7 +53873,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53905,7 +53905,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53935,7 +53935,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53967,7 +53967,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -53997,7 +53997,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54029,7 +54029,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54059,7 +54059,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54091,7 +54091,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54121,7 +54121,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54153,7 +54153,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54183,7 +54183,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54215,7 +54215,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54245,7 +54245,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54277,7 +54277,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54307,7 +54307,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54339,7 +54339,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54369,7 +54369,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54401,7 +54401,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54431,7 +54431,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54463,7 +54463,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54493,7 +54493,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54525,7 +54525,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54555,7 +54555,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54587,7 +54587,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54617,7 +54617,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54649,7 +54649,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54679,7 +54679,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54711,7 +54711,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54741,7 +54741,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54773,7 +54773,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54803,7 +54803,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54835,7 +54835,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54865,7 +54865,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54897,7 +54897,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54927,7 +54927,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54959,7 +54959,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -54989,7 +54989,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55019,7 +55019,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55051,7 +55051,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55083,7 +55083,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55113,7 +55113,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55143,7 +55143,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55175,7 +55175,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55207,7 +55207,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55237,7 +55237,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55269,7 +55269,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55299,7 +55299,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55331,7 +55331,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55361,7 +55361,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55393,7 +55393,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55423,7 +55423,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55455,7 +55455,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55485,7 +55485,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55517,7 +55517,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55547,7 +55547,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55579,7 +55579,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55609,7 +55609,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55639,7 +55639,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55671,7 +55671,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55703,7 +55703,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55733,7 +55733,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55765,7 +55765,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55795,7 +55795,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55825,7 +55825,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55857,7 +55857,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55887,7 +55887,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55919,7 +55919,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -55944,7 +55944,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -55974,7 +55974,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56006,7 +56006,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56036,7 +56036,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56068,7 +56068,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56098,7 +56098,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56130,7 +56130,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56160,7 +56160,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56192,7 +56192,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56222,7 +56222,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56254,7 +56254,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56284,7 +56284,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56316,7 +56316,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56346,7 +56346,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56378,7 +56378,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56408,7 +56408,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56440,7 +56440,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56470,7 +56470,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56502,7 +56502,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56532,7 +56532,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56564,7 +56564,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56594,7 +56594,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56626,7 +56626,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56656,7 +56656,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56688,7 +56688,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56718,7 +56718,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56750,7 +56750,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56780,7 +56780,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56812,7 +56812,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56842,7 +56842,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56874,7 +56874,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56904,7 +56904,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -56936,7 +56936,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57028,7 +57028,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57060,7 +57060,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57081,7 +57081,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57111,7 +57111,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57141,7 +57141,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57173,7 +57173,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57203,7 +57203,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57235,7 +57235,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57265,7 +57265,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57297,7 +57297,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57327,7 +57327,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57359,7 +57359,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57389,7 +57389,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57421,7 +57421,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57451,7 +57451,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57483,7 +57483,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57504,7 +57504,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57534,7 +57534,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57564,7 +57564,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57596,7 +57596,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57626,7 +57626,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57658,7 +57658,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57688,7 +57688,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57720,7 +57720,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57750,7 +57750,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57782,7 +57782,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57812,7 +57812,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57844,7 +57844,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57874,7 +57874,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57906,7 +57906,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57936,7 +57936,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57968,7 +57968,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -57998,7 +57998,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58030,7 +58030,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58060,7 +58060,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58092,7 +58092,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58122,7 +58122,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58154,7 +58154,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58184,7 +58184,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58216,7 +58216,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58246,7 +58246,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58278,7 +58278,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58308,7 +58308,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58340,7 +58340,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58370,7 +58370,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58402,7 +58402,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58432,7 +58432,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58464,7 +58464,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58494,7 +58494,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58526,7 +58526,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58556,7 +58556,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58588,7 +58588,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58618,7 +58618,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58650,7 +58650,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58680,7 +58680,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58712,7 +58712,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58742,7 +58742,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58774,7 +58774,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58804,7 +58804,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58836,7 +58836,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58866,7 +58866,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58898,7 +58898,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58928,7 +58928,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58958,7 +58958,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -58990,7 +58990,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59022,7 +59022,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59052,7 +59052,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59082,7 +59082,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59114,7 +59114,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59146,7 +59146,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59176,7 +59176,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59208,7 +59208,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59238,7 +59238,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59270,7 +59270,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59300,7 +59300,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59332,7 +59332,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59362,7 +59362,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59394,7 +59394,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59424,7 +59424,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59456,7 +59456,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59486,7 +59486,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59518,7 +59518,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59548,7 +59548,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59578,7 +59578,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59610,7 +59610,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59642,7 +59642,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59672,7 +59672,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59704,7 +59704,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59734,7 +59734,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59764,7 +59764,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59796,7 +59796,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59826,7 +59826,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59858,7 +59858,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -59883,7 +59883,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59913,7 +59913,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59945,7 +59945,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -59975,7 +59975,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60007,7 +60007,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60037,7 +60037,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60069,7 +60069,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60099,7 +60099,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60131,7 +60131,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60161,7 +60161,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60193,7 +60193,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60223,7 +60223,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60255,7 +60255,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60285,7 +60285,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60317,7 +60317,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60347,7 +60347,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60379,7 +60379,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60409,7 +60409,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60441,7 +60441,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60471,7 +60471,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60503,7 +60503,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60533,7 +60533,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60565,7 +60565,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60595,7 +60595,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60627,7 +60627,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60657,7 +60657,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60689,7 +60689,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60719,7 +60719,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60751,7 +60751,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60781,7 +60781,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60813,7 +60813,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60843,7 +60843,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60875,7 +60875,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60967,7 +60967,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -60999,7 +60999,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61020,7 +61020,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61050,7 +61050,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61080,7 +61080,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61112,7 +61112,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61133,7 +61133,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61163,7 +61163,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61195,7 +61195,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61225,7 +61225,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61257,7 +61257,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61287,7 +61287,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61319,7 +61319,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61349,7 +61349,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61381,7 +61381,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61411,7 +61411,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61443,7 +61443,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61467,7 +61467,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61497,7 +61497,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61527,7 +61527,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61559,7 +61559,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61589,7 +61589,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61621,7 +61621,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61651,7 +61651,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61683,7 +61683,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61713,7 +61713,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61745,7 +61745,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61775,7 +61775,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61807,7 +61807,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61837,7 +61837,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61869,7 +61869,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61899,7 +61899,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61931,7 +61931,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61961,7 +61961,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -61993,7 +61993,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62023,7 +62023,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62055,7 +62055,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62085,7 +62085,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62117,7 +62117,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62147,7 +62147,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62179,7 +62179,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62209,7 +62209,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62241,7 +62241,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62271,7 +62271,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62303,7 +62303,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62333,7 +62333,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62365,7 +62365,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62395,7 +62395,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62427,7 +62427,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62457,7 +62457,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62489,7 +62489,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62519,7 +62519,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62551,7 +62551,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62581,7 +62581,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62613,7 +62613,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62643,7 +62643,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62675,7 +62675,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62705,7 +62705,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62737,7 +62737,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62767,7 +62767,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62799,7 +62799,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62829,7 +62829,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62861,7 +62861,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62891,7 +62891,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62921,7 +62921,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62953,7 +62953,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -62985,7 +62985,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63015,7 +63015,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63045,7 +63045,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63077,7 +63077,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63109,7 +63109,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63139,7 +63139,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63171,7 +63171,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63201,7 +63201,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63233,7 +63233,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63263,7 +63263,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63295,7 +63295,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63325,7 +63325,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63357,7 +63357,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63387,7 +63387,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63419,7 +63419,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63449,7 +63449,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63481,7 +63481,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63511,7 +63511,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63541,7 +63541,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63573,7 +63573,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63605,7 +63605,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63635,7 +63635,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63667,7 +63667,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63697,7 +63697,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63721,7 +63721,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63751,7 +63751,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63783,7 +63783,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63813,7 +63813,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63845,7 +63845,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -63879,7 +63879,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63911,7 +63911,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63941,7 +63941,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -63973,7 +63973,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64003,7 +64003,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64035,7 +64035,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64065,7 +64065,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64097,7 +64097,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64127,7 +64127,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64159,7 +64159,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64189,7 +64189,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64221,7 +64221,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64251,7 +64251,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64283,7 +64283,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64313,7 +64313,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64345,7 +64345,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64375,7 +64375,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64407,7 +64407,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64437,7 +64437,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64469,7 +64469,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64499,7 +64499,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64531,7 +64531,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64561,7 +64561,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64593,7 +64593,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64623,7 +64623,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64655,7 +64655,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64685,7 +64685,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64717,7 +64717,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64747,7 +64747,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64779,7 +64779,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64809,7 +64809,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64841,7 +64841,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64933,7 +64933,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64965,7 +64965,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -64986,7 +64986,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65016,7 +65016,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65046,7 +65046,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65078,7 +65078,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65099,7 +65099,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65129,7 +65129,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65161,7 +65161,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65191,7 +65191,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65223,7 +65223,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65253,7 +65253,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65285,7 +65285,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65315,7 +65315,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65347,7 +65347,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65377,7 +65377,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65409,7 +65409,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65439,7 +65439,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65469,7 +65469,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65501,7 +65501,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65531,7 +65531,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65563,7 +65563,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65593,7 +65593,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65625,7 +65625,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65655,7 +65655,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65687,7 +65687,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65717,7 +65717,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65749,7 +65749,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65779,7 +65779,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65811,7 +65811,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65841,7 +65841,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65873,7 +65873,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65903,7 +65903,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65935,7 +65935,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65965,7 +65965,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -65997,7 +65997,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66027,7 +66027,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66059,7 +66059,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66089,7 +66089,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66121,7 +66121,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66151,7 +66151,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66183,7 +66183,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66213,7 +66213,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66245,7 +66245,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66275,7 +66275,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66307,7 +66307,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66337,7 +66337,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66369,7 +66369,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66399,7 +66399,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66431,7 +66431,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66461,7 +66461,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66493,7 +66493,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66523,7 +66523,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66555,7 +66555,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66585,7 +66585,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66617,7 +66617,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66647,7 +66647,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66679,7 +66679,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66709,7 +66709,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66741,7 +66741,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66771,7 +66771,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66803,7 +66803,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66833,7 +66833,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66863,7 +66863,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66895,7 +66895,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66927,7 +66927,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66957,7 +66957,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -66987,7 +66987,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67019,7 +67019,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67051,7 +67051,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67081,7 +67081,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67113,7 +67113,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67143,7 +67143,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67175,7 +67175,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67205,7 +67205,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67237,7 +67237,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67267,7 +67267,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67299,7 +67299,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67329,7 +67329,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67361,7 +67361,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67391,7 +67391,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67423,7 +67423,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67453,7 +67453,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67483,7 +67483,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67515,7 +67515,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67547,7 +67547,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67577,7 +67577,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67609,7 +67609,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67639,7 +67639,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67669,7 +67669,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67701,7 +67701,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67731,7 +67731,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67763,7 +67763,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -67797,7 +67797,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67829,7 +67829,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67859,7 +67859,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67891,7 +67891,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67921,7 +67921,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67953,7 +67953,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -67983,7 +67983,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68015,7 +68015,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68045,7 +68045,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68077,7 +68077,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68107,7 +68107,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68139,7 +68139,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68169,7 +68169,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68201,7 +68201,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68231,7 +68231,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68263,7 +68263,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68293,7 +68293,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68325,7 +68325,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68355,7 +68355,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68387,7 +68387,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68417,7 +68417,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68449,7 +68449,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68479,7 +68479,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68511,7 +68511,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68541,7 +68541,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68573,7 +68573,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68603,7 +68603,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68635,7 +68635,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68665,7 +68665,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68697,7 +68697,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68727,7 +68727,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68759,7 +68759,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68851,7 +68851,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68883,7 +68883,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68904,7 +68904,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68934,7 +68934,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68964,7 +68964,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -68996,7 +68996,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69026,7 +69026,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69058,7 +69058,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69088,7 +69088,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69120,7 +69120,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69150,7 +69150,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69182,7 +69182,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69212,7 +69212,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69244,7 +69244,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69274,7 +69274,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69306,7 +69306,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69327,7 +69327,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69357,7 +69357,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69387,7 +69387,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69419,7 +69419,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69449,7 +69449,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69481,7 +69481,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69511,7 +69511,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69543,7 +69543,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69573,7 +69573,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69605,7 +69605,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69635,7 +69635,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69667,7 +69667,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69697,7 +69697,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69729,7 +69729,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69759,7 +69759,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69791,7 +69791,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69821,7 +69821,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69853,7 +69853,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69883,7 +69883,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69915,7 +69915,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69945,7 +69945,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -69977,7 +69977,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70007,7 +70007,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70039,7 +70039,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70069,7 +70069,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70101,7 +70101,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70131,7 +70131,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70163,7 +70163,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70193,7 +70193,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70225,7 +70225,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70255,7 +70255,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70287,7 +70287,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70317,7 +70317,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70349,7 +70349,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70379,7 +70379,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70411,7 +70411,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70441,7 +70441,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70473,7 +70473,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70503,7 +70503,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70535,7 +70535,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70565,7 +70565,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70597,7 +70597,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70627,7 +70627,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70659,7 +70659,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70689,7 +70689,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70721,7 +70721,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70751,7 +70751,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70781,7 +70781,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70813,7 +70813,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70845,7 +70845,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70875,7 +70875,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70905,7 +70905,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70937,7 +70937,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70969,7 +70969,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -70999,7 +70999,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71031,7 +71031,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71061,7 +71061,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71093,7 +71093,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71123,7 +71123,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71155,7 +71155,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71185,7 +71185,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71217,7 +71217,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71247,7 +71247,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71279,7 +71279,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71309,7 +71309,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71341,7 +71341,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71371,7 +71371,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71401,7 +71401,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71433,7 +71433,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71465,7 +71465,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71495,7 +71495,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71527,7 +71527,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71557,7 +71557,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71587,7 +71587,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71619,7 +71619,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71649,7 +71649,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71681,7 +71681,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
@@ -71715,7 +71715,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71747,7 +71747,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71777,7 +71777,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71809,7 +71809,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71839,7 +71839,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71871,7 +71871,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71901,7 +71901,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71933,7 +71933,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71963,7 +71963,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -71995,7 +71995,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72025,7 +72025,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72057,7 +72057,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72087,7 +72087,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72119,7 +72119,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72149,7 +72149,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72181,7 +72181,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72211,7 +72211,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72243,7 +72243,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72273,7 +72273,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72305,7 +72305,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72335,7 +72335,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72367,7 +72367,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72397,7 +72397,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72429,7 +72429,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72459,7 +72459,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72491,7 +72491,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72521,7 +72521,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72553,7 +72553,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72583,7 +72583,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72615,7 +72615,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72645,7 +72645,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72677,7 +72677,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72769,7 +72769,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72801,7 +72801,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72822,7 +72822,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72852,7 +72852,7 @@
           "expiration": 36000,
           "hard_timeout": 14400,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72882,7 +72882,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72914,7 +72914,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72935,7 +72935,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72965,7 +72965,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -72997,7 +72997,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73027,7 +73027,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73059,7 +73059,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73089,7 +73089,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73121,7 +73121,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73151,7 +73151,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73183,7 +73183,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73213,7 +73213,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73245,7 +73245,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73266,7 +73266,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73296,7 +73296,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73326,7 +73326,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73358,7 +73358,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73388,7 +73388,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73420,7 +73420,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73450,7 +73450,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73482,7 +73482,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73512,7 +73512,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73544,7 +73544,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73574,7 +73574,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73606,7 +73606,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73636,7 +73636,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73668,7 +73668,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73698,7 +73698,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73730,7 +73730,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73760,7 +73760,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73792,7 +73792,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73822,7 +73822,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73854,7 +73854,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73884,7 +73884,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73916,7 +73916,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73946,7 +73946,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -73978,7 +73978,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74008,7 +74008,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74040,7 +74040,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74070,7 +74070,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74102,7 +74102,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74132,7 +74132,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74164,7 +74164,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74194,7 +74194,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74226,7 +74226,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74256,7 +74256,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74288,7 +74288,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74318,7 +74318,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74350,7 +74350,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74380,7 +74380,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74412,7 +74412,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74442,7 +74442,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74474,7 +74474,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74504,7 +74504,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74536,7 +74536,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74566,7 +74566,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74598,7 +74598,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74628,7 +74628,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74660,7 +74660,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74690,7 +74690,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74720,7 +74720,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74752,7 +74752,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74784,7 +74784,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74814,7 +74814,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74844,7 +74844,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74876,7 +74876,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74908,7 +74908,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74938,7 +74938,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -74970,7 +74970,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75000,7 +75000,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75032,7 +75032,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75062,7 +75062,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75094,7 +75094,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75124,7 +75124,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75156,7 +75156,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75186,7 +75186,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75218,7 +75218,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75248,7 +75248,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75280,7 +75280,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75310,7 +75310,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75340,7 +75340,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75372,7 +75372,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75404,7 +75404,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75434,7 +75434,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75466,7 +75466,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75496,7 +75496,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75526,7 +75526,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75558,7 +75558,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75588,7 +75588,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": false,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       },
@@ -75620,7 +75620,7 @@
           "expiration": 36000,
           "hard_timeout": 10800,
           "ignore_task_failure": true,
-          "io_timeout": 600,
+          "io_timeout": 1200,
           "upload_test_results": true
         }
       }
diff --git a/testing/buildbot/filters/mojo.fyi.mash.browser_tests.filter b/testing/buildbot/filters/mojo.fyi.mash.browser_tests.filter
index 46dd4bf..928fc179 100644
--- a/testing/buildbot/filters/mojo.fyi.mash.browser_tests.filter
+++ b/testing/buildbot/filters/mojo.fyi.mash.browser_tests.filter
@@ -263,9 +263,6 @@
 -PowerPolicyLoginScreenBrowserTest.SetDevicePolicy
 -EnterpriseEnrollmentTest.TestActiveDirectoryEnrollment_Success
 
-# Timeouts. http://crbug.com/810071
--ExtensionViewTests/ExtensionViewLoadApiTest.*
-
 # Crashes in cc::(anonymous namespace)::ZeroCopyGpuBacking::SharedMemoryGuid
 # http://crbug.com/810073
 -MemoryTracingBrowserTest.TestHeapProfilingPseudo
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
index f6ba9faa..21a9d2be7 100644
--- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
+++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -155,9 +155,7 @@
 -ClientHintsBrowserTest.ClientHintsLifetimeNotAttachedCookiesBlocked
 -ContinueWhereILeftOffTest.CookiesClearedOnExit
 -DevToolsSanityTest.TestNetworkPushTime
--DnsProbeBrowserTest.NxdomainProbeResultWithWorkingCorrections
 -DnsProbeBrowserTest.NxdomainProbeResultWithWorkingSlowCorrections
--DnsProbeBrowserTest.OtherErrorWithCorrectionsSuccess
 -DownloadExtensionTest.DownloadExtensionTest_Download_FileSystemURL
 -LoadImageBrowserTest.LoadImage
 -MimeHandlerViewTests/MimeHandlerViewTest.SingleRequest/0
diff --git a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
index de5e938..332708c 100644
--- a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
+++ b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
@@ -63,8 +63,6 @@
 -PreviewsStateResourceDispatcherHostBrowserTest.ShouldEnableLoFiModeOn
 -PreviewsStateResourceDispatcherHostBrowserTest.ShouldEnableLoFiModeReload
 -PreviewsStateResourceDispatcherHostBrowserTest.ShouldEnableLoFiModeReloadDisableLoFi
--RenderFrameHostImplBrowserTest.AbortedRendererInitiatedNavigationDoNotCancelPendingXHR
--RenderFrameHostImplBrowserTest.StreamHandleReleasedOnRendererCrash
 -RenderThreadImplBrowserTest.NonResourceDispatchIPCTasksDontGoThroughScheduler
 -RenderThreadImplBrowserTest.ResourceDispatchIPCTasksGoThroughScheduler
 -RenderViewBrowserTest.ConfirmCacheInformationPlumbed
@@ -78,9 +76,7 @@
 -RequestDataResourceDispatcherHostBrowserTest.SameOriginAuxiliary
 -RequestDataResourceDispatcherHostBrowserTest.SameOriginNested
 -SitePerProcessIgnoreCertErrorsBrowserTest.SubresourceWithCertificateErrors
--WebContentsImplBrowserTest.ClearNonVisiblePendingOnFail
 -WebContentsImplBrowserTest.DownloadImage_Deny_FileImage
--WebContentsImplBrowserTest.LoadingStateChangedForSameDocumentNavigation
 -WebContentsImplBrowserTest.UserAgentOverride
 -WorkerTest.WorkerTlsClientAuthFetch
 -WorkerTest.WorkerTlsClientAuthImportScripts
diff --git a/testing/buildbot/filters/viz.browser_tests.filter b/testing/buildbot/filters/viz.browser_tests.filter
index 1ea6a89..ccb3dd3 100644
--- a/testing/buildbot/filters/viz.browser_tests.filter
+++ b/testing/buildbot/filters/viz.browser_tests.filter
@@ -34,6 +34,9 @@
 -ThumbnailTest.ShouldCaptureOnNavigatingAwayExplicitWait
 -ThumbnailTest.ShouldCaptureOnNavigatingAwaySlowPageLoad
 
+# Tab Capture on Viz fails FeedbackTest: crbug.com/810389
+-FeedbackTest.*
+
 # WaitForChildFrameSurfaceReady crashes crbug.com/787945
 -PDFExtensionTest.ContextMenuCoordinates
 -WebViewTests/WebViewTest.InterstitialPageFocusedWidget/1
@@ -65,6 +68,7 @@
 # Mac failures to triage
 -ActivityLogApiTest.TriggerEvent
 -AllUrlsApiTest.WhitelistedExtension
+-BrowserTest.WindowOpenClose3
 -DNSErrorPageTest.DNSError_GoBack2Forward2
 -DeclarativeNetRequestBrowserTest.BlockRequests_UrlFilter/0
 -DeclarativeNetRequestBrowserTest.BlockRequests_UrlFilter/1
@@ -84,6 +88,7 @@
 -HardwareAccelerationModePolicyTest.HardwareAccelerationDisabled
 -HostedAppProcessModelTest.PopupsInsideHostedApp/0
 -HostedAppProcessModelTest.PopupsInsideHostedApp/1
+-IndependentOTRProfileManagerTest.DeleteWaitsForLastBrowser
 -IsolatedAppTest.IsolatedAppProcessModel
 -LocalNTPDoodleTest.ShouldNotMoveFakeboxForIframeSizes
 -PluginPowerSaverBrowserTest.BackgroundTabPlugins
diff --git a/testing/buildbot/filters/viz.content_browsertests.filter b/testing/buildbot/filters/viz.content_browsertests.filter
index 48e8268..29ee099 100644
--- a/testing/buildbot/filters/viz.content_browsertests.filter
+++ b/testing/buildbot/filters/viz.content_browsertests.filter
@@ -104,3 +104,7 @@
 # process. http://crbug.com/806635
 -WebContentsVideoCaptureDeviceBrowserTest.*
 -WebContentsVideoCaptureDeviceBrowserTestP.*
+
+# Still work TODO to trigger render process kills on either surface invariant
+# violations or copy request permission violations. http://crbug.com/771354
+-RenderWidgetHostBrowserTest.ProhibitsCopyRequestsFromRenderer
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/disable-blink-features=RootLayerScrolling b/third_party/WebKit/LayoutTests/FlagExpectations/disable-blink-features=RootLayerScrolling
index 6f47a590..39f1d01 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/disable-blink-features=RootLayerScrolling
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/disable-blink-features=RootLayerScrolling
@@ -96,8 +96,6 @@
 crbug.com/417782 virtual/spv175/compositing/overflow/border-radius-composited-subframe.html [ Failure ]
 crbug.com/417782 virtual/spv175/paint/invalidation/window-resize/window-resize-vertical-writing-mode.html [ Crash ]
 
-crbug.com/803774 http/tests/loading/htxg/ [ Skip ]
-
 ########## Ref tests can't be rebaselined ##########
 crbug.com/504613 crbug.com/524248 [ Mac ] paint/images/image-backgrounds-not-antialiased.html [ Failure ]
 
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 1321cf6a..de01850b 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -120,7 +120,7 @@
 crbug.com/591099 animations/animation-ready-reject-script-forbidden.html [ Timeout ]
 crbug.com/591099 animations/cross-fade-list-style-image.html [ Failure ]
 crbug.com/591099 animations/interpolation/backdrop-filter-interpolation.html [ Timeout ]
-crbug.com/591099 animations/interpolation/line-height-interpolation.html [ Pass Timeout ]
+crbug.com/591099 animations/interpolation/line-height-interpolation.html [ Timeout ]
 crbug.com/591099 animations/interpolation/svg-stroke-dasharray-interpolation.html [ Timeout ]
 crbug.com/591099 animations/interpolation/webkit-clip-path-interpolation.html [ Pass Timeout ]
 crbug.com/591099 animations/interpolation/webkit-column-width-interpolation.html [ Pass ]
@@ -676,7 +676,7 @@
 crbug.com/714962 css3/masking/clip-path-columns-shape.html [ Failure ]
 crbug.com/714962 css3/masking/clip-path-columns-svg-clippath-usou.html [ Failure ]
 crbug.com/714962 css3/masking/clip-path-reference-box-inline.html [ Failure ]
-crbug.com/714962 css3/masking/mask-composite-missing-image.html [ Failure ]
+crbug.com/714962 css3/masking/mask-composite-missing-image.html [ Failure Pass ]
 crbug.com/591099 css3/masking/mask-luminance-gradient.html [ Failure ]
 crbug.com/591099 css3/masking/mask-luminance-png.html [ Failure ]
 crbug.com/591099 css3/masking/mask-luminance-svg.html [ Failure ]
@@ -793,7 +793,7 @@
 crbug.com/591099 editing/caret/caret-color.html [ Failure ]
 crbug.com/591099 editing/caret/caret-position.html [ Failure ]
 crbug.com/591099 editing/deleting/4922367.html [ Failure ]
-crbug.com/591099 editing/deleting/5099303.html [ Failure ]
+crbug.com/591099 editing/deleting/5099303.html [ Failure Pass ]
 crbug.com/591099 editing/deleting/5126166.html [ Failure ]
 crbug.com/591099 editing/deleting/5206311-1.html [ Failure ]
 crbug.com/591099 editing/deleting/5272440.html [ Failure ]
@@ -1109,7 +1109,7 @@
 crbug.com/714962 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-image-003.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-image-004.html [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-backgrounds/background-image-005.html [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-image-005.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-image-006.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-details.html [ Crash ]
 crbug.com/714962 external/wpt/css/css-display/display-contents-dynamic-before-after-001.html [ Failure ]
@@ -1458,17 +1458,17 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-030.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-003.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-005.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-007.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-007.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-009.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-011.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-013.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-015.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-015.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-017.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-019.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-019.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-021.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-023.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-025.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-027.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-027.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-029.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-031.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-033.xht [ Failure ]
@@ -1476,7 +1476,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-037.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-039.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-041.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-043.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-043.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-045.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-047.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-049.xht [ Failure ]
@@ -1489,17 +1489,17 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-063.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-065.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-067.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-069.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-069.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-071.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-073.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-075.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-077.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-079.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-081.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-083.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-085.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-083.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-085.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-087.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-089.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-089.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-091.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-093.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-095.xht [ Failure Pass ]
@@ -1507,61 +1507,61 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-103.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-105.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-107.xht [ Failure Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-109.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-111.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-113.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-109.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-111.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-113.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-115.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-117.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-117.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-119.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-121.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-123.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-125.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-127.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-129.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-129.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-131.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-133.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-135.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-137.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-137.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-139.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-141.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-141.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-143.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-145.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-145.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-147.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-149.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-151.xht [ Failure Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-153.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-151.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-153.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-155.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-157.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-157.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-159.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-161.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-163.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-165.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-167.xht [ Failure Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-169.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-169.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-171.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-173.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-175.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-175.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-177.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-179.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-179.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-181.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-183.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-185.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-187.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-189.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-191.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-191.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-193.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-195.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-197.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-199.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-201.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-203.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-203.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-205.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-207.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-209.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-209.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-211.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-213.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-215.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-217.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-217.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-219.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-221.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-223.xht [ Failure ]
@@ -1569,7 +1569,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-227.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-229.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-004.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-004.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-006.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-008.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-010.xht [ Failure ]
@@ -1578,7 +1578,7 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-016.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-018.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-020.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-022.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-022.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-024.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-026.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-028.xht [ Failure ]
@@ -1593,19 +1593,19 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-046.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-048.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-050.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-052.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-052.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-054.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-056.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-058.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-060.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-062.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-062.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-064.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-066.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-068.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-070.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-072.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-074.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-076.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-076.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-078.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-080.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-082.xht [ Failure ]
@@ -1637,7 +1637,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-138.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-140.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-142.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-144.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-144.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-146.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-148.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-150.xht [ Failure ]
@@ -1645,11 +1645,11 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-154.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-156.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-158.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-160.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-160.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-162.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-164.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-166.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-168.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-168.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-170.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-172.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-174.xht [ Failure ]
@@ -1661,7 +1661,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-186.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-188.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-190.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-192.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-192.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-194.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-196.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-198.xht [ Failure ]
@@ -1683,6 +1683,10 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/available-size-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/available-size-002.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/available-size-010.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/available-size-011.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/available-size-012.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/available-size-017.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/available-size-018.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/block-flow-direction-vrl-002.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/block-flow-direction-vrl-005.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/block-flow-direction-vrl-006.xht [ Failure ]
@@ -1698,7 +1702,7 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/clearance-calculations-vrl-006.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/clearance-calculations-vrl-008.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-003.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-005.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-005.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-002.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-002.xht [ Failure ]
@@ -1709,8 +1713,8 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/float-vlr-005.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/float-vlr-007.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-vlr-013.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-004.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-006.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-004.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-006.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/float-vrl-008.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-012.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/horizontal-rule-vrl-002.xht [ Failure ]
@@ -1781,23 +1785,23 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/text-align-vlr-011.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-013.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-015.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-017.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-017.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-019.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-002.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-004.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-006.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-008.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-008.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-010.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-012.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-012.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-014.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-016.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-016.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-018.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-baseline-vlr-007.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-baseline-vrl-006.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-combine-upright-decorations-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-combine-upright-layout-rules-001.html [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-003.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-005.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-003.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-005.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-011.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-013.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-indent-vrl-002.xht [ Failure Pass ]
@@ -1846,7 +1850,7 @@
 crbug.com/714962 external/wpt/css/cssom/medialist-dynamic-001.html [ Failure ]
 crbug.com/626703 external/wpt/css/cssom/stylesheet-replacedata-dynamic.html [ Failure ]
 crbug.com/591099 external/wpt/css/geometry/interfaces.html [ Timeout ]
-crbug.com/591099 external/wpt/css/geometry/interfaces.worker.html [ Pass Timeout ]
+crbug.com/591099 external/wpt/css/geometry/interfaces.worker.html [ Timeout ]
 crbug.com/714962 external/wpt/css/selectors/focus-within-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/selectors/focus-within-004.html [ Failure ]
 crbug.com/714962 external/wpt/css/selectors/focus-within-007.html [ Failure ]
@@ -1884,8 +1888,8 @@
 crbug.com/591099 external/wpt/dom/ranges/Range-mutations-dataChange.html [ Timeout ]
 crbug.com/591099 external/wpt/dom/ranges/Range-set.html [ Timeout ]
 crbug.com/591099 external/wpt/dom/ranges/Range-surroundContents.html [ Timeout ]
-crbug.com/591099 external/wpt/domxpath/xml_xpath_runner.html [ Pass Timeout ]
-crbug.com/591099 external/wpt/editing/run/backcolor.html [ Timeout ]
+crbug.com/591099 external/wpt/domxpath/xml_xpath_runner.html [ Timeout ]
+crbug.com/591099 external/wpt/editing/run/backcolor.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/editing/run/bold.html [ Timeout ]
 crbug.com/591099 external/wpt/editing/run/fontname.html [ Timeout ]
 crbug.com/591099 external/wpt/editing/run/fontsize.html [ Timeout ]
@@ -2125,7 +2129,7 @@
 crbug.com/591099 external/wpt/svg/linking/reftests/href-filter-element.html [ Failure ]
 crbug.com/591099 external/wpt/uievents/order-of-events/focus-events/focus-manual.html [ Timeout ]
 crbug.com/714962 external/wpt/uievents/order-of-events/mouse-events/click-cancel.html [ Failure ]
-crbug.com/591099 external/wpt/url/url-setters.html [ Pass Timeout ]
+crbug.com/591099 external/wpt/url/url-setters.html [ Timeout ]
 crbug.com/591099 external/wpt/wasm/wasm_local_iframe_test.html [ Failure ]
 crbug.com/591099 external/wpt/webmessaging/broadcastchannel/sandbox.html [ Failure ]
 crbug.com/591099 external/wpt/webrtc/interfaces.html [ Pass Timeout ]
@@ -2210,7 +2214,7 @@
 crbug.com/591099 fast/backgrounds/001.html [ Failure ]
 crbug.com/591099 fast/backgrounds/animated-gif-as-background-rounded.html [ Failure ]
 crbug.com/591099 fast/backgrounds/animated-gif-as-background.html [ Failure ]
-crbug.com/591099 fast/backgrounds/animated-svg-as-mask.html [ Failure ]
+crbug.com/591099 fast/backgrounds/animated-svg-as-mask.html [ Failure Pass ]
 crbug.com/591099 fast/backgrounds/background-clip-text-multiline.html [ Failure Pass ]
 crbug.com/591099 fast/backgrounds/background-clip-text-with-blend-mode.html [ Failure ]
 crbug.com/591099 fast/backgrounds/background-clip-text.html [ Failure ]
@@ -2267,7 +2271,7 @@
 crbug.com/591099 fast/block/block-width-recalc-with-relative-height.html [ Failure ]
 crbug.com/591099 fast/block/containing-block-negative-margins.html [ Failure ]
 crbug.com/591099 fast/block/float-avoids-padding-inline-ancestors.html [ Crash ]
-crbug.com/591099 fast/block/float/003.html [ Failure ]
+crbug.com/810335 fast/block/float/003.html [ Failure ]
 crbug.com/591099 fast/block/float/022.html [ Failure ]
 crbug.com/591099 fast/block/float/br-with-clear-2.html [ Failure ]
 crbug.com/591099 fast/block/float/element-clears-float-without-clearance.html [ Failure ]
@@ -2326,7 +2330,7 @@
 crbug.com/591099 fast/body-propagation/background-image/007-declarative.xhtml [ Failure Pass ]
 crbug.com/591099 fast/borders/bidi-002.html [ Failure ]
 crbug.com/591099 fast/borders/bidi-012.html [ Failure ]
-crbug.com/714962 fast/borders/block-mask-overlay-image.html [ Failure ]
+crbug.com/714962 fast/borders/block-mask-overlay-image.html [ Failure Pass ]
 crbug.com/591099 fast/borders/border-antialiasing.html [ Failure ]
 crbug.com/591099 fast/borders/border-image-border-radius.html [ Failure ]
 crbug.com/591099 fast/borders/border-image-fill-inline-no-border.html [ Failure Pass ]
@@ -2969,6 +2973,7 @@
 crbug.com/714962 fast/dom/shadow/scrollbar.html [ Crash ]
 crbug.com/591099 fast/dom/shadow/selections-in-shadow.html [ Timeout ]
 crbug.com/714962 fast/dom/shadow/shadow-boundary-crossing.html [ Failure ]
+crbug.com/591099 fast/dom/shadow/shadow-dom-event-dispatching-details-summary.html [ Pass ]
 crbug.com/591099 fast/dom/shadow/shadow-dom-event-dispatching-svg-in-shadow-subtree.html [ Failure ]
 crbug.com/714962 fast/dom/shadow/touch-event.html [ Failure ]
 crbug.com/714962 fast/dom/shadow/wheel-event-on-input-in-shadow-dom.html [ Failure ]
@@ -3182,7 +3187,7 @@
 crbug.com/591099 fast/forms/button/button-inner-block-reuse.html [ Failure ]
 crbug.com/591099 fast/forms/button/button-type-change.html [ Failure ]
 crbug.com/591099 fast/forms/button/button-white-space.html [ Failure ]
-crbug.com/591099 fast/forms/calendar-picker/calendar-picker-key-operations.html [ Pass Timeout ]
+crbug.com/591099 fast/forms/calendar-picker/calendar-picker-key-operations.html [ Timeout ]
 crbug.com/714962 fast/forms/calendar-picker/calendar-picker-mouse-operations.html [ Failure ]
 crbug.com/714962 fast/forms/calendar-picker/calendar-picker-type-change-onclick.html [ Timeout ]
 crbug.com/591099 fast/forms/calendar-picker/month-picker-key-operations.html [ Timeout ]
@@ -4904,6 +4909,7 @@
 crbug.com/591099 fullscreen/full-screen-css.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-element-stack.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-iframe-not-allowed.html [ Failure ]
+crbug.com/591099 fullscreen/full-screen-remove-ancestor-after.html [ Crash Pass ]
 crbug.com/591099 fullscreen/full-screen-ruleset-crash.html [ Crash Pass ]
 crbug.com/591099 fullscreen/full-screen-twice-newapi.html [ Crash ]
 crbug.com/591099 fullscreen/full-screen-with-css-reference-filter.html [ Crash ]
@@ -4914,7 +4920,7 @@
 crbug.com/591099 fullscreen/model/fully-exit-fullscreen-nested-iframe.html [ Crash ]
 crbug.com/591099 fullscreen/non-ancestor-iframe.html [ Crash ]
 crbug.com/591099 hittesting/border-hittest-inlineFlowBox.html [ Failure ]
-crbug.com/714962 hittesting/border-hittest-with-image-fallback.html [ Failure ]
+crbug.com/714962 hittesting/border-hittest-with-image-fallback.html [ Failure Pass ]
 crbug.com/714962 hittesting/culled-inline.html [ Failure ]
 crbug.com/591099 hittesting/image-with-border-radius.html [ Failure ]
 crbug.com/714962 hittesting/image-with-clip-path.html [ Failure ]
@@ -5009,7 +5015,7 @@
 crbug.com/591099 http/tests/appcache/offline-access.html [ Failure ]
 crbug.com/591099 http/tests/cache/xhr-vary-header.html [ Failure ]
 crbug.com/591099 http/tests/css/css-image-valued-shape.html [ Failure ]
-crbug.com/714962 http/tests/css/css-resources-referrer-srcdoc.html [ Failure Pass ]
+crbug.com/714962 http/tests/css/css-resources-referrer-srcdoc.html [ Failure ]
 crbug.com/591099 http/tests/css/css-resources-referrer.html [ Failure Pass ]
 crbug.com/591099 http/tests/css/shape-image-file.html [ Failure ]
 crbug.com/591099 http/tests/csspaint/invalidation-background-image.html [ Timeout ]
@@ -5024,8 +5030,8 @@
 crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-2.js [ Timeout ]
 crbug.com/714962 http/tests/devtools/editor/text-editor-enter-behaviour.js [ Timeout ]
 crbug.com/714962 http/tests/devtools/editor/text-editor-formatter.js [ Timeout ]
-crbug.com/714962 http/tests/devtools/editor/text-editor-indent-autodetection.js [ Pass Timeout ]
-crbug.com/714962 http/tests/devtools/editor/text-editor-reveal-line.js [ Pass Timeout ]
+crbug.com/714962 http/tests/devtools/editor/text-editor-indent-autodetection.js [ Timeout ]
+crbug.com/714962 http/tests/devtools/editor/text-editor-reveal-line.js [ Timeout ]
 crbug.com/591099 http/tests/devtools/editor/text-editor-word-jumps.js [ Timeout ]
 crbug.com/714962 http/tests/devtools/elements/breadcrumb-updates.js [ Crash ]
 crbug.com/714962 http/tests/devtools/elements/edit/edit-dom-actions-1.js [ Crash ]
@@ -5058,7 +5064,7 @@
 crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar-remove.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/elements/event-listeners-about-blank.js [ Crash Pass ]
-crbug.com/714962 http/tests/devtools/elements/hide-shortcut.js [ Crash Pass ]
+crbug.com/714962 http/tests/devtools/elements/hide-shortcut.js [ Crash ]
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-css-shapes-outside-scroll.js [ Failure ]
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-css-shapes-outside.js [ Failure ]
 crbug.com/714962 http/tests/devtools/elements/highlight/highlight-dom-updates.js [ Crash ]
@@ -5112,12 +5118,12 @@
 crbug.com/591099 http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/sources/debugger-pause/debugger-pause-on-promise-rejection.js [ Crash ]
-crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-into-custom-element-callbacks.js [ Crash Pass ]
+crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-into-custom-element-callbacks.js [ Crash ]
 crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Crash ]
 crbug.com/591099 http/tests/devtools/sources/debugger-ui/watch-expressions-panel-switch.js [ Crash Pass ]
-crbug.com/591099 http/tests/devtools/startup/sources/debugger/script-formatter-breakpoints-1.js [ Crash ]
+crbug.com/591099 http/tests/devtools/startup/sources/debugger/script-formatter-breakpoints-1.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/text-autosizing-override.js [ Failure ]
 crbug.com/591099 http/tests/devtools/tracing/scroll-invalidations.js [ Failure ]
 crbug.com/591099 http/tests/devtools/tracing/timeline-misc/timeline-bound-function.js [ Failure ]
@@ -5414,8 +5420,8 @@
 crbug.com/714962 intersection-observer/text-target.html [ Failure ]
 crbug.com/591099 media/autoplay/document-user-activation.html [ Failure ]
 crbug.com/591099 media/controls/lazy-loaded-style.html [ Failure ]
-crbug.com/591099 media/controls/volumechange-muted-attribute.html [ Failure ]
-crbug.com/714962 media/controls/volumechange-stopimmediatepropagation.html [ Failure Pass ]
+crbug.com/591099 media/controls/volumechange-muted-attribute.html [ Failure Pass ]
+crbug.com/591099 media/controls/volumechange-stopimmediatepropagation.html [ Failure ]
 crbug.com/591099 media/media-document-audio-repaint.html [ Failure ]
 crbug.com/591099 media/video-aspect-ratio.html [ Failure ]
 crbug.com/591099 media/video-canvas-alpha.html [ Failure ]
@@ -5440,7 +5446,6 @@
 crbug.com/591099 overflow/overflow-position-003.html [ Failure ]
 crbug.com/591099 paint/clipath/clip-path-with-background-and-box-behind.html [ Failure ]
 crbug.com/591099 paint/filters/clip-filter-overflow-clip.html [ Failure ]
-crbug.com/714962 paint/float/float-text-clip.html [ Crash Pass ]
 crbug.com/591099 paint/frames/frameset-with-stacking-context-and-not-stacking-context-children.html [ Failure ]
 crbug.com/591099 paint/frames/frameset-with-stacking-contexts.html [ Failure ]
 crbug.com/591099 paint/high-contrast-mode/image-filter-all/text-on-backgrounds.html [ Failure ]
@@ -6194,6 +6199,7 @@
 crbug.com/714962 scrollbars/scrollbar-position-crash.html [ Failure ]
 crbug.com/591099 scrollbars/scrollbars-on-positioned-content.html [ Failure ]
 crbug.com/591099 security/autocomplete-cleared-on-back.html [ Failure ]
+crbug.com/591099 shadow-dom/css-style-inherit.html [ Pass ]
 crbug.com/591099 shadow-dom/event-composed-ua.html [ Timeout ]
 crbug.com/591099 shadow-dom/focus-navigation-with-delegatesFocus.html [ Timeout ]
 crbug.com/714962 shadow-dom/slotted-pseudo-element-dynamic-attribute-change.html [ Failure ]
@@ -6849,7 +6855,7 @@
 crbug.com/591099 virtual/layout_ng/ [ Skip ]
 crbug.com/591099 virtual/mojo-localstorage/ [ Skip ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/anchor-empty-focus.html [ Failure ]
-crbug.com/714962 virtual/mouseevent_fractional/fast/events/autoscroll-disabled-in-fix.html [ Pass Timeout ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/autoscroll-disabled-in-fix.html [ Timeout ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-in-textfield.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-nonscrollable-iframe-in-scrollable-div.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/autoscroll-should-not-stop-on-keypress.html [ Failure ]
@@ -6971,6 +6977,7 @@
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/window-events-capture.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/window-onerror-11.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/window-onerror-12.html [ Failure ]
+crbug.com/591099 virtual/navigation-mojo-response/http/tests/serviceworker/webexposed/global-interface-listing-service-worker.html [ Timeout ]
 crbug.com/591099 virtual/new-remote-playback-pipeline/ [ Skip ]
 crbug.com/591099 virtual/outofblink-cors/ [ Skip ]
 crbug.com/591099 virtual/paint-timing/external/wpt/paint-timing/sibling-painting-first-image.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
index d2033aff..ebc34aa 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -249,3 +249,4 @@
 crbug.com/803958 external/wpt/websockets/cookies/007.html?wss [ Failure ]
 
 crbug.com/809119 http/tests/fetch/chromium/keepalive-resource-exhaustion.html [ Failure ]
+crbug.com/810394 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/fetch-event.https.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 5440d59..80b129f 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -64,8 +64,6 @@
 # spv175+root-layer-scrolls failures. They also fail with root-layer-scrolls without enable-slimming-paint-v175.
 crbug.com/417782 virtual/spv175/paint/invalidation/window-resize/window-resize-vertical-writing-mode.html [ Crash ]
 
-crbug.com/803774 http/tests/loading/htxg/ [ Skip ]
-
 ########## Ref tests can't be rebaselined ##########
 crbug.com/504613 crbug.com/524248 [ Mac ] paint/images/image-backgrounds-not-antialiased.html [ Failure ]
 
@@ -304,7 +302,7 @@
 crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/basic/truncation-rtl.html [ Failure ]
 
 ### virtual/layout_ng/fast/block/float
-crbug.com/635619 virtual/layout_ng/fast/block/float/003.html [ Failure ]
+crbug.com/810335 virtual/layout_ng/fast/block/float/003.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/014.html [ Failure Crash ]
 crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/020.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/022.html [ Failure ]
@@ -847,11 +845,6 @@
 
 # Web Components related tests (Shadow DOM, Custom Elements) failures.
 crbug.com/505364 external/wpt/shadow-dom/untriaged/styles/test-003.html [ Failure ]
-crbug.com/505364 external/wpt/css/css-scoping/css-scoping-shadow-slot-display-override.html [ Failure ]
-crbug.com/505364 external/wpt/css/css-scoping/css-scoping-shadow-slot-style.html [ Failure ]
-crbug.com/505364 external/wpt/css/css-scoping/css-scoping-shadow-nested-slot-display-override.html [ Failure ]
-crbug.com/505364 external/wpt/css/css-scoping/slotted-invalidation.html [ Failure ]
-crbug.com/505364 external/wpt/css/css-scoping/slotted-slot.html [ Failure ]
 
 crbug.com/552494 scrollbars/overflow-scrollbar-combinations.html [ Pass Failure ]
 crbug.com/552494 virtual/prefer_compositing_to_lcd_text/scrollbars/overflow-scrollbar-combinations.html [ Pass Failure ]
@@ -1595,6 +1588,40 @@
 crbug.com/738493 http/tests/performance-timing/longtask-v2/longtask-v8compile.html [ Skip ]
 crbug.com/738493 http/tests/performance-timing/longtask-v2/longtask-executescript.html [ Skip ]
 
+# Expected failures during incremental implementation of mojo notification.
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworker-notification-event.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworker-notification-properties.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworker-notificationclick-event-action-reflection.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworker-notificationclick-event-data-reflection.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworker-notificationclick-event-reply-reflection.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworker-notificationclick-openwindow-crash.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworker-notificationclose-event-data-reflection.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-document-click.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-document-close.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-document-data-invalid.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-document-direction.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-document-fetch-resources.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-document-image-404.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-document-image-redirect-loop.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-document-image-redirect.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-document-image-slow-404.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-document-image-slow.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-get-close.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-get-empty.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-get-filter.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-get-from-service-worker.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-get-replacement.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-get.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-service-worker-click.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-service-worker-fetch-resources.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-service-worker-get-filter.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-service-worker-get.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-service-worker-image-404.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-service-worker-image-redirect-loop.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-service-worker-image-redirect.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-service-worker-image-slow-404.html [ Skip ]
+crbug.com/796991 virtual/mojo-notifications/http/tests/notifications/serviceworkerregistration-service-worker-image-slow.html [ Skip ]
+
 crbug.com/713587 external/wpt/css/css-ui/caret-color-006.html [ Skip ]
 
 # Automatically-added expectations for CSS tests which are temporarily
@@ -2113,6 +2140,7 @@
 crbug.com/626703 virtual/outofblink-cors/external/wpt/fetch/api/abort/general.html [ Timeout ]
 crbug.com/626703 virtual/outofblink-cors/external/wpt/http/basic-auth-cache-test.html [ Timeout ]
 crbug.com/626703 virtual/outofblink-cors/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ]
+crbug.com/626703 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ]
 crbug.com/626703 [ Win10 ] external/wpt/preload/delaying-onload-link-preload-after-discovery.html [ Timeout ]
 crbug.com/626703 [ Win ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vlr-005.xht [ Failure ]
 crbug.com/626703 [ Win ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vrl-004.xht [ Failure ]
@@ -2163,6 +2191,7 @@
 crbug.com/762017 external/wpt/html/semantics/embedded-content/media-elements/video_loop_base.html [ Pass Crash ]
 crbug.com/807954 external/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html [ Crash ]
 crbug.com/807954 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html [ Crash ]
+crbug.com/807954 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html [ Crash ]
 
 # Other untriaged test failures, timeouts and crashes from newly-imported WPT tests.
 crbug.com/666703 external/wpt/html/browsers/sandboxing/sandbox-disallow-same-origin.html [ Timeout ]
@@ -2322,6 +2351,7 @@
 crbug.com/691944 external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ]
 crbug.com/691944 virtual/mojo-blobs/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ]
 crbug.com/691944 virtual/outofblink-cors/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ]
+crbug.com/691944 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ]
 
 # These tests (erroneously) see a platform-specific User-Agent header
 crbug.com/595993 external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ]
@@ -2329,7 +2359,9 @@
 crbug.com/595993 external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ]
 crbug.com/595993 virtual/mojo-blobs/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ]
 crbug.com/595993 virtual/outofblink-cors/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ]
+crbug.com/595993 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ]
 crbug.com/595993 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ]
+crbug.com/595993 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ]
 
 crbug.com/619427 [ Mac Linux ] fast/overflow/overflow-height-float-not-removed-crash3.html [ Pass Failure ]
 
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites
index d8e7d74b..d90d8fb 100644
--- a/third_party/WebKit/LayoutTests/VirtualTestSuites
+++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -605,18 +605,18 @@
     "args": ["--autoplay-policy=document-user-activation-required"]
   },
   {
-    "prefix": "htxg",
-    "base": "http/tests/loading/htxg/",
-    "args": ["--enable-features=SignedHTTPExchange"]
-  },
-  {
-    "prefix": "htxg-with-network-service",
-    "base": "http/tests/loading/htxg/",
-    "args": ["--enable-features=SignedHTTPExchange,NetworkService"]
-  },
-  {
     "prefix": "sampling-heap-profiler",
     "base": "inspector-protocol/memory",
     "args": ["--sampling-heap-profiler"]
+  },
+  {
+    "prefix": "navigation-mojo-response",
+    "base": "http/tests/serviceworker",
+    "args": ["--enable-features=NavigationMojoResponse"]
+  },
+  {
+    "prefix": "navigation-mojo-response",
+    "base": "external/wpt/service-workers/service-worker",
+    "args": ["--enable-features=NavigationMojoResponse"]
   }
 ]
diff --git a/third_party/WebKit/LayoutTests/editing/assert_selection.html b/third_party/WebKit/LayoutTests/editing/assert_selection.html
index 7cab89e..51e6f8ad 100644
--- a/third_party/WebKit/LayoutTests/editing/assert_selection.html
+++ b/third_party/WebKit/LayoutTests/editing/assert_selection.html
@@ -195,9 +195,13 @@
     [
         '<div id="host">',
             '<span id="ghi">ghi</span>',
-            '<b id="def" slot="def">|def</b>',
+            '<slot name="def">',
+                '<b id="def" slot="def">|def</b>',
+            '</slot>',
             '<span id="jkl">jkl</span>',
-            '<b id="abc" slot="abc">^abc</b>',
+            '<slot name="abc">',
+                '<b id="abc" slot="abc">^abc</b>',
+            '</slot>',
             '<span id="mno">mno</span>',
         '</div>',
     ].join(''),
diff --git a/third_party/WebKit/LayoutTests/editing/deleting/5099303.html b/third_party/WebKit/LayoutTests/editing/deleting/5099303.html
index f1d4a4c..43dab6e 100644
--- a/third_party/WebKit/LayoutTests/editing/deleting/5099303.html
+++ b/third_party/WebKit/LayoutTests/editing/deleting/5099303.html
@@ -1,8 +1,32 @@
-<p>This tests for a bug where deleting from the start of a paragraph after a table would leave the caret in the wrong position.</p>
-<div contenteditable="true"><table border="1"><tr><td>The caret should be between these two parenthesis: (</td><td contenteditable="false"></td></tr></table><div id="div">).</div></div>
-
+<!doctype html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../assert_selection.js"></script>
 <script>
-var sel = window.getSelection();
-var div = document.getElementById("div");
-sel.collapse(div, 0);
+// Test collapsing the selection of a paragraph after a table
+// leaves the caret in the right position.
+selection_test(
+    [
+        '<div contenteditable="true">',
+            '<table border="1"><tbody><tr>',
+                '<td>The caret should be between these two parenthesis: (</td>',
+                '<td contenteditable="false"></td>',
+            '</tr></tbody></table>',
+            '<div id="div">)</div>',
+        '</div>'
+    ],
+    selection => {
+        var div = selection.document.getElementById("div");
+        selection.collapse(div, 0);
+    },
+    [
+        '<div contenteditable="true">',
+            '<table border="1"><tbody><tr>',
+                '<td>The caret should be between these two parenthesis: (</td>',
+                '<td contenteditable="false"></td>',
+            '</tr></tbody></table>',
+            '<div id="div">|)</div>',
+        '</div>'
+    ],
+    'Deleting from the start of a paragraph after a table');
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index a1d8c40..68b63a6 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -221167,24 +221167,96 @@
      {}
     ]
    ],
+   "webauthn/createcredential-badargs-attestation.https.html": [
+    [
+     "/webauthn/createcredential-badargs-attestation.https.html",
+     {}
+    ]
+   ],
+   "webauthn/createcredential-badargs-authnrselection.https.html": [
+    [
+     "/webauthn/createcredential-badargs-authnrselection.https.html",
+     {}
+    ]
+   ],
+   "webauthn/createcredential-badargs-challenge.https.html": [
+    [
+     "/webauthn/createcredential-badargs-challenge.https.html",
+     {}
+    ]
+   ],
    "webauthn/createcredential-badargs-rp.https.html": [
     [
      "/webauthn/createcredential-badargs-rp.https.html",
      {}
     ]
    ],
+   "webauthn/createcredential-badargs-user.https.html": [
+    [
+     "/webauthn/createcredential-badargs-user.https.html",
+     {}
+    ]
+   ],
+   "webauthn/createcredential-excludecredentials.https.html": [
+    [
+     "/webauthn/createcredential-excludecredentials.https.html",
+     {}
+    ]
+   ],
+   "webauthn/createcredential-extensions.https.html": [
+    [
+     "/webauthn/createcredential-extensions.https.html",
+     {}
+    ]
+   ],
    "webauthn/createcredential-passing.https.html": [
     [
      "/webauthn/createcredential-passing.https.html",
      {}
     ]
    ],
+   "webauthn/createcredential-pubkeycredparams.https.html": [
+    [
+     "/webauthn/createcredential-pubkeycredparams.https.html",
+     {}
+    ]
+   ],
+   "webauthn/createcredential-timeout.https.html": [
+    [
+     "/webauthn/createcredential-timeout.https.html",
+     {}
+    ]
+   ],
+   "webauthn/getcredential-badargs-rpid.https.html": [
+    [
+     "/webauthn/getcredential-badargs-rpid.https.html",
+     {}
+    ]
+   ],
+   "webauthn/getcredential-badargs-userverification.https.html": [
+    [
+     "/webauthn/getcredential-badargs-userverification.https.html",
+     {}
+    ]
+   ],
+   "webauthn/getcredential-extensions.https.html": [
+    [
+     "/webauthn/getcredential-extensions.https.html",
+     {}
+    ]
+   ],
    "webauthn/getcredential-passing.https.html": [
     [
      "/webauthn/getcredential-passing.https.html",
      {}
     ]
    ],
+   "webauthn/getcredential-timeout.https.html": [
+    [
+     "/webauthn/getcredential-timeout.https.html",
+     {}
+    ]
+   ],
    "webauthn/interfaces.https.html": [
     [
      "/webauthn/interfaces.https.html",
@@ -233201,7 +233273,7 @@
    "support"
   ],
   "./lint.whitelist": [
-   "fc1e09fcc92c3f54ed75fe93681c5ff0a53d25a4",
+   "626b91c285aee2f19f3ca80750b093594de2054b",
    "support"
   ],
   "./update-built-tests.sh": [
@@ -305397,7 +305469,7 @@
    "testharness"
   ],
   "custom-elements/Document-createElementNS.html": [
-   "04cd97839e98c6082f67740dbcfc7588e2b251b9",
+   "799f59e3bf8ab0830e44faa3ffef6d3303da42eb",
    "testharness"
   ],
   "custom-elements/HTMLElement-constructor.html": [
@@ -358244,12 +358316,36 @@
    "832fb99e215923e9d102f48f2a0cd06ea11ff86b",
    "support"
   ],
+  "webauthn/createcredential-badargs-attestation.https.html": [
+   "397a6f0b95e75cf2b743eb208f6c79c767ec648a",
+   "testharness"
+  ],
+  "webauthn/createcredential-badargs-authnrselection.https.html": [
+   "f5f5c8316551a921823bfe000031d42d91d9baa1",
+   "testharness"
+  ],
+  "webauthn/createcredential-badargs-challenge.https.html": [
+   "741efba3e4c583d5983a5005803f718bdaa435b0",
+   "testharness"
+  ],
   "webauthn/createcredential-badargs-rp.https-expected.txt": [
    "6b8193f882d66d96ace82fbd997eb624d90b19e7",
    "support"
   ],
   "webauthn/createcredential-badargs-rp.https.html": [
-   "941a9bda02e22b7d54855e3a4714a49d8392fa9d",
+   "8ab678da79853a5c41ff142704bb4732b026e06c",
+   "testharness"
+  ],
+  "webauthn/createcredential-badargs-user.https.html": [
+   "37f734eed5ecd34f6feb90bb96154e16a763140a",
+   "testharness"
+  ],
+  "webauthn/createcredential-excludecredentials.https.html": [
+   "387387626892215c1552ef5e742fd32d800df4ad",
+   "testharness"
+  ],
+  "webauthn/createcredential-extensions.https.html": [
+   "9642dafa7ed7ce75d5812328fcd3ac2239e33ebd",
    "testharness"
   ],
   "webauthn/createcredential-passing.https-expected.txt": [
@@ -358257,7 +358353,27 @@
    "support"
   ],
   "webauthn/createcredential-passing.https.html": [
-   "32a6ac38f91ec6b887e9e57519eb1603b4abcdbb",
+   "e89da85133f56cf0b5b78f6d6f39b43926ed9fda",
+   "testharness"
+  ],
+  "webauthn/createcredential-pubkeycredparams.https.html": [
+   "009193df4404190c820618840104da8db380eaa8",
+   "testharness"
+  ],
+  "webauthn/createcredential-timeout.https.html": [
+   "c0e639f8a32a1bc3553fd437a4fcf694a63960c2",
+   "testharness"
+  ],
+  "webauthn/getcredential-badargs-rpid.https.html": [
+   "275511dbafc9a536f92e74ef4c0531a7d8b7a437",
+   "testharness"
+  ],
+  "webauthn/getcredential-badargs-userverification.https.html": [
+   "5ac7b919d473bfc126c3e57df70c2f0defc60671",
+   "testharness"
+  ],
+  "webauthn/getcredential-extensions.https.html": [
+   "ea4d0533a5939927dd9eaa5d81116dbcc2f3ccbe",
    "testharness"
   ],
   "webauthn/getcredential-passing.https-expected.txt": [
@@ -358265,11 +358381,15 @@
    "support"
   ],
   "webauthn/getcredential-passing.https.html": [
-   "6272128ea3af65ecb4fc40055b062a678bfbb2fd",
+   "1b0f77b533a4e528b3abc484ba4d74b56833131f",
+   "testharness"
+  ],
+  "webauthn/getcredential-timeout.https.html": [
+   "b8c71a3fccdf39c2e35bd34a3cd42561cac5836b",
    "testharness"
   ],
   "webauthn/helpers.js": [
-   "e6224e8e2be8657e2e312f4197cbe0225c819cea",
+   "9ce729fb89ba1863fb14dfc4d567e6b544a5238d",
    "support"
   ],
   "webauthn/interfaces.https-expected.txt": [
@@ -358289,11 +358409,11 @@
    "support"
   ],
   "webauthn/securecontext.http.html": [
-   "afc1492723d140e34027a3bdbf0d1e09843ef5d6",
+   "7abf48e74debed79578e39934d1b84655731a3ea",
    "testharness"
   ],
   "webauthn/securecontext.https.html": [
-   "7f7a7aba32b9e049c618203121fae0884936643a",
+   "9bdd7e09c7f468b9b0c106d4764d61e77b32131f",
    "testharness"
   ],
   "webmessaging/Channel_postMessage_Blob.htm": [
@@ -358921,7 +359041,7 @@
    "testharness"
   ],
   "webrtc/RTCPeerConnection-createAnswer-expected.txt": [
-   "3ec80a67f9db046ba1862953adb02619b0e2ead4",
+   "c252cbbfe2b415241f1bee617b86b40c1c9163f5",
    "support"
   ],
   "webrtc/RTCPeerConnection-createAnswer.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/interleaved-cursors.html b/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/interleaved-cursors-common.js
similarity index 93%
rename from third_party/WebKit/LayoutTests/external/wpt/IndexedDB/interleaved-cursors.html
rename to third_party/WebKit/LayoutTests/external/wpt/IndexedDB/interleaved-cursors-common.js
index 31126908..a76ec528 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/interleaved-cursors.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/interleaved-cursors-common.js
@@ -1,12 +1,5 @@
-<!doctype html>
-<meta charset="utf-8">
-<meta name="timeout" content="long">
-<title>IndexedDB: Interleaved iteration of multiple cursors</title>
-<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="support-promises.js"></script>
-<script>
+// Infrastructure shared by interleaved-cursors-{small,large}.html
+
 // Number of objects that each iterator goes over.
 const itemCount = 10;
 
@@ -169,7 +162,7 @@
   });
 }
 
-for (let cursorCount of [1, 10, 100, 500]) {
+function cursorTest(cursorCount) {
   promise_test(testCase => {
     return createDatabase(testCase, (database, transaction) => {
       const store = database.createObjectStore('cache',
@@ -193,4 +186,3 @@
     });
   }, `${cursorCount} cursors`);
 }
-</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/interleaved-cursors-large.html b/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/interleaved-cursors-large.html
new file mode 100644
index 0000000..6f4e440e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/interleaved-cursors-large.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>IndexedDB: Interleaved iteration of multiple cursors</title>
+<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support-promises.js"></script>
+<script src="interleaved-cursors-common.js"></script>
+<script>
+cursorTest(250);
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/interleaved-cursors-small.html b/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/interleaved-cursors-small.html
new file mode 100644
index 0000000..a4c4777
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/IndexedDB/interleaved-cursors-small.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<title>IndexedDB: Interleaved iteration of multiple cursors</title>
+<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support-promises.js"></script>
+<script src="interleaved-cursors-common.js"></script>
+<script>
+cursorTest(1);
+cursorTest(10);
+cursorTest(100);
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist b/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist
index 2f9b44d..95f82ea 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist
+++ b/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist
@@ -225,6 +225,7 @@
 SET TIMEOUT: user-timing/*
 SET TIMEOUT: webaudio/js/lodash.js
 SET TIMEOUT: webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html
+SET TIMEOUT: webauthn/*timeout.https.html
 SET TIMEOUT: webdriver/*
 SET TIMEOUT: webmessaging/*
 SET TIMEOUT: websockets/*
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-attestation.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-attestation.https.html
new file mode 100644
index 0000000..a56f4f0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-attestation.https.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.create() attestation parameter Tests</title>
+<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
+<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+standardSetup(function() {
+    "use strict";
+
+    // attestation bad values
+    new CreateCredentialsTest("options.publicKey.attestation", {}).runTest("Bad attestation parameter: attestation is empty object", new TypeError());
+    new CreateCredentialsTest("options.publicKey.attestation", []).runTest("Bad attestation parameter: attestation is empty array", new TypeError());
+    new CreateCredentialsTest("options.publicKey.attestation", null).runTest("Bad attestation parameter: attestation is null", new TypeError());
+    new CreateCredentialsTest("options.publicKey.attestation", "noneofyourbusiness").runTest("Bad attestation parameter: attestation is \"noneofyourbusiness\"", new TypeError());
+    new CreateCredentialsTest("options.publicKey.attestation", "").runTest("Bad attestation parameter: attestation is empty string", new TypeError());
+});
+
+/* JSHINT */
+/* globals standardSetup, CreateCredentialsTest */
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-authnrselection.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-authnrselection.https.html
new file mode 100644
index 0000000..2c42135
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-authnrselection.https.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.create() authenticator selection Tests</title>
+<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
+<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+standardSetup(function() {
+    "use strict";
+
+    var defaultAuthnrSel = {
+        authenticatorAttachment: "cross-platform",
+        requireResidentKey: false,
+        userVerification: "preferred"
+    };
+    // attachment
+    var authnrSelAttachPlatform = cloneObject(defaultAuthnrSel);
+    authnrSelAttachPlatform.authenticatorAttachment = "platform";
+    var authnrSelBadAttachEmptyStr = cloneObject(defaultAuthnrSel);
+    authnrSelBadAttachEmptyStr.authenticatorAttachment = "";
+    var authnrSelBadAttachEmptyObj = cloneObject(defaultAuthnrSel);
+    authnrSelBadAttachEmptyObj.authenticatorAttachment = {};
+    var authnrSelBadAttachNull = cloneObject(defaultAuthnrSel);
+    authnrSelBadAttachNull.authenticatorAttachment = null;
+    // resident key
+    var authnrSelRkTrue = cloneObject(defaultAuthnrSel);
+    authnrSelRkTrue.requireResidentKey = true;
+    var authnrSelRkBadString = cloneObject(defaultAuthnrSel);
+    authnrSelRkBadString.requireResidentKey = "foo";
+    // user verification
+    var authnrSelUvRequired = cloneObject(defaultAuthnrSel);
+    authnrSelUvRequired.userVerification = "required";
+    var authnrSelBadUvEmptyStr = cloneObject(defaultAuthnrSel);
+    authnrSelBadUvEmptyStr.userVerification = "";
+    var authnrSelBadUvEmptyObj = cloneObject(defaultAuthnrSel);
+    authnrSelBadUvEmptyObj.userVerification = {};
+    var authnrSelBadUvStr = cloneObject(defaultAuthnrSel);
+    authnrSelBadUvStr.userVerification = "requiredshirtshoestshirt";
+    var authnrSelBadUvNull = cloneObject(defaultAuthnrSel);
+    authnrSelBadUvNull.userVerification = null;
+
+    // authenticatorSelection bad values
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", []).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection is empty array", new TypeError());
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", null).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection is null", new TypeError());
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", "").runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection is empty string", new TypeError());
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", "none").runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection is string", new TypeError());
+
+    // authenticatorSelection bad attachment values
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadAttachEmptyStr).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is empty string", new TypeError());
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadAttachEmptyObj).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is empty object", new TypeError());
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadAttachNull).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is null", new TypeError());
+    // XXX: assumes authnr is behaving like most U2F authnrs; really depends on the authnr or mock configuration
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelAttachPlatform).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment platform", "NotAllowedError");
+
+    // authenticatorSelection bad requireResidentKey values
+   // XXX: assumes authnr is behaving like most U2F authnrs; really depends on the authnr or mock configuration
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelRkTrue).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection residentKey true", "NotAllowedError");
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelRkBadString).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection residentKey is string", new TypeError());
+    // TODO: not sure if rk is "boolean" or "truthy"; add test cases if it should only accept boolean values
+
+    // authenticatorSelection bad userVerification values
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadUvEmptyStr).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification empty string", new TypeError());
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadUvEmptyObj).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification empty object", new TypeError());
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadUvStr).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification bad value", new TypeError());
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelBadUvNull).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification null", new TypeError());
+    // XXX: assumes this is a mock authenticator the properly reports that it is not doing userVerfication
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelUvRequired).runTest("Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification required", "NotAllowedError");
+});
+
+/* JSHINT */
+/* globals standardSetup, CreateCredentialsTest, cloneObject */
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-challenge.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-challenge.https.html
new file mode 100644
index 0000000..0ad67f2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-challenge.https.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.create() challenge Tests</title>
+<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
+<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+standardSetup(function() {
+    "use strict";
+
+    // bad challenge values
+    new CreateCredentialsTest({path: "options.publicKey.challenge", value: undefined}).runTest("Bad challenge: challenge missing", new TypeError());
+    new CreateCredentialsTest("options.publicKey.challenge", "hi mom").runTest("Bad challenge: challenge is string", new TypeError());
+    new CreateCredentialsTest("options.publicKey.challenge", null).runTest("Bad challenge: challenge is null", new TypeError());
+    new CreateCredentialsTest("options.publicKey.challenge", {}).runTest("Bad challenge: challenge is empty object", new TypeError());
+    new CreateCredentialsTest("options.publicKey.challenge", new Array()).runTest("Bad challenge: challenge is empty Array", new TypeError());
+    new CreateCredentialsTest("options.publicKey.challenge", new ArrayBuffer(0)).runTest("Bad challenge: challenge is empty ArrayBuffer", new TypeError());
+});
+
+/* JSHINT */
+/* globals standardSetup, CreateCredentialsTest */
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-rp.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-rp.https.html
index f06e02c..9958b2c 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-rp.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-rp.https.html
@@ -12,29 +12,29 @@
     "use strict";
 
     // rp bad values
-    new CreateCredentialsTest({path: "options.publicKey.rp", value: undefined}).testBadArgs("rp missing");
-    new CreateCredentialsTest("options.publicKey.rp", "hi mom").testBadArgs("rp is string");
-    // new CreateCredentialsTest("options.publicKey.rp", {}).testBadArgs("rp is empty object");
+    new CreateCredentialsTest({path: "options.publicKey.rp", value: undefined}).runTest("Bad rp: rp missing", new TypeError());
+    new CreateCredentialsTest("options.publicKey.rp", "hi mom").runTest("Bad rp: rp is string", new TypeError());
+    new CreateCredentialsTest("options.publicKey.rp", {}).runTest("Bad rp: rp is empty object", new TypeError());
 
-    // rp.id
-    // new CreateCredentialsTest({path: "options.publicKey.rp.id", value: undefined}).testBadArgs("rp missing id");
-    new CreateCredentialsTest("options.publicKey.rp.id", {}).testBadArgs("Bad rp: id is object");
-    new CreateCredentialsTest("options.publicKey.rp.id", null).testBadArgs("Bad rp: id is null");
-    new CreateCredentialsTest("options.publicKey.rp.id", "").testBadArgs("Bad rp: id is empty String");
+    // // rp.id
+    new CreateCredentialsTest("options.publicKey.rp.id", {}).runTest("Bad rp: id is object", new TypeError());
+    new CreateCredentialsTest("options.publicKey.rp.id", null).runTest("Bad rp: id is null", "SecurityError");
+    new CreateCredentialsTest("options.publicKey.rp.id", "").runTest("Bad rp: id is empty String", "SecurityError");
+    new CreateCredentialsTest("options.publicKey.rp.id", "invalid domain.com").runTest("Bad rp: id is invalid domain (has space)", "SecurityError");
+    new CreateCredentialsTest("options.publicKey.rp.id", "-invaliddomain.com").runTest("Bad rp: id is invalid domain (starts with dash)", "SecurityError");
+    new CreateCredentialsTest("options.publicKey.rp.id", "0invaliddomain.com").runTest("Bad rp: id is invalid domain (starts with number)", "SecurityError");
 
-    // rp.name
-    // new CreateCredentialsTest({path: "options.publicKey.rp.name", value: undefined}).testBadArgs("rp missing name");
-    new CreateCredentialsTest("options.publicKey.rp.name", {}).testBadArgs("Bad rp: name is object");
-    new CreateCredentialsTest("options.publicKey.rp.name", null).testBadArgs("Bad rp: name is null");
-    new CreateCredentialsTest("options.publicKey.rp.name", "").testBadArgs("Bad rp: name is empty String");
+    // // rp.name
+    new CreateCredentialsTest({path: "options.publicKey.rp.name", value: undefined}).runTest("rp missing name", new TypeError());
+    new CreateCredentialsTest("options.publicKey.rp.name", {}).runTest("Bad rp: name is object", new TypeError());
+    new CreateCredentialsTest("options.publicKey.rp.name", null).runTest("Bad rp: name is null", new TypeError());
+    new CreateCredentialsTest("options.publicKey.rp.name", "").runTest("Bad rp: name is empty String", new TypeError());
 
-    // rp.icon
-    // new CreateCredentialsTest({path: "options.publicKey.rp.icon", value: undefined}).testBadArgs("rp missing icon");
-    new CreateCredentialsTest("options.publicKey.rp.icon", {}).testBadArgs("Bad rp: icon is object");
-    new CreateCredentialsTest("options.publicKey.rp.icon", null).testBadArgs("Bad rp: icon is null");
-    new CreateCredentialsTest("options.publicKey.rp.icon", "").testBadArgs("Bad rp: icon is empty String");
-    // TODO: see https://github.com/w3c/webauthn/issues/587 for the 'undefined' tests that are commented out above
-    // TODO: unicode tests for icon URL (see also: USVString)
+    // // rp.icon
+    new CreateCredentialsTest("options.publicKey.rp.icon", {}).runTest("Bad rp: icon is object", new TypeError());
+    new CreateCredentialsTest("options.publicKey.rp.icon", null).runTest("Bad rp: icon is null", new TypeError());
+    new CreateCredentialsTest("options.publicKey.rp.icon", "").runTest("Bad rp: icon is empty String", new TypeError());
+    // // TODO: unicode tests for icon URL (see also: USVString)
 });
 
 /* JSHINT */
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-user.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-user.https.html
new file mode 100644
index 0000000..dd1870a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-user.https.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.create() user Tests</title>
+<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
+<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+standardSetup(function() {
+    "use strict";
+
+    // user bad values
+    new CreateCredentialsTest({path: "options.publicKey.user", value: undefined}).runTest("Bad user: user missing", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user", "hi mom").runTest("Bad user: user is string", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user", {}).runTest("Bad user: user is empty object", new TypeError());
+
+    // // user.id
+    new CreateCredentialsTest({path: "options.publicKey.user.id", value: undefined}).runTest("Bad user: id is undefined", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.id", {}).runTest("Bad user: id is object", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.id", null).runTest("Bad user: id is null", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.id", "").runTest("Bad user: id is empty String", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.id", new Array()).runTest("Bad user: id is empty Array", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.id", new ArrayBuffer(0)).runTest("Bad user: id is empty ArrayBuffer", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.id", new ArrayBuffer(65)).runTest("Bad user: ArrayBuffer id is too long (65 bytes)", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.id", new Int16Array(33)).runTest("Bad user: Int16Array id is too long (66 bytes)", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.id", new Int32Array(17)).runTest("Bad user: Int32Array id is too long (68 bytes)", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.id", new Float32Array(17)).runTest("Bad user: Float32Array id is too long (68 bytes)", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.id", new Float64Array(9)).runTest("Bad user: Float64Array id is too long (72 bytes)", new TypeError());
+    var buf = new ArrayBuffer(65);
+    new CreateCredentialsTest("options.publicKey.user.id", new DataView(buf)).runTest("Bad user: id is too long (65 bytes)", new TypeError());
+
+    // // user.name
+    new CreateCredentialsTest({path: "options.publicKey.user.name", value: undefined}).runTest("user missing name", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.name", {}).runTest("Bad user: name is object", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.name", null).runTest("Bad user: name is null", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.name", "").runTest("Bad user: name is empty String", new TypeError());
+
+    // // user.icon
+    new CreateCredentialsTest("options.publicKey.user.icon", {}).runTest("Bad user: icon is object", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.icon", null).runTest("Bad user: icon is null", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.icon", "").runTest("Bad user: icon is empty String", new TypeError());
+    // // TODO: unicode tests for icon URL (see also: USVString)
+
+    // // user.displayName
+    new CreateCredentialsTest({path: "options.publicKey.user.displayName", value: undefined}).runTest("Bad user: displayName is undefined", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.displayName", {}).runTest("Bad user: displayName is object", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.displayName", null).runTest("Bad user: displayName is null", new TypeError());
+    new CreateCredentialsTest("options.publicKey.user.displayName", "").runTest("Bad user: displayName is empty String", new TypeError());
+});
+
+/* JSHINT */
+/* globals standardSetup, CreateCredentialsTest */
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-excludecredentials.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-excludecredentials.https.html
new file mode 100644
index 0000000..a4cfb0a4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-excludecredentials.https.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.create() excludeCredentials Tests</title>
+<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
+<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+standardSetup(function() {
+    "use strict";
+
+    // bad excludeCredentials values
+    new CreateCredentialsTest("options.publicKey.excludeCredentials", "hi mom").runTest("Bad excludeCredentials: string", new TypeError());
+    new CreateCredentialsTest("options.publicKey.excludeCredentials", {}).runTest("Bad excludeCredentials: empty object", new TypeError());
+    // TODO: bad excludeCredentials with [{.type}] or [{.id}] or [{.transports}] wrong
+
+    // good excludeCredentials values
+    new CreateCredentialsTest({path: "options.publicKey.excludeCredentials", value: undefined}).runTest("excludeCredentials missing");
+    new CreateCredentialsTest("options.publicKey.excludeCredentials", []).runTest("excludeCredentials empty array");
+
+    // proper excludeCredentials behavior
+    // should error on excluding existing credential
+    promise_test((t) => {
+        var cred1;
+        return Promise.resolve()
+            .then(() => {
+                return createCredential();
+            })
+            .then((cred) => {
+                cred1 = cred;
+                var excludeCred = {
+                    id: cred.rawId,
+                    type: "public-key"
+                };
+                var args = {
+                    options: {
+                        publicKey: {
+                            excludeCredentials: [excludeCred]
+                        }
+                    }
+                };
+                var p = createCredential(args);
+                return promise_rejects (t, "NotAllowedError", p, "expected to fail on excluded credenetial");
+            });
+    }, "exclude existing credential");
+
+    // should not error on excluding random credential
+    promise_test(() => {
+        return Promise.resolve()
+            .then(() => {
+                return createCredential();
+            })
+            .then(() => {
+                var randomCredId = new Uint8Array(162);
+                window.crypto.getRandomValues(randomCredId);
+
+                var excludeCred = {
+                    id: randomCredId,
+                    type: "public-key"
+                };
+                var args = {
+                    options: {
+                        publicKey: {
+                            excludeCredentials: [excludeCred]
+                        }
+                    }
+                };
+                return createCredential(args);
+            });
+    }, "exclude random (non-existing) credential");
+
+    // TODO: exclude including transport type (USB, BLE, NFC)
+});
+
+/* JSHINT */
+/* globals standardSetup, CreateCredentialsTest, createCredential, promise_test, promise_rejects */
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-extensions.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-extensions.https.html
new file mode 100644
index 0000000..3b3c9bf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-extensions.https.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.create() extensions Tests</title>
+<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
+<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+standardSetup(function() {
+    "use strict";
+
+    var dummyExtension = {
+        foo: true,
+        bar: "yup"
+    };
+
+    // bad extension values
+    new CreateCredentialsTest("options.publicKey.extensions", "hi mom").runTest("Bad extensions: extensions is string", new TypeError());
+    new CreateCredentialsTest("options.publicKey.extensions", null).runTest("Bad extensions: extensions is null", new TypeError());
+    new CreateCredentialsTest("options.publicKey.extensions", []).runTest("Bad extensions: extensions is empty Array", new TypeError());
+    new CreateCredentialsTest("options.publicKey.extensions", new ArrayBuffer(0)).runTest("Bad extensions: extensions is empty ArrayBuffer", new TypeError());
+    var badJson = '{"foo": true, "bar: "yup"}'; // missing quote after "bar"
+    new CreateCredentialsTest("options.publicKey.extensions", {foo: badJson}).runTest("Bad extensions: malformatted JSON", new TypeError());
+    new CreateCredentialsTest("options.publicKey.extensions", {foo: dummyExtension}).runTest("Bad extensions: JavaScript object", new TypeError());
+    var badExtId = {};
+    badExtId[createRandomString(65)] = dummyExtension;
+    new CreateCredentialsTest("options.publicKey.extensions", {badExtId: dummyExtension}).runTest("Bad extensions: extension ID too long", new TypeError());
+
+    // phony extensions
+    // TODO: not sure if this should pass or fail
+    // should be clarified as part of https://github.com/w3c/webauthn/pull/765
+    var randomExtId = {};
+    randomExtId[createRandomString(64)] = dummyExtension;
+    new CreateCredentialsTest("options.publicKey.extensions", {foo: JSON.stringify(randomExtId)}).runTest("extensions is a nonsensical JSON string");
+
+    // TODO
+    // defined extensions:
+    // * appid
+    // * txAuthSimple
+    // * txAuthGeneric
+    // * authnSel
+    // * exts
+    // * uvi
+    // * loc
+    // * uvm
+});
+
+/* JSHINT */
+/* globals standardSetup, CreateCredentialsTest, createRandomString */
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-passing.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-passing.https.html
index a66d3c1..25dba1db 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-passing.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-passing.https.html
@@ -12,9 +12,108 @@
     "use strict";
 
     // CreateCredentialTest passing tests
-    new CreateCredentialsTest().test();
+
+    // default arguments
+    new CreateCredentialsTest().runTest("passing credentials.create() with default arguments");
+
+    // rp
+    new CreateCredentialsTest({path: "options.publicKey.rp.id", value: window.location.host}).runTest("passing credentials.create() with rpId (host and port)");
+    new CreateCredentialsTest({path: "options.publicKey.rp.id", value: window.location.hostname}).runTest("passing credentials.create() with rpId (hostname)");
+    new CreateCredentialsTest({path: "options.publicKey.rp.icon", value: undefined}).runTest("passing credentials.create() without rp.icon");
+
+    // user
+    new CreateCredentialsTest("options.publicKey.user.id", new ArrayBuffer(1)).runTest("very short user id");
+    new CreateCredentialsTest("options.publicKey.user.id", new ArrayBuffer(64)).runTest("max length user id");
+    new CreateCredentialsTest("options.publicKey.user.id", new Uint8Array(64)).runTest("Uint8Array user id");
+    new CreateCredentialsTest("options.publicKey.user.id", new Int8Array(64)).runTest("Int8Array user id");
+    new CreateCredentialsTest("options.publicKey.user.id", new Int16Array(32)).runTest("Int16Array user id");
+    new CreateCredentialsTest("options.publicKey.user.id", new Int32Array(16)).runTest("Int32Array user id");
+    new CreateCredentialsTest("options.publicKey.user.id", new Float32Array(16)).runTest("Float32Array user id");
+    var dvBuf1 = new ArrayBuffer(16);
+    new CreateCredentialsTest("options.publicKey.user.id", new DataView(dvBuf1)).runTest("DataView user id");
+    new CreateCredentialsTest({path: "options.publicKey.user.icon", value: undefined}).runTest("passing credentials.create() without user.icon");
+
+    // good challenge values
+    // all these challenges are zero-filled buffers... think anyone will complain?
+    new CreateCredentialsTest("options.publicKey.challenge", new Int16Array(33)).runTest("Int16Array challenge");
+    new CreateCredentialsTest("options.publicKey.challenge", new Int32Array(17)).runTest("Int32Array challenge");
+    new CreateCredentialsTest("options.publicKey.challenge", new Float32Array(17)).runTest("Float32Array challenge");
+    new CreateCredentialsTest("options.publicKey.challenge", new Float64Array(9)).runTest("Float64Array challenge");
+    var dvBuf2 = new ArrayBuffer(65);
+    new CreateCredentialsTest("options.publicKey.challenge", new DataView(dvBuf2)).runTest("DataView challenge");
+    new CreateCredentialsTest("options.publicKey.challenge", new ArrayBuffer(8192)).runTest("Absurdly large challenge");
+
+    // good pubKeyCredParams values
+    new CreateCredentialsTest("options.publicKey.pubKeyCredParams", []).runTest("Bad pubKeyCredParams: pubKeyCredParams is empty Array");
+    const pkParamEC256 = {
+        type: "public-key",
+        alg: cose_alg_ECDSA_w_SHA256
+    };
+    const pkParamEC512 = {
+        type: "public-key",
+        alg: cose_alg_ECDSA_w_SHA512
+    };
+    // XXX: presumes all mock authenticators support EC256
+    new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC256]).runTest("EC256 pubKeyCredParams");
+    new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC512, pkParamEC256])
+        .runTest("SelectEC256 pubKeyCredParams from a list");
+    // TODO: currently most browsers are mocking FIDO U2F, which is EC256 only
+    // new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC512]).runTest("EC512 pubKeyCredParams");
+
+    // NOTE: excludeCredentials parameter -- see also: createcredential-excludecredentials.https.html
+
+    // timeout
+    new CreateCredentialsTest({path: "options.publicKey.timeout", value: undefined}).runTest("passing credentials.create() with no timeout");
+
+    // valid authenticatorSelection values
+    var defaultAuthnrSel = {
+        authenticatorAttachment: "cross-platform",
+        requireResidentKey: false,
+        userVerification: "preferred"
+    };
+    // attachment
+    var authnrSelAttachUndef = cloneObject(defaultAuthnrSel);
+    authnrSelAttachUndef.authenticatorAttachment = undefined;
+    // resident key
+    var authnrSelRkUndef = cloneObject(defaultAuthnrSel);
+    authnrSelRkUndef.requireResidentKey = undefined;
+    var authnrSelRkFalse = cloneObject(defaultAuthnrSel);
+    authnrSelRkFalse.requireResidentKey = false;
+    // user verification
+    var authnrSelUvUndef = cloneObject(defaultAuthnrSel);
+    authnrSelUvUndef.userVerification = undefined;
+    var authnrSelUvDiscouraged = cloneObject(defaultAuthnrSel);
+    authnrSelUvDiscouraged.userVerification = "discouraged";
+    new CreateCredentialsTest({path: "options.publicKey.authenticatorSelection", value: undefined}).runTest("authenticatorSelection is undefined");
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", {}).runTest("authenticatorSelection is empty object");
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", cloneObject(defaultAuthnrSel)).runTest("authenticatorSelection default values");
+
+    // authnr selection attachment
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelAttachUndef).runTest("authenticatorSelection attachment undefined");
+
+    // authnr selection resident key
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelRkUndef).runTest("authenticatorSelection residentKey undefined");
+    // XXX: assumes authnr is behaving like most U2F authnrs; really depends on the authnr or mock configuration
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelRkFalse).runTest("authenticatorSelection residentKey false");
+
+    // authnr selection user verification
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelUvUndef).runTest("authenticatorSelection userVerification undefined");
+    new CreateCredentialsTest("options.publicKey.authenticatorSelection", authnrSelUvDiscouraged).runTest("authenticatorSelection userVerification discouraged");
+
+
+    // good attestation values
+    new CreateCredentialsTest("options.publicKey.attestation", "none").runTest("attestation parameter: attestation is \"none\"");
+    new CreateCredentialsTest("options.publicKey.attestation", "indirect").runTest("attestation parameter: attestation is \"indirect\"");
+    new CreateCredentialsTest("options.publicKey.attestation", "direct").runTest("attestation parameter: attestation is \"direct\"");
+    new CreateCredentialsTest({path: "options.publicKey.attestation", value: undefined}).runTest("attestation parameter: attestation is undefined");
+    // TODO: test this with multiple mock authenticators to make sure that the right options are chosen when available?
+
+    // good extension values
+    new CreateCredentialsTest({path: "options.publicKey.extensions", value: undefined}).runTest("extensions undefined");
+    new CreateCredentialsTest("options.publicKey.extensions", {}).runTest("extensions are empty object");
+    new CreateCredentialsTest("options.publicKey.extensions", {foo: "", bar: "", bat: ""}).runTest("extensions are dict of empty strings");
 });
 
 /* JSHINT */
-/* globals standardSetup, CreateCredentialsTest */
+/* globals standardSetup, CreateCredentialsTest, cose_alg_ECDSA_w_SHA256, cose_alg_ECDSA_w_SHA512, cloneObject */
 </script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-pubkeycredparams.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-pubkeycredparams.https.html
new file mode 100644
index 0000000..325191c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-pubkeycredparams.https.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.create() pubKeyCredParams Tests</title>
+<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
+<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+standardSetup(function() {
+    "use strict";
+
+    var badType = {
+        type: "something-else",
+        alg: cose_alg_ECDSA_w_SHA512
+    };
+    var badTypeEmptyString = cloneObject(badType);
+    badTypeEmptyString.type = "";
+    var badTypeNull = cloneObject(badType);
+    badTypeNull.type = null;
+    var badTypeEmptyObj = cloneObject(badType);
+    badTypeEmptyObj.type = {};
+
+    var badAlg = {
+        type: "public-key",
+        alg: 42
+    };
+    var badAlgZero = cloneObject(badAlg);
+    badAlgZero.alg = 0;
+
+    // bad pubKeyCredParams values
+    new CreateCredentialsTest({path: "options.publicKey.pubKeyCredParams", value: undefined}).runTest("Bad pubKeyCredParams: pubKeyCredParams is undefined", new TypeError());
+    new CreateCredentialsTest("options.publicKey.pubKeyCredParams", "hi mom").runTest("Bad pubKeyCredParams: pubKeyCredParams is string", new TypeError());
+    new CreateCredentialsTest("options.publicKey.pubKeyCredParams", null).runTest("Bad pubKeyCredParams: pubKeyCredParams is null", new TypeError());
+    new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badType]).runTest("Bad pubKeyCredParams: first param has bad type (\"something-else\")", new TypeError());
+    new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeEmptyString]).runTest("Bad pubKeyCredParams: first param has bad type (\"\")", new TypeError());
+    new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeNull]).runTest("Bad pubKeyCredParams: first param has bad type (null)", new TypeError());
+    new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeEmptyObj]).runTest("Bad pubKeyCredParams: first param has bad type (empty object)", new TypeError());
+    new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badAlg]).runTest("Bad pubKeyCredParams: first param has bad alg (42)", "NotSupportedError");
+    new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badAlgZero]).runTest("Bad pubKeyCredParams: first param has bad alg (0)", "NotSupportedError");
+
+    // TODO: come back to this when mock authenticators support multiple cryptos so that we can test the preference ranking
+    // function verifyEC256(res) {
+    //     debug ("verifyEC256 got", res);
+    //     debug ("client data JSON", ab2str(res.response.clientDataJSON));
+    //     parseAuthenticatorData(res.response.attestationObject);
+    // }
+    // new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC256, pkParamEC512])
+    //     .afterTest(verifyEC256)
+    //     .runTest("EC256, EC512 pubKeyCredParams");
+    // function verifyEC512(res) {
+    //     debug ("verifyEC512 got", res);
+    //     debug ("client data JSON", ab2str(res.response.clientDataJSON));
+    //     // parseAuthenticatorData(res.response.attestationObject);
+    //     printHex ("clientDataJSON", res.response.clientDataJSON);
+    //     printHex ("attestationObject", res.response.attestationObject);
+    // }
+    // new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC512, pkParamEC256])
+    //     .afterTest(verifyEC512)
+    //     .runTest("EC512, EC256 pubKeyCredParams");
+});
+
+/* JSHINT */
+/* globals standardSetup, CreateCredentialsTest, cose_alg_ECDSA_w_SHA512, cloneObject */
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-timeout.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-timeout.https.html
new file mode 100644
index 0000000..b94ae582
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-timeout.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.create() timeout Tests</title>
+<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
+<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+standardSetup(function() {
+    "use strict";
+
+    // bad timeout values
+    // TODO: there is some debate as to whether MAX_UNSIGNED_LONG + 1 and / or -1 should be disallowed since they get converted to valid values internally
+    // new CreateCredentialsTest({path: "options.publicKey.timeout", value: -1}).runTest("Bad timeout: negative", new TypeError());
+    // new CreateCredentialsTest({path: "options.publicKey.timeout", value: 4294967295 + 1}).runTest("Bad timeout: too big", new TypeError());
+
+    // timeout test
+    // XXX: this probably always passes with most mock authenticators unless
+    // some setup happens right here to make sure they don't return a credential
+    // right away. So... uhh... I guess test this with a real authenticator if you
+    // want to see if it really works.
+    promise_test(() => {
+        return new Promise((resolve, reject) => {
+            var args = {
+                options: {
+                    publicKey: {
+                        timeout: 1
+                    }
+                }
+            };
+
+            setTimeout(() => {
+                reject(new Error ("timed out"));
+            }, 1000);
+
+            createCredential(args).then((res) => {
+                resolve(res);
+            });
+        });
+    }, "ensure create credential times out");
+    // TODO: createCredential.timeout > 1s && setTimeout < 1s
+    // TODO: createCredential.timeout < 5s && setTimeout > 5s
+});
+
+/* JSHINT */
+/* globals standardSetup, CreateCredentialsTest, createCredential, promise_test */
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-badargs-rpid.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-badargs-rpid.https.html
new file mode 100644
index 0000000..9e8da4d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-badargs-rpid.https.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn credential.get() rpId Tests</title>
+<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
+<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+standardSetup(function() {
+    "use strict";
+
+    var credPromise = createCredential();
+
+    new GetCredentialsTest("options.publicKey.rpId", "")
+        .addCredential(credPromise)
+        .runTest("Bad rpId: empty string", "SecurityError");
+    new GetCredentialsTest("options.publicKey.rpId", null)
+        .addCredential(credPromise)
+        .runTest("Bad rpId: null", "SecurityError");
+    new GetCredentialsTest("options.publicKey.rpId", "invalid domain.com")
+        .addCredential(credPromise)
+        .runTest("Bad rpId: invalid domain (has space)", "SecurityError");
+    new GetCredentialsTest("options.publicKey.rpId", "-invaliddomain.com")
+        .addCredential(credPromise)
+        .runTest("Bad rpId: invalid domain (starts with dash)", "SecurityError");
+    new GetCredentialsTest("options.publicKey.rpId", "0invaliddomain.com")
+        .addCredential(credPromise)
+        .runTest("Bad rpId: invalid domain (starts with number)", "SecurityError");
+});
+
+/* JSHINT */
+/* globals standardSetup, GetCredentialsTest, createCredential */
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-badargs-userverification.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-badargs-userverification.https.html
new file mode 100644
index 0000000..6101540
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-badargs-userverification.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.get() user verification Tests</title>
+<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
+<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+standardSetup(function() {
+    "use strict";
+
+    var credPromise = createCredential();
+
+    // authenticatorSelection bad userVerification values
+    new GetCredentialsTest("options.publicKey.userVerification", "")
+        .addCredential(credPromise)
+        .runTest("Bad userVerification: empty string", new TypeError());
+    new GetCredentialsTest("options.publicKey.userVerification", {})
+        .addCredential(credPromise)
+        .runTest("Bad userVerification: empty object", new TypeError());
+    new GetCredentialsTest("options.publicKey.userVerification", "requiredshirtshoestshirt")
+        .addCredential(credPromise)
+        .runTest("Bad userVerification: bad value", new TypeError());
+    new GetCredentialsTest("options.publicKey.userVerification", null)
+        .addCredential(credPromise)
+        .runTest("Bad userVerification: null", new TypeError());
+    // XXX: assumes this is a mock authenticator the properly reports that it is not doing userVerfication
+    new GetCredentialsTest("options.publicKey.userVerification", "required")
+        .addCredential(credPromise)
+        .runTest("Bad userVerification: \"required\"", "NotAllowedError");
+});
+
+/* JSHINT */
+/* globals standardSetup, GetCredentialsTest, createCredential */
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-extensions.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-extensions.https.html
new file mode 100644
index 0000000..bad5ce45
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-extensions.https.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.get() extensions Tests</title>
+<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
+<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+standardSetup(function() {
+    "use strict";
+
+    var dummyExtension = {
+        foo: true,
+        bar: "yup"
+    };
+    var credPromise = createCredential();
+
+    // bad extension values
+    new GetCredentialsTest("options.publicKey.extensions", "hi mom")
+        .addCredential(credPromise)
+        .runTest("Bad extensions: extensions is string", new TypeError());
+    new GetCredentialsTest("options.publicKey.extensions", null)
+        .addCredential(credPromise)
+        .runTest("Bad extensions: extensions is null", new TypeError());
+    new GetCredentialsTest("options.publicKey.extensions", [])
+        .addCredential(credPromise)
+        .runTest("Bad extensions: extensions is empty Array", new TypeError());
+    new GetCredentialsTest("options.publicKey.extensions", new ArrayBuffer(0))
+        .addCredential(credPromise)
+        .runTest("Bad extensions: extensions is empty ArrayBuffer", new TypeError());
+    var badJson = '{"foo": true, "bar: "yup"}'; // missing quote after "bar"
+    new GetCredentialsTest("options.publicKey.extensions", {foo: badJson})
+        .addCredential(credPromise)
+        .runTest("Bad extensions: malformatted JSON", new TypeError());
+    new GetCredentialsTest("options.publicKey.extensions", {foo: dummyExtension})
+        .addCredential(credPromise)
+        .runTest("Bad extensions: JavaScript object", new TypeError());
+    var badExtId = {};
+    badExtId[createRandomString(65)] = dummyExtension;
+    new GetCredentialsTest("options.publicKey.extensions", {badExtId: dummyExtension})
+        .addCredential(credPromise)
+        .runTest("Bad extensions: extension ID too long", new TypeError());
+
+    // phony extensions
+    // TODO: not sure if this should pass or fail
+    // should be clarified as part of https://github.com/w3c/webauthn/pull/765
+    var randomExtId = {};
+    randomExtId[createRandomString(64)] = dummyExtension;
+    new GetCredentialsTest("options.publicKey.extensions", {foo: JSON.stringify(randomExtId)})
+        .addCredential(credPromise)
+        .runTest("extensions is a nonsensical JSON string");
+
+    // TODO
+    // defined extensions:
+    // * appid
+    // * txAuthSimple
+    // * txAuthGeneric
+    // * authnSel
+    // * exts
+    // * uvi
+    // * loc
+    // * uvm
+});
+
+/* JSHINT */
+/* globals standardSetup, GetCredentialsTest, createRandomString, createCredential */
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-passing.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-passing.https.html
index c7cf794..58b085f 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-passing.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-passing.https.html
@@ -11,11 +11,56 @@
 standardSetup(function() {
     "use strict";
 
-    // GetCredentialsTest passing tests
-    // new GetCredentialsTest().addCredential();
-    new GetCredentialsTest().addCredential().test();
+    var credPromise = createCredential();
+
+    // GetCredentialsTest with default args
+    new GetCredentialsTest()
+        .addCredential(credPromise)
+        .runTest("passing credentials.get() with default args");
+
+    // timeout
+    new GetCredentialsTest({path: "options.publicKey.timeout", value: undefined})
+        .addCredential(credPromise)
+        .runTest("passing credentials.create() with no timeout");
+
+    // rpId
+    new GetCredentialsTest({path: "options.publicKey.rpId", value: undefined})
+        .addCredential(credPromise)
+        .runTest("rpId undefined");
+    new GetCredentialsTest({path: "options.publicKey.rpId", value: window.location.host})
+        .addCredential(credPromise)
+        .runTest("passing credentials.get() with rpId (host and port)");
+    new GetCredentialsTest({path: "options.publicKey.rpId", value: window.location.hostname})
+        .addCredential(credPromise)
+        .runTest("passing credentials.get() with rpId (hostname)");
+
+    // allowCredentials
+    new GetCredentialsTest({path: "options.publicKey.allowCredentials", value: undefined})
+        .runTest("no credential specified");
+
+    // authnr selection user verification
+    new GetCredentialsTest({path: "options.publicKey.userVerification", value: undefined})
+        .addCredential(credPromise)
+        .runTest("authenticatorSelection userVerification undefined");
+    new GetCredentialsTest("options.publicKey.userVerification", "preferred")
+        .addCredential(credPromise)
+        .runTest("authenticatorSelection userVerification preferred");
+    new GetCredentialsTest("options.publicKey.userVerification", "discouraged")
+        .addCredential(credPromise)
+        .runTest("authenticatorSelection userVerification discouraged");
+
+    // good extension values
+    new GetCredentialsTest({path: "options.publicKey.extensions", value: undefined})
+        .addCredential(credPromise)
+        .runTest("extensions undefined");
+    new GetCredentialsTest("options.publicKey.extensions", {})
+        .addCredential(credPromise)
+        .runTest("extensions are empty object");
+    new GetCredentialsTest("options.publicKey.extensions", {foo: "", bar: "", bat: ""})
+        .addCredential(credPromise)
+        .runTest("extensions are dict of empty strings");
 });
 
 /* JSHINT */
-/* globals standardSetup, GetCredentialsTest */
+/* globals standardSetup, GetCredentialsTest, createCredential */
 </script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-timeout.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-timeout.https.html
new file mode 100644
index 0000000..8f5c2f32
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/getcredential-timeout.https.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.get() timeout Tests</title>
+<link rel="author" title="Adam Powers" href="mailto:adam@fidoalliance.org">
+<link rel="help" href="https://w3c.github.io/webauthn/#iface-credential">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+standardSetup(function() {
+    "use strict";
+
+    var credPromise = createCredential();
+
+    // bad timeout values
+    // TODO: there is some debate as to whether MAX_UNSIGNED_LONG + 1 and / or -1 should be disallowed since they get converted to valid values internally
+    // new GetCredentialsTest({path: "options.publicKey.timeout", value: -1})
+    //     .addCredential(credPromise)
+    //     .runTest("Bad timeout: negative", new TypeError());
+    // new GetCredentialsTest({path: "options.publicKey.timeout", value: 4294967295 + 1})
+    //     .addCredential(credPromise)
+    //     .runTest("Bad timeout: too big", new TypeError());
+
+    // timeout test
+    // XXX: this probably always passes with most mock authenticators unless
+    // some setup happens right here to make sure they don't return a credential
+    // right away. So... uhh... I guess test this with a real authenticator if you
+    // want to see if it really works.
+    var timer;
+    function startTimer() {
+        timer = setTimeout(() => {
+            throw new Error("Timer went off before timeout");
+        }, 1000);
+    }
+    function stopTimer() {
+        clearTimeout(timer);
+    }
+    new GetCredentialsTest({path: "options.publicKey.timeout", value: 1})
+        .addCredential(credPromise)
+        .beforeTest(startTimer)
+        .afterTest(stopTimer)
+        .runTest("ensure create credential times out");
+    // TODO: createCredential.timeout > 1s && setTimeout < 1s
+    // TODO: createCredential.timeout < 5s && setTimeout > 5s
+});
+
+/* JSHINT */
+/* globals standardSetup, GetCredentialsTest, createCredential */
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/helpers.js b/third_party/WebKit/LayoutTests/external/wpt/webauthn/helpers.js
index 11d0aee..568d3e2 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webauthn/helpers.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/helpers.js
@@ -1,5 +1,4 @@
-
-/* Useful constants for working with COSE key objects */
+// Useful constants for working with COSE key objects
 const cose_kty = 1;
 const cose_kty_ec2 = 2;
 const cose_alg = 3;
@@ -11,6 +10,117 @@
 const cose_crv_y = -3;
 
 /**
+ * These are the default arguments that will be passed to navigator.credentials.create()
+ * unless modified by a specific test case
+ */
+var createCredentialDefaultArgs = {
+    options: {
+        publicKey: {
+            // Relying Party:
+            rp: {
+                name: "Acme",
+                icon: "https://www.w3.org/StyleSheets/TR/2016/logos/W3C"
+            },
+
+            // User:
+            user: {
+                id: new Uint8Array(16), // Won't survive the copy, must be rebuilt
+                name: "john.p.smith@example.com",
+                displayName: "John P. Smith",
+                icon: "https://pics.acme.com/00/p/aBjjjpqPb.png"
+            },
+
+            pubKeyCredParams: [{
+                type: "public-key",
+                alg: cose_alg_ECDSA_w_SHA256,
+            }],
+
+            timeout: 60000, // 1 minute
+            excludeCredentials: [] // No excludeList
+        }
+    }
+};
+
+/**
+ * These are the default arguments that will be passed to navigator.credentials.get()
+ * unless modified by a specific test case
+ */
+var getCredentialDefaultArgs = {
+    options: {
+        publicKey: {
+            timeout: 60000
+            // allowCredentials: [newCredential]
+        }
+    }
+};
+
+function createCredential(opts) {
+    opts = opts || {};
+
+    // set the default options
+    var createArgs = cloneObject(createCredentialDefaultArgs);
+    let challengeBytes = new Uint8Array(16);
+    window.crypto.getRandomValues(challengeBytes);
+    createArgs.options.publicKey.challenge = challengeBytes;
+    createArgs.options.publicKey.user.id = new Uint8Array(16);
+
+    // change the defaults with any options that were passed in
+    extendObject (createArgs, opts);
+
+    // create the credential, return the Promise
+    return navigator.credentials.create(createArgs.options);
+}
+
+function createRandomString(len) {
+    var text = "";
+    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+    for(var i = 0; i < len; i++) {
+        text += possible.charAt(Math.floor(Math.random() * possible.length));
+    }
+    return text;
+}
+
+
+function ab2str(buf) {
+    return String.fromCharCode.apply(null, new Uint8Array(buf));
+}
+
+// Useful constants for working with attestation data
+const authenticator_data_user_present = 0x01;
+const authenticator_data_user_verified = 0x04;
+const authenticator_data_attested_cred_data = 0x40;
+const authenticator_data_extension_data = 0x80;
+
+function parseAuthenticatorData(buf) {
+    if (buf.byteLength < 37) {
+        throw new TypeError ("parseAuthenticatorData: buffer must be at least 37 bytes");
+    }
+
+    printHex ("authnrData", buf);
+
+    var authnrData = new DataView(buf);
+    var authnrDataObj = {};
+    authnrDataObj.length = buf.byteLength;
+
+    authnrDataObj.rpIdHash = new Uint8Array (buf.slice (0,32));
+    authnrDataObj.rawFlags = authnrData.getUint8(32);
+    authnrDataObj.counter = authnrData.getUint32(33, false);
+    authnrDataObj.rawCounter = [];
+    authnrDataObj.rawCounter[0] = authnrData.getUint8(33);
+    authnrDataObj.rawCounter[1] = authnrData.getUint8(34);
+    authnrDataObj.rawCounter[2] = authnrData.getUint8(35);
+    authnrDataObj.rawCounter[3] = authnrData.getUint8(36);
+    authnrDataObj.flags = {};
+
+    authnrDataObj.flags.userPresent = (authnrDataObj.rawFlags&authenticator_data_user_present)?true:false;
+    authnrDataObj.flags.userVerified = (authnrDataObj.rawFlags&authenticator_data_user_verified)?true:false;
+    authnrDataObj.flags.attestedCredentialData = (authnrDataObj.rawFlags&authenticator_data_attested_cred_data)?true:false;
+    authnrDataObj.flags.extensionData = (authnrDataObj.rawFlags&authenticator_data_extension_data)?true:false;
+
+    return authnrDataObj;
+}
+
+/**
  * TestCase
  *
  * A generic template for test cases
@@ -118,66 +228,127 @@
 
     /**
      * run the test function with the top-level properties of the test object applied as arguments
+     * expects the test to pass, and then validates the results
      */
-    test(desc) {
-        promise_test(() => {
-            return this.doIt()
-                .then((ret) => {
-                    // check the result
-                    this.validateRet(ret);
-                    return ret;
-                });
-        }, desc);
+    testPasses(desc) {
+        return this.doIt()
+            .then((ret) => {
+                // check the result
+                this.validateRet(ret);
+                return ret;
+            });
+    }
+
+    /**
+     * run the test function with the top-level properties of the test object applied as arguments
+     * expects the test to fail
+     */
+    testFails(t, testDesc, expectedErr) {
+        return promise_rejects(t, expectedErr, this.doIt(), "Expected bad parameters to fail");
+    }
+
+    /**
+     * Runs the test that's implemented by the class by calling the doIt() function
+     * @param  {String} desc                A description of the test being run
+     * @param  [Error|String] expectedErr   A string matching an error type, such as "SecurityError" or an object with a .name value that is an error type string
+     */
+    runTest(desc, expectedErr) {
+        promise_test((t) => {
+            return Promise.resolve().then(() => {
+                return this.testSetup();
+            }).then(() => {
+                if (expectedErr === undefined) {
+                    return this.testPasses(desc);
+                } else {
+                    return this.testFails(t, desc, expectedErr);
+                }
+            }).then((res) => {
+                return this.testTeardown(res);
+            })
+        }, desc)
+    }
+
+    /**
+     * called before runTest
+     * virtual method expected to be overridden by child class if needed
+     */
+    testSetup() {
+        if (this.beforeTestFn) {
+            this.beforeTestFn.call(this);
+        }
+
+        return Promise.resolve();
+    }
+
+    /**
+     * Adds a callback function that gets called in the TestCase context
+     * and within the testing process.
+     */
+    beforeTest(fn) {
+        if (typeof fn !== "function") {
+            throw new Error ("Tried to call non-function before test");
+        }
+
+        this.beforeTestFn = fn;
+
+        return this;
+    }
+
+    /**
+     * called after runTest
+     * virtual method expected to be overridden by child class if needed
+     */
+    testTeardown(res) {
+        if (this.afterTestFn) {
+            this.afterTestFn.call(this, res);
+        }
+
+        return Promise.resolve();
+    }
+
+    /**
+     * Adds a callback function that gets called in the TestCase context
+     * and within the testing process. Good for validating results.
+     */
+    afterTest(fn) {
+        if (typeof fn !== "function") {
+            throw new Error ("Tried to call non-function after test");
+        }
+
+        this.afterTestFn = fn;
+
+        return this;
     }
 
     /**
      * validates the value returned from the test function
+     * virtual method expected to be overridden by child class
      */
     validateRet() {
         throw new Error("Not implemented");
     }
-
-    /**
-     * calls doIt() with testObject() and expects it to fail with a TypeError()
-     */
-    testBadArgs(testDesc) {
-        promise_test(function(t) {
-            return promise_rejects(t, new TypeError(), this.doIt(), "Expected bad parameters to fail");
-        }.bind(this), testDesc);
-    }
 }
 
-var createCredentialDefaultArgs = {
-    options: {
-        publicKey: {
-            // Relying Party:
-            rp: {
-                name: "Acme"
-            },
-
-            // User:
-            user: {
-                id: new Uint8Array(), // Won't survive the copy, must be rebuilt
-                name: "john.p.smith@example.com",
-                displayName: "John P. Smith",
-                icon: "https://pics.acme.com/00/p/aBjjjpqPb.png"
-            },
-
-            pubKeyCredParams: [{
-                type: "public-key",
-                alg: cose_alg_ECDSA_w_SHA256,
-            }],
-
-            timeout: 60000, // 1 minute
-            excludeCredentials: [] // No excludeList
-        }
-    }
-};
-
 function cloneObject(o) {
     return JSON.parse(JSON.stringify(o));
 }
 
+function extendObject(dst, src) {
+    Object.keys(src).forEach(function(key) {
+        if (isSimpleObject(src[key])) {
+            extendObject (dst[key], src[key]);
+        } else {
+            dst[key] = src[key];
+        }
+    });
+}
+
+function isSimpleObject(o) {
+    return (typeof o === "object" &&
+        !Array.isArray(o) &&
+        !(o instanceof ArrayBuffer));
+}
+
 /**
  * CreateCredentialTest
  *
@@ -198,7 +369,7 @@
         window.crypto.getRandomValues(challengeBytes);
         this.testObject = cloneObject(createCredentialDefaultArgs);
         // cloneObject can't clone the BufferSource in user.id, so let's recreate it.
-        this.testObject.options.publicKey.user.id = new Uint8Array();
+        this.testObject.options.publicKey.user.id = new Uint8Array(16);
         this.testObject.options.publicKey.challenge = challengeBytes;
 
         // how to order the properties of testObject when passing them to makeCredential
@@ -235,15 +406,8 @@
         // default arguments
         let challengeBytes = new Uint8Array(16);
         window.crypto.getRandomValues(challengeBytes);
-        this.testObject = {
-            options: {
-                publicKey: {
-                    challenge: challengeBytes,
-                    // timeout: 60000,
-                    // allowCredentials: [newCredential]
-                }
-            }
-        };
+        this.testObject = cloneObject(getCredentialDefaultArgs);
+        this.testObject.options.publicKey.challenge = challengeBytes;
 
         // how to order the properties of testObject when passing them to makeCredential
         this.argOrder = [
@@ -266,33 +430,28 @@
         // if a Promise was passed in, add it to the list
         if (arg instanceof Promise) {
             this.credentialPromiseList.push(arg);
-            return;
+            return this;
         }
 
         // if a credential object was passed in, convert it to a Promise for consistency
         if (typeof arg === "object") {
             this.credentialPromiseList.push(Promise.resolve(arg));
-            return;
+            return this;
         }
 
-        // if a credential wasn't passed in, create one
-        let challengeBytes = new Uint8Array(16);
-        window.crypto.getRandomValues(challengeBytes);
-        var createArgs = cloneObject(createCredentialDefaultArgs);
-        createArgs.options.publicKey.challenge = challengeBytes;
-        createArgs.options.publicKey.user.id = new Uint8Array();
-        var p = navigator.credentials.create(createArgs.options);
+        // if no credential specified then create one
+        var p = createCredential();
         this.credentialPromiseList.push(p);
 
         return this;
     }
 
-    test() {
+    testSetup(desc) {
         if (!this.credentialPromiseList.length) {
             throw new Error("Attempting list without defining credential to test");
         }
 
-        Promise.all(this.credentialPromiseList)
+        return Promise.all(this.credentialPromiseList)
             .then((credList) => {
                 var idList = credList.map((cred) => {
                     return {
@@ -302,12 +461,15 @@
                     };
                 });
                 this.testObject.options.publicKey.allowCredentials = idList;
-                return super.test();
+                // return super.test(desc);
+            })
+            .catch((err) => {
+                throw Error(err);
             });
     }
 
     validateRet(ret) {
-        validatePublicKeyCredential (ret);
+        validatePublicKeyCredential(ret);
         validateAuthenticatorAssertionResponse(ret.response);
     }
 }
@@ -335,12 +497,16 @@
 function validateAuthenticatorAttestationResponse(attr) {
     // class
     assert_class_string(attr, "AuthenticatorAttestationResponse", "Expected credentials.create() to return instance of 'AuthenticatorAttestationResponse' class");
+
     // clientDataJSON
     assert_idl_attribute(attr, "clientDataJSON", "credentials.create() should return AuthenticatorAttestationResponse with clientDataJSON attribute");
     assert_readonly(attr, "clientDataJSON", "credentials.create() should return AuthenticatorAttestationResponse with readonly clientDataJSON attribute");
+    // TODO: clientDataJSON() and make sure fields are correct
+
     // attestationObject
     assert_idl_attribute(attr, "attestationObject", "credentials.create() should return AuthenticatorAttestationResponse with attestationObject attribute");
     assert_readonly(attr, "attestationObject", "credentials.create() should return AuthenticatorAttestationResponse with readonly attestationObject attribute");
+    // TODO: parseAuthenticatorData() and make sure flags are correct
 }
 
 /**
@@ -349,15 +515,20 @@
 function validateAuthenticatorAssertionResponse(assert) {
     // class
     assert_class_string(assert, "AuthenticatorAssertionResponse", "Expected credentials.create() to return instance of 'AuthenticatorAssertionResponse' class");
+
     // clientDataJSON
     assert_idl_attribute(assert, "clientDataJSON", "credentials.get() should return AuthenticatorAssertionResponse with clientDataJSON attribute");
     assert_readonly(assert, "clientDataJSON", "credentials.get() should return AuthenticatorAssertionResponse with readonly clientDataJSON attribute");
+    // TODO: clientDataJSON() and make sure fields are correct
+
     // signature
     assert_idl_attribute(assert, "signature", "credentials.get() should return AuthenticatorAssertionResponse with signature attribute");
     assert_readonly(assert, "signature", "credentials.get() should return AuthenticatorAssertionResponse with readonly signature attribute");
+
     // authenticatorData
     assert_idl_attribute(assert, "authenticatorData", "credentials.get() should return AuthenticatorAssertionResponse with authenticatorData attribute");
     assert_readonly(assert, "authenticatorData", "credentials.get() should return AuthenticatorAssertionResponse with readonly authenticatorData attribute");
+    // TODO: parseAuthenticatorData() and make sure flags are correct
 }
 
 //************* BEGIN DELETE AFTER 1/1/2018 *************** //
@@ -370,8 +541,8 @@
 // note that the polyfill only gets loaded if navigator.credentials create doesn't exist
 // AND if the polyfill script is found at the right path (i.e. - the polyfill is opt-in)
 function ensureInterface() {
-    if (typeof navigator.credentials.create !== "function") {
-        debug = console.log;
+    if (typeof navigator.credentials === "object" && typeof navigator.credentials.create !== "function") {
+        // debug = onsole.log;
 
         return loadJavaScript("/webauthn/webauthn-polyfill/webauthn-polyfill.js")
             .then(() => {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/securecontext.http.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/securecontext.http.html
index 82464bd8..5278695 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webauthn/securecontext.http.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/securecontext.http.html
@@ -17,7 +17,7 @@
     // Example 1
     // http://example.com/ opened in a top-level browsing context is not a secure context, as it was not delivered over an authenticated and encrypted channel.
     test (() => {
-        assert_false (typeof navigator.credentials.create === "function");
+        assert_false (typeof navigator.credentials === "object" && typeof navigator.credentials.create === "function");
     }, "no navigator.credentials.create in non-secure context");
 
     // Example 4: TODO
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webauthn/securecontext.https.html b/third_party/WebKit/LayoutTests/external/wpt/webauthn/securecontext.https.html
index 9810a7fe..6c9aabd1 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webauthn/securecontext.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webauthn/securecontext.https.html
@@ -17,7 +17,7 @@
     // Example 2
     // https://example.com/ opened in a top-level browsing context is a secure context, as it was delivered over an authenticated and encrypted channel.
     test (() => {
-        assert_true (typeof navigator.credentials.create === "function");
+        assert_true (typeof navigator.credentials === "object" && typeof navigator.credentials.create === "function");
     }, "navigator.credentials.create exists in secure context");
 
     // Example 3: TODO
diff --git a/third_party/WebKit/LayoutTests/fast/events/mouse-relative-position-zoomed.html b/third_party/WebKit/LayoutTests/fast/events/mouse-relative-position-zoomed.html
new file mode 100644
index 0000000..50a84a7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/events/mouse-relative-position-zoomed.html
@@ -0,0 +1,54 @@
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<style>
+
+html { position: absolute; }
+body {
+    margin: 0;
+    height: 2000px;
+}
+#container {
+    position: absolute;
+    left: 0;
+    top: 50px;
+    width: 700px;
+    height: 2000px;
+}
+#target {
+    margin-top: 150px;
+    margin-left: 100px;
+    width: 200px;
+    height: 100px;
+    background: silver;
+}
+
+</style>
+<div id="container">
+  <div id="target"></div>
+</div>
+<script>
+
+function run(zoom, scroll) {
+    internals.setZoomFactor(zoom);
+    scrollTo(0, scroll);
+    var result;
+    var target = document.querySelector("#target");
+    var rect = target.getBoundingClientRect();
+    target.addEventListener("click", (event) => {
+        result = [event.offsetX, event.offsetY, event.layerX, event.layerY];
+    });
+    eventSender.mouseMoveTo(
+        (rect.left + rect.width / 2) * zoom,
+        (rect.top + rect.height / 2) * zoom);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+    // layerX and layerY are relative to #container
+    assert_array_approx_equals(result, [100, 50, 200, 200], 5);
+}
+
+test(() => { run(1, 0); }, 'no zoom or scroll');
+test(() => { run(1, 100); }, 'scroll without zoom');
+test(() => { run(2, 0); }, 'zoom without scroll');
+test(() => { run(2, 100); }, 'zoom and scroll');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/canvas/fillrect_gradient-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/canvas/fillrect_gradient-expected.png
index 2a3a3c2..e27dc16 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/canvas/fillrect_gradient-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/canvas/fillrect_gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css3-text/css3-text-justify/text-justify-8bits-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css3-text/css3-text-justify/text-justify-8bits-expected.png
index ba08e614..1148090b 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css3-text/css3-text-justify/text-justify-8bits-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/css3-text/css3-text-justify/text-justify-8bits-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-nbsp-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-nbsp-expected.png
index 1504cbe..7d69836 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-nbsp-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/justify-nbsp-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/origin-signed-response.html b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/origin-signed-response.html
deleted file mode 100644
index ea2892f6..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/origin-signed-response.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE html>
-<title>Location of origin-signed HTTP response</title>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="../../resources/get-host-info.js?pipe=sub"></script>
-<body>
-<script>
-function with_iframe(url) {
-  return new Promise(function(resolve) {
-      const frame = document.createElement('iframe');
-      frame.src = url;
-      frame.onload = function() { resolve(frame); };
-      document.body.appendChild(frame);
-    });
-}
-
-promise_test(function(t) {
-  const url = 'resources/origin-signed-response-iframe.php';
-  return with_iframe(url)
-    .then((frame) => {
-      var channel = new MessageChannel();
-      var promise =
-          new Promise((resolve) => { channel.port1.onmessage = resolve; });
-      frame.contentWindow.postMessage(
-        {port: channel.port2}, '*', [channel.port2]);
-      return promise;
-    })
-    .then((event) => {
-      assert_equals(event.data.location, 'https://example.com/test.html');
-    });
-}, 'Location of origin-signed HTTP response');
-</script>
-</body>
-
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/origin-signed-response-iframe.php b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/origin-signed-response-iframe.php
deleted file mode 100644
index 178fac3..0000000
--- a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/origin-signed-response-iframe.php
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-$fp = fopen("origin-signed-response-iframe.htxg", "rb");
-header('Content-Type: application/http-exchange+cbor');
-header("HTTP/1.0 200 OK");
-fpassthru($fp);
-?>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-input-value-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-input-value-expected.txt
index bf09d5b..a8f2252 100644
--- a/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-input-value-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-input-value-expected.txt
@@ -41,7 +41,7 @@
       "childNodeIndexes": [
         4,
         5,
-        32
+        33
       ],
       "attributes": [
         {
@@ -65,11 +65,10 @@
       "childNodeIndexes": [
         6,
         7,
-        12,
         13,
-        16,
+        14,
         17,
-        19,
+        18,
         20,
         21,
         22,
@@ -79,7 +78,8 @@
         26,
         27,
         28,
-        31
+        29,
+        32
       ],
       "attributes": [
         {
@@ -101,19 +101,34 @@
       "nodeValue": "",
       "backendNodeId": "<number>",
       "childNodeIndexes": [
-        8,
-        10
+        8
       ],
       "layoutNodeIndex": 4
     },
     {
       "nodeType": 1,
+      "nodeName": "SLOT",
+      "nodeValue": "",
+      "backendNodeId": "<number>",
+      "childNodeIndexes": [
+        9,
+        11
+      ],
+      "attributes": [
+        {
+          "name": "name",
+          "value": "user-agent-custom-assign-slot"
+        }
+      ]
+    },
+    {
+      "nodeType": 1,
       "nodeName": "OPTION",
       "nodeValue": "",
       "optionSelected": true,
       "backendNodeId": "<number>",
       "childNodeIndexes": [
-        9
+        10
       ],
       "attributes": [
         {
@@ -135,7 +150,7 @@
       "optionSelected": false,
       "backendNodeId": "<number>",
       "childNodeIndexes": [
-        11
+        12
       ],
       "attributes": [
         {
@@ -164,7 +179,7 @@
       "inputValue": "InputValue",
       "backendNodeId": "<number>",
       "childNodeIndexes": [
-        14
+        15
       ],
       "attributes": [
         {
@@ -185,7 +200,7 @@
       "nodeValue": "",
       "backendNodeId": "<number>",
       "childNodeIndexes": [
-        15
+        16
       ],
       "layoutNodeIndex": 7,
       "isClickable": true
@@ -212,7 +227,7 @@
       "inputValue": "ButtonValue",
       "backendNodeId": "<number>",
       "childNodeIndexes": [
-        18
+        19
       ],
       "attributes": [
         {
@@ -380,7 +395,7 @@
       "textValue": "TextAreaValue",
       "backendNodeId": "<number>",
       "childNodeIndexes": [
-        29
+        30
       ],
       "attributes": [
         {
@@ -396,7 +411,7 @@
       "nodeValue": "",
       "backendNodeId": "<number>",
       "childNodeIndexes": [
-        30
+        31
       ],
       "layoutNodeIndex": 22,
       "isClickable": true
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/5099303-expected.png b/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/5099303-expected.png
deleted file mode 100644
index f98c26e..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/5099303-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/5099303-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/5099303-expected.txt
deleted file mode 100644
index 031653d..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/editing/deleting/5099303-expected.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {P} at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 756x19
-          text run at (0,0) width 756: "This tests for a bug where deleting from the start of a paragraph after a table would leave the caret in the wrong position."
-      LayoutBlockFlow {DIV} at (0,36) size 784x50
-        LayoutTable {TABLE} at (0,0) size 348x30 [border: (1px outset #808080)]
-          LayoutTableSection {TBODY} at (1,1) size 346x28
-            LayoutTableRow {TR} at (0,2) size 346x24
-              LayoutTableCell {TD} at (2,2) size 336x24 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
-                LayoutText {#text} at (2,2) size 332x19
-                  text run at (2,2) width 332: "The caret should be between these two parenthesis: ("
-              LayoutTableCell {TD} at (340,12) size 4x4 [border: (1px inset #808080)] [r=0 c=1 rs=1 cs=1]
-        LayoutBlockFlow {DIV} at (0,30) size 784x20
-          LayoutText {#text} at (0,0) size 9x19
-            text run at (0,0) width 9: ")."
-caret: position 0 of child 0 {#text} of child 1 {DIV} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-badargs-authnrselection.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-badargs-authnrselection.https-expected.txt
new file mode 100644
index 0000000..ffede7d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-badargs-authnrselection.https-expected.txt
@@ -0,0 +1,18 @@
+This is a testharness.js-based test.
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection is empty array assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+PASS Bad AuthenticatorSelectionCriteria: authenticatorSelection is empty string
+PASS Bad AuthenticatorSelectionCriteria: authenticatorSelection is string
+PASS Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is empty string
+PASS Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is empty object
+PASS Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is null
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment platform assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." that is not a DOMException NotAllowedError: property "code" is equal to 9, expected 0
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection residentKey true assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." that is not a DOMException NotAllowedError: property "code" is equal to 9, expected 0
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection residentKey is string assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification empty string assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification empty object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification bad value assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification required assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." that is not a DOMException NotAllowedError: property "code" is equal to 9, expected 0
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-badargs-challenge.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-badargs-challenge.https-expected.txt
new file mode 100644
index 0000000..13bd75df0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-badargs-challenge.https-expected.txt
@@ -0,0 +1,9 @@
+This is a testharness.js-based test.
+PASS Bad challenge: challenge missing
+PASS Bad challenge: challenge is string
+PASS Bad challenge: challenge is null
+PASS Bad challenge: challenge is empty object
+PASS Bad challenge: challenge is empty Array
+FAIL Bad challenge: challenge is empty ArrayBuffer assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt
new file mode 100644
index 0000000..8f9b546b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt
@@ -0,0 +1,19 @@
+This is a testharness.js-based test.
+PASS Bad rp: rp missing
+PASS Bad rp: rp is string
+PASS Bad rp: rp is empty object
+FAIL Bad rp: id is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "SecurityError: The relying party ID '[object Object]' is not a registrable domain suffix of, nor equal to 'https://web-platform.test:8444'." ("SecurityError") expected object "TypeError" ("TypeError")
+PASS Bad rp: id is null
+FAIL Bad rp: id is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." that is not a DOMException SecurityError: property "code" is equal to 9, expected 18
+PASS Bad rp: id is invalid domain (has space)
+PASS Bad rp: id is invalid domain (starts with dash)
+PASS Bad rp: id is invalid domain (starts with number)
+PASS rp missing name
+FAIL Bad rp: name is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad rp: name is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad rp: name is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad rp: icon is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad rp: icon is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad rp: icon is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-badargs-user.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-badargs-user.https-expected.txt
new file mode 100644
index 0000000..f4483f9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-badargs-user.https-expected.txt
@@ -0,0 +1,29 @@
+This is a testharness.js-based test.
+PASS Bad user: user missing
+PASS Bad user: user is string
+PASS Bad user: user is empty object
+PASS Bad user: id is undefined
+PASS Bad user: id is object
+PASS Bad user: id is null
+PASS Bad user: id is empty String
+PASS Bad user: id is empty Array
+FAIL Bad user: id is empty ArrayBuffer assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: ArrayBuffer id is too long (65 bytes) assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: Int16Array id is too long (66 bytes) assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: Int32Array id is too long (68 bytes) assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: Float32Array id is too long (68 bytes) assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: Float64Array id is too long (72 bytes) assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: id is too long (65 bytes) assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+PASS user missing name
+FAIL Bad user: name is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: name is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: name is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: icon is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: icon is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: icon is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+PASS Bad user: displayName is undefined
+FAIL Bad user: displayName is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: displayName is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: displayName is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-excludecredentials.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-excludecredentials.https-expected.txt
new file mode 100644
index 0000000..38e27530
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-excludecredentials.https-expected.txt
@@ -0,0 +1,9 @@
+This is a testharness.js-based test.
+PASS Bad excludeCredentials: string
+PASS Bad excludeCredentials: empty object
+FAIL excludeCredentials missing promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL excludeCredentials empty array promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL exclude existing credential promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL exclude random (non-existing) credential promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-extensions.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-extensions.https-expected.txt
new file mode 100644
index 0000000..e4804ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-extensions.https-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL Bad extensions: extensions is string assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad extensions: extensions is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad extensions: extensions is empty Array assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad extensions: extensions is empty ArrayBuffer assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad extensions: malformatted JSON assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad extensions: JavaScript object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad extensions: extension ID too long assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL extensions is a nonsensical JSON string promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-passing.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-passing.https-expected.txt
new file mode 100644
index 0000000..a02742bd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-passing.https-expected.txt
@@ -0,0 +1,41 @@
+This is a testharness.js-based test.
+FAIL passing credentials.create() with default arguments promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.create() with rpId (host and port) promise_test: Unhandled rejection with value: object "SecurityError: The relying party ID 'web-platform.test:8444' is not a registrable domain suffix of, nor equal to 'https://web-platform.test:8444'."
+FAIL passing credentials.create() with rpId (hostname) promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.create() without rp.icon promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL very short user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL max length user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Uint8Array user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Int8Array user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Int16Array user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Int32Array user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Float32Array user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL DataView user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.create() without user.icon promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Int16Array challenge promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Int32Array challenge promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Float32Array challenge promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Float64Array challenge promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL DataView challenge promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Absurdly large challenge promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Bad pubKeyCredParams: pubKeyCredParams is empty Array promise_test: Unhandled rejection with value: object "NotSupportedError: Required parameters missing in `options.publicKey`."
+FAIL EC256 pubKeyCredParams promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL SelectEC256 pubKeyCredParams from a list promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.create() with no timeout promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection is undefined promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection is empty object promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection default values promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection attachment undefined promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection residentKey undefined promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection residentKey false promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection userVerification undefined promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection userVerification discouraged promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL attestation parameter: attestation is "none" promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL attestation parameter: attestation is "indirect" promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL attestation parameter: attestation is "direct" promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL attestation parameter: attestation is undefined promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL extensions undefined promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL extensions are empty object promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL extensions are dict of empty strings promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-timeout.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-timeout.https-expected.txt
new file mode 100644
index 0000000..6b52a554
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/createcredential-timeout.https-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = The user agent does not implement a password store.
+FAIL ensure create credential times out promise_test: Unhandled rejection with value: object "Error: timed out"
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-badargs-rpid.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-badargs-rpid.https-expected.txt
new file mode 100644
index 0000000..764d364a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-badargs-rpid.https-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL Bad rpId: empty string promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad rpId: null promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad rpId: invalid domain (has space) promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad rpId: invalid domain (starts with dash) promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad rpId: invalid domain (starts with number) promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-badargs-userverification.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-badargs-userverification.https-expected.txt
new file mode 100644
index 0000000..c6dfa025
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-badargs-userverification.https-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL Bad userVerification: empty string promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad userVerification: empty object promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad userVerification: bad value promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad userVerification: null promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad userVerification: "required" promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-extensions.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-extensions.https-expected.txt
new file mode 100644
index 0000000..50dde17
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-extensions.https-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL Bad extensions: extensions is string promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad extensions: extensions is null promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad extensions: extensions is empty Array promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad extensions: extensions is empty ArrayBuffer promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad extensions: malformatted JSON promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad extensions: JavaScript object promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad extensions: extension ID too long promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL extensions is a nonsensical JSON string promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-passing.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-passing.https-expected.txt
new file mode 100644
index 0000000..7e13307
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-passing.https-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+FAIL passing credentials.get() with default args promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.create() with no timeout promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL rpId undefined promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.get() with rpId (host and port) promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.get() with rpId (hostname) promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL no credential specified promise_test: Unhandled rejection with value: object "Error: Attempting list without defining credential to test"
+FAIL authenticatorSelection userVerification undefined promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection userVerification preferred promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection userVerification discouraged promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL extensions undefined promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL extensions are empty object promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL extensions are dict of empty strings promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-timeout.https-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-timeout.https-expected.txt
new file mode 100644
index 0000000..f7553fe
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/getcredential-timeout.https-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL ensure create credential times out promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/securecontext.http-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/securecontext.http-expected.txt
new file mode 100644
index 0000000..21f6fd77
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/external/wpt/webauthn/securecontext.http-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+PASS no navigator.credentials.create in non-secure context
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/5099303-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/5099303-expected.png
deleted file mode 100644
index a78289a..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/5099303-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/5099303-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/5099303-expected.txt
deleted file mode 100644
index cd42c67..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/deleting/5099303-expected.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {P} at (0,0) size 784x18
-        LayoutText {#text} at (0,0) size 773x18
-          text run at (0,0) width 773: "This tests for a bug where deleting from the start of a paragraph after a table would leave the caret in the wrong position."
-      LayoutBlockFlow {DIV} at (0,34) size 784x46
-        LayoutTable {TABLE} at (0,0) size 354x28 [border: (1px outset #808080)]
-          LayoutTableSection {TBODY} at (1,1) size 352x26
-            LayoutTableRow {TR} at (0,2) size 352x22
-              LayoutTableCell {TD} at (2,2) size 342x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
-                LayoutText {#text} at (2,2) size 338x18
-                  text run at (2,2) width 338: "The caret should be between these two parenthesis: ("
-              LayoutTableCell {TD} at (346,11) size 4x4 [border: (1px inset #808080)] [r=0 c=1 rs=1 cs=1]
-        LayoutBlockFlow {DIV} at (0,28) size 784x18
-          LayoutText {#text} at (0,0) size 10x18
-            text run at (0,0) width 10: ")."
-caret: position 0 of child 0 {#text} of child 1 {DIV} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/deleting/5099303-expected.png b/third_party/WebKit/LayoutTests/platform/win/editing/deleting/5099303-expected.png
deleted file mode 100644
index 85b51d14..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/editing/deleting/5099303-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/deleting/5099303-expected.txt b/third_party/WebKit/LayoutTests/platform/win/editing/deleting/5099303-expected.txt
deleted file mode 100644
index 658b07c..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/editing/deleting/5099303-expected.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {P} at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 721x19
-          text run at (0,0) width 721: "This tests for a bug where deleting from the start of a paragraph after a table would leave the caret in the wrong position."
-      LayoutBlockFlow {DIV} at (0,36) size 784x50
-        LayoutTable {TABLE} at (0,0) size 335x30 [border: (1px outset #808080)]
-          LayoutTableSection {TBODY} at (1,1) size 333x28
-            LayoutTableRow {TR} at (0,2) size 333x24
-              LayoutTableCell {TD} at (2,2) size 323x24 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
-                LayoutText {#text} at (2,2) size 319x19
-                  text run at (2,2) width 319: "The caret should be between these two parenthesis: ("
-              LayoutTableCell {TD} at (327,12) size 4x4 [border: (1px inset #808080)] [r=0 c=1 rs=1 cs=1]
-        LayoutBlockFlow {DIV} at (0,30) size 784x20
-          LayoutText {#text} at (0,0) size 9x19
-            text run at (0,0) width 9: ")."
-caret: position 0 of child 0 {#text} of child 1 {DIV} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-badargs-authnrselection.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-badargs-authnrselection.https-expected.txt
new file mode 100644
index 0000000..ffede7d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-badargs-authnrselection.https-expected.txt
@@ -0,0 +1,18 @@
+This is a testharness.js-based test.
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection is empty array assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+PASS Bad AuthenticatorSelectionCriteria: authenticatorSelection is empty string
+PASS Bad AuthenticatorSelectionCriteria: authenticatorSelection is string
+PASS Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is empty string
+PASS Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is empty object
+PASS Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment is null
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection attachment platform assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." that is not a DOMException NotAllowedError: property "code" is equal to 9, expected 0
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection residentKey true assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." that is not a DOMException NotAllowedError: property "code" is equal to 9, expected 0
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection residentKey is string assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification empty string assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification empty object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification bad value assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad AuthenticatorSelectionCriteria: authenticatorSelection userVerification required assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." that is not a DOMException NotAllowedError: property "code" is equal to 9, expected 0
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-badargs-challenge.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-badargs-challenge.https-expected.txt
new file mode 100644
index 0000000..13bd75df0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-badargs-challenge.https-expected.txt
@@ -0,0 +1,9 @@
+This is a testharness.js-based test.
+PASS Bad challenge: challenge missing
+PASS Bad challenge: challenge is string
+PASS Bad challenge: challenge is null
+PASS Bad challenge: challenge is empty object
+PASS Bad challenge: challenge is empty Array
+FAIL Bad challenge: challenge is empty ArrayBuffer assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt
new file mode 100644
index 0000000..8f9b546b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt
@@ -0,0 +1,19 @@
+This is a testharness.js-based test.
+PASS Bad rp: rp missing
+PASS Bad rp: rp is string
+PASS Bad rp: rp is empty object
+FAIL Bad rp: id is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "SecurityError: The relying party ID '[object Object]' is not a registrable domain suffix of, nor equal to 'https://web-platform.test:8444'." ("SecurityError") expected object "TypeError" ("TypeError")
+PASS Bad rp: id is null
+FAIL Bad rp: id is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." that is not a DOMException SecurityError: property "code" is equal to 9, expected 18
+PASS Bad rp: id is invalid domain (has space)
+PASS Bad rp: id is invalid domain (starts with dash)
+PASS Bad rp: id is invalid domain (starts with number)
+PASS rp missing name
+FAIL Bad rp: name is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad rp: name is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad rp: name is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad rp: icon is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad rp: icon is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad rp: icon is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-badargs-user.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-badargs-user.https-expected.txt
new file mode 100644
index 0000000..f4483f9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-badargs-user.https-expected.txt
@@ -0,0 +1,29 @@
+This is a testharness.js-based test.
+PASS Bad user: user missing
+PASS Bad user: user is string
+PASS Bad user: user is empty object
+PASS Bad user: id is undefined
+PASS Bad user: id is object
+PASS Bad user: id is null
+PASS Bad user: id is empty String
+PASS Bad user: id is empty Array
+FAIL Bad user: id is empty ArrayBuffer assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: ArrayBuffer id is too long (65 bytes) assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: Int16Array id is too long (66 bytes) assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: Int32Array id is too long (68 bytes) assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: Float32Array id is too long (68 bytes) assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: Float64Array id is too long (72 bytes) assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: id is too long (65 bytes) assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+PASS user missing name
+FAIL Bad user: name is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: name is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: name is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: icon is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: icon is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: icon is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+PASS Bad user: displayName is undefined
+FAIL Bad user: displayName is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: displayName is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad user: displayName is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-excludecredentials.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-excludecredentials.https-expected.txt
new file mode 100644
index 0000000..38e27530
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-excludecredentials.https-expected.txt
@@ -0,0 +1,9 @@
+This is a testharness.js-based test.
+PASS Bad excludeCredentials: string
+PASS Bad excludeCredentials: empty object
+FAIL excludeCredentials missing promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL excludeCredentials empty array promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL exclude existing credential promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL exclude random (non-existing) credential promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-extensions.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-extensions.https-expected.txt
new file mode 100644
index 0000000..e4804ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-extensions.https-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL Bad extensions: extensions is string assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad extensions: extensions is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad extensions: extensions is empty Array assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad extensions: extensions is empty ArrayBuffer assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad extensions: malformatted JSON assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad extensions: JavaScript object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL Bad extensions: extension ID too long assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError")
+FAIL extensions is a nonsensical JSON string promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-passing.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-passing.https-expected.txt
new file mode 100644
index 0000000..a02742bd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-passing.https-expected.txt
@@ -0,0 +1,41 @@
+This is a testharness.js-based test.
+FAIL passing credentials.create() with default arguments promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.create() with rpId (host and port) promise_test: Unhandled rejection with value: object "SecurityError: The relying party ID 'web-platform.test:8444' is not a registrable domain suffix of, nor equal to 'https://web-platform.test:8444'."
+FAIL passing credentials.create() with rpId (hostname) promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.create() without rp.icon promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL very short user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL max length user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Uint8Array user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Int8Array user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Int16Array user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Int32Array user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Float32Array user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL DataView user id promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.create() without user.icon promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Int16Array challenge promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Int32Array challenge promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Float32Array challenge promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Float64Array challenge promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL DataView challenge promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Absurdly large challenge promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL Bad pubKeyCredParams: pubKeyCredParams is empty Array promise_test: Unhandled rejection with value: object "NotSupportedError: Required parameters missing in `options.publicKey`."
+FAIL EC256 pubKeyCredParams promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL SelectEC256 pubKeyCredParams from a list promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.create() with no timeout promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection is undefined promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection is empty object promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection default values promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection attachment undefined promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection residentKey undefined promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection residentKey false promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection userVerification undefined promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection userVerification discouraged promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL attestation parameter: attestation is "none" promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL attestation parameter: attestation is "indirect" promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL attestation parameter: attestation is "direct" promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL attestation parameter: attestation is undefined promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL extensions undefined promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL extensions are empty object promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+FAIL extensions are dict of empty strings promise_test: Unhandled rejection with value: object "NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-timeout.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-timeout.https-expected.txt
new file mode 100644
index 0000000..6b52a554
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/createcredential-timeout.https-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = The user agent does not implement a password store.
+FAIL ensure create credential times out promise_test: Unhandled rejection with value: object "Error: timed out"
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-badargs-rpid.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-badargs-rpid.https-expected.txt
new file mode 100644
index 0000000..764d364a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-badargs-rpid.https-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL Bad rpId: empty string promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad rpId: null promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad rpId: invalid domain (has space) promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad rpId: invalid domain (starts with dash) promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad rpId: invalid domain (starts with number) promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-badargs-userverification.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-badargs-userverification.https-expected.txt
new file mode 100644
index 0000000..c6dfa025
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-badargs-userverification.https-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL Bad userVerification: empty string promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad userVerification: empty object promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad userVerification: bad value promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad userVerification: null promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad userVerification: "required" promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-extensions.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-extensions.https-expected.txt
new file mode 100644
index 0000000..50dde17
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-extensions.https-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL Bad extensions: extensions is string promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad extensions: extensions is null promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad extensions: extensions is empty Array promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad extensions: extensions is empty ArrayBuffer promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad extensions: malformatted JSON promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad extensions: JavaScript object promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL Bad extensions: extension ID too long promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL extensions is a nonsensical JSON string promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-passing.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-passing.https-expected.txt
new file mode 100644
index 0000000..7e13307
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-passing.https-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+FAIL passing credentials.get() with default args promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.create() with no timeout promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL rpId undefined promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.get() with rpId (host and port) promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL passing credentials.get() with rpId (hostname) promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL no credential specified promise_test: Unhandled rejection with value: object "Error: Attempting list without defining credential to test"
+FAIL authenticatorSelection userVerification undefined promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection userVerification preferred promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL authenticatorSelection userVerification discouraged promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL extensions undefined promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL extensions are empty object promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+FAIL extensions are dict of empty strings promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-timeout.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-timeout.https-expected.txt
new file mode 100644
index 0000000..f7553fe
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/getcredential-timeout.https-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL ensure create credential times out promise_test: Unhandled rejection with value: object "Error: NotSupportedError: The user agent does not implement a password store."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/securecontext.http-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/securecontext.http-expected.txt
new file mode 100644
index 0000000..21f6fd77
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/webauthn/securecontext.http-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+PASS no navigator.credentials.create in non-secure context
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/background-image.html b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/background-image.html
index fff4a87a..572f837 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/background-image.html
+++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/background-image.html
@@ -22,7 +22,8 @@
     new CSSURLImageValue(window.location.href + '/resources/1x1-green.jpg'),
     new CSSURLImageValue(window.location.href)
   ],
-  supportsMultiple: false,
+  supportsMultiple: true,
+  separator: ' ',
   invalidObjects: [new CSSUnitValue(4, 'px')]
 });
 </script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/property-suite.js b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/property-suite.js
index 17247ea..4091b92 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/property-suite.js
+++ b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/property-suite.js
@@ -12,6 +12,8 @@
  *       the same as something else in Typed OM.
  *   supportsMultiple: boolean; whether the property supports a list of
  *       properties,
+ *   separator: string; for list-valued properties, what string is used to
+ *       separate each item in the list. Defaults to ', '.
  *   invalidObjects: array of CSSStyleValue instances that are invalid for the
  *       property
  * }
@@ -66,10 +68,11 @@
   runDeletionTests(config.property, validObject, element);
   runGetPropertiesTests(config.property, validObject, element);
   if (config.supportsMultiple) {
+    const separator = config.separator || ', ';
     runSequenceSetterTests(
-        config.property, validObject, invalidObjects[0], element);
+        config.property, validObject, invalidObjects[0], element, separator);
     runAppendTests(
-        config.property, validObject, invalidObjects[0], element);
+        config.property, validObject, invalidObjects[0], element, separator);
   } else {
     runMultipleValuesNotSupportedTests(
         config.property, validObject, element);
@@ -150,17 +153,17 @@
 }
 
 function runSequenceSetterTests(
-    propertyName, validObject, invalidObject, element) {
+    propertyName, validObject, invalidObject, element, separator) {
   test(function() {
     element.style = '';
     element.attributeStyleMap.set(propertyName, validObject, validObject);
     assert_equals(
-        element.style[propertyName], validObject.toString() + ', ' +
+        element.style[propertyName], validObject.toString() + separator +
         validObject.toString());
     // Force a style recalc to check for crashes in style recalculation.
     getComputedStyle(element)[propertyName];
     assert_equals(
-        element.style[propertyName], validObject.toString() + ', ' +
+        element.style[propertyName], validObject.toString() + separator +
         validObject.toString());
   }, 'Set ' + propertyName + ' to a sequence');
 
@@ -172,7 +175,7 @@
 }
 
 function runAppendTests(
-    propertyName, validObject, invalidObject, element) {
+    propertyName, validObject, invalidObject, element, separator) {
   test(function() {
     element.style = '';
 
@@ -181,12 +184,12 @@
 
     element.attributeStyleMap.append(propertyName, validObject);
     assert_equals(
-        element.style[propertyName], validObject.toString() + ', ' +
+        element.style[propertyName], validObject.toString() + separator +
         validObject.toString());
     // Force a style recalc to check for crashes in style recalculation.
     getComputedStyle(element)[propertyName];
     assert_equals(
-        element.style[propertyName], validObject.toString() + ', ' +
+        element.style[propertyName], validObject.toString() + separator +
         validObject.toString());
   }, 'Appending a ' + validObject.constructor.name + ' to ' + propertyName);
 
@@ -195,12 +198,12 @@
 
     element.attributeStyleMap.append(propertyName, validObject, validObject);
     assert_equals(
-        element.style[propertyName], validObject.toString() + ', ' +
+        element.style[propertyName], validObject.toString() + separator +
         validObject.toString());
     // Force a style recalc to check for crashes in style recalculation.
     getComputedStyle(element)[propertyName];
     assert_equals(
-        element.style[propertyName], validObject.toString() + ', ' +
+        element.style[propertyName], validObject.toString() + separator +
         validObject.toString());
   }, 'Append a sequence to ' + propertyName);
 
diff --git a/third_party/WebKit/LayoutTests/virtual/htxg-with-network-service/http/tests/loading/htxg/README.txt b/third_party/WebKit/LayoutTests/virtual/htxg-with-network-service/http/tests/loading/htxg/README.txt
deleted file mode 100644
index 214b437..0000000
--- a/third_party/WebKit/LayoutTests/virtual/htxg-with-network-service/http/tests/loading/htxg/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This directory is for testing the SignedHTTPExchange feature with the Network
-Service.
diff --git a/third_party/WebKit/LayoutTests/virtual/htxg/http/tests/loading/htxg/README.txt b/third_party/WebKit/LayoutTests/virtual/htxg/http/tests/loading/htxg/README.txt
deleted file mode 100644
index 815a30d..0000000
--- a/third_party/WebKit/LayoutTests/virtual/htxg/http/tests/loading/htxg/README.txt
+++ /dev/null
@@ -1 +0,0 @@
-This directory is for testing the SignedHTTPExchange feature.
diff --git a/third_party/WebKit/LayoutTests/virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/README.txt b/third_party/WebKit/LayoutTests/virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/README.txt
new file mode 100644
index 0000000..31efed8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/README.txt
@@ -0,0 +1,3 @@
+This directory is for testing NavigationMojoResponse with ServiceWorker.
+TODO(arthursonzogni): Remove this once it is used by default.
+See https://crbug.com/805851.
diff --git a/third_party/WebKit/LayoutTests/virtual/navigation-mojo-response/http/tests/serviceworker/README.txt b/third_party/WebKit/LayoutTests/virtual/navigation-mojo-response/http/tests/serviceworker/README.txt
new file mode 100644
index 0000000..31efed8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/navigation-mojo-response/http/tests/serviceworker/README.txt
@@ -0,0 +1,3 @@
+This directory is for testing NavigationMojoResponse with ServiceWorker.
+TODO(arthursonzogni): Remove this once it is used by default.
+See https://crbug.com/805851.
diff --git a/third_party/WebKit/LayoutTests/webaudio/BiquadFilter/biquad-basic.html b/third_party/WebKit/LayoutTests/webaudio/BiquadFilter/biquad-basic.html
new file mode 100644
index 0000000..ab2a9eb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/webaudio/BiquadFilter/biquad-basic.html
@@ -0,0 +1,134 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>
+      Test Basic BiquadFilterNode Properties
+    </title>
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script>
+    <script src="../resources/audit-util.js"></script>
+    <script src="../resources/audit.js"></script>
+  </head>
+  <body>
+    <script id="layout-test-code">
+      let sampleRate = 48000;
+      let testFrames = 100;
+
+      // Global context that can be used by the individual tasks. It must be
+      // defined by the initialize task.
+      let context;
+
+      let audit = Audit.createTaskRunner();
+
+      audit.define('initialize', (task, should) => {
+        should(() => {
+          context = new OfflineAudioContext(1, testFrames, sampleRate);
+        }, 'Initialize context for testing').notThrow();
+        task.done();
+      });
+
+      audit.define('existence', (task, should) => {
+        should(context.createBiquadFilter, 'context.createBiquadFilter')
+            .exist();
+        task.done();
+      });
+
+      audit.define('parameters', (task, should) => {
+        // Create a really simple IIR filter. Doesn't much matter what.
+        let coef = Float32Array.from([1]);
+
+        let f = context.createBiquadFilter(coef, coef);
+
+        should(f.numberOfInputs, 'numberOfInputs').beEqualTo(1);
+        should(f.numberOfOutputs, 'numberOfOutputs').beEqualTo(1);
+        should(f.channelCountMode, 'channelCountMode').beEqualTo('max');
+        should(f.channelInterpretation, 'channelInterpretation')
+            .beEqualTo('speakers');
+
+        task.done();
+      });
+
+      audit.define('exceptions-createBiquadFilter', (task, should) => {
+        should(function() {
+          // Two args are required.
+          context.createBiquadFilter();
+        }, 'createBiquadFilter()').notThrow();
+
+        task.done();
+      });
+
+      audit.define('exceptions-getFrequencyData', (task, should) => {
+        // Create a really simple IIR filter. Doesn't much matter what.
+        let coef = Float32Array.from([1]);
+
+        let f = context.createBiquadFilter(coef, coef);
+
+        should(
+            function() {
+              // frequencyHz can't be null.
+              f.getFrequencyResponse(
+                  null, new Float32Array(1), new Float32Array(1));
+            },
+            'getFrequencyResponse(' +
+                'null, ' +
+                'new Float32Array(1), ' +
+                'new Float32Array(1))')
+            .throw('TypeError');
+
+        should(
+            function() {
+              // magResponse can't be null.
+              f.getFrequencyResponse(
+                  new Float32Array(1), null, new Float32Array(1));
+            },
+            'getFrequencyResponse(' +
+                'new Float32Array(1), ' +
+                'null, ' +
+                'new Float32Array(1))')
+            .throw('TypeError');
+
+        should(
+            function() {
+              // phaseResponse can't be null.
+              f.getFrequencyResponse(
+                  new Float32Array(1), new Float32Array(1), null);
+            },
+            'getFrequencyResponse(' +
+                'new Float32Array(1), ' +
+                'new Float32Array(1), ' +
+                'null)')
+            .throw('TypeError');
+
+        should(
+            function() {
+              // magResponse array must the same length as frequencyHz
+              f.getFrequencyResponse(
+                  new Float32Array(10), new Float32Array(1),
+                  new Float32Array(20));
+            },
+            'getFrequencyResponse(' +
+                'new Float32Array(10), ' +
+                'new Float32Array(1), ' +
+                'new Float32Array(20))')
+            .throw('InvalidAccessError');
+
+        should(
+            function() {
+              // phaseResponse array must be the same length as frequencyHz
+              f.getFrequencyResponse(
+                  new Float32Array(10), new Float32Array(20),
+                  new Float32Array(1));
+            },
+            'getFrequencyResponse(' +
+                'new Float32Array(10), ' +
+                'new Float32Array(20), ' +
+                'new Float32Array(1))')
+            .throw('InvalidAccessError');
+
+        task.done();
+      });
+
+      audit.run();
+    </script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/IIRFilter/iirfilter-basic.html b/third_party/WebKit/LayoutTests/webaudio/IIRFilter/iirfilter-basic.html
index b14cf27..b9a97f37 100644
--- a/third_party/WebKit/LayoutTests/webaudio/IIRFilter/iirfilter-basic.html
+++ b/third_party/WebKit/LayoutTests/webaudio/IIRFilter/iirfilter-basic.html
@@ -177,34 +177,23 @@
 
         should(
             function() {
-              // magResponse array must be longer than frequencyHz
+              // magResponse array must the same length as frequencyHz
               f.getFrequencyResponse(
                   new Float32Array(10), new Float32Array(1),
                   new Float32Array(20));
             },
             'getFrequencyResponse(new Float32Array(10), new Float32Array(1), new Float32Array(20))')
-            .throw('NotSupportedError');
+            .throw('InvalidAccessError');
 
         should(
             function() {
-              // phaseResponse array must be longer than frequencyHz
+              // phaseResponse array must be the same length as frequencyHz
               f.getFrequencyResponse(
                   new Float32Array(10), new Float32Array(20),
                   new Float32Array(1));
             },
             'getFrequencyResponse(new Float32Array(10), new Float32Array(20), new Float32Array(1))')
-            .throw('NotSupportedError');
-
-        should(
-            function() {
-              // Ok if magResponse and phaseResponse have different lengths as
-              // long as they're longer than frequencyHz.
-              f.getFrequencyResponse(
-                  new Float32Array(10), new Float32Array(20),
-                  new Float32Array(30));
-            },
-            'getFrequencyResponse(new Float32Array(10), new Float32Array(20), new Float32Array(30))')
-            .notThrow();
+            .throw('InvalidAccessError');
 
         task.done();
       });
diff --git a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp
index 2739157..afbc4d4 100644
--- a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp
@@ -121,7 +121,7 @@
       WebThreadCreationParams(WebThreadType::kTestThread)
           .SetThreadName("DOMWrapperWorld test thread"));
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner =
-      Platform::Current()->CurrentThread()->GetWebTaskRunner();
+      Platform::Current()->CurrentThread()->GetTaskRunner();
   thread->BackingThread().PostTask(
       FROM_HERE,
       CrossThreadBind(&WorkerThreadFunc, CrossThreadUnretained(thread.get()),
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.cpp
index 19b34b5..2c5ce53 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.cpp
@@ -38,7 +38,7 @@
   MutexLocker locker(mutex_);
   DCHECK(!running_task_);
   running_task_ = true;
-  PostCrossThreadTask(*PlatformThread().GetWebTaskRunner(), FROM_HERE,
+  PostCrossThreadTask(*PlatformThread().GetTaskRunner(), FROM_HERE,
                       std::move(task));
 }
 
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_types.py b/third_party/WebKit/Source/bindings/scripts/v8_types.py
index c8e41511..07855489 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_types.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_types.py
@@ -789,7 +789,7 @@
         'cpp_type': this_cpp_type,
         'cpp_name': variable_name,
         'declare_variable': declare_variable,
-        'return_expression': bailout_return_value,
+        'return_expression': return_expression,
         'set_expression': set_expression,
     }
 
diff --git a/third_party/WebKit/Source/controller/BUILD.gn b/third_party/WebKit/Source/controller/BUILD.gn
index cf5e741e..67afa8b0 100644
--- a/third_party/WebKit/Source/controller/BUILD.gn
+++ b/third_party/WebKit/Source/controller/BUILD.gn
@@ -73,6 +73,7 @@
   ]
 
   if (is_android) {
+    enable_multidex = true
     deps += [
       "//base:base_java",
       "//content/public/android:content_java",
diff --git a/third_party/WebKit/Source/controller/BlinkInitializer.cpp b/third_party/WebKit/Source/controller/BlinkInitializer.cpp
index 914358d1..010c250 100644
--- a/third_party/WebKit/Source/controller/BlinkInitializer.cpp
+++ b/third_party/WebKit/Source/controller/BlinkInitializer.cpp
@@ -121,9 +121,9 @@
     service_manager::BinderRegistry& registry) {
   ModulesInitializer::RegisterInterfaces(registry);
   WebThread* main_thread = Platform::Current()->MainThread();
-  // GetSingleThreadTaskRunner() uses GetWebTaskRunner() internally.
+  // GetSingleThreadTaskRunner() uses GetTaskRunner() internally.
   // crbug.com/781664
-  if (!main_thread || !main_thread->GetWebTaskRunner())
+  if (!main_thread || !main_thread->GetTaskRunner())
     return;
 
   registry.AddInterface(
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index c5716d6..f4f33fc2a 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -749,6 +749,7 @@
       interpolable: true,
       keywords: ["auto", "none"],
       typedom_types: ["Image"],
+      separator: " ",
       custom_apply_functions_all: true,
     },
     {
diff --git a/third_party/WebKit/Source/core/css/cssom/StylePropertyMapReadOnly.cpp b/third_party/WebKit/Source/core/css/cssom/StylePropertyMapReadOnly.cpp
index e5ab35c..c577686 100644
--- a/third_party/WebKit/Source/core/css/cssom/StylePropertyMapReadOnly.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/StylePropertyMapReadOnly.cpp
@@ -60,8 +60,26 @@
 
 CSSStyleValue* StylePropertyMapReadOnly::get(const String& property_name,
                                              ExceptionState& exception_state) {
-  CSSStyleValueVector style_vector = getAll(property_name, exception_state);
-  return style_vector.IsEmpty() ? nullptr : style_vector[0];
+  const CSSPropertyID property_id = cssPropertyID(property_name);
+  if (property_id == CSSPropertyInvalid) {
+    exception_state.ThrowTypeError("Invalid propertyName: " + property_name);
+    return nullptr;
+  }
+
+  DCHECK(isValidCSSPropertyID(property_id));
+  const CSSValue* value = (property_id == CSSPropertyVariable)
+                              ? GetCustomProperty(AtomicString(property_name))
+                              : GetProperty(property_id);
+  if (!value)
+    return nullptr;
+
+  if (CSSProperty::Get(property_id).IsRepeated()) {
+    CSSStyleValueVector values =
+        StyleValueFactory::CssValueToStyleValueVector(property_id, *value);
+    return values.IsEmpty() ? nullptr : values[0];
+  }
+
+  return StyleValueFactory::CssValueToStyleValue(property_id, *value);
 }
 
 CSSStyleValueVector StylePropertyMapReadOnly::getAll(
diff --git a/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.cpp b/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.cpp
index f6589fd..032efe3 100644
--- a/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.cpp
@@ -27,20 +27,6 @@
 
 namespace {
 
-CSSStyleValue* CreateStyleValueWithPropertyInternal(CSSPropertyID property_id,
-                                                    const CSSValue& value) {
-  switch (property_id) {
-    case CSSPropertyTransform:
-      return CSSTransformValue::FromCSSValue(value);
-    case CSSPropertyObjectPosition:
-      return CSSPositionValue::FromCSSValue(value);
-    default:
-      // TODO(meade): Implement other properties.
-      break;
-  }
-  return nullptr;
-}
-
 CSSStyleValue* CreateStyleValue(const CSSValue& value) {
   if (value.IsIdentifierValue() || value.IsCustomIdentValue())
     return CSSKeywordValue::FromCSSValue(value);
@@ -60,6 +46,34 @@
   return nullptr;
 }
 
+CSSStyleValue* CreateStyleValueWithPropertyInternal(CSSPropertyID property_id,
+                                                    const CSSValue& value) {
+  // FIXME: We should enforce/document what the possible CSSValue structures
+  // are for each property.
+  switch (property_id) {
+    case CSSPropertyTransform:
+      return CSSTransformValue::FromCSSValue(value);
+    case CSSPropertyObjectPosition:
+      return CSSPositionValue::FromCSSValue(value);
+    case CSSPropertyAlignItems: {
+      // Computed align-items is a ValueList of either length 1 or 2.
+      // Typed OM level 1 can't support "pairs", so we only return
+      // a Typed OM object for length 1 lists.
+      if (value.IsValueList()) {
+        const auto& value_list = ToCSSValueList(value);
+        if (value_list.length() != 1U)
+          return nullptr;
+        return CreateStyleValue(value_list.Item(0));
+      }
+      return CreateStyleValue(value);
+    }
+    default:
+      // TODO(meade): Implement other properties.
+      break;
+  }
+  return nullptr;
+}
+
 CSSStyleValue* CreateStyleValueWithProperty(CSSPropertyID property_id,
                                             const CSSValue& value) {
   if (value.IsCSSWideKeyword())
@@ -124,6 +138,17 @@
   return style_value_vector;
 }
 
+CSSStyleValue* StyleValueFactory::CssValueToStyleValue(
+    CSSPropertyID property_id,
+    const CSSValue& css_value) {
+  DCHECK(!CSSProperty::Get(property_id).IsRepeated());
+  CSSStyleValue* style_value =
+      CreateStyleValueWithProperty(property_id, css_value);
+  if (!style_value)
+    return CSSUnsupportedStyleValue::Create(property_id, css_value);
+  return style_value;
+}
+
 CSSStyleValueVector StyleValueFactory::CssValueToStyleValueVector(
     CSSPropertyID property_id,
     const CSSValue& css_value) {
diff --git a/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.h b/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.h
index c5bd981..9ec0395 100644
--- a/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.h
+++ b/third_party/WebKit/Source/core/css/cssom/StyleValueFactory.h
@@ -21,6 +21,7 @@
   static CSSStyleValueVector FromString(CSSPropertyID,
                                         const String&,
                                         const CSSParserContext*);
+  static CSSStyleValue* CssValueToStyleValue(CSSPropertyID, const CSSValue&);
   static CSSStyleValueVector CssValueToStyleValueVector(CSSPropertyID,
                                                         const CSSValue&);
   // If you don't have complex CSS properties, use this one.
diff --git a/third_party/WebKit/Source/core/css/parser/CSSSelectorParserTest.cpp b/third_party/WebKit/Source/core/css/parser/CSSSelectorParserTest.cpp
index f130ee2..3e36614c 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSSelectorParserTest.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSSelectorParserTest.cpp
@@ -459,6 +459,46 @@
   }
 }
 
+TEST(CSSSelectorParserTest, InvalidPseudoMatchesArguments) {
+  // Pseudo-elements are not valid within :matches() as per the spec:
+  // https://drafts.csswg.org/selectors-4/#matches
+  const char* test_cases[] = {":matches(::-webkit-progress-bar)",
+                              ":matches(::-webkit-progress-value)",
+                              ":matches(::-webkit-slider-runnable-track)",
+                              ":matches(::-webkit-slider-thumb)",
+                              ":matches(::after)",
+                              ":matches(::backdrop)",
+                              ":matches(::before)",
+                              ":matches(::cue)",
+                              ":matches(::first-letter)",
+                              ":matches(::first-line)",
+                              ":matches(::grammar-error)",
+                              ":matches(::marker)",
+                              ":matches(::placeholder)",
+                              ":matches(::selection)",
+                              ":matches(::slotted)",
+                              ":matches(::spelling-error)",
+                              ":matches(:after)",
+                              ":matches(:before)",
+                              ":matches(:cue)",
+                              ":matches(:first-letter)",
+                              ":matches(:first-line)"};
+
+  CSSParserContext* context = CSSParserContext::Create(
+      kHTMLStandardMode, SecureContextMode::kInsecureContext);
+  StyleSheetContents* sheet = StyleSheetContents::Create(context);
+
+  for (auto test_case : test_cases) {
+    SCOPED_TRACE(test_case);
+    CSSTokenizer tokenizer(test_case);
+    const auto tokens = tokenizer.TokenizeToEOF();
+    CSSParserTokenRange range(tokens);
+    CSSSelectorList list =
+        CSSSelectorParser::ParseSelector(range, context, sheet);
+    EXPECT_FALSE(list.IsValid());
+  }
+}
+
 namespace {
 
 const auto TagLocalName = [](const CSSSelector* selector) {
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp b/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
index cf9073f..82836570 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
@@ -679,9 +679,10 @@
   // If intrinsically sized images or videos are disallowed by feature policy,
   // use default size (300 x 150) instead.
   if (IsImageOrVideoElement(element)) {
-    if (IsSupportedInFeaturePolicy(FeaturePolicyFeature::kUnsizedMedia) &&
+    if (IsSupportedInFeaturePolicy(
+            mojom::FeaturePolicyFeature::kUnsizedMedia) &&
         !element->GetDocument().GetFrame()->IsFeatureEnabled(
-            FeaturePolicyFeature::kUnsizedMedia)) {
+            mojom::FeaturePolicyFeature::kUnsizedMedia)) {
       if (!style.Width().IsSpecified())
         style.SetLogicalWidth(Length(LayoutReplaced::kDefaultWidth, kFixed));
       if (!style.Height().IsSpecified())
diff --git a/third_party/WebKit/Source/core/css/threaded/MultiThreadedTestUtil.h b/third_party/WebKit/Source/core/css/threaded/MultiThreadedTestUtil.h
index c116711a..99d2387 100644
--- a/third_party/WebKit/Source/core/css/threaded/MultiThreadedTestUtil.h
+++ b/third_party/WebKit/Source/core/css/threaded/MultiThreadedTestUtil.h
@@ -65,7 +65,7 @@
 
     for (int i = 0; i < num_threads_; ++i) {
       base::SingleThreadTaskRunner* task_runner =
-          threads[i]->PlatformThread().GetWebTaskRunner();
+          threads[i]->PlatformThread().GetTaskRunner().get();
 
       PostCrossThreadTask(*task_runner, FROM_HERE,
                           CrossThreadBind(
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 299fce2..d978363 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -7291,7 +7291,7 @@
   // cases, though, there isn't a good candidate (most commonly when either the
   // passed-in document or ContextDocument() used to be attached to a Frame but
   // has since been detached).
-  return Platform::Current()->CurrentThread()->GetWebTaskRunner();
+  return Platform::Current()->CurrentThread()->GetTaskRunner();
 }
 
 Policy* Document::policy() {
diff --git a/third_party/WebKit/Source/core/dom/FlatTreeTraversal.cpp b/third_party/WebKit/Source/core/dom/FlatTreeTraversal.cpp
index d23aa5c..62e5aed1 100644
--- a/third_party/WebKit/Source/core/dom/FlatTreeTraversal.cpp
+++ b/third_party/WebKit/Source/core/dom/FlatTreeTraversal.cpp
@@ -212,7 +212,7 @@
 }
 
 Node* FlatTreeTraversal::ChildAt(const Node& node, unsigned index) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::ChildAt(node, index);
   AssertPrecondition(node);
   Node* child = TraverseFirstChild(node);
@@ -223,7 +223,7 @@
 }
 
 Node* FlatTreeTraversal::NextSkippingChildren(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::NextSkippingChildren(node);
   if (Node* next_sibling = TraverseNextSibling(node))
     return next_sibling;
@@ -233,7 +233,7 @@
 bool FlatTreeTraversal::ContainsIncludingPseudoElement(
     const ContainerNode& container,
     const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::ContainsIncludingPseudoElement(container, node);
   AssertPrecondition(container);
   AssertPrecondition(node);
@@ -248,7 +248,7 @@
 }
 
 Node* FlatTreeTraversal::PreviousSkippingChildren(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::PreviousSkippingChildren(node);
   if (Node* previous_sibling = TraversePreviousSibling(node))
     return previous_sibling;
@@ -273,7 +273,7 @@
 // between DOM tree traversal and flat tree tarversal.
 Node* FlatTreeTraversal::PreviousPostOrder(const Node& current,
                                            const Node* stay_within) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::PreviousPostOrder(current, stay_within);
   AssertPrecondition(current);
   if (stay_within)
@@ -292,7 +292,7 @@
 }
 
 bool FlatTreeTraversal::IsDescendantOf(const Node& node, const Node& other) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::IsDescendantOf(node, other);
   AssertPrecondition(node);
   AssertPrecondition(other);
@@ -308,7 +308,7 @@
 
 Node* FlatTreeTraversal::CommonAncestor(const Node& node_a,
                                         const Node& node_b) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::CommonAncestor(node_a, node_b);
   AssertPrecondition(node_a);
   AssertPrecondition(node_b);
@@ -339,7 +339,7 @@
 }
 
 unsigned FlatTreeTraversal::Index(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::Index(node);
   AssertPrecondition(node);
   unsigned count = 0;
@@ -350,7 +350,7 @@
 }
 
 unsigned FlatTreeTraversal::CountChildren(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::CountChildren(node);
   AssertPrecondition(node);
   unsigned count = 0;
@@ -361,7 +361,7 @@
 }
 
 Node* FlatTreeTraversal::LastWithin(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::LastWithin(node);
   AssertPrecondition(node);
   Node* descendant = TraverseLastChild(node);
@@ -372,7 +372,7 @@
 }
 
 Node& FlatTreeTraversal::LastWithinOrSelf(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::LastWithinOrSelf(node);
   AssertPrecondition(node);
   Node* last_descendant = LastWithin(node);
diff --git a/third_party/WebKit/Source/core/dom/FlatTreeTraversal.h b/third_party/WebKit/Source/core/dom/FlatTreeTraversal.h
index 383941d..c2adb21 100644
--- a/third_party/WebKit/Source/core/dom/FlatTreeTraversal.h
+++ b/third_party/WebKit/Source/core/dom/FlatTreeTraversal.h
@@ -98,7 +98,7 @@
   static bool IsDescendantOf(const Node& /*node*/, const Node& other);
 
   static bool Contains(const ContainerNode& container, const Node& node) {
-    if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+    if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
       return FlatTreeTraversalNg::Contains(container, node);
     AssertPrecondition(container);
     AssertPrecondition(node);
@@ -193,7 +193,7 @@
 inline ContainerNode* FlatTreeTraversal::Parent(
     const Node& node,
     ParentTraversalDetails* details) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::Parent(node, details);
   AssertPrecondition(node);
   ContainerNode* result = TraverseParent(node, details);
@@ -202,14 +202,14 @@
 }
 
 inline Element* FlatTreeTraversal::ParentElement(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::ParentElement(node);
   ContainerNode* parent = FlatTreeTraversal::Parent(node);
   return parent && parent->IsElementNode() ? ToElement(parent) : nullptr;
 }
 
 inline Node* FlatTreeTraversal::NextSibling(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::NextSibling(node);
   AssertPrecondition(node);
   Node* result = TraverseSiblings(node, kTraversalDirectionForward);
@@ -218,7 +218,7 @@
 }
 
 inline Node* FlatTreeTraversal::PreviousSibling(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::PreviousSibling(node);
   AssertPrecondition(node);
   Node* result = TraverseSiblings(node, kTraversalDirectionBackward);
@@ -227,7 +227,7 @@
 }
 
 inline Node* FlatTreeTraversal::Next(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::Next(node);
   AssertPrecondition(node);
   Node* result = TraverseNext(node);
@@ -237,7 +237,7 @@
 
 inline Node* FlatTreeTraversal::Next(const Node& node,
                                      const Node* stay_within) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::Next(node, stay_within);
   AssertPrecondition(node);
   Node* result = TraverseNext(node, stay_within);
@@ -247,7 +247,7 @@
 
 inline Node* FlatTreeTraversal::NextSkippingChildren(const Node& node,
                                                      const Node* stay_within) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::NextSkippingChildren(node, stay_within);
   AssertPrecondition(node);
   Node* result = TraverseNextSkippingChildren(node, stay_within);
@@ -285,7 +285,7 @@
 }
 
 inline Node* FlatTreeTraversal::Previous(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::Previous(node);
   AssertPrecondition(node);
   Node* result = TraversePrevious(node);
@@ -303,7 +303,7 @@
 }
 
 inline Node* FlatTreeTraversal::FirstChild(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::FirstChild(node);
   AssertPrecondition(node);
   Node* result = TraverseChild(node, kTraversalDirectionForward);
@@ -312,7 +312,7 @@
 }
 
 inline Node* FlatTreeTraversal::LastChild(const Node& node) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return FlatTreeTraversalNg::LastChild(node);
   AssertPrecondition(node);
   Node* result = TraverseLastChild(node);
diff --git a/third_party/WebKit/Source/core/dom/FlatTreeTraversalTest.cpp b/third_party/WebKit/Source/core/dom/FlatTreeTraversalTest.cpp
index d96825df3..fb392ea 100644
--- a/third_party/WebKit/Source/core/dom/FlatTreeTraversalTest.cpp
+++ b/third_party/WebKit/Source/core/dom/FlatTreeTraversalTest.cpp
@@ -15,6 +15,7 @@
 #include "core/html/HTMLElement.h"
 #include "core/testing/PageTestBase.h"
 #include "platform/geometry/IntSize.h"
+#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
 #include "platform/wtf/Compiler.h"
 #include "platform/wtf/StdLibExtras.h"
 #include "platform/wtf/Vector.h"
@@ -22,7 +23,11 @@
 
 namespace blink {
 
-class FlatTreeTraversalTest : public PageTestBase {
+class FlatTreeTraversalTest : public PageTestBase,
+                              private ScopedSlotInFlatTreeForTest {
+ public:
+  FlatTreeTraversalTest() : ScopedSlotInFlatTreeForTest(false) {}
+
  protected:
   // Sets |mainHTML| to BODY element with |innerHTML| property and attaches
   // shadow root to child with |shadowHTML|, then update distribution for
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp
index 98e1888..390ca5d 100644
--- a/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -846,10 +846,9 @@
   if (node.IsPseudoElement())
     return node.ParentOrShadowHostNode();
   if (node.IsChildOfV1ShadowHost()) {
-    HTMLSlotElement* slot =
-        RuntimeEnabledFeatures::IncrementalShadowDOMEnabled()
-            ? node.AssignedSlot()
-            : node.FinalDestinationSlot();
+    HTMLSlotElement* slot = RuntimeEnabledFeatures::SlotInFlatTreeEnabled()
+                                ? node.AssignedSlot()
+                                : node.FinalDestinationSlot();
     if (slot)
       return slot;
   }
@@ -1163,7 +1162,7 @@
 
 bool Node::CanParticipateInFlatTree() const {
   // TODO(hayato): Return false for pseudo elements.
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled()) {
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled()) {
     return !IsShadowRoot() && !IsActiveV0InsertionPoint(*this);
   }
   return !IsShadowRoot() && !IsActiveSlotOrActiveV0InsertionPoint();
diff --git a/third_party/WebKit/Source/core/dom/ng/flat_tree_traversal_ng_test.cc b/third_party/WebKit/Source/core/dom/ng/flat_tree_traversal_ng_test.cc
index 88cc051..f24b5fc 100644
--- a/third_party/WebKit/Source/core/dom/ng/flat_tree_traversal_ng_test.cc
+++ b/third_party/WebKit/Source/core/dom/ng/flat_tree_traversal_ng_test.cc
@@ -27,9 +27,9 @@
 namespace flat_tree_traversal_ng_test {
 
 class FlatTreeTraversalNgTest : public PageTestBase,
-                                private ScopedIncrementalShadowDOMForTest {
+                                private ScopedSlotInFlatTreeForTest {
  public:
-  FlatTreeTraversalNgTest() : ScopedIncrementalShadowDOMForTest(true) {}
+  FlatTreeTraversalNgTest() : ScopedSlotInFlatTreeForTest(true) {}
 
  protected:
   // Sets |mainHTML| to BODY element with |innerHTML| property and attaches
diff --git a/third_party/WebKit/Source/core/editing/PositionIteratorTest.cpp b/third_party/WebKit/Source/core/editing/PositionIteratorTest.cpp
index f60d312..e671fb38 100644
--- a/third_party/WebKit/Source/core/editing/PositionIteratorTest.cpp
+++ b/third_party/WebKit/Source/core/editing/PositionIteratorTest.cpp
@@ -82,11 +82,6 @@
   EXPECT_EQ(PositionInFlatTree::AfterNode(*select),
             flat_iterator.ComputePosition());
   flat_iterator.Decrement();
-  EXPECT_EQ(PositionInFlatTree::AfterNode(*select),
-            flat_iterator.ComputePosition())
-      << "This is redundant result, we should not have. see "
-         "http://crbug.com/697283";
-  flat_iterator.Decrement();
   EXPECT_EQ(PositionInFlatTree::BeforeNode(*select),
             flat_iterator.ComputePosition());
   flat_iterator.Decrement();
@@ -205,11 +200,6 @@
   EXPECT_EQ(PositionInFlatTree::AfterNode(*select),
             flat_iterator.ComputePosition());
   flat_iterator.Increment();
-  EXPECT_EQ(PositionInFlatTree::AfterNode(*select),
-            flat_iterator.ComputePosition())
-      << "This is redundant result, we should not have. see "
-         "http://crbug.com/697283";
-  flat_iterator.Increment();
   EXPECT_EQ(PositionInFlatTree(GetDocument().body(), 1),
             flat_iterator.ComputePosition());
   flat_iterator.Increment();
diff --git a/third_party/WebKit/Source/core/editing/testing/SelectionSampleTest.cpp b/third_party/WebKit/Source/core/editing/testing/SelectionSampleTest.cpp
index 9718834..65aed03 100644
--- a/third_party/WebKit/Source/core/editing/testing/SelectionSampleTest.cpp
+++ b/third_party/WebKit/Source/core/editing/testing/SelectionSampleTest.cpp
@@ -32,7 +32,8 @@
   GetDocument().body()->UpdateDistribution();
   EXPECT_EQ(
       "<p>"
-      "    ze^ro <b slot=\"one\">one</b> <b slot=\"two\">tw|o</b> three  "
+      "    ze^ro <slot name=\"one\"><b slot=\"one\">one</b></slot> <slot "
+      "name=\"two\"><b slot=\"two\">tw|o</b></slot> three  "
       "</p>",
       SelectionSample::GetSelectionTextInFlatTree(
           *GetDocument().body(), ConvertToSelectionInFlatTree(selection)));
diff --git a/third_party/WebKit/Source/core/events/MouseEvent.cpp b/third_party/WebKit/Source/core/events/MouseEvent.cpp
index cb4518b..e6ffa5c 100644
--- a/third_party/WebKit/Source/core/events/MouseEvent.cpp
+++ b/third_party/WebKit/Source/core/events/MouseEvent.cpp
@@ -500,13 +500,14 @@
   LocalFrame* frame = view() && view()->IsLocalDOMWindow()
                           ? ToLocalDOMWindow(view())->GetFrame()
                           : nullptr;
-  if (frame && frame->View())
-    absolute_location_ = frame->View()->DocumentToAbsolute(page_location_);
-  else
-    absolute_location_ = page_location_;
-
-  float scale_factor = PageZoomFactor(this);
-  absolute_location_.Scale(scale_factor, scale_factor);
+  DoublePoint scaled_page_location =
+      page_location_.ScaledBy(PageZoomFactor(this));
+  if (frame && frame->View()) {
+    absolute_location_ =
+        frame->View()->DocumentToAbsolute(scaled_page_location);
+  } else {
+    absolute_location_ = scaled_page_location;
+  }
 }
 
 void MouseEvent::ReceivedTarget() {
@@ -521,6 +522,7 @@
   // Compute coordinates that are based on the target.
   layer_location_ = page_location_;
   offset_location_ = page_location_;
+  float inverse_zoom_factor = 1 / PageZoomFactor(this);
 
   // Must have an updated layout tree for this math to work correctly.
   target_node->GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
@@ -540,9 +542,8 @@
     }
 
     offset_location_ = DoublePoint(local_pos);
-    float scale_factor = 1 / PageZoomFactor(this);
-    if (scale_factor != 1.0f)
-      offset_location_.Scale(scale_factor, scale_factor);
+    if (inverse_zoom_factor != 1.0f)
+      offset_location_.Scale(inverse_zoom_factor, inverse_zoom_factor);
   }
 
   // Adjust layerLocation to be relative to the layer.
@@ -554,8 +555,10 @@
     n = n->parentNode();
 
   if (n) {
+    DoublePoint scaled_page_location =
+        page_location_.ScaledBy(PageZoomFactor(this));
     if (LocalFrameView* view = n->GetLayoutObject()->View()->GetFrameView())
-      layer_location_ = view->DocumentToAbsolute(page_location_);
+      layer_location_ = view->DocumentToAbsolute(scaled_page_location);
 
     // FIXME: This logic is a wrong implementation of convertToLayerCoords.
     for (PaintLayer* layer = n->GetLayoutObject()->EnclosingLayer(); layer;
@@ -563,6 +566,8 @@
       layer_location_ -= DoubleSize(layer->Location().X().ToDouble(),
                                     layer->Location().Y().ToDouble());
     }
+    if (inverse_zoom_factor != 1.0f)
+      layer_location_.Scale(inverse_zoom_factor, inverse_zoom_factor);
   }
 
   has_cached_relative_position_ = true;
diff --git a/third_party/WebKit/Source/core/events/MouseEvent.h b/third_party/WebKit/Source/core/events/MouseEvent.h
index 013e85c..23614ac 100644
--- a/third_party/WebKit/Source/core/events/MouseEvent.h
+++ b/third_party/WebKit/Source/core/events/MouseEvent.h
@@ -235,7 +235,7 @@
   // fractional flag is removed.
   DoublePoint screen_location_;
   DoublePoint client_location_;
-  DoublePoint page_location_;
+  DoublePoint page_location_;  // zoomed CSS pixels
 
  private:
   void InitMouseEventInternal(const AtomicString& type,
@@ -261,9 +261,9 @@
 
   DoublePoint movement_delta_;
 
-  DoublePoint layer_location_;
-  DoublePoint offset_location_;
-  DoublePoint absolute_location_;
+  DoublePoint layer_location_;     // zoomed CSS pixels
+  DoublePoint offset_location_;    // zoomed CSS pixels
+  DoublePoint absolute_location_;  // (un-zoomed) FrameView content space
   PositionType position_type_;
   bool has_cached_relative_position_;
   short button_;
diff --git a/third_party/WebKit/Source/core/exported/WebAssociatedURLLoaderImpl.cpp b/third_party/WebKit/Source/core/exported/WebAssociatedURLLoaderImpl.cpp
index bd4dfd0..428b4c1 100644
--- a/third_party/WebKit/Source/core/exported/WebAssociatedURLLoaderImpl.cpp
+++ b/third_party/WebKit/Source/core/exported/WebAssociatedURLLoaderImpl.cpp
@@ -400,7 +400,7 @@
     task_runner = ToDocument(observer_->LifecycleContext())
                       ->GetTaskRunner(TaskType::kUnspecedLoading);
   } else {
-    task_runner = Platform::Current()->CurrentThread()->GetWebTaskRunner();
+    task_runner = Platform::Current()->CurrentThread()->GetTaskRunner();
   }
   client_ = client;
   client_adapter_ = ClientAdapter::Create(
diff --git a/third_party/WebKit/Source/core/fetch/DataConsumerHandleTestUtil.cpp b/third_party/WebKit/Source/core/fetch/DataConsumerHandleTestUtil.cpp
index 840aabe..d53dc3f0 100644
--- a/third_party/WebKit/Source/core/fetch/DataConsumerHandleTestUtil.cpp
+++ b/third_party/WebKit/Source/core/fetch/DataConsumerHandleTestUtil.cpp
@@ -226,7 +226,7 @@
     return;
   DCHECK(reader_thread_);
   PostCrossThreadTask(
-      *reader_thread_->GetWebTaskRunner(), FROM_HERE,
+      *reader_thread_->GetTaskRunner(), FROM_HERE,
       CrossThreadBind(&Context::NotifyInternal, WrapRefCounted(this)));
 }
 
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp
index 1ae59bd4..650e4c6 100644
--- a/third_party/WebKit/Source/core/frame/Deprecation.cpp
+++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -19,7 +19,7 @@
 #include "public/platform/Platform.h"
 #include "public/platform/reporting.mojom-blink.h"
 #include "services/service_manager/public/cpp/connector.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom-blink.h"
 
 using blink::WebFeature;
 
@@ -706,8 +706,9 @@
   CountDeprecationCrossOriginIframe(frame, feature);
 }
 
-void Deprecation::CountDeprecationFeaturePolicy(const Document& document,
-                                                FeaturePolicyFeature feature) {
+void Deprecation::CountDeprecationFeaturePolicy(
+    const Document& document,
+    mojom::FeaturePolicyFeature feature) {
   // If feature policy is not enabled, don't do anything.
   if (!RuntimeEnabledFeatures::FeaturePolicyEnabled())
     return;
@@ -727,30 +728,30 @@
   // (until the general syntax is shipped) and this is also a good enough
   // approximation for deprecation messages.
   switch (feature) {
-    case FeaturePolicyFeature::kEncryptedMedia:
+    case mojom::FeaturePolicyFeature::kEncryptedMedia:
       CountDeprecationCrossOriginIframe(
           frame,
           WebFeature::
               kEncryptedMediaDisallowedByFeaturePolicyInCrossOriginIframe);
       break;
-    case FeaturePolicyFeature::kGeolocation:
+    case mojom::FeaturePolicyFeature::kGeolocation:
       CountDeprecationCrossOriginIframe(
           frame,
           WebFeature::kGeolocationDisallowedByFeaturePolicyInCrossOriginIframe);
       break;
-    case FeaturePolicyFeature::kMicrophone:
+    case mojom::FeaturePolicyFeature::kMicrophone:
       CountDeprecationCrossOriginIframe(
           frame,
           WebFeature::
               kGetUserMediaMicDisallowedByFeaturePolicyInCrossOriginIframe);
       break;
-    case FeaturePolicyFeature::kCamera:
+    case mojom::FeaturePolicyFeature::kCamera:
       CountDeprecationCrossOriginIframe(
           frame,
           WebFeature::
               kGetUserMediaCameraDisallowedByFeaturePolicyInCrossOriginIframe);
       break;
-    case FeaturePolicyFeature::kMidiFeature:
+    case mojom::FeaturePolicyFeature::kMidiFeature:
       CountDeprecationCrossOriginIframe(
           frame,
           WebFeature::
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.h b/third_party/WebKit/Source/core/frame/Deprecation.h
index 245e7698..212cd8c 100644
--- a/third_party/WebKit/Source/core/frame/Deprecation.h
+++ b/third_party/WebKit/Source/core/frame/Deprecation.h
@@ -12,9 +12,11 @@
 #include "platform/wtf/BitVector.h"
 
 namespace blink {
+namespace mojom {
+enum class FeaturePolicyFeature;
+}  // namespace mojom
 
 class LocalFrame;
-enum class FeaturePolicyFeature;
 
 class CORE_EXPORT Deprecation {
   DISALLOW_NEW();
@@ -49,7 +51,7 @@
   static void CountDeprecationCrossOriginIframe(const Document&, WebFeature);
 
   static void CountDeprecationFeaturePolicy(const Document&,
-                                            FeaturePolicyFeature);
+                                            mojom::FeaturePolicyFeature);
 
   static String DeprecationMessage(WebFeature);
 
diff --git a/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.cpp b/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.cpp
index e22dbcf..fad44402 100644
--- a/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.cpp
+++ b/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.cpp
@@ -91,12 +91,12 @@
 }
 
 bool DeviceSingleWindowEventController::CheckPolicyFeatures(
-    const Vector<FeaturePolicyFeature>& features) const {
+    const Vector<mojom::FeaturePolicyFeature>& features) const {
   LocalFrame* frame = GetDocument().GetFrame();
   if (!frame)
     return false;
   return std::all_of(features.begin(), features.end(),
-                     [frame](FeaturePolicyFeature feature) {
+                     [frame](mojom::FeaturePolicyFeature feature) {
                        return frame->IsFeatureEnabled(feature);
                      });
 }
diff --git a/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.h b/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.h
index 41e67d8..136077d 100644
--- a/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.h
+++ b/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.h
@@ -36,7 +36,8 @@
 
   Document& GetDocument() const { return *document_; }
   bool IsSameSecurityOriginAsMainFrame() const;
-  bool CheckPolicyFeatures(const Vector<FeaturePolicyFeature>& features) const;
+  bool CheckPolicyFeatures(
+      const Vector<mojom::FeaturePolicyFeature>& features) const;
 
   void DispatchDeviceEvent(Event*);
 
diff --git a/third_party/WebKit/Source/core/frame/Frame.cpp b/third_party/WebKit/Source/core/frame/Frame.cpp
index c3edcb3b..b8cd482 100644
--- a/third_party/WebKit/Source/core/frame/Frame.cpp
+++ b/third_party/WebKit/Source/core/frame/Frame.cpp
@@ -238,7 +238,7 @@
              : UserGestureIndicator::ConsumeUserGesture();
 }
 
-bool Frame::IsFeatureEnabled(FeaturePolicyFeature feature) const {
+bool Frame::IsFeatureEnabled(mojom::FeaturePolicyFeature feature) const {
   FeaturePolicy* feature_policy = GetSecurityContext()->GetFeaturePolicy();
   // The policy should always be initialized before checking it to ensure we
   // properly inherit the parent policy.
diff --git a/third_party/WebKit/Source/core/frame/Frame.h b/third_party/WebKit/Source/core/frame/Frame.h
index 0b9e0c3..e31e8daf 100644
--- a/third_party/WebKit/Source/core/frame/Frame.h
+++ b/third_party/WebKit/Source/core/frame/Frame.h
@@ -188,7 +188,7 @@
 
   // Tests whether the feature-policy controlled feature is enabled by policy in
   // the given frame.
-  bool IsFeatureEnabled(FeaturePolicyFeature) const;
+  bool IsFeatureEnabled(mojom::FeaturePolicyFeature) const;
 
   // Called to make a frame inert or non-inert. A frame is inert when there
   // is a modal dialog displayed within an ancestor frame, and this frame
diff --git a/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp b/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp
index 55de857..b6b9f90 100644
--- a/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameTestHelpers.cpp
@@ -80,7 +80,7 @@
   // getting the platform's one. (crbug.com/751425)
   Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
   if (TestWebFrameClient::IsLoading()) {
-    Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+    Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
         FROM_HERE, WTF::Bind(&RunServeAsyncRequestsTask));
   } else {
     testing::ExitRunLoop();
@@ -139,7 +139,7 @@
 }
 
 void PumpPendingRequestsForFrameToLoad(WebFrame* frame) {
-  Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+  Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
       FROM_HERE, WTF::Bind(&RunServeAsyncRequestsTask));
   testing::EnterRunLoop();
 }
diff --git a/third_party/WebKit/Source/core/frame/UseCounterTest.cpp b/third_party/WebKit/Source/core/frame/UseCounterTest.cpp
index e246687..2417e4b 100644
--- a/third_party/WebKit/Source/core/frame/UseCounterTest.cpp
+++ b/third_party/WebKit/Source/core/frame/UseCounterTest.cpp
@@ -528,7 +528,8 @@
        TestCountDeprecationFeaturePolicy) {
   // The specific feature we use here isn't important, but we need the
   // corresponding FP feature as well.
-  FeaturePolicyFeature policy_feature = FeaturePolicyFeature::kGeolocation;
+  mojom::FeaturePolicyFeature policy_feature =
+      mojom::FeaturePolicyFeature::kGeolocation;
   WebFeature feature =
       WebFeature::kGeolocationDisallowedByFeaturePolicyInCrossOriginIframe;
 
diff --git a/third_party/WebKit/Source/core/fullscreen/Fullscreen.cpp b/third_party/WebKit/Source/core/fullscreen/Fullscreen.cpp
index c85d8b9..61d029a 100644
--- a/third_party/WebKit/Source/core/fullscreen/Fullscreen.cpp
+++ b/third_party/WebKit/Source/core/fullscreen/Fullscreen.cpp
@@ -65,7 +65,7 @@
   if (!frame)
     return false;
 
-  if (!IsSupportedInFeaturePolicy(FeaturePolicyFeature::kFullscreen)) {
+  if (!IsSupportedInFeaturePolicy(mojom::FeaturePolicyFeature::kFullscreen)) {
     // 2. If |document|'s browsing context is a top-level browsing context, then
     // return true.
     if (frame->IsMainFrame())
@@ -84,7 +84,7 @@
 
   // 2. If Feature Policy is enabled, return the policy for "fullscreen"
   // feature.
-  return frame->IsFeatureEnabled(FeaturePolicyFeature::kFullscreen);
+  return frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kFullscreen);
 }
 
 bool AllowedToRequestFullscreen(Document& document) {
diff --git a/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp b/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp
index 48aa35b..3b37109 100644
--- a/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp
@@ -84,7 +84,7 @@
   // https://fullscreen.spec.whatwg.org/#model
   ParsedFeaturePolicy container_policy;
   ParsedFeaturePolicyDeclaration whitelist;
-  whitelist.feature = FeaturePolicyFeature::kFullscreen;
+  whitelist.feature = mojom::FeaturePolicyFeature::kFullscreen;
   whitelist.matches_all_origins = false;
   container_policy.push_back(whitelist);
   return container_policy;
diff --git a/third_party/WebKit/Source/core/html/HTMLFrameElementTest.cpp b/third_party/WebKit/Source/core/html/HTMLFrameElementTest.cpp
index 65f459f..6e5f04f 100644
--- a/third_party/WebKit/Source/core/html/HTMLFrameElementTest.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLFrameElementTest.cpp
@@ -29,7 +29,8 @@
       frame_element->ContainerPolicy();
   EXPECT_EQ(1UL, container_policy.size());
   // Fullscreen should be disabled in this frame
-  EXPECT_EQ(FeaturePolicyFeature::kFullscreen, container_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
+            container_policy[0].feature);
   EXPECT_FALSE(container_policy[0].matches_all_origins);
   EXPECT_EQ(0UL, container_policy[0].origins.size());
 }
diff --git a/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp b/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp
index 23fca847..9bb3dc5b 100644
--- a/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp
@@ -227,7 +227,7 @@
   if (AllowFullscreen()) {
     bool has_fullscreen_policy = false;
     for (const auto& declaration : container_policy) {
-      if (declaration.feature == FeaturePolicyFeature::kFullscreen) {
+      if (declaration.feature == mojom::FeaturePolicyFeature::kFullscreen) {
         has_fullscreen_policy = true;
         if (messages) {
           messages->push_back(
@@ -238,7 +238,7 @@
     }
     if (!has_fullscreen_policy) {
       ParsedFeaturePolicyDeclaration whitelist;
-      whitelist.feature = FeaturePolicyFeature::kFullscreen;
+      whitelist.feature = mojom::FeaturePolicyFeature::kFullscreen;
       whitelist.matches_all_origins = true;
       container_policy.push_back(whitelist);
     }
@@ -248,7 +248,7 @@
   if (AllowPaymentRequest()) {
     bool has_payment_policy = false;
     for (const auto& declaration : container_policy) {
-      if (declaration.feature == FeaturePolicyFeature::kPayment) {
+      if (declaration.feature == mojom::FeaturePolicyFeature::kPayment) {
         has_payment_policy = true;
         if (messages) {
           messages->push_back(
@@ -259,7 +259,7 @@
     }
     if (!has_payment_policy) {
       ParsedFeaturePolicyDeclaration whitelist;
-      whitelist.feature = FeaturePolicyFeature::kPayment;
+      whitelist.feature = mojom::FeaturePolicyFeature::kPayment;
       whitelist.matches_all_origins = true;
       whitelist.origins = std::vector<url::Origin>(0UL);
       container_policy.push_back(whitelist);
diff --git a/third_party/WebKit/Source/core/html/HTMLIFrameElementTest.cpp b/third_party/WebKit/Source/core/html/HTMLIFrameElementTest.cpp
index 920708b..29b06359 100644
--- a/third_party/WebKit/Source/core/html/HTMLIFrameElementTest.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLIFrameElementTest.cpp
@@ -191,7 +191,8 @@
       frame_element->ContainerPolicy();
 
   EXPECT_EQ(1UL, container_policy1.size());
-  EXPECT_EQ(FeaturePolicyFeature::kFullscreen, container_policy1[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
+            container_policy1[0].feature);
   EXPECT_FALSE(container_policy1[0].matches_all_origins);
   EXPECT_EQ(1UL, container_policy1[0].origins.size());
   EXPECT_EQ("http://example.net", container_policy1[0].origins[0].Serialize());
@@ -202,11 +203,13 @@
   const ParsedFeaturePolicy& container_policy2 =
       frame_element->ContainerPolicy();
   EXPECT_EQ(2UL, container_policy2.size());
+  EXPECT_TRUE(container_policy2[0].feature ==
+                  mojom::FeaturePolicyFeature::kFullscreen ||
+              container_policy2[1].feature ==
+                  mojom::FeaturePolicyFeature::kFullscreen);
   EXPECT_TRUE(
-      container_policy2[0].feature == FeaturePolicyFeature::kFullscreen ||
-      container_policy2[1].feature == FeaturePolicyFeature::kFullscreen);
-  EXPECT_TRUE(container_policy2[0].feature == FeaturePolicyFeature::kPayment ||
-              container_policy2[1].feature == FeaturePolicyFeature::kPayment);
+      container_policy2[0].feature == mojom::FeaturePolicyFeature::kPayment ||
+      container_policy2[1].feature == mojom::FeaturePolicyFeature::kPayment);
   EXPECT_FALSE(container_policy2[0].matches_all_origins);
   EXPECT_EQ(1UL, container_policy2[0].origins.size());
   EXPECT_EQ("http://example.net", container_policy2[0].origins[0].Serialize());
@@ -221,11 +224,13 @@
   const ParsedFeaturePolicy& container_policy3 =
       frame_element->ContainerPolicy();
   EXPECT_EQ(2UL, container_policy3.size());
+  EXPECT_TRUE(container_policy3[0].feature ==
+                  mojom::FeaturePolicyFeature::kFullscreen ||
+              container_policy3[1].feature ==
+                  mojom::FeaturePolicyFeature::kFullscreen);
   EXPECT_TRUE(
-      container_policy3[0].feature == FeaturePolicyFeature::kFullscreen ||
-      container_policy3[1].feature == FeaturePolicyFeature::kFullscreen);
-  EXPECT_TRUE(container_policy3[0].feature == FeaturePolicyFeature::kPayment ||
-              container_policy3[1].feature == FeaturePolicyFeature::kPayment);
+      container_policy3[0].feature == mojom::FeaturePolicyFeature::kPayment ||
+      container_policy3[1].feature == mojom::FeaturePolicyFeature::kPayment);
   EXPECT_FALSE(container_policy3[0].matches_all_origins);
   EXPECT_EQ(1UL, container_policy3[0].origins.size());
   EXPECT_EQ("http://example.net", container_policy3[0].origins[0].Serialize());
@@ -253,7 +258,8 @@
       frame_element->ContainerPolicy();
 
   EXPECT_EQ(1UL, container_policy.size());
-  EXPECT_EQ(FeaturePolicyFeature::kFullscreen, container_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
+            container_policy[0].feature);
   EXPECT_FALSE(container_policy[0].matches_all_origins);
   EXPECT_EQ(1UL, container_policy[0].origins.size());
   EXPECT_TRUE(container_policy[0].origins[0].unique());
@@ -279,7 +285,8 @@
       frame_element->ContainerPolicy();
 
   EXPECT_EQ(1UL, container_policy.size());
-  EXPECT_EQ(FeaturePolicyFeature::kFullscreen, container_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
+            container_policy[0].feature);
   EXPECT_FALSE(container_policy[0].matches_all_origins);
   EXPECT_EQ(1UL, container_policy[0].origins.size());
   EXPECT_FALSE(container_policy[0].origins[0].unique());
@@ -314,12 +321,12 @@
   ParsedFeaturePolicy container_policy =
       frame_element->ConstructContainerPolicy(nullptr, nullptr);
   EXPECT_EQ(2UL, container_policy.size());
-  EXPECT_EQ(FeaturePolicyFeature::kPayment, container_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, container_policy[0].feature);
   EXPECT_FALSE(container_policy[0].matches_all_origins);
   EXPECT_EQ(1UL, container_policy[0].origins.size());
   EXPECT_TRUE(container_policy[0].origins[0].IsSameOriginWith(
       GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin()));
-  EXPECT_EQ(FeaturePolicyFeature::kUsb, container_policy[1].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kUsb, container_policy[1].feature);
   EXPECT_FALSE(container_policy[1].matches_all_origins);
   EXPECT_EQ(1UL, container_policy[1].origins.size());
   EXPECT_TRUE(container_policy[1].origins[0].IsSameOriginWith(
@@ -340,7 +347,8 @@
   ParsedFeaturePolicy container_policy =
       frame_element->ConstructContainerPolicy(nullptr, nullptr);
   EXPECT_EQ(1UL, container_policy.size());
-  EXPECT_EQ(FeaturePolicyFeature::kFullscreen, container_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
+            container_policy[0].feature);
   EXPECT_TRUE(container_policy[0].matches_all_origins);
 }
 
@@ -359,12 +367,12 @@
   ParsedFeaturePolicy container_policy =
       frame_element->ConstructContainerPolicy(nullptr, nullptr);
   EXPECT_EQ(2UL, container_policy.size());
-  EXPECT_EQ(FeaturePolicyFeature::kUsb, container_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kUsb, container_policy[0].feature);
   EXPECT_FALSE(container_policy[0].matches_all_origins);
   EXPECT_EQ(1UL, container_policy[0].origins.size());
   EXPECT_TRUE(container_policy[0].origins[0].IsSameOriginWith(
       GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin()));
-  EXPECT_EQ(FeaturePolicyFeature::kPayment, container_policy[1].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, container_policy[1].feature);
   EXPECT_TRUE(container_policy[1].matches_all_origins);
 }
 
@@ -388,17 +396,18 @@
   ParsedFeaturePolicy container_policy =
       frame_element->ConstructContainerPolicy(nullptr, nullptr);
   EXPECT_EQ(3UL, container_policy.size());
-  EXPECT_EQ(FeaturePolicyFeature::kPayment, container_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, container_policy[0].feature);
   EXPECT_FALSE(container_policy[0].matches_all_origins);
   EXPECT_EQ(1UL, container_policy[0].origins.size());
   EXPECT_TRUE(container_policy[0].origins[0].IsSameOriginWith(
       GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin()));
-  EXPECT_EQ(FeaturePolicyFeature::kUsb, container_policy[1].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kUsb, container_policy[1].feature);
   EXPECT_FALSE(container_policy[1].matches_all_origins);
   EXPECT_EQ(1UL, container_policy[1].origins.size());
   EXPECT_TRUE(container_policy[1].origins[0].IsSameOriginWith(
       GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin()));
-  EXPECT_EQ(FeaturePolicyFeature::kFullscreen, container_policy[2].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen,
+            container_policy[2].feature);
   EXPECT_TRUE(container_policy[2].matches_all_origins);
 }
 
diff --git a/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp b/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
index 25814ce..4d1da3e 100644
--- a/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
@@ -306,7 +306,7 @@
   // https://fullscreen.spec.whatwg.org/#model
   ParsedFeaturePolicy container_policy;
   ParsedFeaturePolicyDeclaration whitelist;
-  whitelist.feature = FeaturePolicyFeature::kFullscreen;
+  whitelist.feature = mojom::FeaturePolicyFeature::kFullscreen;
   whitelist.matches_all_origins = false;
   container_policy.push_back(whitelist);
   return container_policy;
diff --git a/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp b/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
index 1253f8b..829e360 100644
--- a/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
@@ -34,6 +34,7 @@
 #include "core/css/StyleChangeReason.h"
 #include "core/css/StyleEngine.h"
 #include "core/dom/ElementShadow.h"
+#include "core/dom/NodeComputedStyle.h"
 #include "core/dom/NodeTraversal.h"
 #include "core/dom/SlotAssignment.h"
 #include "core/dom/V0InsertionPoint.h"
@@ -43,6 +44,7 @@
 #include "core/html/AssignedNodesOptions.h"
 #include "core/html_names.h"
 #include "core/probe/CoreProbes.h"
+#include "core/style/ComputedStyle.h"
 #include "platform/bindings/Microtask.h"
 
 namespace blink {
@@ -251,9 +253,11 @@
 }
 
 Node* HTMLSlotElement::AssignedNodeNextTo(const Node& node) const {
-  DCHECK(RuntimeEnabledFeatures::IncrementalShadowDOMEnabled());
   DCHECK(SupportsAssignment());
-  ContainingShadowRoot()->GetSlotAssignment().ResolveAssignmentNg();
+  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+    ContainingShadowRoot()->GetSlotAssignment().ResolveAssignmentNg();
+  else
+    DCHECK(!NeedsDistributionRecalc());
   // TODO(crbug.com/776656): Use {node -> index} map to avoid O(N) lookup
   size_t index = assigned_nodes_.Find(&node);
   DCHECK(index != WTF::kNotFound);
@@ -263,9 +267,11 @@
 }
 
 Node* HTMLSlotElement::AssignedNodePreviousTo(const Node& node) const {
-  DCHECK(RuntimeEnabledFeatures::IncrementalShadowDOMEnabled());
   DCHECK(SupportsAssignment());
-  ContainingShadowRoot()->GetSlotAssignment().ResolveAssignmentNg();
+  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+    ContainingShadowRoot()->GetSlotAssignment().ResolveAssignmentNg();
+  else
+    DCHECK(!NeedsDistributionRecalc());
   // TODO(crbug.com/776656): Use {node -> index} map to avoid O(N) lookup
   size_t index = assigned_nodes_.Find(&node);
   DCHECK(index != WTF::kNotFound);
@@ -303,6 +309,20 @@
 }
 
 void HTMLSlotElement::AttachLayoutTree(AttachContext& context) {
+  if (!GetNonAttachedStyle() && ParentComputedStyle()) {
+    // The select/optgroup/option assumes computed style is stored on optgroup
+    // and option even when they are display:none to update selected indices
+    // correctly. See HTMLOptionElement::IsDisplayNone(). The select and
+    // optgroup elements use a UA shadow with slots for rendering. With slot
+    // elements in the flat tree, we need to ensure that also the slot element
+    // child of optgroups gets their ComputedStyle set in order to inherit and
+    // set the ComputedStyle of display:none option elements.
+    if (Element* host = ParentOrShadowHostElement()) {
+      if (IsHTMLOptGroupElement(host))
+        SetNonAttachedStyle(StyleForLayoutObject());
+    }
+  }
+
   HTMLElement::AttachLayoutTree(context);
 
   if (SupportsAssignment()) {
@@ -322,7 +342,7 @@
 // of IncementalShadowDOM.
 const HeapVector<Member<Node>>&
 HTMLSlotElement::ChildrenInFlatTreeIfAssignmentIsSupported() {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return AssignedNodes();
   DCHECK(!NeedsDistributionRecalc());
   return distributed_nodes_;
@@ -331,9 +351,8 @@
 void HTMLSlotElement::DetachLayoutTree(const AttachContext& context) {
   if (SupportsAssignment()) {
     const HeapVector<Member<Node>>& flat_tree_children =
-        RuntimeEnabledFeatures::IncrementalShadowDOMEnabled()
-            ? assigned_nodes_
-            : distributed_nodes_;
+        RuntimeEnabledFeatures::SlotInFlatTreeEnabled() ? assigned_nodes_
+                                                        : distributed_nodes_;
     for (auto& node : flat_tree_children)
       node->LazyReattachIfAttached();
   }
@@ -421,7 +440,7 @@
 }
 
 void HTMLSlotElement::WillRecalcStyle(StyleRecalcChange change) {
-  if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return;
   if (change < kIndependentInherit &&
       GetStyleChangeType() < kSubtreeStyleChange) {
@@ -436,7 +455,7 @@
 }
 
 void HTMLSlotElement::DidRecalcStyle(StyleRecalcChange change) {
-  if (!RuntimeEnabledFeatures::IncrementalShadowDOMEnabled())
+  if (!RuntimeEnabledFeatures::SlotInFlatTreeEnabled())
     return;
   if (change < kIndependentInherit)
     return;
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp
index 568a607..8a67725 100644
--- a/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp
+++ b/third_party/WebKit/Source/core/html/canvas/CanvasAsyncBlobCreatorTest.cpp
@@ -58,8 +58,8 @@
     base::OnceClosure task,
     double delay_ms) {
   DCHECK(IsMainThread());
-  Platform::Current()->MainThread()->GetWebTaskRunner()->PostTask(
-      location, std::move(task));
+  Platform::Current()->MainThread()->GetTaskRunner()->PostTask(location,
+                                                               std::move(task));
 }
 
 //==============================================================================
@@ -94,7 +94,7 @@
 
  protected:
   void ScheduleInitiateEncoding(double quality) override {
-    Platform::Current()->MainThread()->GetWebTaskRunner()->PostTask(
+    Platform::Current()->MainThread()->GetTaskRunner()->PostTask(
         FROM_HERE,
         WTF::Bind(&MockCanvasAsyncBlobCreatorWithoutComplete::InitiateEncoding,
                   WrapPersistent(this), quality,
diff --git a/third_party/WebKit/Source/core/html/media/AutoplayPolicy.cpp b/third_party/WebKit/Source/core/html/media/AutoplayPolicy.cpp
index a6210b2..53cfd0e6 100644
--- a/third_party/WebKit/Source/core/html/media/AutoplayPolicy.cpp
+++ b/third_party/WebKit/Source/core/html/media/AutoplayPolicy.cpp
@@ -17,7 +17,7 @@
 #include "platform/wtf/Assertions.h"
 #include "public/platform/WebMediaPlayer.h"
 #include "public/web/WebSettings.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom-blink.h"
 
 namespace blink {
 
@@ -85,7 +85,7 @@
 
   // Check feature policy before traversing the tree.
   if (!RuntimeEnabledFeatures::FeaturePolicyAutoplayFeatureEnabled() ||
-      !frame.IsFeatureEnabled(FeaturePolicyFeature::kAutoplay)) {
+      !frame.IsFeatureEnabled(mojom::FeaturePolicyFeature::kAutoplay)) {
     return false;
   }
 
diff --git a/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp b/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
index b23b16e..ab3d2ea 100644
--- a/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
+++ b/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
@@ -94,7 +94,7 @@
       viewport_anchor_(DoublePoint(kDefaultAnchorPointX, kDefaultAnchorPointY)),
       scroll_(kDefaultScroll),
       current_top_(0),
-      scroll_timer_(Platform::Current()->CurrentThread()->GetWebTaskRunner(),
+      scroll_timer_(Platform::Current()->CurrentThread()->GetTaskRunner(),
                     this,
                     &VTTRegion::ScrollTimerFired) {}
 
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.cpp b/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.cpp
index 55fbcfc..1982f9960 100644
--- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.cpp
@@ -849,7 +849,7 @@
     skia_image = surface->makeImageSnapshot();
   }
   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
-      Platform::Current()->MainThread()->GetWebTaskRunner();
+      Platform::Current()->MainThread()->GetTaskRunner();
   PostCrossThreadTask(*task_runner, FROM_HERE,
                       CrossThreadBind(&ResolvePromiseOnOriginalThread,
                                       WrapCrossThreadPersistent(resolver),
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.cpp b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.cpp
index bc33d29..a5d4e1a 100644
--- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.cpp
+++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmapFactories.cpp
@@ -303,7 +303,7 @@
 void ImageBitmapFactories::ImageBitmapLoader::ScheduleAsyncImageBitmapDecoding(
     DOMArrayBuffer* array_buffer) {
   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
-      Platform::Current()->CurrentThread()->GetWebTaskRunner();
+      Platform::Current()->CurrentThread()->GetTaskRunner();
   BackgroundTaskRunner::PostOnBackgroundThread(
       FROM_HERE,
       CrossThreadBind(
diff --git a/third_party/WebKit/Source/core/leak_detector/BlinkLeakDetector.cpp b/third_party/WebKit/Source/core/leak_detector/BlinkLeakDetector.cpp
index fcb688b..f1370d0 100644
--- a/third_party/WebKit/Source/core/leak_detector/BlinkLeakDetector.cpp
+++ b/third_party/WebKit/Source/core/leak_detector/BlinkLeakDetector.cpp
@@ -22,10 +22,9 @@
 namespace blink {
 
 BlinkLeakDetector::BlinkLeakDetector(BlinkLeakDetectorClient* client)
-    : delayed_gc_timer_(
-          Platform::Current()->CurrentThread()->GetWebTaskRunner(),
-          this,
-          &BlinkLeakDetector::TimerFiredGC),
+    : delayed_gc_timer_(Platform::Current()->CurrentThread()->GetTaskRunner(),
+                        this,
+                        &BlinkLeakDetector::TimerFiredGC),
       number_of_gc_needed_(0),
       client_(client) {}
 
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
index dbd29b8..00ace92 100644
--- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
@@ -80,7 +80,7 @@
    public:
     explicit EmptyDataReader(WebDataConsumerHandle::Client* client)
         : factory_(this) {
-      Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+      Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
           FROM_HERE, WTF::Bind(&EmptyDataReader::Notify, factory_.GetWeakPtr(),
                                WTF::Unretained(client)));
     }
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.cpp b/third_party/WebKit/Source/core/loader/EmptyClients.cpp
index d65fae5..2eff492d 100644
--- a/third_party/WebKit/Source/core/loader/EmptyClients.cpp
+++ b/third_party/WebKit/Source/core/loader/EmptyClients.cpp
@@ -65,7 +65,7 @@
 
   scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(
       TaskType type) override {
-    return Platform::Current()->MainThread()->GetWebTaskRunner();
+    return Platform::Current()->MainThread()->GetTaskRunner();
   }
 
   void AddThrottlingObserver(ObserverType, Observer*) override {}
diff --git a/third_party/WebKit/Source/core/loader/InteractiveDetector.cpp b/third_party/WebKit/Source/core/loader/InteractiveDetector.cpp
index df2ce33..48f96cc5 100644
--- a/third_party/WebKit/Source/core/loader/InteractiveDetector.cpp
+++ b/third_party/WebKit/Source/core/loader/InteractiveDetector.cpp
@@ -103,11 +103,17 @@
 }
 
 TimeTicks InteractiveDetector::GetInteractiveTime() const {
-  return interactive_time_;
+  // TODO(crbug.com/808685) Simplify FMP and TTI input invalidation.
+  return page_event_times_.first_meaningful_paint_invalidated
+             ? TimeTicks()
+             : interactive_time_;
 }
 
 TimeTicks InteractiveDetector::GetInteractiveDetectionTime() const {
-  return interactive_detection_time_;
+  // TODO(crbug.com/808685) Simplify FMP and TTI input invalidation.
+  return page_event_times_.first_meaningful_paint_invalidated
+             ? TimeTicks()
+             : interactive_detection_time_;
 }
 
 TimeTicks InteractiveDetector::GetFirstInvalidatingInputTime() const {
@@ -239,10 +245,14 @@
   StartOrPostponeCITimer(end_time + kTimeToInteractiveWindow);
 }
 
-void InteractiveDetector::OnFirstMeaningfulPaintDetected(TimeTicks fmp_time) {
+void InteractiveDetector::OnFirstMeaningfulPaintDetected(
+    TimeTicks fmp_time,
+    FirstMeaningfulPaintDetector::HadUserInput user_input_before_fmp) {
   DCHECK(page_event_times_.first_meaningful_paint
              .is_null());  // Should not set FMP twice.
   page_event_times_.first_meaningful_paint = fmp_time;
+  page_event_times_.first_meaningful_paint_invalidated =
+      user_input_before_fmp == FirstMeaningfulPaintDetector::kHadUserInput;
   if (CurrentTimeTicks() - fmp_time >= kTimeToInteractiveWindow) {
     // We may have reached TTCI already. Check right away.
     CheckTimeToInteractiveReached();
@@ -429,8 +439,13 @@
       GetSupplementable()->GetFrame(), "had_user_input_before_interactive",
       had_user_input_before_interactive);
 
-  if (GetSupplementable()->Loader())
-    GetSupplementable()->Loader()->DidChangePerformanceTiming();
+  // We only send TTI to Performance Timing Observers if FMP was not invalidated
+  // by input.
+  // TODO(crbug.com/808685) Simplify FMP and TTI input invalidation.
+  if (!page_event_times_.first_meaningful_paint_invalidated) {
+    if (GetSupplementable()->Loader())
+      GetSupplementable()->Loader()->DidChangePerformanceTiming();
+  }
 }
 
 void InteractiveDetector::Trace(Visitor* visitor) {
diff --git a/third_party/WebKit/Source/core/loader/InteractiveDetector.h b/third_party/WebKit/Source/core/loader/InteractiveDetector.h
index 4b45985..09ef152f 100644
--- a/third_party/WebKit/Source/core/loader/InteractiveDetector.h
+++ b/third_party/WebKit/Source/core/loader/InteractiveDetector.h
@@ -7,6 +7,7 @@
 
 #include "base/macros.h"
 #include "core/CoreExport.h"
+#include "core/paint/FirstMeaningfulPaintDetector.h"
 #include "platform/LongTaskDetector.h"
 #include "platform/PODInterval.h"
 #include "platform/Supplementable.h"
@@ -56,7 +57,9 @@
   void OnResourceLoadEnd(WTF::Optional<TimeTicks> load_finish_time);
 
   void SetNavigationStartTime(TimeTicks navigation_start_time);
-  void OnFirstMeaningfulPaintDetected(TimeTicks fmp_time);
+  void OnFirstMeaningfulPaintDetected(
+      TimeTicks fmp_time,
+      FirstMeaningfulPaintDetector::HadUserInput user_input_before_fmp);
   void OnDomContentLoadedEnd(TimeTicks dcl_time);
   void OnInvalidatingInputEvent(TimeTicks invalidation_time);
   void OnFirstInputDelay(TimeDelta delay_seconds);
@@ -90,13 +93,14 @@
   TimeTicks interactive_detection_time_;
 
   // Page event times that Interactive Detector depends on.
-  // Value of 0.0 indicate the event has not been detected yet.
+  // Null TimeTicks values indicate the event has not been detected yet.
   struct {
     TimeTicks first_meaningful_paint;
     TimeTicks dom_content_loaded_end;
     TimeTicks nav_start;
     TimeTicks first_invalidating_input;
     TimeDelta first_input_delay;
+    bool first_meaningful_paint_invalidated = false;
   } page_event_times_;
 
   // Stores sufficiently long quiet windows on main thread and network.
diff --git a/third_party/WebKit/Source/core/loader/InteractiveDetectorTest.cpp b/third_party/WebKit/Source/core/loader/InteractiveDetectorTest.cpp
index ecc7b622..6230738 100644
--- a/third_party/WebKit/Source/core/loader/InteractiveDetectorTest.cpp
+++ b/third_party/WebKit/Source/core/loader/InteractiveDetectorTest.cpp
@@ -5,6 +5,7 @@
 #include "core/loader/InteractiveDetector.h"
 
 #include "core/dom/Document.h"
+#include "core/paint/FirstMeaningfulPaintDetector.h"
 #include "core/testing/PageTestBase.h"
 #include "platform/CrossThreadFunctional.h"
 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
@@ -82,7 +83,9 @@
 
   void SimulateFMPDetected(double fmp_time, double detection_time) {
     RunTillTimestamp(detection_time);
-    detector_->OnFirstMeaningfulPaintDetected(TimeTicksFromSeconds(fmp_time));
+    detector_->OnFirstMeaningfulPaintDetected(
+        TimeTicksFromSeconds(fmp_time),
+        FirstMeaningfulPaintDetector::kNoUserInput);
   }
 
   void SimulateInteractiveInvalidatingInput(double timestamp) {
@@ -408,7 +411,7 @@
   SimulateFMPDetected(/* fmp_time */ t0 + 3.0, /* detection_time */ t0 + 4.0);
   // Invalidating input timestamp is earlier than navigation start.
   SimulateInteractiveInvalidatingInput(t0 - 10.0);
-  // Run till 5 seconds after long task 2 end.
+  // Run till 5 seconds after FMP.
   RunTillTimestamp((t0 + 7.1) + 5.0 + 0.1);
   EXPECT_EQ(GetInteractiveTime(), t0 + 3.0);  // TTI at FMP.
   // Invalidating input timestamp is clamped at navigation start.
@@ -416,6 +419,28 @@
             t0);
 }
 
+TEST_F(InteractiveDetectorTest, InvalidatedFMP) {
+  double t0 = CurrentTimeTicksInSeconds();
+  SimulateNavigationStart(t0);
+  // Network is forever quiet for this test.
+  SetActiveConnections(1);
+  SimulateInteractiveInvalidatingInput(t0 + 1.0);
+  SimulateDOMContentLoadedEnd(t0 + 2.0);
+  RunTillTimestamp(t0 + 4.0);  // FMP Detection time.
+  GetDetector()->OnFirstMeaningfulPaintDetected(
+      TimeTicksFromSeconds(t0 + 3.0),
+      FirstMeaningfulPaintDetector::kHadUserInput);
+  // Run till 5 seconds after FMP.
+  RunTillTimestamp((t0 + 3.0) + 5.0 + 0.1);
+  // Since FMP was invalidated, we do not have TTI or TTI Detection Time.
+  EXPECT_EQ(GetInteractiveTime(), 0.0);
+  EXPECT_EQ(TimeTicksInSeconds(GetDetector()->GetInteractiveDetectionTime()),
+            0.0);
+  // Invalidating input timestamp is available.
+  EXPECT_EQ(TimeTicksInSeconds(GetDetector()->GetFirstInvalidatingInputTime()),
+            t0 + 1.0);
+}
+
 class InteractiveDetectorTestWithDummyPage : public PageTestBase {
  public:
   // Public because it's executed on a task queue.
@@ -448,11 +473,13 @@
   // DummyPageHolder automatically fires DomContentLoadedEnd, but not First
   // Meaningful Paint. We therefore manually Invoking the listener on
   // InteractiveDetector.
-  detector->OnFirstMeaningfulPaintDetected(TimeTicksFromSeconds(t0 + 3.0));
+  detector->OnFirstMeaningfulPaintDetected(
+      TimeTicksFromSeconds(t0 + 3.0),
+      FirstMeaningfulPaintDetector::kNoUserInput);
 
   // Post a task with 6 seconds duration.
   PostCrossThreadTask(
-      *platform_->CurrentThread()->GetWebTaskRunner(), FROM_HERE,
+      *platform_->CurrentThread()->GetTaskRunner(), FROM_HERE,
       CrossThreadBind(
           &InteractiveDetectorTestWithDummyPage::DummyTaskWithDuration,
           CrossThreadUnretained(this), 6.0));
@@ -473,11 +500,13 @@
   // DummyPageHolder automatically fires DomContentLoadedEnd, but not First
   // Meaningful Paint. We therefore manually Invoking the listener on
   // InteractiveDetector.
-  detector->OnFirstMeaningfulPaintDetected(TimeTicksFromSeconds(t0 + 3.0));
+  detector->OnFirstMeaningfulPaintDetected(
+      TimeTicksFromSeconds(t0 + 3.0),
+      FirstMeaningfulPaintDetector::kNoUserInput);
 
   // Long task 1.
   PostCrossThreadTask(
-      *platform_->CurrentThread()->GetWebTaskRunner(), FROM_HERE,
+      *platform_->CurrentThread()->GetTaskRunner(), FROM_HERE,
       CrossThreadBind(
           &InteractiveDetectorTestWithDummyPage::DummyTaskWithDuration,
           CrossThreadUnretained(this), 0.1));
@@ -491,7 +520,7 @@
 
   // Long task 2.
   PostCrossThreadTask(
-      *platform_->CurrentThread()->GetWebTaskRunner(), FROM_HERE,
+      *platform_->CurrentThread()->GetTaskRunner(), FROM_HERE,
       CrossThreadBind(
           &InteractiveDetectorTestWithDummyPage::DummyTaskWithDuration,
           CrossThreadUnretained(this), 0.1));
diff --git a/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp b/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp
index 024655e..1953b82 100644
--- a/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp
+++ b/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp
@@ -51,7 +51,7 @@
   void DidSendDOMContentLoadedForLinkPrerender() override {}
 
   scoped_refptr<base::SingleThreadTaskRunner> GetLoadingTaskRunner() override {
-    return Platform::Current()->CurrentThread()->GetWebTaskRunner();
+    return Platform::Current()->CurrentThread()->GetTaskRunner();
   }
 
  private:
diff --git a/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp b/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
index 37dac6e..8c63229 100644
--- a/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/ImageResource.cpp
@@ -308,7 +308,7 @@
   // after a conservative GC prevents resetAnimation() from upsetting ongoing
   // animation updates (crbug.com/613709)
   if (!ThreadHeap::WillObjectBeLazilySwept(this)) {
-    Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+    Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
         FROM_HERE, WTF::Bind(&ImageResourceContent::DoResetAnimation,
                              WrapWeakPersistent(GetContent())));
   } else {
diff --git a/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.cpp b/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.cpp
index 5582cd2..7d96cde2 100644
--- a/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.cpp
+++ b/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.cpp
@@ -231,7 +231,7 @@
          (image_ && image_->MaybeAnimated());
 }
 
-blink::Image* ImageResourceContent::GetImage() {
+blink::Image* ImageResourceContent::GetImage() const {
   if (!image_ || ErrorOccurred())
     return Image::NullImage();
 
diff --git a/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.h b/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.h
index 68c3f5f..4be2876 100644
--- a/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.h
+++ b/third_party/WebKit/Source/core/loader/resource/ImageResourceContent.h
@@ -58,7 +58,7 @@
   static ImageResourceContent* Fetch(FetchParameters&, ResourceFetcher*);
 
   // Returns the NullImage() if the image is not available yet.
-  blink::Image* GetImage();
+  blink::Image* GetImage() const;
   bool HasImage() const { return image_.get(); }
 
   // The device pixel ratio we got from the server for this image, or 1.0.
diff --git a/third_party/WebKit/Source/core/paint/PaintTiming.cpp b/third_party/WebKit/Source/core/paint/PaintTiming.cpp
index 84da59c..900fcbb 100644
--- a/third_party/WebKit/Source/core/paint/PaintTiming.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintTiming.cpp
@@ -112,7 +112,7 @@
   InteractiveDetector* interactive_detector(
       InteractiveDetector::From(*GetSupplementable()));
   if (interactive_detector) {
-    interactive_detector->OnFirstMeaningfulPaintDetected(swap_stamp);
+    interactive_detector->OnFirstMeaningfulPaintDetected(swap_stamp, had_input);
   }
 
   // Notify FMP for UMA only if there's no user input before FMP, so that layout
diff --git a/third_party/WebKit/Source/core/script/ModuleMapTest.cpp b/third_party/WebKit/Source/core/script/ModuleMapTest.cpp
index 2d7dfe2..71111039 100644
--- a/third_party/WebKit/Source/core/script/ModuleMapTest.cpp
+++ b/third_party/WebKit/Source/core/script/ModuleMapTest.cpp
@@ -98,7 +98,7 @@
   }
 
   base::SingleThreadTaskRunner* TaskRunner() override {
-    return Platform::Current()->CurrentThread()->GetWebTaskRunner();
+    return Platform::Current()->CurrentThread()->GetTaskRunner().get();
   };
 
   void FetchNewSingleModule(const ModuleScriptFetchRequest&,
diff --git a/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp b/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp
index 4227d8b..eb58aa9 100644
--- a/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp
+++ b/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp
@@ -48,7 +48,7 @@
 
 scoped_refptr<base::SingleThreadTaskRunner> NullExecutionContext::GetTaskRunner(
     TaskType) {
-  return Platform::Current()->CurrentThread()->GetWebTaskRunner();
+  return Platform::Current()->CurrentThread()->GetTaskRunner();
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp
index 028afb51..f410ce8 100644
--- a/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp
+++ b/third_party/WebKit/Source/core/workers/ParentFrameTaskRunners.cpp
@@ -31,9 +31,9 @@
                     TaskType::kNetworking, TaskType::kPostedMessage,
                     TaskType::kCanvasBlobSerialization, TaskType::kUnthrottled,
                     TaskType::kInternalTest}) {
-    auto task_runner =
-        frame ? frame->GetTaskRunner(type)
-              : Platform::Current()->MainThread()->GetWebTaskRunner();
+    auto task_runner = frame
+                           ? frame->GetTaskRunner(type)
+                           : Platform::Current()->MainThread()->GetTaskRunner();
     task_runners_.insert(type, std::move(task_runner));
   }
 }
@@ -51,7 +51,7 @@
 void ParentFrameTaskRunners::ContextDestroyed(ExecutionContext*) {
   MutexLocker lock(task_runners_mutex_);
   for (auto& entry : task_runners_)
-    entry.value = Platform::Current()->CurrentThread()->GetWebTaskRunner();
+    entry.value = Platform::Current()->CurrentThread()->GetTaskRunner();
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/workers/WorkerBackingThread.cpp b/third_party/WebKit/Source/core/workers/WorkerBackingThread.cpp
index 9519c79..50ae5fe 100644
--- a/third_party/WebKit/Source/core/workers/WorkerBackingThread.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerBackingThread.cpp
@@ -77,7 +77,7 @@
 
   DCHECK(!isolate_);
   isolate_ = V8PerIsolateData::Initialize(
-      backing_thread_->PlatformThread().GetWebTaskRunner(),
+      backing_thread_->PlatformThread().GetTaskRunner(),
       V8PerIsolateData::V8ContextSnapshotMode::kDontUseSnapshot);
   AddWorkerIsolate(isolate_);
   V8Initializer::InitializeWorker(isolate_);
diff --git a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
index e34d3ca62..8563aa1 100644
--- a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
+++ b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
@@ -88,7 +88,7 @@
 #include "platform/wtf/text/CString.h"
 #include "public/platform/WebCORS.h"
 #include "public/platform/WebURLRequest.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom-blink.h"
 
 namespace blink {
 
@@ -767,9 +767,9 @@
 
   if (!async_) {
     if (GetExecutionContext()->IsDocument() &&
-        IsSupportedInFeaturePolicy(FeaturePolicyFeature::kSyncXHR) &&
+        IsSupportedInFeaturePolicy(mojom::FeaturePolicyFeature::kSyncXHR) &&
         !GetDocument()->GetFrame()->IsFeatureEnabled(
-            FeaturePolicyFeature::kSyncXHR)) {
+            mojom::FeaturePolicyFeature::kSyncXHR)) {
       LogConsoleError(GetExecutionContext(),
                       "Synchronous requests are disabled by Feature Policy.");
       HandleNetworkError();
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js b/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js
index 596d9e9e..795d64e30 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js
@@ -112,7 +112,7 @@
     if (fromURL === toSourceCode.url()) {
       var provisionalBreakpoints = this._provisionalBreakpointsForURL(fromURL);
       for (var breakpoint of provisionalBreakpoints.values())
-        breakpoint.remove();
+        breakpoint.remove(true /* keepInStorage */);
     }
   }
 
@@ -358,7 +358,7 @@
   removeAllBreakpoints() {
     var breakpoints = this._allBreakpoints();
     for (var i = 0; i < breakpoints.length; ++i)
-      breakpoints[i].remove();
+      breakpoints[i].remove(false /* keepInStorage */);
   }
 
   /**
@@ -368,7 +368,7 @@
     var allBreakpoints = this._allBreakpoints();
     allBreakpoints.forEach(breakpoint => {
       if (!selectedBreakpoints.has(breakpoint))
-        breakpoint.remove();
+        breakpoint.remove(false /* keepInStorage */);
     });
   }
 
@@ -651,7 +651,7 @@
   }
 
   /**
-   * @param {boolean=} keepInStorage
+   * @param {boolean} keepInStorage
    */
   remove(keepInStorage) {
     this._isRemoved = true;
@@ -926,7 +926,7 @@
         uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
     if (breakpoint && breakpoint !== this._breakpoint) {
       // location clash
-      this._breakpoint.remove();
+      this._breakpoint.remove(false /* keepInStorage */);
       return false;
     }
     this._debuggerWorkspaceBinding.createLiveLocation(
diff --git a/third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js b/third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js
index 83fa3e7..2351da31 100644
--- a/third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js
+++ b/third_party/WebKit/Source/devtools/front_end/persistence/Persistence.js
@@ -259,7 +259,7 @@
   _moveBreakpoints(from, to) {
     var breakpoints = this._breakpointManager.breakpointsForUISourceCode(from);
     for (var breakpoint of breakpoints) {
-      breakpoint.remove();
+      breakpoint.remove(true /* keepInStorage */);
       this._breakpointManager.setBreakpoint(
           to, breakpoint.lineNumber(), breakpoint.columnNumber(), breakpoint.condition(), breakpoint.enabled());
     }
diff --git a/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js b/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js
index 98066f8e..c1bf7ab 100644
--- a/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/snippets/ScriptSnippetModel.js
@@ -305,7 +305,7 @@
   _removeBreakpoints(uiSourceCode) {
     var breakpointLocations = Bindings.breakpointManager.breakpointLocationsForUISourceCode(uiSourceCode);
     for (var i = 0; i < breakpointLocations.length; ++i)
-      breakpointLocations[i].breakpoint.remove();
+      breakpointLocations[i].breakpoint.remove(false /* keepInStorage */);
     return breakpointLocations;
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js
index b10a881..ec33d74 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptBreakpointsSidebarPane.js
@@ -181,7 +181,8 @@
     var contextMenu = new UI.ContextMenu(event);
     var removeEntryTitle = breakpoints.length > 1 ? Common.UIString('Remove all breakpoints in line') :
                                                     Common.UIString('Remove breakpoint');
-    contextMenu.defaultSection().appendItem(removeEntryTitle, () => breakpoints.map(breakpoint => breakpoint.remove()));
+    contextMenu.defaultSection().appendItem(
+        removeEntryTitle, () => breakpoints.map(breakpoint => breakpoint.remove(false /* keepInStorage */)));
 
     var breakpointActive = this._breakpointManager.breakpointsActive();
     var breakpointActiveTitle =
diff --git a/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.cpp b/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.cpp
index fb22d62..d43b05b 100644
--- a/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.cpp
@@ -65,9 +65,26 @@
   if (!HasDocumentDefinition())
     return false;
   definition = paint_worklet_->GetDocumentDefinitionMap().at(name_);
+  if (definition != kInvalidDocumentPaintDefinition &&
+      definition->GetRegisteredDefinitionCount() !=
+          PaintWorklet::kNumGlobalScopes) {
+    definition = kInvalidDocumentPaintDefinition;
+    return false;
+  }
   return definition != kInvalidDocumentPaintDefinition;
 }
 
+unsigned CSSPaintImageGeneratorImpl::GetRegisteredDefinitionCountForTesting()
+    const {
+  if (!HasDocumentDefinition())
+    return 0;
+  DocumentPaintDefinition* definition =
+      paint_worklet_->GetDocumentDefinitionMap().at(name_);
+  if (definition == kInvalidDocumentPaintDefinition)
+    return 0;
+  return definition->GetRegisteredDefinitionCount();
+}
+
 const Vector<CSSPropertyID>&
 CSSPaintImageGeneratorImpl::NativeInvalidationProperties() const {
   DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, empty_vector, ());
diff --git a/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.h b/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.h
index 154c47a..26b06bc 100644
--- a/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.h
+++ b/third_party/WebKit/Source/modules/csspaint/CSSPaintImageGeneratorImpl.h
@@ -7,6 +7,7 @@
 
 #include "core/css/CSSPaintImageGenerator.h"
 #include "core/css/cssom/CSSStyleValue.h"
+#include "modules/ModulesExport.h"
 #include "platform/bindings/ScopedPersistent.h"
 #include "platform/geometry/IntSize.h"
 #include "platform/heap/Handle.h"
@@ -20,7 +21,8 @@
 class Image;
 class PaintWorklet;
 
-class CSSPaintImageGeneratorImpl final : public CSSPaintImageGenerator {
+class MODULES_EXPORT CSSPaintImageGeneratorImpl final
+    : public CSSPaintImageGenerator {
  public:
   static CSSPaintImageGenerator* Create(const String& name,
                                         const Document&,
@@ -41,6 +43,12 @@
   // is registered with the same name.
   void NotifyGeneratorReady();
 
+  bool GetValidDocumentDefinitionForTesting(
+      DocumentPaintDefinition*& definition) const {
+    return GetValidDocumentDefinition(definition);
+  }
+  unsigned GetRegisteredDefinitionCountForTesting() const;
+
   void Trace(blink::Visitor*) override;
 
  private:
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletTest.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorkletTest.cpp
index c0a3aac..20ee912 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletTest.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletTest.cpp
@@ -160,6 +160,25 @@
   EXPECT_NE(image, nullptr);
 }
 
+// In this test, we have only one global scope, which means registerPaint is
+// called only once, and hence we have only one document paint definition
+// registered. In the real world, this document paint definition should not be
+// used to paint until we see a second one being registed with the same name.
+TEST_F(PaintWorkletTest, SinglyRegisteredDocumentDefinitionNotUsed) {
+  PaintWorkletGlobalScope* global_scope = GetProxy()->global_scope();
+  global_scope->ScriptController()->Evaluate(
+      ScriptSourceCode("registerPaint('foo', class { paint() { } });"));
+
+  CSSPaintImageGeneratorImpl* generator =
+      static_cast<CSSPaintImageGeneratorImpl*>(
+          CSSPaintImageGeneratorImpl::Create("foo", GetDocument(), nullptr));
+  EXPECT_TRUE(generator);
+  EXPECT_EQ(generator->GetRegisteredDefinitionCountForTesting(), 1u);
+  DocumentPaintDefinition* definition;
+  EXPECT_FALSE(generator->GetValidDocumentDefinitionForTesting(definition));
+  EXPECT_FALSE(definition);
+}
+
 // In this test, we set a list of "paints_to_switch" numbers, and in each frame,
 // we switch to a new global scope when the number of paint calls is >= the
 // corresponding number.
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionController.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionController.cpp
index e3d7acb..6658a3e 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionController.cpp
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionController.cpp
@@ -67,8 +67,8 @@
           "DeviceSensors.DeviceMotionCrossOrigin", WebURL(GetDocument().Url()));
     }
 
-    if (!CheckPolicyFeatures({FeaturePolicyFeature::kAccelerometer,
-                              FeaturePolicyFeature::kGyroscope})) {
+    if (!CheckPolicyFeatures({mojom::FeaturePolicyFeature::kAccelerometer,
+                              mojom::FeaturePolicyFeature::kGyroscope})) {
       DeviceOrientationController::LogToConsolePolicyFeaturesDisabled(
           frame, EventTypeName());
       return;
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationAbsoluteController.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationAbsoluteController.cpp
index 16838f6..ca0f17a 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationAbsoluteController.cpp
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationAbsoluteController.cpp
@@ -59,9 +59,9 @@
   if (!has_event_listener_) {
     // TODO: add rappor url logging as in DeviceOrientationController.
 
-    if (!CheckPolicyFeatures({FeaturePolicyFeature::kAccelerometer,
-                              FeaturePolicyFeature::kGyroscope,
-                              FeaturePolicyFeature::kMagnetometer})) {
+    if (!CheckPolicyFeatures({mojom::FeaturePolicyFeature::kAccelerometer,
+                              mojom::FeaturePolicyFeature::kGyroscope,
+                              mojom::FeaturePolicyFeature::kMagnetometer})) {
       LogToConsolePolicyFeaturesDisabled(frame, EventTypeName());
       return;
     }
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationController.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationController.cpp
index 04cbcc4..ace93d0 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationController.cpp
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationController.cpp
@@ -82,8 +82,8 @@
           WebURL(GetDocument().Url()));
     }
 
-    if (!CheckPolicyFeatures({FeaturePolicyFeature::kAccelerometer,
-                              FeaturePolicyFeature::kGyroscope})) {
+    if (!CheckPolicyFeatures({mojom::FeaturePolicyFeature::kAccelerometer,
+                              mojom::FeaturePolicyFeature::kGyroscope})) {
       LogToConsolePolicyFeaturesDisabled(frame, EventTypeName());
       return;
     }
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
index 6945a59..f12992ab 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
+++ b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
@@ -32,7 +32,7 @@
 #include "public/platform/WebMediaKeySystemConfiguration.h"
 #include "public/platform/WebMediaKeySystemMediaCapability.h"
 #include "public/platform/WebVector.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom-blink.h"
 
 namespace blink {
 
@@ -279,8 +279,9 @@
   Document* document = ToDocument(execution_context);
 
   if (RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
-    if (!document->GetFrame() || !document->GetFrame()->IsFeatureEnabled(
-                                     FeaturePolicyFeature::kEncryptedMedia)) {
+    if (!document->GetFrame() ||
+        !document->GetFrame()->IsFeatureEnabled(
+            mojom::FeaturePolicyFeature::kEncryptedMedia)) {
       UseCounter::Count(document,
                         WebFeature::kEncryptedMediaDisabledByFeaturePolicy);
       document->AddConsoleMessage(
@@ -294,7 +295,7 @@
     }
   } else {
     Deprecation::CountDeprecationFeaturePolicy(
-        *document, FeaturePolicyFeature::kEncryptedMedia);
+        *document, mojom::FeaturePolicyFeature::kEncryptedMedia);
   }
 
   // From https://w3c.github.io/encrypted-media/#requestMediaKeySystemAccess
diff --git a/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp b/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp
index e5cd1930..98f740e 100644
--- a/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp
+++ b/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp
@@ -41,7 +41,7 @@
 #include "platform/wtf/Time.h"
 #include "public/platform/Platform.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom-blink.h"
 
 namespace blink {
 namespace {
@@ -162,7 +162,7 @@
         *document, WebFeature::kGeolocationSecureOriginIframe);
     if (!RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
       Deprecation::CountDeprecationFeaturePolicy(
-          *document, FeaturePolicyFeature::kGeolocation);
+          *document, mojom::FeaturePolicyFeature::kGeolocation);
     }
   } else if (GetFrame()
                  ->GetSettings()
@@ -180,7 +180,7 @@
         *document, HostsUsingFeatures::Feature::kGeolocationInsecureHost);
     if (!RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
       Deprecation::CountDeprecationFeaturePolicy(
-          *document, FeaturePolicyFeature::kGeolocation);
+          *document, mojom::FeaturePolicyFeature::kGeolocation);
     }
   } else {
     Deprecation::CountDeprecation(document,
@@ -241,7 +241,8 @@
   }
 
   if (RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
-    if (!GetFrame()->IsFeatureEnabled(FeaturePolicyFeature::kGeolocation)) {
+    if (!GetFrame()->IsFeatureEnabled(
+            mojom::FeaturePolicyFeature::kGeolocation)) {
       UseCounter::Count(GetDocument(),
                         WebFeature::kGeolocationDisabledByFeaturePolicy);
       GetDocument()->AddConsoleMessage(
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsOrientationLockDelegateTest.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsOrientationLockDelegateTest.cpp
index b168f8f1d..f3a5cbd 100644
--- a/third_party/WebKit/Source/modules/media_controls/MediaControlsOrientationLockDelegateTest.cpp
+++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsOrientationLockDelegateTest.cpp
@@ -115,12 +115,12 @@
   // The real ChromeClient::EnterFullscreen/ExitFullscreen implementation is
   // async due to IPC, emulate that by posting tasks:
   void EnterFullscreen(LocalFrame& frame) override {
-    Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+    Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
         FROM_HERE,
         WTF::Bind(DidEnterFullscreen, WrapPersistent(frame.GetDocument())));
   }
   void ExitFullscreen(LocalFrame& frame) override {
-    Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+    Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
         FROM_HERE,
         WTF::Bind(DidExitFullscreen, WrapPersistent(frame.GetDocument())));
   }
diff --git a/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp b/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp
index 17d032b..f30bd51e3 100644
--- a/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp
+++ b/third_party/WebKit/Source/modules/mediastream/UserMediaRequest.cpp
@@ -51,7 +51,7 @@
 #include "modules/mediastream/UserMediaController.h"
 #include "platform/mediastream/MediaStreamCenter.h"
 #include "platform/mediastream/MediaStreamDescriptor.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom-blink.h"
 
 namespace blink {
 
@@ -465,25 +465,25 @@
     if (Audio()) {
       if (RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
         if (!document->GetFrame()->IsFeatureEnabled(
-                FeaturePolicyFeature::kMicrophone)) {
+                mojom::FeaturePolicyFeature::kMicrophone)) {
           UseCounter::Count(
               document, WebFeature::kMicrophoneDisabledByFeaturePolicyEstimate);
         }
       } else {
         Deprecation::CountDeprecationFeaturePolicy(
-            *document, FeaturePolicyFeature::kMicrophone);
+            *document, mojom::FeaturePolicyFeature::kMicrophone);
       }
     }
     if (Video()) {
       if (RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
         if (!document->GetFrame()->IsFeatureEnabled(
-                FeaturePolicyFeature::kCamera)) {
+                mojom::FeaturePolicyFeature::kCamera)) {
           UseCounter::Count(document,
                             WebFeature::kCameraDisabledByFeaturePolicyEstimate);
         }
       } else {
         Deprecation::CountDeprecationFeaturePolicy(
-            *document, FeaturePolicyFeature::kCamera);
+            *document, mojom::FeaturePolicyFeature::kCamera);
       }
     }
 
diff --git a/third_party/WebKit/Source/modules/notifications/Notification.cpp b/third_party/WebKit/Source/modules/notifications/Notification.cpp
index 8057b40..aad30538 100644
--- a/third_party/WebKit/Source/modules/notifications/Notification.cpp
+++ b/third_party/WebKit/Source/modules/notifications/Notification.cpp
@@ -250,6 +250,11 @@
 
   state_ = State::kClosed;
 
+  if (RuntimeEnabledFeatures::NotificationsWithMojoEnabled()) {
+    // TODO(https://crbug.com/796991): Implement this via mojo.
+    return;
+  }
+
   const SecurityOrigin* origin = GetExecutionContext()->GetSecurityOrigin();
   DCHECK(origin);
 
diff --git a/third_party/WebKit/Source/modules/notifications/ServiceWorkerRegistrationNotifications.cpp b/third_party/WebKit/Source/modules/notifications/ServiceWorkerRegistrationNotifications.cpp
index 0e6bc67..08ae0d05 100644
--- a/third_party/WebKit/Source/modules/notifications/ServiceWorkerRegistrationNotifications.cpp
+++ b/third_party/WebKit/Source/modules/notifications/ServiceWorkerRegistrationNotifications.cpp
@@ -20,6 +20,7 @@
 #include "modules/serviceworkers/ServiceWorkerRegistration.h"
 #include "platform/Histogram.h"
 #include "platform/heap/Handle.h"
+#include "platform/runtime_enabled_features.h"
 #include "platform/wtf/Assertions.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebSecurityOrigin.h"
@@ -123,12 +124,16 @@
       std::make_unique<CallbackPromiseAdapter<NotificationArray, void>>(
           resolver);
 
-  WebNotificationManager* notification_manager =
-      Platform::Current()->GetWebNotificationManager();
-  DCHECK(notification_manager);
+  if (RuntimeEnabledFeatures::NotificationsWithMojoEnabled()) {
+    // TODO(https://crbug.com/796991): Implement this via mojo.
+  } else {
+    WebNotificationManager* notification_manager =
+        Platform::Current()->GetWebNotificationManager();
+    DCHECK(notification_manager);
 
-  notification_manager->GetNotifications(
-      options.tag(), registration.WebRegistration(), std::move(callbacks));
+    notification_manager->GetNotifications(
+        options.tag(), registration.WebRegistration(), std::move(callbacks));
+  }
   return promise;
 }
 
@@ -185,13 +190,17 @@
     NotificationResourcesLoader* loader) {
   DCHECK(loaders_.Contains(loader));
 
-  WebNotificationManager* notification_manager =
-      Platform::Current()->GetWebNotificationManager();
-  DCHECK(notification_manager);
+  if (RuntimeEnabledFeatures::NotificationsWithMojoEnabled()) {
+    // TODO(https://crbug.com/796991): Implement this via mojo.
+  } else {
+    WebNotificationManager* notification_manager =
+        Platform::Current()->GetWebNotificationManager();
+    DCHECK(notification_manager);
 
-  notification_manager->ShowPersistent(
-      WebSecurityOrigin(origin.get()), data, loader->GetResources(),
-      registration_->WebRegistration(), std::move(callbacks));
+    notification_manager->ShowPersistent(
+        WebSecurityOrigin(origin.get()), data, loader->GetResources(),
+        registration_->WebRegistration(), std::move(callbacks));
+  }
   loaders_.erase(loader);
 }
 
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
index d374b41..43965dc 100644
--- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
+++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
@@ -746,7 +746,7 @@
   if (!frame)
     return false;
 
-  if (!IsSupportedInFeaturePolicy(FeaturePolicyFeature::kPayment)) {
+  if (!IsSupportedInFeaturePolicy(mojom::FeaturePolicyFeature::kPayment)) {
     // 2. If |document|'s browsing context is a top-level browsing context, then
     // return true.
     if (frame->IsMainFrame())
@@ -764,7 +764,7 @@
   }
 
   // 2. If Feature Policy is enabled, return the policy for "payment" feature.
-  return frame->IsFeatureEnabled(FeaturePolicyFeature::kPayment);
+  return frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kPayment);
 }
 
 void WarnIgnoringQueryQuotaForCanMakePayment(
diff --git a/third_party/WebKit/Source/modules/picture_in_picture/PictureInPictureController.cpp b/third_party/WebKit/Source/modules/picture_in_picture/PictureInPictureController.cpp
index 6f5df9a..633118d 100644
--- a/third_party/WebKit/Source/modules/picture_in_picture/PictureInPictureController.cpp
+++ b/third_party/WebKit/Source/modules/picture_in_picture/PictureInPictureController.cpp
@@ -54,9 +54,9 @@
   // If document is not allowed to use the policy-controlled feature named
   // "picture-in-picture", return kDisabledByFeaturePolicy status.
   if (IsSupportedInFeaturePolicy(
-          blink::FeaturePolicyFeature::kPictureInPicture) &&
+          blink::mojom::FeaturePolicyFeature::kPictureInPicture) &&
       !frame->IsFeatureEnabled(
-          blink::FeaturePolicyFeature::kPictureInPicture)) {
+          blink::mojom::FeaturePolicyFeature::kPictureInPicture)) {
     return Status::kDisabledByFeaturePolicy;
   }
 
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationAvailabilityState.cpp b/third_party/WebKit/Source/modules/presentation/PresentationAvailabilityState.cpp
index 5109dac..161799f 100644
--- a/third_party/WebKit/Source/modules/presentation/PresentationAvailabilityState.cpp
+++ b/third_party/WebKit/Source/modules/presentation/PresentationAvailabilityState.cpp
@@ -23,7 +23,7 @@
   auto screen_availability = GetScreenAvailability(urls);
   // Reject Promise if screen availability is unsupported for all URLs.
   if (screen_availability == mojom::blink::ScreenAvailability::DISABLED) {
-    Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+    Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
         FROM_HERE,
         WTF::Bind(
             &PresentationAvailabilityCallbacks::RejectAvailabilityNotSupported,
@@ -39,7 +39,7 @@
   }
 
   if (screen_availability != mojom::blink::ScreenAvailability::UNKNOWN) {
-    Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+    Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
         FROM_HERE, WTF::Bind(&PresentationAvailabilityCallbacks::Resolve,
                              std::move(callback),
                              screen_availability ==
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp
index eb1575d2..f29512ae 100644
--- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp
@@ -175,9 +175,9 @@
     return;
   }
 
-  auto callback =
-      WTF::Bind(&RequestStorageQuotaCallback, WrapPersistent(success_callback),
-                WrapPersistent(error_callback));
+  auto callback = WTF::Bind(&RequestStorageQuotaCallback,
+                            WrapPersistentCallbackFunction(success_callback),
+                            WrapPersistentCallbackFunction(error_callback));
 
   Document* document = ToDocument(execution_context);
   const SecurityOrigin* security_origin = document->GetSecurityOrigin();
diff --git a/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.cpp b/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.cpp
index 6dfed6c4..ebb6bc1 100644
--- a/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.cpp
+++ b/third_party/WebKit/Source/modules/sensor/AbsoluteOrientationSensor.cpp
@@ -31,9 +31,9 @@
                         options,
                         exception_state,
                         SensorType::ABSOLUTE_ORIENTATION_QUATERNION,
-                        {FeaturePolicyFeature::kAccelerometer,
-                         FeaturePolicyFeature::kGyroscope,
-                         FeaturePolicyFeature::kMagnetometer}) {}
+                        {mojom::FeaturePolicyFeature::kAccelerometer,
+                         mojom::FeaturePolicyFeature::kGyroscope,
+                         mojom::FeaturePolicyFeature::kMagnetometer}) {}
 
 void AbsoluteOrientationSensor::Trace(blink::Visitor* visitor) {
   OrientationSensor::Trace(visitor);
diff --git a/third_party/WebKit/Source/modules/sensor/Accelerometer.cpp b/third_party/WebKit/Source/modules/sensor/Accelerometer.cpp
index 7af7acb9..75df4b8 100644
--- a/third_party/WebKit/Source/modules/sensor/Accelerometer.cpp
+++ b/third_party/WebKit/Source/modules/sensor/Accelerometer.cpp
@@ -13,7 +13,7 @@
                                      ExceptionState& exception_state) {
   return new Accelerometer(execution_context, options, exception_state,
                            SensorType::ACCELEROMETER,
-                           {FeaturePolicyFeature::kAccelerometer});
+                           {mojom::FeaturePolicyFeature::kAccelerometer});
 }
 
 // static
@@ -22,11 +22,12 @@
   return Create(execution_context, SpatialSensorOptions(), exception_state);
 }
 
-Accelerometer::Accelerometer(ExecutionContext* execution_context,
-                             const SpatialSensorOptions& options,
-                             ExceptionState& exception_state,
-                             SensorType sensor_type,
-                             const Vector<FeaturePolicyFeature>& features)
+Accelerometer::Accelerometer(
+    ExecutionContext* execution_context,
+    const SpatialSensorOptions& options,
+    ExceptionState& exception_state,
+    SensorType sensor_type,
+    const Vector<mojom::FeaturePolicyFeature>& features)
     : Sensor(execution_context,
              options,
              exception_state,
diff --git a/third_party/WebKit/Source/modules/sensor/Accelerometer.h b/third_party/WebKit/Source/modules/sensor/Accelerometer.h
index b8f6d8c9..373f622 100644
--- a/third_party/WebKit/Source/modules/sensor/Accelerometer.h
+++ b/third_party/WebKit/Source/modules/sensor/Accelerometer.h
@@ -30,7 +30,7 @@
                 const SpatialSensorOptions&,
                 ExceptionState&,
                 device::mojom::blink::SensorType,
-                const Vector<FeaturePolicyFeature>&);
+                const Vector<mojom::FeaturePolicyFeature>&);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.cpp b/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.cpp
index 79c3ccf..3c9d819 100644
--- a/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.cpp
+++ b/third_party/WebKit/Source/modules/sensor/AmbientLightSensor.cpp
@@ -33,7 +33,7 @@
              options,
              exception_state,
              SensorType::AMBIENT_LIGHT,
-             {FeaturePolicyFeature::kAmbientLightSensor}) {}
+             {mojom::FeaturePolicyFeature::kAmbientLightSensor}) {}
 
 double AmbientLightSensor::illuminance(bool& is_null) const {
   INIT_IS_NULL_AND_RETURN(is_null, 0.0);
diff --git a/third_party/WebKit/Source/modules/sensor/Gyroscope.cpp b/third_party/WebKit/Source/modules/sensor/Gyroscope.cpp
index 65544e0..8236434 100644
--- a/third_party/WebKit/Source/modules/sensor/Gyroscope.cpp
+++ b/third_party/WebKit/Source/modules/sensor/Gyroscope.cpp
@@ -28,7 +28,7 @@
              options,
              exception_state,
              SensorType::GYROSCOPE,
-             {FeaturePolicyFeature::kGyroscope}) {}
+             {mojom::FeaturePolicyFeature::kGyroscope}) {}
 
 double Gyroscope::x(bool& is_null) const {
   INIT_IS_NULL_AND_RETURN(is_null, 0.0);
diff --git a/third_party/WebKit/Source/modules/sensor/LinearAccelerationSensor.cpp b/third_party/WebKit/Source/modules/sensor/LinearAccelerationSensor.cpp
index a347010..b08b2639 100644
--- a/third_party/WebKit/Source/modules/sensor/LinearAccelerationSensor.cpp
+++ b/third_party/WebKit/Source/modules/sensor/LinearAccelerationSensor.cpp
@@ -31,7 +31,7 @@
                     options,
                     exception_state,
                     SensorType::LINEAR_ACCELERATION,
-                    {FeaturePolicyFeature::kAccelerometer}) {}
+                    {mojom::FeaturePolicyFeature::kAccelerometer}) {}
 
 void LinearAccelerationSensor::Trace(blink::Visitor* visitor) {
   Accelerometer::Trace(visitor);
diff --git a/third_party/WebKit/Source/modules/sensor/Magnetometer.cpp b/third_party/WebKit/Source/modules/sensor/Magnetometer.cpp
index e0bd3f00..505861c 100644
--- a/third_party/WebKit/Source/modules/sensor/Magnetometer.cpp
+++ b/third_party/WebKit/Source/modules/sensor/Magnetometer.cpp
@@ -28,7 +28,7 @@
              options,
              exception_state,
              SensorType::MAGNETOMETER,
-             {FeaturePolicyFeature::kMagnetometer}) {}
+             {mojom::FeaturePolicyFeature::kMagnetometer}) {}
 
 double Magnetometer::x(bool& is_null) const {
   INIT_IS_NULL_AND_RETURN(is_null, 0.0);
diff --git a/third_party/WebKit/Source/modules/sensor/OrientationSensor.cpp b/third_party/WebKit/Source/modules/sensor/OrientationSensor.cpp
index f1925bc0..5b211b6 100644
--- a/third_party/WebKit/Source/modules/sensor/OrientationSensor.cpp
+++ b/third_party/WebKit/Source/modules/sensor/OrientationSensor.cpp
@@ -119,7 +119,7 @@
     const SensorOptions& options,
     ExceptionState& exception_state,
     device::mojom::blink::SensorType type,
-    const Vector<FeaturePolicyFeature>& features)
+    const Vector<mojom::FeaturePolicyFeature>& features)
     : Sensor(execution_context, options, exception_state, type, features),
       reading_dirty_(true) {}
 
diff --git a/third_party/WebKit/Source/modules/sensor/OrientationSensor.h b/third_party/WebKit/Source/modules/sensor/OrientationSensor.h
index 7091bda..cc87558 100644
--- a/third_party/WebKit/Source/modules/sensor/OrientationSensor.h
+++ b/third_party/WebKit/Source/modules/sensor/OrientationSensor.h
@@ -27,7 +27,7 @@
                     const SensorOptions&,
                     ExceptionState&,
                     device::mojom::blink::SensorType,
-                    const Vector<FeaturePolicyFeature>& features);
+                    const Vector<mojom::FeaturePolicyFeature>& features);
 
  private:
   // SensorProxy override.
diff --git a/third_party/WebKit/Source/modules/sensor/RelativeOrientationSensor.cpp b/third_party/WebKit/Source/modules/sensor/RelativeOrientationSensor.cpp
index cf7d69b..0b26173 100644
--- a/third_party/WebKit/Source/modules/sensor/RelativeOrientationSensor.cpp
+++ b/third_party/WebKit/Source/modules/sensor/RelativeOrientationSensor.cpp
@@ -31,8 +31,8 @@
                         options,
                         exception_state,
                         SensorType::RELATIVE_ORIENTATION_QUATERNION,
-                        {FeaturePolicyFeature::kAccelerometer,
-                         FeaturePolicyFeature::kGyroscope}) {}
+                        {mojom::FeaturePolicyFeature::kAccelerometer,
+                         mojom::FeaturePolicyFeature::kGyroscope}) {}
 
 void RelativeOrientationSensor::Trace(blink::Visitor* visitor) {
   OrientationSensor::Trace(visitor);
diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.cpp b/third_party/WebKit/Source/modules/sensor/Sensor.cpp
index 1a340cf9..8ea9b70 100644
--- a/third_party/WebKit/Source/modules/sensor/Sensor.cpp
+++ b/third_party/WebKit/Source/modules/sensor/Sensor.cpp
@@ -23,9 +23,9 @@
 const double kWaitingIntervalThreshold = 0.01;
 
 bool AreFeaturesEnabled(LocalFrame* frame,
-                        const Vector<FeaturePolicyFeature>& features) {
+                        const Vector<mojom::FeaturePolicyFeature>& features) {
   return std::all_of(features.begin(), features.end(),
-                     [frame](FeaturePolicyFeature feature) {
+                     [frame](mojom::FeaturePolicyFeature feature) {
                        return frame->IsFeatureEnabled(feature);
                      });
 }
@@ -36,7 +36,7 @@
                const SensorOptions& sensor_options,
                ExceptionState& exception_state,
                device::mojom::blink::SensorType type,
-               const Vector<FeaturePolicyFeature>& features)
+               const Vector<mojom::FeaturePolicyFeature>& features)
     : ContextLifecycleObserver(execution_context),
       frequency_(0.0),
       type_(type),
@@ -74,7 +74,7 @@
                const SpatialSensorOptions& options,
                ExceptionState& exception_state,
                device::mojom::blink::SensorType sensor_type,
-               const Vector<FeaturePolicyFeature>& features)
+               const Vector<mojom::FeaturePolicyFeature>& features)
     : Sensor(execution_context,
              static_cast<const SensorOptions&>(options),
              exception_state,
diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.h b/third_party/WebKit/Source/modules/sensor/Sensor.h
index 83f1f037..6d90de94 100644
--- a/third_party/WebKit/Source/modules/sensor/Sensor.h
+++ b/third_party/WebKit/Source/modules/sensor/Sensor.h
@@ -68,13 +68,13 @@
          const SensorOptions&,
          ExceptionState&,
          device::mojom::blink::SensorType,
-         const Vector<FeaturePolicyFeature>&);
+         const Vector<mojom::FeaturePolicyFeature>&);
 
   Sensor(ExecutionContext*,
          const SpatialSensorOptions&,
          ExceptionState&,
          device::mojom::blink::SensorType,
-         const Vector<FeaturePolicyFeature>&);
+         const Vector<mojom::FeaturePolicyFeature>&);
 
   using SensorConfigurationPtr = device::mojom::blink::SensorConfigurationPtr;
   using SensorConfiguration = device::mojom::blink::SensorConfiguration;
diff --git a/third_party/WebKit/Source/modules/serviceworkers/WaitUntilObserver.cpp b/third_party/WebKit/Source/modules/serviceworkers/WaitUntilObserver.cpp
index c80b019..d8efc66 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/WaitUntilObserver.cpp
+++ b/third_party/WebKit/Source/modules/serviceworkers/WaitUntilObserver.cpp
@@ -194,7 +194,7 @@
       type_(type),
       event_id_(event_id),
       consume_window_interaction_timer_(
-          Platform::Current()->CurrentThread()->GetWebTaskRunner(),
+          Platform::Current()->CurrentThread()->GetTaskRunner(),
           this,
           &WaitUntilObserver::ConsumeWindowInteraction) {}
 
diff --git a/third_party/WebKit/Source/modules/vibration/NavigatorVibration.cpp b/third_party/WebKit/Source/modules/vibration/NavigatorVibration.cpp
index c280966..15df48a 100644
--- a/third_party/WebKit/Source/modules/vibration/NavigatorVibration.cpp
+++ b/third_party/WebKit/Source/modules/vibration/NavigatorVibration.cpp
@@ -82,8 +82,9 @@
   if (!frame->GetPage()->IsPageVisible())
     return false;
 
-  if (IsSupportedInFeaturePolicy(blink::FeaturePolicyFeature::kVibrate) &&
-      !frame->IsFeatureEnabled(blink::FeaturePolicyFeature::kVibrate)) {
+  if (IsSupportedInFeaturePolicy(
+          blink::mojom::FeaturePolicyFeature::kVibrate) &&
+      !frame->IsFeatureEnabled(blink::mojom::FeaturePolicyFeature::kVibrate)) {
     frame->DomWindow()->PrintErrorMessage(
         "Navigator.vibrate() is not enabled in feature policy for this "
         "frame.");
diff --git a/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp b/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp
index 4de7ddd..78789cf1 100644
--- a/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp
+++ b/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp
@@ -123,8 +123,8 @@
         script_state, DOMException::Create(kInvalidStateError,
                                            kNotAssociatedWithDocumentMessage));
   }
-  if (IsSupportedInFeaturePolicy(FeaturePolicyFeature::kWebVr)) {
-    if (!frame->IsFeatureEnabled(FeaturePolicyFeature::kWebVr)) {
+  if (IsSupportedInFeaturePolicy(mojom::FeaturePolicyFeature::kWebVr)) {
+    if (!frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebVr)) {
       return ScriptPromise::RejectWithDOMException(
           script_state,
           DOMException::Create(kSecurityError, kFeaturePolicyBlockedMessage));
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
index 345bbe3d..094d232 100644
--- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
+++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
@@ -611,7 +611,7 @@
   // schedule a VRDisplay.rAF in case they do so only while presenting.
   if (!pending_vrdisplay_raf_ && !capabilities_->hasExternalDisplay()) {
     double timestamp = WTF::CurrentTimeTicksInSeconds();
-    Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+    Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
         FROM_HERE, WTF::Bind(&VRDisplay::ProcessScheduledWindowAnimations,
                              WrapWeakPersistent(this), timestamp));
   }
@@ -944,7 +944,7 @@
   // this is due to WaitForIncomingMethodCall receiving the OnVSync
   // but queueing it for immediate execution since it doesn't match
   // the interface being waited on.
-  Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+  Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
       FROM_HERE, WTF::Bind(&VRDisplay::ProcessScheduledAnimations,
                            WrapWeakPersistent(this), time_delta.InSecondsF()));
 }
diff --git a/third_party/WebKit/Source/modules/webaudio/AsyncAudioDecoder.cpp b/third_party/WebKit/Source/modules/webaudio/AsyncAudioDecoder.cpp
index 32096ed6..e6c7c71 100644
--- a/third_party/WebKit/Source/modules/webaudio/AsyncAudioDecoder.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/AsyncAudioDecoder.cpp
@@ -80,7 +80,7 @@
   // exist any more.
   if (context) {
     PostCrossThreadTask(
-        *Platform::Current()->MainThread()->GetWebTaskRunner(), FROM_HERE,
+        *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
         CrossThreadBind(&AsyncAudioDecoder::NotifyComplete,
                         WrapCrossThreadPersistent(audio_data),
                         WrapCrossThreadPersistent(success_callback),
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp
index 818353b..4dba427 100644
--- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContext.cpp
@@ -862,7 +862,7 @@
   if (has_posted_cleanup_task_)
     return;
   PostCrossThreadTask(
-      *Platform::Current()->MainThread()->GetWebTaskRunner(), FROM_HERE,
+      *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
       CrossThreadBind(&BaseAudioContext::PerformCleanupOnMainThread,
                       WrapCrossThreadPersistent(this)));
   has_posted_cleanup_task_ = true;
diff --git a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.cpp b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.cpp
index 00dcf1b..c50f040e 100644
--- a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.cpp
@@ -27,6 +27,9 @@
 
 #include <memory>
 
+#include "bindings/core/v8/ExceptionMessages.h"
+#include "bindings/core/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
 #include "modules/webaudio/AudioBasicProcessorHandler.h"
 #include "modules/webaudio/BiquadFilterOptions.h"
 #include "platform/Histogram.h"
@@ -175,19 +178,33 @@
 void BiquadFilterNode::getFrequencyResponse(
     NotShared<const DOMFloat32Array> frequency_hz,
     NotShared<DOMFloat32Array> mag_response,
-    NotShared<DOMFloat32Array> phase_response) {
-  DCHECK(frequency_hz);
-  DCHECK(mag_response);
-  DCHECK(phase_response);
+    NotShared<DOMFloat32Array> phase_response,
+    ExceptionState& exception_state) {
+  unsigned frequency_hz_length = frequency_hz.View()->length();
 
-  int n = std::min(
-      frequency_hz.View()->length(),
-      std::min(mag_response.View()->length(), phase_response.View()->length()));
-  if (n) {
-    GetBiquadProcessor()->GetFrequencyResponse(n, frequency_hz.View()->Data(),
-                                               mag_response.View()->Data(),
-                                               phase_response.View()->Data());
+  if (mag_response.View()->length() != frequency_hz_length) {
+    exception_state.ThrowDOMException(
+        kInvalidAccessError,
+        ExceptionMessages::IndexOutsideRange(
+            "magResponse length", mag_response.View()->length(),
+            frequency_hz_length, ExceptionMessages::kInclusiveBound,
+            frequency_hz_length, ExceptionMessages::kInclusiveBound));
+    return;
   }
+
+  if (phase_response.View()->length() != frequency_hz_length) {
+    exception_state.ThrowDOMException(
+        kInvalidAccessError,
+        ExceptionMessages::IndexOutsideRange(
+            "phaseResponse length", phase_response.View()->length(),
+            frequency_hz_length, ExceptionMessages::kInclusiveBound,
+            frequency_hz_length, ExceptionMessages::kInclusiveBound));
+    return;
+  }
+
+  GetBiquadProcessor()->GetFrequencyResponse(
+      frequency_hz_length, frequency_hz.View()->Data(),
+      mag_response.View()->Data(), phase_response.View()->Data());
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.h b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.h
index 53914203..4d3e75b3 100644
--- a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.h
+++ b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.h
@@ -73,7 +73,8 @@
   // set of frequencies (in Hz). The phase response is in radians.
   void getFrequencyResponse(NotShared<const DOMFloat32Array> frequency_hz,
                             NotShared<DOMFloat32Array> mag_response,
-                            NotShared<DOMFloat32Array> phase_response);
+                            NotShared<DOMFloat32Array> phase_response,
+                            ExceptionState&);
 
  private:
   BiquadFilterNode(BaseAudioContext&);
diff --git a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.idl b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.idl
index 90f76ee..cd743d1 100644
--- a/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.idl
+++ b/third_party/WebKit/Source/modules/webaudio/BiquadFilterNode.idl
@@ -48,7 +48,7 @@
     readonly attribute AudioParam Q; // Quality factor
     readonly attribute AudioParam gain; // in Decibels
 
-    void getFrequencyResponse(Float32Array frequencyHz,
-                              Float32Array magResponse,
-                              Float32Array phaseResponse);
+    [RaisesException] void getFrequencyResponse(Float32Array frequencyHz,
+                                                Float32Array magResponse,
+                                                Float32Array phaseResponse);
 };
diff --git a/third_party/WebKit/Source/modules/webaudio/DeferredTaskHandler.cpp b/third_party/WebKit/Source/modules/webaudio/DeferredTaskHandler.cpp
index 716d863..3910ed92 100644
--- a/third_party/WebKit/Source/modules/webaudio/DeferredTaskHandler.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/DeferredTaskHandler.cpp
@@ -268,7 +268,7 @@
   deletable_orphan_handlers_.AppendVector(rendering_orphan_handlers_);
   rendering_orphan_handlers_.clear();
   PostCrossThreadTask(
-      *Platform::Current()->MainThread()->GetWebTaskRunner(), FROM_HERE,
+      *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
       CrossThreadBind(&DeferredTaskHandler::DeleteHandlersOnMainThread,
                       scoped_refptr<DeferredTaskHandler>(this)));
 }
diff --git a/third_party/WebKit/Source/modules/webaudio/IIRFilterNode.cpp b/third_party/WebKit/Source/modules/webaudio/IIRFilterNode.cpp
index 7385b87..20b4a31 100644
--- a/third_party/WebKit/Source/modules/webaudio/IIRFilterNode.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/IIRFilterNode.cpp
@@ -192,41 +192,27 @@
     NotShared<DOMFloat32Array> mag_response,
     NotShared<DOMFloat32Array> phase_response,
     ExceptionState& exception_state) {
-  if (!frequency_hz.View()) {
-    exception_state.ThrowDOMException(kNotSupportedError,
-                                      "frequencyHz array cannot be null");
-    return;
-  }
-
-  if (!mag_response.View()) {
-    exception_state.ThrowDOMException(kNotSupportedError,
-                                      "magResponse array cannot be null");
-    return;
-  }
-
-  if (!phase_response.View()) {
-    exception_state.ThrowDOMException(kNotSupportedError,
-                                      "phaseResponse array cannot be null");
-    return;
-  }
-
   unsigned frequency_hz_length = frequency_hz.View()->length();
 
-  if (mag_response.View()->length() < frequency_hz_length) {
+  // All the arrays must have the same length.  Just verify that all
+  // the arrays have the same length as the |frequency_hz| array.
+  if (mag_response.View()->length() != frequency_hz_length) {
     exception_state.ThrowDOMException(
-        kNotSupportedError,
-        ExceptionMessages::IndexExceedsMinimumBound(
+        kInvalidAccessError,
+        ExceptionMessages::IndexOutsideRange(
             "magResponse length", mag_response.View()->length(),
-            frequency_hz_length));
+            frequency_hz_length, ExceptionMessages::kInclusiveBound,
+            frequency_hz_length, ExceptionMessages::kInclusiveBound));
     return;
   }
 
-  if (phase_response.View()->length() < frequency_hz_length) {
+  if (phase_response.View()->length() != frequency_hz_length) {
     exception_state.ThrowDOMException(
-        kNotSupportedError,
-        ExceptionMessages::IndexExceedsMinimumBound(
+        kInvalidAccessError,
+        ExceptionMessages::IndexOutsideRange(
             "phaseResponse length", phase_response.View()->length(),
-            frequency_hz_length));
+            frequency_hz_length, ExceptionMessages::kInclusiveBound,
+            frequency_hz_length, ExceptionMessages::kInclusiveBound));
     return;
   }
 
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp
index cd02c94..b014e98 100644
--- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp
@@ -115,7 +115,7 @@
   if (!is_rendering_started_) {
     is_rendering_started_ = true;
     PostCrossThreadTask(
-        *GetRenderingThread()->GetWebTaskRunner(), FROM_HERE,
+        *GetRenderingThread()->GetTaskRunner(), FROM_HERE,
         CrossThreadBind(&OfflineAudioDestinationHandler::StartOfflineRendering,
                         WrapRefCounted(this)));
     return;
@@ -124,7 +124,7 @@
   // Rendering is already started, which implicitly means we resume the
   // rendering by calling |doOfflineRendering| on the render thread.
   PostCrossThreadTask(
-      *GetRenderingThread()->GetWebTaskRunner(), FROM_HERE,
+      *GetRenderingThread()->GetTaskRunner(), FROM_HERE,
       CrossThreadBind(&OfflineAudioDestinationHandler::DoOfflineRendering,
                       WrapRefCounted(this)));
 }
@@ -200,7 +200,7 @@
     bool has_lock = ProcessHeap::CrossThreadPersistentMutex().TryLock();
     if (!has_lock) {
       // To ensure that the rendering step eventually happens, repost.
-      GetRenderingThread()->GetWebTaskRunner()->PostTask(
+      GetRenderingThread()->GetTaskRunner()->PostTask(
           FROM_HERE,
           WTF::Bind(&OfflineAudioDestinationHandler::DoOfflineRendering,
                     WrapRefCounted(this)));
diff --git a/third_party/WebKit/Source/modules/webgl/DEPS b/third_party/WebKit/Source/modules/webgl/DEPS
index 3058c13..a1d284b 100644
--- a/third_party/WebKit/Source/modules/webgl/DEPS
+++ b/third_party/WebKit/Source/modules/webgl/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
     "+gpu/GLES2/gl2extchromium.h",
     "+gpu/command_buffer/client/gles2_interface.h",
+    "+gpu/config/gpu_feature_info.h",
     "+skia/ext",
 ]
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
index 964615b..dd86768ee 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.cpp
@@ -38,10 +38,6 @@
 
 const GLuint64 kMaxClientWaitTimeout = 0u;
 
-GLsync SyncObjectOrZero(const WebGLSync* object) {
-  return object ? object->Object() : nullptr;
-}
-
 // TODO(kainino): Change outByteLength to GLuint and change the associated
 // range checking (and all uses) - overflow becomes possible in cases below
 bool ValidateSubSourceAndGetData(DOMArrayBufferView* view,
@@ -4166,7 +4162,25 @@
     return GL_WAIT_FAILED;
   }
 
-  return ContextGL()->ClientWaitSync(SyncObjectOrZero(sync), flags, timeout);
+  // clientWaitSync must poll for updates no more than once per
+  // requestAnimationFrame, so all validation, and the implementation,
+  // must be done inline.
+  if (!(flags == 0 || flags == GL_SYNC_FLUSH_COMMANDS_BIT)) {
+    SynthesizeGLError(GL_INVALID_VALUE, "clientWaitSync", "invalid flags");
+    return GL_WAIT_FAILED;
+  }
+
+  if (sync->IsSignaled()) {
+    return GL_ALREADY_SIGNALED;
+  }
+
+  sync->UpdateCache(ContextGL());
+
+  if (sync->IsSignaled()) {
+    return GL_CONDITION_SATISFIED;
+  }
+
+  return GL_TIMEOUT_EXPIRED;
 }
 
 void WebGL2RenderingContextBase::waitSync(WebGLSync* sync,
@@ -4200,10 +4214,8 @@
     case GL_SYNC_STATUS:
     case GL_SYNC_CONDITION:
     case GL_SYNC_FLAGS: {
-      GLint value = 0;
-      GLsizei length = -1;
-      ContextGL()->GetSynciv(SyncObjectOrZero(sync), pname, 1, &length, &value);
-      return WebGLAny(script_state, static_cast<unsigned>(value));
+      sync->UpdateCache(ContextGL());
+      return WebGLAny(script_state, sync->GetCachedResult(pname));
     }
     default:
       SynthesizeGLError(GL_INVALID_ENUM, "getSyncParameter",
diff --git a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h
index 0691c23..7257f62e 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGL2RenderingContextBase.h
@@ -981,6 +981,7 @@
  protected:
   friend class V8WebGL2RenderingContext;
   friend class WebGLGetBufferSubDataAsync;
+  friend class WebGLSync;
 
   WebGL2RenderingContextBase(
       CanvasRenderingContextHost*,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLQuery.cpp b/third_party/WebKit/Source/modules/webgl/WebGLQuery.cpp
index 9fe9b2c4..b378bf75 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLQuery.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLQuery.cpp
@@ -26,7 +26,7 @@
         ctx->canvas()->GetDocument().GetTaskRunner(TaskType::kUnthrottled);
   } else {
     // Fallback for OffscreenCanvas (no frame scheduler)
-    task_runner_ = Platform::Current()->CurrentThread()->GetWebTaskRunner();
+    task_runner_ = Platform::Current()->CurrentThread()->GetTaskRunner();
   }
   GLuint query;
   ctx->ContextGL()->GenQueriesEXT(1, &query);
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index fce41f20..9d4ebb1 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -50,6 +50,7 @@
 #include "core/typed_arrays/DOMTypedArray.h"
 #include "core/typed_arrays/FlexibleArrayBufferView.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/config/gpu_feature_info.h"
 #include "modules/webgl/ANGLEInstancedArrays.h"
 #include "modules/webgl/EXTBlendMinMax.h"
 #include "modules/webgl/EXTFragDepth.h"
@@ -614,7 +615,7 @@
   creation_info.url = url.Copy();
   creation_info.using_gpu_compositing = using_gpu_compositing;
   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
-      Platform::Current()->MainThread()->GetWebTaskRunner();
+      Platform::Current()->MainThread()->GetTaskRunner();
   PostCrossThreadTask(*task_runner, FROM_HERE,
                       CrossThreadBind(&CreateContextProviderOnMainThread,
                                       CrossThreadUnretained(&creation_info),
@@ -1031,6 +1032,16 @@
   GetDrawingBuffer()->Bind(GL_FRAMEBUFFER);
   SetupFlags();
 
+  String disabled_webgl_extensions(GetDrawingBuffer()
+                                       ->ContextProvider()
+                                       ->GetGpuFeatureInfo()
+                                       .disabled_webgl_extensions.c_str());
+  Vector<String> disabled_extension_list;
+  disabled_webgl_extensions.Split(' ', disabled_extension_list);
+  for (const auto& entry : disabled_extension_list) {
+    disabled_extensions_.insert(entry);
+  }
+
 #define ADD_VALUES_TO_SET(set, values)                    \
   for (size_t i = 0; i < WTF_ARRAY_LENGTH(values); ++i) { \
     set.insert(values[i]);                                \
@@ -2814,6 +2825,8 @@
     return false;
   if (!tracker->Supported(this))
     return false;
+  if (disabled_extensions_.Contains(String(tracker->ExtensionName())))
+    return false;
   return true;
 }
 
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
index 6a6fb34..50158067 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -903,6 +903,7 @@
 
   bool extension_enabled_[kWebGLExtensionNameCount];
   HeapVector<TraceWrapperMember<ExtensionTracker>> extensions_;
+  HashSet<String> disabled_extensions_;
 
   template <typename T>
   void RegisterExtension(Member<T>& extension_ptr,
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLSync.cpp b/third_party/WebKit/Source/modules/webgl/WebGLSync.cpp
index 7a189e02..8dd22e74 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLSync.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLSync.cpp
@@ -6,18 +6,86 @@
 
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "modules/webgl/WebGL2RenderingContextBase.h"
+#include "public/platform/Platform.h"
+#include "public/platform/TaskType.h"
 
 namespace blink {
 
 WebGLSync::WebGLSync(WebGL2RenderingContextBase* ctx,
                      GLsync object,
                      GLenum object_type)
-    : WebGLSharedObject(ctx), object_(object), object_type_(object_type) {}
+    : WebGLSharedObject(ctx),
+      sync_status_(GL_UNSIGNALED),
+      object_(object),
+      object_type_(object_type) {
+  if (ctx->canvas()) {
+    task_runner_ =
+        ctx->canvas()->GetDocument().GetTaskRunner(TaskType::kUnthrottled);
+  } else {
+    // Fallback for OffscreenCanvas (no frame scheduler)
+    task_runner_ = Platform::Current()->CurrentThread()->GetWebTaskRunner();
+  }
+  ScheduleAllowCacheUpdate();
+}
 
 WebGLSync::~WebGLSync() {
   RunDestructor();
 }
 
+void WebGLSync::UpdateCache(gpu::gles2::GLES2Interface* gl) {
+  if (sync_status_ == GL_SIGNALED) {
+    return;
+  }
+
+  if (!allow_cache_update_) {
+    return;
+  }
+
+  // We can only update the cached result when control returns to the browser.
+  allow_cache_update_ = false;
+  GLsizei length = -1;
+  GLint value = 0;
+  gl->GetSynciv(object_, GL_SYNC_STATUS, 1, &length, &value);
+  if (value) {
+    sync_status_ = value;
+  }
+  if (sync_status_ != GL_SIGNALED) {
+    ScheduleAllowCacheUpdate();
+  }
+}
+
+GLint WebGLSync::GetCachedResult(GLenum pname) {
+  switch (pname) {
+    case GL_OBJECT_TYPE:
+      return object_type_;
+    case GL_SYNC_STATUS:
+      return sync_status_;
+    case GL_SYNC_CONDITION:
+      return GL_SYNC_GPU_COMMANDS_COMPLETE;
+    case GL_SYNC_FLAGS:
+      return 0;
+  }
+
+  NOTREACHED();
+  return 0;
+}
+
+bool WebGLSync::IsSignaled() const {
+  return (sync_status_ == GL_SIGNALED);
+}
+
+void WebGLSync::ScheduleAllowCacheUpdate() {
+  if (task_handle_.IsActive())
+    return;
+  task_handle_ = PostCancellableTask(
+      *task_runner_, FROM_HERE,
+      WTF::Bind(&WebGLSync::AllowCacheUpdate, WrapWeakPersistent(this)));
+}
+
+void WebGLSync::AllowCacheUpdate() {
+  allow_cache_update_ = true;
+}
+
 void WebGLSync::DeleteObjectImpl(gpu::gles2::GLES2Interface* gl) {
   gl->DeleteSync(object_);
   object_ = nullptr;
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLSync.h b/third_party/WebKit/Source/modules/webgl/WebGLSync.h
index d473093..b871790 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLSync.h
+++ b/third_party/WebKit/Source/modules/webgl/WebGLSync.h
@@ -5,8 +5,15 @@
 #ifndef WebGLSync_h
 #define WebGLSync_h
 
+#include "base/single_thread_task_runner.h"
 #include "modules/webgl/WebGLSharedObject.h"
-#include "third_party/khronos/GLES2/gl2.h"
+#include "platform/WebTaskRunner.h"
+
+namespace gpu {
+namespace gles2 {
+class GLES2Interface;
+}
+}  // namespace gpu
 
 namespace blink {
 
@@ -20,6 +27,10 @@
 
   GLsync Object() const { return object_; }
 
+  void UpdateCache(gpu::gles2::GLES2Interface*);
+  GLint GetCachedResult(GLenum pname);
+  bool IsSignaled() const;
+
  protected:
   WebGLSync(WebGL2RenderingContextBase*, GLsync, GLenum object_type);
 
@@ -31,8 +42,18 @@
  private:
   bool IsSync() const override { return true; }
 
+  void ScheduleAllowCacheUpdate();
+  void AllowCacheUpdate();
+
+  bool allow_cache_update_ = false;
+  // Initialized in cpp file to avoid including gl3.h in this header.
+  GLint sync_status_;
+
   GLsync object_;
   GLenum object_type_;
+
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  TaskHandle task_handle_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/webmidi/NavigatorWebMIDI.cpp b/third_party/WebKit/Source/modules/webmidi/NavigatorWebMIDI.cpp
index f308ea7..2eca995 100644
--- a/third_party/WebKit/Source/modules/webmidi/NavigatorWebMIDI.cpp
+++ b/third_party/WebKit/Source/modules/webmidi/NavigatorWebMIDI.cpp
@@ -42,7 +42,7 @@
 #include "core/inspector/ConsoleMessage.h"
 #include "modules/webmidi/MIDIAccessInitializer.h"
 #include "modules/webmidi/MIDIOptions.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom-blink.h"
 
 namespace blink {
 namespace {
@@ -106,7 +106,7 @@
 
   if (RuntimeEnabledFeatures::FeaturePolicyForPermissionsEnabled()) {
     if (!document.GetFrame()->IsFeatureEnabled(
-            FeaturePolicyFeature::kMidiFeature)) {
+            mojom::FeaturePolicyFeature::kMidiFeature)) {
       UseCounter::Count(document, WebFeature::kMidiDisabledByFeaturePolicy);
       document.AddConsoleMessage(
           ConsoleMessage::Create(kJSMessageSource, kWarningMessageLevel,
@@ -117,7 +117,7 @@
     }
   } else {
     Deprecation::CountDeprecationFeaturePolicy(
-        document, FeaturePolicyFeature::kMidiFeature);
+        document, mojom::FeaturePolicyFeature::kMidiFeature);
   }
 
   return MIDIAccessInitializer::Start(script_state, options);
diff --git a/third_party/WebKit/Source/modules/webusb/USB.cpp b/third_party/WebKit/Source/modules/webusb/USB.cpp
index 4fe4b06..7f7863b 100644
--- a/third_party/WebKit/Source/modules/webusb/USB.cpp
+++ b/third_party/WebKit/Source/modules/webusb/USB.cpp
@@ -82,8 +82,8 @@
         script_state, DOMException::Create(kNotSupportedError));
   }
 
-  if (IsSupportedInFeaturePolicy(FeaturePolicyFeature::kUsb)) {
-    if (!frame->IsFeatureEnabled(FeaturePolicyFeature::kUsb)) {
+  if (IsSupportedInFeaturePolicy(mojom::FeaturePolicyFeature::kUsb)) {
+    if (!frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kUsb)) {
       return ScriptPromise::RejectWithDOMException(
           script_state,
           DOMException::Create(kSecurityError, kFeaturePolicyBlocked));
@@ -110,8 +110,8 @@
         script_state, DOMException::Create(kNotSupportedError));
   }
 
-  if (IsSupportedInFeaturePolicy(FeaturePolicyFeature::kUsb)) {
-    if (!frame->IsFeatureEnabled(FeaturePolicyFeature::kUsb)) {
+  if (IsSupportedInFeaturePolicy(mojom::FeaturePolicyFeature::kUsb)) {
+    if (!frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kUsb)) {
       return ScriptPromise::RejectWithDOMException(
           script_state,
           DOMException::Create(kSecurityError, kFeaturePolicyBlocked));
@@ -254,8 +254,8 @@
   if (!frame)
     return;
 
-  if (IsSupportedInFeaturePolicy(FeaturePolicyFeature::kUsb)) {
-    if (frame->IsFeatureEnabled(FeaturePolicyFeature::kUsb))
+  if (IsSupportedInFeaturePolicy(mojom::FeaturePolicyFeature::kUsb)) {
+    if (frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kUsb))
       EnsureDeviceManagerConnection();
   } else if (frame->IsMainFrame()) {
     EnsureDeviceManagerConnection();
diff --git a/third_party/WebKit/Source/modules/xr/XR.cpp b/third_party/WebKit/Source/modules/xr/XR.cpp
index 93476716..7672e8c 100644
--- a/third_party/WebKit/Source/modules/xr/XR.cpp
+++ b/third_party/WebKit/Source/modules/xr/XR.cpp
@@ -66,8 +66,8 @@
         DOMException::Create(kInvalidStateError, kNavigatorDetachedError));
   }
 
-  if (IsSupportedInFeaturePolicy(FeaturePolicyFeature::kWebVr)) {
-    if (!frame->IsFeatureEnabled(FeaturePolicyFeature::kWebVr)) {
+  if (IsSupportedInFeaturePolicy(mojom::FeaturePolicyFeature::kWebVr)) {
+    if (!frame->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebVr)) {
       // Only allow the call to be made if the appropraite feature policy is in
       // place.
       return ScriptPromise::RejectWithDOMException(
diff --git a/third_party/WebKit/Source/modules/xr/XRFrameProvider.cpp b/third_party/WebKit/Source/modules/xr/XRFrameProvider.cpp
index 0e5eb3a..6f8e36d 100644
--- a/third_party/WebKit/Source/modules/xr/XRFrameProvider.cpp
+++ b/third_party/WebKit/Source/modules/xr/XRFrameProvider.cpp
@@ -254,7 +254,7 @@
   // between frames. Executing mojo tasks back to back within the same
   // execution context caused extreme input delay due to processing
   // multiple frames without yielding, see crbug.com/701444.
-  Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+  Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
       FROM_HERE, WTF::Bind(&XRFrameProvider::ProcessScheduledFrame,
                            WrapWeakPersistent(this), time_delta.InSecondsF()));
 }
@@ -268,7 +268,7 @@
   if (exclusive_session_)
     return;
 
-  Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+  Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
       FROM_HERE, WTF::Bind(&XRFrameProvider::ProcessScheduledFrame,
                            WrapWeakPersistent(this), timestamp));
 }
diff --git a/third_party/WebKit/Source/platform/LongTaskDetectorTest.cpp b/third_party/WebKit/Source/platform/LongTaskDetectorTest.cpp
index 06b71f2..243f363 100644
--- a/third_party/WebKit/Source/platform/LongTaskDetectorTest.cpp
+++ b/third_party/WebKit/Source/platform/LongTaskDetectorTest.cpp
@@ -54,7 +54,7 @@
 
   void SimulateTask(double duration_seconds) {
     PostCrossThreadTask(
-        *platform_->CurrentThread()->GetWebTaskRunner(), FROM_HERE,
+        *platform_->CurrentThread()->GetTaskRunner(), FROM_HERE,
         CrossThreadBind(&LongTaskDetectorTest::DummyTaskWithDuration,
                         CrossThreadUnretained(this), duration_seconds));
     platform_->RunUntilIdle();
diff --git a/third_party/WebKit/Source/platform/MemoryCoordinator.cpp b/third_party/WebKit/Source/platform/MemoryCoordinator.cpp
index 48dc857..c1164e9 100644
--- a/third_party/WebKit/Source/platform/MemoryCoordinator.cpp
+++ b/third_party/WebKit/Source/platform/MemoryCoordinator.cpp
@@ -111,11 +111,11 @@
 
   // Thread-specific data never issues a layout, so we are safe here.
   for (auto thread : web_threads_) {
-    if (!thread->GetWebTaskRunner())
+    if (!thread->GetTaskRunner())
       continue;
 
     PostCrossThreadTask(
-        *thread->GetWebTaskRunner(), FROM_HERE,
+        *thread->GetTaskRunner(), FROM_HERE,
         CrossThreadBind(MemoryCoordinator::ClearThreadSpecificMemory));
   }
 }
diff --git a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
index 05b6562..a6de78fd 100644
--- a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
+++ b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
@@ -37,25 +37,23 @@
   ~WebThreadSupportingGC();
 
   void PostTask(const base::Location& location, base::OnceClosure task) {
-    thread_->GetWebTaskRunner()->PostTask(location, std::move(task));
+    thread_->GetTaskRunner()->PostTask(location, std::move(task));
   }
 
   void PostDelayedTask(const base::Location& location,
                        base::OnceClosure task,
                        TimeDelta delay) {
-    thread_->GetWebTaskRunner()->PostDelayedTask(location, std::move(task),
-                                                 delay);
+    thread_->GetTaskRunner()->PostDelayedTask(location, std::move(task), delay);
   }
 
   void PostTask(const base::Location& location, CrossThreadClosure task) {
-    PostCrossThreadTask(*thread_->GetWebTaskRunner(), location,
-                        std::move(task));
+    PostCrossThreadTask(*thread_->GetTaskRunner(), location, std::move(task));
   }
 
   void PostDelayedTask(const base::Location& location,
                        CrossThreadClosure task,
                        TimeDelta delay) {
-    PostDelayedCrossThreadTask(*thread_->GetWebTaskRunner(), location,
+    PostDelayedCrossThreadTask(*thread_->GetTaskRunner(), location,
                                std::move(task), delay);
   }
 
diff --git a/third_party/WebKit/Source/platform/audio/AudioDestination.cpp b/third_party/WebKit/Source/platform/audio/AudioDestination.cpp
index d49176f..f80de9975 100644
--- a/third_party/WebKit/Source/platform/audio/AudioDestination.cpp
+++ b/third_party/WebKit/Source/platform/audio/AudioDestination.cpp
@@ -134,7 +134,7 @@
   // is available.
   if (worklet_backing_thread_) {
     PostCrossThreadTask(
-        *worklet_backing_thread_->GetWebTaskRunner(), FROM_HERE,
+        *worklet_backing_thread_->GetTaskRunner(), FROM_HERE,
         CrossThreadBind(&AudioDestination::RequestRender, WrapRefCounted(this),
                         number_of_frames, frames_to_render, delay,
                         delay_timestamp, prior_frames_skipped));
diff --git a/third_party/WebKit/Source/platform/audio/HRTFDatabaseLoader.cpp b/third_party/WebKit/Source/platform/audio/HRTFDatabaseLoader.cpp
index 4ca8b2b..7aab44a 100644
--- a/third_party/WebKit/Source/platform/audio/HRTFDatabaseLoader.cpp
+++ b/third_party/WebKit/Source/platform/audio/HRTFDatabaseLoader.cpp
@@ -98,7 +98,7 @@
   thread_ = Platform::Current()->CreateThread(
       WebThreadCreationParams(WebThreadType::kHRTFDatabaseLoaderThread));
   // TODO(alexclarke): Should this be posted as a loading task?
-  PostCrossThreadTask(*thread_->GetWebTaskRunner(), FROM_HERE,
+  PostCrossThreadTask(*thread_->GetTaskRunner(), FROM_HERE,
                       CrossThreadBind(&HRTFDatabaseLoader::LoadTask,
                                       CrossThreadUnretained(this)));
 }
@@ -128,7 +128,7 @@
 
   WaitableEvent sync;
   // TODO(alexclarke): Should this be posted as a loading task?
-  PostCrossThreadTask(*thread_->GetWebTaskRunner(), FROM_HERE,
+  PostCrossThreadTask(*thread_->GetTaskRunner(), FROM_HERE,
                       CrossThreadBind(&HRTFDatabaseLoader::CleanupTask,
                                       CrossThreadUnretained(this),
                                       CrossThreadUnretained(&sync)));
diff --git a/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp b/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp
index 74920e1..fe704f7a 100644
--- a/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp
+++ b/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp
@@ -38,7 +38,7 @@
   WaitableEvent* Start(double duration_ms, double interval_ms) {
     duration_ms_ = duration_ms;
     interval_ms_ = interval_ms;
-    PostCrossThreadTask(*client_thread_->GetWebTaskRunner(), FROM_HERE,
+    PostCrossThreadTask(*client_thread_->GetTaskRunner(), FROM_HERE,
                         CrossThreadBind(&FIFOClient::RunTaskOnOwnThread,
                                         CrossThreadUnretained(this)));
     return done_event_.get();
@@ -60,7 +60,7 @@
     RunTask();
     if (elapsed_ms_ < duration_ms_) {
       PostDelayedCrossThreadTask(
-          *client_thread_->GetWebTaskRunner(), FROM_HERE,
+          *client_thread_->GetTaskRunner(), FROM_HERE,
           CrossThreadBind(&FIFOClient::RunTaskOnOwnThread,
                           CrossThreadUnretained(this)),
           TimeDelta::FromMillisecondsD(interval_with_jitter));
diff --git a/third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp b/third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp
index a7c8f56..ec8c3424 100644
--- a/third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp
+++ b/third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp
@@ -201,7 +201,7 @@
   // Now that we've buffered more input, post another task to the background
   // thread.
   if (background_thread_) {
-    PostCrossThreadTask(*background_thread_->GetWebTaskRunner(), FROM_HERE,
+    PostCrossThreadTask(*background_thread_->GetTaskRunner(), FROM_HERE,
                         CrossThreadBind(&ReverbConvolver::ProcessInBackground,
                                         CrossThreadUnretained(this)));
   }
diff --git a/third_party/WebKit/Source/platform/blob/BlobBytesProvider.cpp b/third_party/WebKit/Source/platform/blob/BlobBytesProvider.cpp
index b0b288d..a2a3f6b 100644
--- a/third_party/WebKit/Source/platform/blob/BlobBytesProvider.cpp
+++ b/third_party/WebKit/Source/platform/blob/BlobBytesProvider.cpp
@@ -84,7 +84,7 @@
 // This keeps the process alive while blobs are being transferred.
 void IncreaseChildProcessRefCount() {
   if (!Platform::Current()->MainThread()->IsCurrentThread()) {
-    PostCrossThreadTask(*Platform::Current()->MainThread()->GetWebTaskRunner(),
+    PostCrossThreadTask(*Platform::Current()->MainThread()->GetTaskRunner(),
                         FROM_HERE,
                         CrossThreadBind(&IncreaseChildProcessRefCount));
     return;
@@ -95,7 +95,7 @@
 
 void DecreaseChildProcessRefCount() {
   if (!Platform::Current()->MainThread()->IsCurrentThread()) {
-    PostCrossThreadTask(*Platform::Current()->MainThread()->GetWebTaskRunner(),
+    PostCrossThreadTask(*Platform::Current()->MainThread()->GetTaskRunner(),
                         FROM_HERE,
                         CrossThreadBind(&DecreaseChildProcessRefCount));
     return;
diff --git a/third_party/WebKit/Source/platform/exported/Platform.cpp b/third_party/WebKit/Source/platform/exported/Platform.cpp
index e342a16..c8dbc1e2 100644
--- a/third_party/WebKit/Source/platform/exported/Platform.cpp
+++ b/third_party/WebKit/Source/platform/exported/Platform.cpp
@@ -107,7 +107,7 @@
 static void CallOnMainThreadFunction(WTF::MainThreadFunction function,
                                      void* context) {
   PostCrossThreadTask(
-      *Platform::Current()->MainThread()->GetWebTaskRunner(), FROM_HERE,
+      *Platform::Current()->MainThread()->GetTaskRunner(), FROM_HERE,
       CrossThreadBind(function, CrossThreadUnretained(context)));
 }
 
@@ -187,7 +187,7 @@
 }
 
 base::SingleThreadTaskRunner* Platform::FileTaskRunner() const {
-  return file_thread_ ? file_thread_->GetWebTaskRunner() : nullptr;
+  return file_thread_ ? file_thread_->GetTaskRunner().get() : nullptr;
 }
 
 scoped_refptr<base::SingleThreadTaskRunner> Platform::BaseFileTaskRunner()
diff --git a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
index ec51273..3e0b9b3 100644
--- a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
+++ b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
@@ -120,7 +120,7 @@
 
   ParsedFeaturePolicy whitelists;
   BitVector features_specified(
-      static_cast<int>(FeaturePolicyFeature::LAST_FEATURE));
+      static_cast<int>(mojom::FeaturePolicyFeature::kLastFeature));
 
   // RFC2616, section 4.2 specifies that headers appearing multiple times can be
   // combined with a comma. Walk the header string, and parse each comma
@@ -146,7 +146,7 @@
         continue;
       }
 
-      FeaturePolicyFeature feature = feature_names.at(tokens[0]);
+      mojom::FeaturePolicyFeature feature = feature_names.at(tokens[0]);
       // If a policy has already been specified for the current feature, drop
       // the new policy.
       if (features_specified.QuickGet(static_cast<int>(feature)))
@@ -199,25 +199,25 @@
   return whitelists;
 }
 
-bool IsSupportedInFeaturePolicy(FeaturePolicyFeature feature) {
+bool IsSupportedInFeaturePolicy(mojom::FeaturePolicyFeature feature) {
   if (!RuntimeEnabledFeatures::FeaturePolicyEnabled())
     return false;
   switch (feature) {
-    case FeaturePolicyFeature::kFullscreen:
-    case FeaturePolicyFeature::kPayment:
-    case FeaturePolicyFeature::kUsb:
-    case FeaturePolicyFeature::kWebVr:
-    case FeaturePolicyFeature::kAccelerometer:
-    case FeaturePolicyFeature::kAmbientLightSensor:
-    case FeaturePolicyFeature::kGyroscope:
-    case FeaturePolicyFeature::kMagnetometer:
+    case mojom::FeaturePolicyFeature::kFullscreen:
+    case mojom::FeaturePolicyFeature::kPayment:
+    case mojom::FeaturePolicyFeature::kUsb:
+    case mojom::FeaturePolicyFeature::kWebVr:
+    case mojom::FeaturePolicyFeature::kAccelerometer:
+    case mojom::FeaturePolicyFeature::kAmbientLightSensor:
+    case mojom::FeaturePolicyFeature::kGyroscope:
+    case mojom::FeaturePolicyFeature::kMagnetometer:
       return true;
-    case FeaturePolicyFeature::kPictureInPicture:
+    case mojom::FeaturePolicyFeature::kPictureInPicture:
       return RuntimeEnabledFeatures::PictureInPictureAPIEnabled();
-    case FeaturePolicyFeature::kSyncXHR:
+    case mojom::FeaturePolicyFeature::kSyncXHR:
       return true;
-    case FeaturePolicyFeature::kVibrate:
-    case FeaturePolicyFeature::kUnsizedMedia:
+    case mojom::FeaturePolicyFeature::kVibrate:
+    case mojom::FeaturePolicyFeature::kUnsizedMedia:
       return RuntimeEnabledFeatures::FeaturePolicyExperimentalFeaturesEnabled();
     default:
       return false;
@@ -228,46 +228,55 @@
   DEFINE_STATIC_LOCAL(FeatureNameMap, default_feature_name_map, ());
   if (default_feature_name_map.IsEmpty()) {
     default_feature_name_map.Set("fullscreen",
-                                 FeaturePolicyFeature::kFullscreen);
-    default_feature_name_map.Set("payment", FeaturePolicyFeature::kPayment);
-    default_feature_name_map.Set("usb", FeaturePolicyFeature::kUsb);
-    default_feature_name_map.Set("camera", FeaturePolicyFeature::kCamera);
+                                 mojom::FeaturePolicyFeature::kFullscreen);
+    default_feature_name_map.Set("payment",
+                                 mojom::FeaturePolicyFeature::kPayment);
+    default_feature_name_map.Set("usb", mojom::FeaturePolicyFeature::kUsb);
+    default_feature_name_map.Set("camera",
+                                 mojom::FeaturePolicyFeature::kCamera);
     default_feature_name_map.Set("encrypted-media",
-                                 FeaturePolicyFeature::kEncryptedMedia);
+                                 mojom::FeaturePolicyFeature::kEncryptedMedia);
     default_feature_name_map.Set("microphone",
-                                 FeaturePolicyFeature::kMicrophone);
-    default_feature_name_map.Set("speaker", FeaturePolicyFeature::kSpeaker);
+                                 mojom::FeaturePolicyFeature::kMicrophone);
+    default_feature_name_map.Set("speaker",
+                                 mojom::FeaturePolicyFeature::kSpeaker);
     default_feature_name_map.Set("geolocation",
-                                 FeaturePolicyFeature::kGeolocation);
-    default_feature_name_map.Set("midi", FeaturePolicyFeature::kMidiFeature);
-    default_feature_name_map.Set("sync-xhr", FeaturePolicyFeature::kSyncXHR);
-    default_feature_name_map.Set("vr", FeaturePolicyFeature::kWebVr);
+                                 mojom::FeaturePolicyFeature::kGeolocation);
+    default_feature_name_map.Set("midi",
+                                 mojom::FeaturePolicyFeature::kMidiFeature);
+    default_feature_name_map.Set("sync-xhr",
+                                 mojom::FeaturePolicyFeature::kSyncXHR);
+    default_feature_name_map.Set("vr", mojom::FeaturePolicyFeature::kWebVr);
     default_feature_name_map.Set("accelerometer",
-                                 FeaturePolicyFeature::kAccelerometer);
-    default_feature_name_map.Set("ambient-light-sensor",
-                                 FeaturePolicyFeature::kAmbientLightSensor);
-    default_feature_name_map.Set("gyroscope", FeaturePolicyFeature::kGyroscope);
+                                 mojom::FeaturePolicyFeature::kAccelerometer);
+    default_feature_name_map.Set(
+        "ambient-light-sensor",
+        mojom::FeaturePolicyFeature::kAmbientLightSensor);
+    default_feature_name_map.Set("gyroscope",
+                                 mojom::FeaturePolicyFeature::kGyroscope);
     default_feature_name_map.Set("magnetometer",
-                                 FeaturePolicyFeature::kMagnetometer);
+                                 mojom::FeaturePolicyFeature::kMagnetometer);
     if (RuntimeEnabledFeatures::PictureInPictureAPIEnabled()) {
-      default_feature_name_map.Set("picture-in-picture",
-                                   FeaturePolicyFeature::kPictureInPicture);
+      default_feature_name_map.Set(
+          "picture-in-picture", mojom::FeaturePolicyFeature::kPictureInPicture);
     }
     if (RuntimeEnabledFeatures::FeaturePolicyExperimentalFeaturesEnabled()) {
-      default_feature_name_map.Set("vibrate", FeaturePolicyFeature::kVibrate);
-      default_feature_name_map.Set("cookie",
-                                   FeaturePolicyFeature::kDocumentCookie);
-      default_feature_name_map.Set("domain",
-                                   FeaturePolicyFeature::kDocumentDomain);
+      default_feature_name_map.Set("vibrate",
+                                   mojom::FeaturePolicyFeature::kVibrate);
+      default_feature_name_map.Set(
+          "cookie", mojom::FeaturePolicyFeature::kDocumentCookie);
+      default_feature_name_map.Set(
+          "domain", mojom::FeaturePolicyFeature::kDocumentDomain);
       default_feature_name_map.Set("docwrite",
-                                   FeaturePolicyFeature::kDocumentWrite);
+                                   mojom::FeaturePolicyFeature::kDocumentWrite);
       default_feature_name_map.Set("sync-script",
-                                   FeaturePolicyFeature::kSyncScript);
+                                   mojom::FeaturePolicyFeature::kSyncScript);
       default_feature_name_map.Set("unsized-media",
-                                   FeaturePolicyFeature::kUnsizedMedia);
+                                   mojom::FeaturePolicyFeature::kUnsizedMedia);
     }
     if (RuntimeEnabledFeatures::FeaturePolicyAutoplayFeatureEnabled()) {
-      default_feature_name_map.Set("autoplay", FeaturePolicyFeature::kAutoplay);
+      default_feature_name_map.Set("autoplay",
+                                   mojom::FeaturePolicyFeature::kAutoplay);
     }
   }
   return default_feature_name_map;
diff --git a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.h b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.h
index 42e8db8..c219d6f 100644
--- a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.h
+++ b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.h
@@ -19,9 +19,9 @@
 
 namespace blink {
 
-// Returns a map between feature name (string) and FeaturePolicyFeature
+// Returns a map between feature name (string) and mojom::FeaturePolicyFeature
 // (enum).
-typedef HashMap<String, FeaturePolicyFeature> FeatureNameMap;
+typedef HashMap<String, mojom::FeaturePolicyFeature> FeatureNameMap;
 PLATFORM_EXPORT const FeatureNameMap& GetDefaultFeatureNameMap();
 
 // Converts a header policy string into a vector of whitelists, one for each
@@ -72,7 +72,7 @@
 
 // Verifies whether feature policy is enabled and |feature| is supported in
 // feature policy.
-PLATFORM_EXPORT bool IsSupportedInFeaturePolicy(FeaturePolicyFeature);
+PLATFORM_EXPORT bool IsSupportedInFeaturePolicy(mojom::FeaturePolicyFeature);
 
 }  // namespace blink
 
diff --git a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicyTest.cpp b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicyTest.cpp
index f77b1f5..854b59b 100644
--- a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicyTest.cpp
+++ b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicyTest.cpp
@@ -74,9 +74,9 @@
   url::Origin expected_url_origin_c_ = url::Origin::Create(GURL(ORIGIN_C));
 
   const FeatureNameMap test_feature_name_map = {
-      {"fullscreen", blink::FeaturePolicyFeature::kFullscreen},
-      {"payment", blink::FeaturePolicyFeature::kPayment},
-      {"vibrate", blink::FeaturePolicyFeature::kVibrate}};
+      {"fullscreen", blink::mojom::FeaturePolicyFeature::kFullscreen},
+      {"payment", blink::mojom::FeaturePolicyFeature::kPayment},
+      {"vibrate", blink::mojom::FeaturePolicyFeature::kVibrate}};
 };
 
 TEST_F(FeaturePolicyTest, ParseValidPolicy) {
@@ -113,7 +113,7 @@
                          &messages, test_feature_name_map);
   EXPECT_EQ(1UL, parsed_policy.size());
 
-  EXPECT_EQ(FeaturePolicyFeature::kVibrate, parsed_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kVibrate, parsed_policy[0].feature);
   EXPECT_FALSE(parsed_policy[0].matches_all_origins);
   EXPECT_EQ(1UL, parsed_policy[0].origins.size());
   EXPECT_TRUE(
@@ -123,7 +123,7 @@
       ParseFeaturePolicy("vibrate *", origin_a_.get(), origin_b_.get(),
                          &messages, test_feature_name_map);
   EXPECT_EQ(1UL, parsed_policy.size());
-  EXPECT_EQ(FeaturePolicyFeature::kVibrate, parsed_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kVibrate, parsed_policy[0].feature);
   EXPECT_TRUE(parsed_policy[0].matches_all_origins);
   EXPECT_EQ(0UL, parsed_policy[0].origins.size());
 
@@ -134,17 +134,17 @@
       "payment 'self'",
       origin_a_.get(), origin_b_.get(), &messages, test_feature_name_map);
   EXPECT_EQ(3UL, parsed_policy.size());
-  EXPECT_EQ(FeaturePolicyFeature::kVibrate, parsed_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kVibrate, parsed_policy[0].feature);
   EXPECT_TRUE(parsed_policy[0].matches_all_origins);
   EXPECT_EQ(0UL, parsed_policy[0].origins.size());
-  EXPECT_EQ(FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
   EXPECT_FALSE(parsed_policy[1].matches_all_origins);
   EXPECT_EQ(2UL, parsed_policy[1].origins.size());
   EXPECT_TRUE(
       parsed_policy[1].origins[0].IsSameOriginWith(expected_url_origin_b_));
   EXPECT_TRUE(
       parsed_policy[1].origins[1].IsSameOriginWith(expected_url_origin_c_));
-  EXPECT_EQ(FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
   EXPECT_FALSE(parsed_policy[2].matches_all_origins);
   EXPECT_EQ(1UL, parsed_policy[2].origins.size());
   EXPECT_TRUE(
@@ -157,17 +157,17 @@
       "payment 'self' badorigin",
       origin_a_.get(), origin_b_.get(), &messages, test_feature_name_map);
   EXPECT_EQ(3UL, parsed_policy.size());
-  EXPECT_EQ(FeaturePolicyFeature::kVibrate, parsed_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kVibrate, parsed_policy[0].feature);
   EXPECT_TRUE(parsed_policy[0].matches_all_origins);
   EXPECT_EQ(0UL, parsed_policy[0].origins.size());
-  EXPECT_EQ(FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
   EXPECT_FALSE(parsed_policy[1].matches_all_origins);
   EXPECT_EQ(2UL, parsed_policy[1].origins.size());
   EXPECT_TRUE(
       parsed_policy[1].origins[0].IsSameOriginWith(expected_url_origin_b_));
   EXPECT_TRUE(
       parsed_policy[1].origins[1].IsSameOriginWith(expected_url_origin_c_));
-  EXPECT_EQ(FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
   EXPECT_FALSE(parsed_policy[2].matches_all_origins);
   EXPECT_EQ(1UL, parsed_policy[2].origins.size());
   EXPECT_TRUE(
@@ -182,17 +182,17 @@
   // feature name.
   EXPECT_EQ(2UL, messages.size());
   EXPECT_EQ(3UL, parsed_policy.size());
-  EXPECT_EQ(FeaturePolicyFeature::kVibrate, parsed_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kVibrate, parsed_policy[0].feature);
   EXPECT_FALSE(parsed_policy[0].matches_all_origins);
   EXPECT_EQ(1UL, parsed_policy[0].origins.size());
   EXPECT_TRUE(
       parsed_policy[0].origins[0].IsSameOriginWith(expected_url_origin_a_));
-  EXPECT_EQ(FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
   EXPECT_FALSE(parsed_policy[1].matches_all_origins);
   EXPECT_EQ(1UL, parsed_policy[1].origins.size());
   EXPECT_TRUE(
       parsed_policy[1].origins[0].IsSameOriginWith(expected_url_origin_a_));
-  EXPECT_EQ(FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
   EXPECT_FALSE(parsed_policy[2].matches_all_origins);
   EXPECT_EQ(1UL, parsed_policy[2].origins.size());
   EXPECT_TRUE(
@@ -203,17 +203,17 @@
       ParseFeaturePolicy("vibrate;fullscreen;payment", origin_a_.get(), nullptr,
                          &messages, test_feature_name_map);
   EXPECT_EQ(3UL, parsed_policy.size());
-  EXPECT_EQ(FeaturePolicyFeature::kVibrate, parsed_policy[0].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kVibrate, parsed_policy[0].feature);
   EXPECT_FALSE(parsed_policy[0].matches_all_origins);
   EXPECT_EQ(1UL, parsed_policy[0].origins.size());
   EXPECT_TRUE(
       parsed_policy[0].origins[0].IsSameOriginWith(expected_url_origin_a_));
-  EXPECT_EQ(FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature);
   EXPECT_FALSE(parsed_policy[1].matches_all_origins);
   EXPECT_EQ(1UL, parsed_policy[1].origins.size());
   EXPECT_TRUE(
       parsed_policy[1].origins[0].IsSameOriginWith(expected_url_origin_a_));
-  EXPECT_EQ(FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
+  EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, parsed_policy[2].feature);
   EXPECT_FALSE(parsed_policy[2].matches_all_origins);
   EXPECT_EQ(1UL, parsed_policy[2].origins.size());
   EXPECT_TRUE(
diff --git a/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm b/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
index b55abfd..f6efeed 100644
--- a/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
+++ b/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
@@ -66,7 +66,7 @@
 
 static void InvalidateFontCache() {
   if (!IsMainThread()) {
-    Platform::Current()->MainThread()->GetWebTaskRunner()->PostTask(
+    Platform::Current()->MainThread()->GetTaskRunner()->PostTask(
         FROM_HERE, WTF::Bind(&InvalidateFontCache));
     return;
   }
diff --git a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp
index e24cbb3..56d233b 100644
--- a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp
+++ b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.cpp
@@ -124,7 +124,7 @@
   DCHECK(original_skia_image_);
   WebThread* thread = Platform::Current()->CurrentThread();
   original_skia_image_thread_id_ = thread->ThreadId();
-  original_skia_image_task_runner_ = thread->GetWebTaskRunner();
+  original_skia_image_task_runner_ = thread->GetTaskRunner();
 }
 
 IntSize AcceleratedStaticBitmapImage::Size() const {
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
index 99f4d1e..821f351f 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -431,7 +431,7 @@
     logger_->ReportHibernationEvent(kHibernationScheduled);
     hibernation_scheduled_ = true;
     if (dont_use_idle_scheduling_for_testing_) {
-      Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+      Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
           FROM_HERE, WTF::Bind(&HibernateWrapperForTesting,
                                weak_ptr_factory_.GetWeakPtr()));
     } else {
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorMutatorClient.h b/third_party/WebKit/Source/platform/graphics/CompositorMutatorClient.h
index ea26b0af..d6ddd5d 100644
--- a/third_party/WebKit/Source/platform/graphics/CompositorMutatorClient.h
+++ b/third_party/WebKit/Source/platform/graphics/CompositorMutatorClient.h
@@ -5,17 +5,16 @@
 #ifndef CompositorMutatorClient_h
 #define CompositorMutatorClient_h
 
+#include <memory>
+#include "cc/trees/layer_tree_mutator.h"
 #include "platform/PlatformExport.h"
 #include "platform/heap/Handle.h"
-#include "public/platform/WebCompositorMutatorClient.h"
-#include <memory>
 
 namespace blink {
 
 class CompositorMutator;
 
-class PLATFORM_EXPORT CompositorMutatorClient
-    : public WebCompositorMutatorClient {
+class PLATFORM_EXPORT CompositorMutatorClient : public cc::LayerTreeMutator {
  public:
   explicit CompositorMutatorClient(CompositorMutator*);
   virtual ~CompositorMutatorClient();
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorMutatorImpl.cpp b/third_party/WebKit/Source/platform/graphics/CompositorMutatorImpl.cpp
index 22c3335..dd674eda 100644
--- a/third_party/WebKit/Source/platform/graphics/CompositorMutatorImpl.cpp
+++ b/third_party/WebKit/Source/platform/graphics/CompositorMutatorImpl.cpp
@@ -35,7 +35,7 @@
   std::unique_ptr<CompositorMutatorClient> mutator_client;
   WaitableEvent done_event;
   if (WebThread* compositor_thread = Platform::Current()->CompositorThread()) {
-    PostCrossThreadTask(*compositor_thread->GetWebTaskRunner(), FROM_HERE,
+    PostCrossThreadTask(*compositor_thread->GetTaskRunner(), FROM_HERE,
                         CrossThreadBind(&CreateCompositorMutatorClient,
                                         CrossThreadUnretained(&mutator_client),
                                         CrossThreadUnretained(&done_event)));
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
index 9a102a0e..6c50a9ae 100644
--- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
@@ -229,7 +229,7 @@
       WebThreadCreationParams(WebThreadType::kTestThread)
           .SetThreadName("RasterThread"));
   PostCrossThreadTask(
-      *thread->GetWebTaskRunner(), FROM_HERE,
+      *thread->GetTaskRunner(), FROM_HERE,
       CrossThreadBind(&RasterizeMain, CrossThreadUnretained(canvas_.get()),
                       record));
   thread.reset();
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGeneratorTest.cpp b/third_party/WebKit/Source/platform/graphics/ImageFrameGeneratorTest.cpp
index 74cb01f..48a51a77d 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGeneratorTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGeneratorTest.cpp
@@ -260,7 +260,7 @@
       WebThreadCreationParams(WebThreadType::kTestThread)
           .SetThreadName("DecodeThread"));
   PostCrossThreadTask(
-      *thread->GetWebTaskRunner(), FROM_HERE,
+      *thread->GetTaskRunner(), FROM_HERE,
       CrossThreadBind(&DecodeThreadMain, WTF::RetainedRef(generator_),
                       WTF::RetainedRef(segment_reader_)));
   thread.reset();
diff --git a/third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.cpp b/third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.cpp
index 4f83b700..a8b1f85 100644
--- a/third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.cpp
@@ -119,7 +119,7 @@
 void MailboxTextureHolder::InitCommon() {
   WebThread* thread = Platform::Current()->CurrentThread();
   thread_id_ = thread->ThreadId();
-  texture_thread_task_runner_ = thread->GetWebTaskRunner();
+  texture_thread_task_runner_ = thread->GetTaskRunner();
 }
 
 bool MailboxTextureHolder::IsValid() const {
diff --git a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp
index ffbc3373..178cbdf 100644
--- a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp
+++ b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp
@@ -120,7 +120,7 @@
     scoped_refptr<StaticBitmapImage> image,
     unsigned resource_id) {
   scoped_refptr<base::SingleThreadTaskRunner> dispatcher_task_runner =
-      Platform::Current()->CurrentThread()->GetWebTaskRunner();
+      Platform::Current()->CurrentThread()->GetTaskRunner();
 
   PostCrossThreadTask(
       *Platform::Current()->MainThread()->Scheduler()->CompositorTaskRunner(),
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp
index dc8887ab..0f67ced 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp
@@ -123,7 +123,7 @@
     // this once per thread.
     WaitableEvent waitable_event;
     scoped_refptr<base::SingleThreadTaskRunner> task_runner =
-        Platform::Current()->MainThread()->GetWebTaskRunner();
+        Platform::Current()->MainThread()->GetTaskRunner();
     PostCrossThreadTask(
         *task_runner, FROM_HERE,
         CrossThreadBind(&CreateContextProviderOnMainThread,
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
index 87c2c61..20ea356 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -485,7 +485,7 @@
           WebThreadCreationParams(WebThreadType::kTestThread)
               .SetThreadName("blink gc testing thread")));
       PostCrossThreadTask(
-          *threads.back()->GetWebTaskRunner(), FROM_HERE,
+          *threads.back()->GetTaskRunner(), FROM_HERE,
           CrossThreadBind(ThreadFunc, CrossThreadUnretained(tester)));
     }
     while (tester->threads_to_finish_) {
@@ -5471,7 +5471,7 @@
         Platform::Current()->CreateThread(
             WebThreadCreationParams(WebThreadType::kTestThread)
                 .SetThreadName("Test Worker Thread"));
-    PostCrossThreadTask(*worker_thread->GetWebTaskRunner(), FROM_HERE,
+    PostCrossThreadTask(*worker_thread->GetTaskRunner(), FROM_HERE,
                         CrossThreadBind(WorkerThreadMain));
 
     // Wait for the worker thread initialization. The worker
@@ -5573,7 +5573,7 @@
             WebThreadCreationParams(WebThreadType::kTestThread)
                 .SetThreadName("Test Worker Thread"));
     PostCrossThreadTask(
-        *worker_thread->GetWebTaskRunner(), FROM_HERE,
+        *worker_thread->GetTaskRunner(), FROM_HERE,
         CrossThreadBind(&MemberSameThreadCheckTester::WorkerThreadMain,
                         CrossThreadUnretained(this)));
 
@@ -5618,7 +5618,7 @@
             WebThreadCreationParams(WebThreadType::kTestThread)
                 .SetThreadName("Test Worker Thread"));
     PostCrossThreadTask(
-        *worker_thread->GetWebTaskRunner(), FROM_HERE,
+        *worker_thread->GetTaskRunner(), FROM_HERE,
         CrossThreadBind(&PersistentSameThreadCheckTester::WorkerThreadMain,
                         CrossThreadUnretained(this)));
 
@@ -5664,7 +5664,7 @@
                 .SetThreadName("Test Worker Thread"));
     Persistent<MainThreadObject> main_thread_object = new MainThreadObject();
     PostCrossThreadTask(
-        *worker_thread->GetWebTaskRunner(), FROM_HERE,
+        *worker_thread->GetTaskRunner(), FROM_HERE,
         CrossThreadBind(&MarkingSameThreadCheckTester::WorkerThreadMain,
                         CrossThreadUnretained(this),
                         WrapCrossThreadPersistent(main_thread_object.Get())));
@@ -6464,7 +6464,7 @@
           .SetThreadName("Test Worker Thread"));
   DestructorLockingObject* object = nullptr;
   PostCrossThreadTask(
-      *worker_thread->GetWebTaskRunner(), FROM_HERE,
+      *worker_thread->GetTaskRunner(), FROM_HERE,
       CrossThreadBind(WorkerThreadMainForCrossThreadWeakPersistentTest,
                       CrossThreadUnretained(&object)));
   ParkMainThread();
diff --git a/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriterTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriterTest.cpp
index b96f972..87813dc 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriterTest.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriterTest.cpp
@@ -41,7 +41,7 @@
     input.push_back(static_cast<char>(engine() % 26 + 'A'));
 
   auto writer = std::make_unique<BufferingDataPipeWriter>(
-      std::move(producer), platform->CurrentThread()->GetWebTaskRunner());
+      std::move(producer), platform->CurrentThread()->GetTaskRunner().get());
 
   for (size_t i = 0; i < total;) {
     // We use a temporary buffer to check that the buffer is copied immediately.
diff --git a/third_party/WebKit/Source/platform/loader/fetch/FetchContext.h b/third_party/WebKit/Source/platform/loader/fetch/FetchContext.h
index 8363f09..7545aa6 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/FetchContext.h
+++ b/third_party/WebKit/Source/platform/loader/fetch/FetchContext.h
@@ -252,7 +252,7 @@
   // (after Detach() is called, this will return a generic timer suitable for
   // post-detach actions like keepalive requests.
   virtual scoped_refptr<base::SingleThreadTaskRunner> GetLoadingTaskRunner() {
-    return Platform::Current()->CurrentThread()->GetWebTaskRunner();
+    return Platform::Current()->CurrentThread()->GetTaskRunner();
   }
 
   // Called when the underlying context is detached. Note that some
diff --git a/third_party/WebKit/Source/platform/loader/fetch/MemoryCacheTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/MemoryCacheTest.cpp
index 4180c0d2..677ce36 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/MemoryCacheTest.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/MemoryCacheTest.cpp
@@ -213,10 +213,10 @@
   resource2->AppendData(kData, 4u);
   resource2->FinishForTest();
 
-  Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+  Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
       FROM_HERE, WTF::Bind(&RunTask1, WrapPersistent(resource1),
                            WrapPersistent(resource2)));
-  Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+  Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
       FROM_HERE,
       WTF::Bind(&RunTask2,
                 resource1->EncodedSize() + resource1->OverheadSize() +
diff --git a/third_party/WebKit/Source/platform/loader/fetch/RawResourceTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/RawResourceTest.cpp
index 27d28289..1de3fad 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/RawResourceTest.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/RawResourceTest.cpp
@@ -126,12 +126,12 @@
     // First schedule an asynchronous task to remove the client.
     // We do not expect a client to be called if the client is removed before
     // a callback invocation task queued inside addClient() is scheduled.
-    Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+    Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
         FROM_HERE,
         WTF::Bind(&AddingClient::RemoveClient, WrapPersistent(this)));
     resource->AddClient(
         dummy_client_,
-        Platform::Current()->CurrentThread()->GetWebTaskRunner());
+        Platform::Current()->CurrentThread()->GetTaskRunner().get());
   }
   String DebugName() const override { return "AddingClient"; }
 
@@ -158,7 +158,7 @@
   Persistent<AddingClient> adding_client =
       new AddingClient(dummy_client.Get(), raw);
   raw->AddClient(adding_client,
-                 Platform::Current()->CurrentThread()->GetWebTaskRunner());
+                 Platform::Current()->CurrentThread()->GetTaskRunner().get());
   platform_->RunUntilIdle();
   raw->RemoveClient(adding_client);
   EXPECT_FALSE(dummy_client->Called());
@@ -200,9 +200,9 @@
   Persistent<RemovingClient> removing_client =
       new RemovingClient(dummy_client.Get());
   raw->AddClient(dummy_client,
-                 Platform::Current()->CurrentThread()->GetWebTaskRunner());
+                 Platform::Current()->CurrentThread()->GetTaskRunner().get());
   raw->AddClient(removing_client,
-                 Platform::Current()->CurrentThread()->GetWebTaskRunner());
+                 Platform::Current()->CurrentThread()->GetTaskRunner().get());
   platform_->RunUntilIdle();
   EXPECT_FALSE(raw->IsAlive());
 }
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceResponseTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceResponseTest.cpp
index 813f85e..218552c 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceResponseTest.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceResponseTest.cpp
@@ -79,7 +79,7 @@
   std::unique_ptr<WebThread> thread = Platform::Current()->CreateThread(
       WebThreadCreationParams(WebThreadType::kTestThread)
           .SetThreadName("WorkerThread"));
-  PostCrossThreadTask(*thread->GetWebTaskRunner(), FROM_HERE,
+  PostCrossThreadTask(*thread->GetTaskRunner(), FROM_HERE,
                       CrossThreadBind(&RunInThread));
   thread.reset();
 }
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceTest.cpp
index 6c1150d..9c2f77e4 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceTest.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceTest.cpp
@@ -409,8 +409,8 @@
 
   // Test the case where a client is added after revalidation is completed.
   Persistent<MockResourceClient> client2 = new MockResourceClient;
-  resource->AddClient(client2,
-                      Platform::Current()->CurrentThread()->GetWebTaskRunner());
+  resource->AddClient(
+      client2, Platform::Current()->CurrentThread()->GetTaskRunner().get());
 
   // Because the client is added asynchronously,
   // |runUntilIdle()| is called to make |client2| to be notified.
diff --git a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
index 72c219e..8c024ed 100644
--- a/third_party/WebKit/Source/platform/runtime_enabled_features.json5
+++ b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
@@ -1001,6 +1001,10 @@
       name: "SlimmingPaintV2",
     },
     {
+      name: "SlotInFlatTree",
+      status: "experimental",
+    },
+    {
       name: "SMIL",
       status: "stable",
     },
diff --git a/third_party/WebKit/Source/platform/scheduler/util/thread_cpu_throttler.cc b/third_party/WebKit/Source/platform/scheduler/util/thread_cpu_throttler.cc
index f68158d..dbb54e1 100644
--- a/third_party/WebKit/Source/platform/scheduler/util/thread_cpu_throttler.cc
+++ b/third_party/WebKit/Source/platform/scheduler/util/thread_cpu_throttler.cc
@@ -11,7 +11,7 @@
 #include "base/threading/platform_thread.h"
 #include "build/build_config.h"
 
-#if defined(OS_POSIX)
+#if defined(OS_POSIX) && !defined(OS_FUCHSIA)
 #include <signal.h>
 #define USE_SIGNALS 1
 #elif defined(OS_WIN)
@@ -145,7 +145,10 @@
 
 void ThreadCPUThrottler::ThrottlingThread::Throttle() {
   const int quant_time_us = 200;
-#if defined(OS_WIN)
+#ifdef USE_SIGNALS
+  pthread_kill(throttled_thread_handle_.platform_handle(), SIGUSR2);
+  Sleep(base::TimeDelta::FromMicroseconds(quant_time_us));
+#elif defined(OS_WIN)
   double rate = Acquire_Load(&throttling_rate_percent_) / 100.;
   base::TimeDelta run_duration =
       base::TimeDelta::FromMicroseconds(static_cast<int>(quant_time_us / rate));
@@ -156,8 +159,7 @@
   Sleep(sleep_duration);
   ::ResumeThread(throttled_thread_handle_.platform_handle());
 #else
-  pthread_kill(throttled_thread_handle_.platform_handle(), SIGUSR2);
-  Sleep(base::TimeDelta::FromMicroseconds(quant_time_us));
+  ALLOW_UNUSED_LOCAL(quant_time_us);
 #endif
 }
 
@@ -165,7 +167,8 @@
 #ifdef USE_SIGNALS
   InstallSignalHandler();
 #elif !defined(OS_WIN)
-  LOG(ERROR) << "CPU throttling is not supported."
+  LOG(ERROR) << "CPU throttling is not supported.";
+  return;
 #endif
   if (!base::PlatformThread::Create(0, this, &throttling_thread_handle_)) {
     LOG(ERROR) << "Failed to create throttling thread.";
diff --git a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
index 81f8eee..33de0d0a 100644
--- a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
+++ b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
@@ -53,7 +53,7 @@
 }  // namespace
 
 void RunPendingTasks() {
-  Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostTask(
+  Platform::Current()->CurrentThread()->GetTaskRunner()->PostTask(
       FROM_HERE, WTF::Bind(&ExitRunLoop));
 
   // We forbid GC in the tasks. Otherwise the registered GCTaskObserver tries
@@ -64,7 +64,7 @@
 }
 
 void RunDelayedTasks(TimeDelta delay) {
-  Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostDelayedTask(
+  Platform::Current()->CurrentThread()->GetTaskRunner()->PostDelayedTask(
       FROM_HERE, WTF::Bind(&ExitRunLoop), delay);
   EnterRunLoop();
 }
diff --git a/third_party/WebKit/common/feature_policy/README.md b/third_party/WebKit/common/feature_policy/README.md
index 2cf0f11..9193b795 100644
--- a/third_party/WebKit/common/feature_policy/README.md
+++ b/third_party/WebKit/common/feature_policy/README.md
@@ -4,7 +4,7 @@
 Feature policy (see [spec](https://wicg.github.io/feature-policy/)) is a
 mechanism that allows developers to selectively enable and disable various
 [browser features and
-APIs](https://cs.chromium.org/chromium/src/third_party/WebKit/common/feature_policy/feature_policy_feature.h)
+APIs](https://cs.chromium.org/chromium/src/third_party/WebKit/common/feature_policy/feature_policy.mojom)
 (e.g, "vibrate", "fullscreen", "usb", etc.). A feature policy can be defined
 via a HTTP header and/or an iframe "allow" attribute.
 
diff --git a/third_party/WebKit/common/feature_policy/feature_policy.cc b/third_party/WebKit/common/feature_policy/feature_policy.cc
index 83a6650..550da15 100644
--- a/third_party/WebKit/common/feature_policy/feature_policy.cc
+++ b/third_party/WebKit/common/feature_policy/feature_policy.cc
@@ -9,7 +9,6 @@
 #include "base/stl_util.h"
 
 namespace blink {
-
 namespace {
 
 // Extracts a Whitelist from a ParsedFeaturePolicyDeclaration.
@@ -30,7 +29,7 @@
     : matches_all_origins(false) {}
 
 ParsedFeaturePolicyDeclaration::ParsedFeaturePolicyDeclaration(
-    FeaturePolicyFeature feature,
+    mojom::FeaturePolicyFeature feature,
     bool matches_all_origins,
     std::vector<url::Origin> origins)
     : feature(feature),
@@ -118,12 +117,14 @@
   return new_policy;
 }
 
-bool FeaturePolicy::IsFeatureEnabled(FeaturePolicyFeature feature) const {
+bool FeaturePolicy::IsFeatureEnabled(
+    mojom::FeaturePolicyFeature feature) const {
   return IsFeatureEnabledForOrigin(feature, origin_);
 }
 
-bool FeaturePolicy::IsFeatureEnabledForOrigin(FeaturePolicyFeature feature,
-                                              const url::Origin& origin) const {
+bool FeaturePolicy::IsFeatureEnabledForOrigin(
+    mojom::FeaturePolicyFeature feature,
+    const url::Origin& origin) const {
   DCHECK(base::ContainsKey(feature_list_, feature));
   DCHECK(base::ContainsKey(inherited_policies_, feature));
   if (!inherited_policies_.at(feature))
@@ -146,7 +147,7 @@
 }
 
 const FeaturePolicy::Whitelist FeaturePolicy::GetWhitelistForFeature(
-    FeaturePolicyFeature feature) const {
+    mojom::FeaturePolicyFeature feature) const {
   DCHECK(base::ContainsKey(feature_list_, feature));
   DCHECK(base::ContainsKey(inherited_policies_, feature));
   // Disabled through inheritance.
@@ -173,8 +174,8 @@
   DCHECK(whitelists_.empty());
   for (const ParsedFeaturePolicyDeclaration& parsed_declaration :
        parsed_header) {
-    FeaturePolicyFeature feature = parsed_declaration.feature;
-    DCHECK(feature != FeaturePolicyFeature::kNotFound);
+    mojom::FeaturePolicyFeature feature = parsed_declaration.feature;
+    DCHECK(feature != mojom::FeaturePolicyFeature::kNotFound);
     whitelists_[feature] = WhitelistFromDeclaration(parsed_declaration);
   }
 }
@@ -222,8 +223,8 @@
     // If a feature is enabled in the parent frame, and the parent chooses to
     // delegate it to the child frame, using the iframe attribute, then the
     // feature should be enabled in the child frame.
-    FeaturePolicyFeature feature = parsed_declaration.feature;
-    if (feature == FeaturePolicyFeature::kNotFound)
+    mojom::FeaturePolicyFeature feature = parsed_declaration.feature;
+    if (feature == mojom::FeaturePolicyFeature::kNotFound)
       continue;
     if (WhitelistFromDeclaration(parsed_declaration)->Contains(origin_) &&
         parent_policy->IsFeatureEnabled(feature)) {
@@ -239,51 +240,51 @@
 // each feature (in spec, implemented, etc).
 const FeaturePolicy::FeatureList& FeaturePolicy::GetDefaultFeatureList() {
   CR_DEFINE_STATIC_LOCAL(FeatureList, default_feature_list,
-                         ({{FeaturePolicyFeature::kAutoplay,
+                         ({{mojom::FeaturePolicyFeature::kAutoplay,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kCamera,
+                           {mojom::FeaturePolicyFeature::kCamera,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kEncryptedMedia,
+                           {mojom::FeaturePolicyFeature::kEncryptedMedia,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kFullscreen,
+                           {mojom::FeaturePolicyFeature::kFullscreen,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kGeolocation,
+                           {mojom::FeaturePolicyFeature::kGeolocation,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kMicrophone,
+                           {mojom::FeaturePolicyFeature::kMicrophone,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kMidiFeature,
+                           {mojom::FeaturePolicyFeature::kMidiFeature,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kPayment,
+                           {mojom::FeaturePolicyFeature::kPayment,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kSpeaker,
+                           {mojom::FeaturePolicyFeature::kSpeaker,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kVibrate,
+                           {mojom::FeaturePolicyFeature::kVibrate,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kDocumentCookie,
+                           {mojom::FeaturePolicyFeature::kDocumentCookie,
                             FeaturePolicy::FeatureDefault::EnableForAll},
-                           {FeaturePolicyFeature::kDocumentDomain,
+                           {mojom::FeaturePolicyFeature::kDocumentDomain,
                             FeaturePolicy::FeatureDefault::EnableForAll},
-                           {FeaturePolicyFeature::kDocumentWrite,
+                           {mojom::FeaturePolicyFeature::kDocumentWrite,
                             FeaturePolicy::FeatureDefault::EnableForAll},
-                           {FeaturePolicyFeature::kSyncScript,
+                           {mojom::FeaturePolicyFeature::kSyncScript,
                             FeaturePolicy::FeatureDefault::EnableForAll},
-                           {FeaturePolicyFeature::kSyncXHR,
+                           {mojom::FeaturePolicyFeature::kSyncXHR,
                             FeaturePolicy::FeatureDefault::EnableForAll},
-                           {FeaturePolicyFeature::kUsb,
+                           {mojom::FeaturePolicyFeature::kUsb,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kWebVr,
+                           {mojom::FeaturePolicyFeature::kWebVr,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kAccelerometer,
+                           {mojom::FeaturePolicyFeature::kAccelerometer,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kAmbientLightSensor,
+                           {mojom::FeaturePolicyFeature::kAmbientLightSensor,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kGyroscope,
+                           {mojom::FeaturePolicyFeature::kGyroscope,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kMagnetometer,
+                           {mojom::FeaturePolicyFeature::kMagnetometer,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
-                           {FeaturePolicyFeature::kUnsizedMedia,
+                           {mojom::FeaturePolicyFeature::kUnsizedMedia,
                             FeaturePolicy::FeatureDefault::EnableForAll},
-                           {FeaturePolicyFeature::kPictureInPicture,
+                           {mojom::FeaturePolicyFeature::kPictureInPicture,
                             FeaturePolicy::FeatureDefault::EnableForSelf}}));
   return default_feature_list;
 }
diff --git a/third_party/WebKit/common/feature_policy/feature_policy.h b/third_party/WebKit/common/feature_policy/feature_policy.h
index 6304020a..7549eca 100644
--- a/third_party/WebKit/common/feature_policy/feature_policy.h
+++ b/third_party/WebKit/common/feature_policy/feature_policy.h
@@ -12,7 +12,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "third_party/WebKit/common/common_export.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
+#include "third_party/WebKit/common/feature_policy/feature_policy.mojom.h"
 #include "url/origin.h"
 
 namespace blink {
@@ -34,7 +34,7 @@
 // Features
 // --------
 // Features which can be controlled by policy are defined by instances of enum
-// FeaturePolicyFeature, declared in |feature_policy_feature.h|.
+// mojom::FeaturePolicyFeature, declared in |feature_policy.mojom|.
 //
 // Whitelists
 // ----------
@@ -89,7 +89,7 @@
 // TODO(lunalu): Remove unnecessary types used for transferring over IPC.
 struct BLINK_COMMON_EXPORT ParsedFeaturePolicyDeclaration {
   ParsedFeaturePolicyDeclaration();
-  ParsedFeaturePolicyDeclaration(FeaturePolicyFeature feature,
+  ParsedFeaturePolicyDeclaration(mojom::FeaturePolicyFeature feature,
                                  bool matches_all_origins,
                                  std::vector<url::Origin> origins);
   ParsedFeaturePolicyDeclaration(const ParsedFeaturePolicyDeclaration& rhs);
@@ -97,7 +97,7 @@
       const ParsedFeaturePolicyDeclaration& rhs);
   ~ParsedFeaturePolicyDeclaration();
 
-  FeaturePolicyFeature feature;
+  mojom::FeaturePolicyFeature feature;
   bool matches_all_origins;
   std::vector<url::Origin> origins;
 };
@@ -158,7 +158,7 @@
     EnableForAll
   };
 
-  using FeatureList = std::map<FeaturePolicyFeature, FeatureDefault>;
+  using FeatureList = std::map<mojom::FeaturePolicyFeature, FeatureDefault>;
 
   ~FeaturePolicy();
 
@@ -171,15 +171,16 @@
       const FeaturePolicy& policy,
       const url::Origin& origin);
 
-  bool IsFeatureEnabled(FeaturePolicyFeature feature) const;
+  bool IsFeatureEnabled(mojom::FeaturePolicyFeature feature) const;
 
   // Returns whether or not the given feature is enabled by this policy for a
   // specific origin.
-  bool IsFeatureEnabledForOrigin(FeaturePolicyFeature feature,
+  bool IsFeatureEnabledForOrigin(mojom::FeaturePolicyFeature feature,
                                  const url::Origin& origin) const;
 
   // Returns the whitelist of a given feature by this policy.
-  const Whitelist GetWhitelistForFeature(FeaturePolicyFeature feature) const;
+  const Whitelist GetWhitelistForFeature(
+      mojom::FeaturePolicyFeature feature) const;
 
   // Sets the declared policy from the parsed Feature-Policy HTTP header.
   // Unrecognized features will be ignored.
@@ -210,13 +211,13 @@
 
   // Map of feature names to declared whitelists. Any feature which is missing
   // from this map should use the inherited policy.
-  std::map<FeaturePolicyFeature, std::unique_ptr<Whitelist>> whitelists_;
+  std::map<mojom::FeaturePolicyFeature, std::unique_ptr<Whitelist>> whitelists_;
 
   // Records whether or not each feature was enabled for this frame by its
   // parent frame.
   // TODO(iclelland): Generate, instead of this map, a set of bool flags, one
   // for each feature, as all features are supposed to be represented here.
-  std::map<FeaturePolicyFeature, bool> inherited_policies_;
+  std::map<mojom::FeaturePolicyFeature, bool> inherited_policies_;
 
   const FeatureList& feature_list_;
 
diff --git a/third_party/WebKit/common/feature_policy/feature_policy.mojom b/third_party/WebKit/common/feature_policy/feature_policy.mojom
index 6219304..93ac073 100644
--- a/third_party/WebKit/common/feature_policy/feature_policy.mojom
+++ b/third_party/WebKit/common/feature_policy/feature_policy.mojom
@@ -34,7 +34,6 @@
 // https://github.com/WICG/feature-policy/blob/gh-pages/features.md. Many of
 // these are still under development in blink behind the
 // featurePolicyExperimentalFeatures flag.
-// This enum is also defined in ./feature_policy_feature.h
 enum FeaturePolicyFeature {
   kNotFound = 0,
   // Controls access to media autoplay.
@@ -86,6 +85,7 @@
   kUnsizedMedia,
   // Controls access to Picture-in-Picture.
   kPictureInPicture,
+  kLastFeature = kPictureInPicture,
 };
 
 // This struct holds feature policy whitelist data that needs to be replicated
diff --git a/third_party/WebKit/common/feature_policy/feature_policy.typemap b/third_party/WebKit/common/feature_policy/feature_policy.typemap
index 9107d26..bd7b333 100644
--- a/third_party/WebKit/common/feature_policy/feature_policy.typemap
+++ b/third_party/WebKit/common/feature_policy/feature_policy.typemap
@@ -5,7 +5,6 @@
 mojom = "//third_party/WebKit/common/feature_policy/feature_policy.mojom"
 public_headers = [
   "//third_party/WebKit/common/feature_policy/feature_policy.h",
-  "//third_party/WebKit/common/feature_policy/feature_policy_feature.h",
   "//third_party/WebKit/common/sandbox_flags.h",
 ]
 traits_headers = [
@@ -15,7 +14,6 @@
   "//third_party/WebKit/common/feature_policy/feature_policy_struct_traits.cc",
 ]
 type_mappings = [
-  "blink.mojom.FeaturePolicyFeature=blink::FeaturePolicyFeature",
   "blink.mojom.ParsedFeaturePolicyDeclaration=blink::ParsedFeaturePolicyDeclaration",
   "blink.mojom.WebSandboxFlags=blink::WebSandboxFlags",
 ]
diff --git a/third_party/WebKit/common/feature_policy/feature_policy_feature.h b/third_party/WebKit/common/feature_policy/feature_policy_feature.h
deleted file mode 100644
index 7982b0e..0000000
--- a/third_party/WebKit/common/feature_policy/feature_policy_feature.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_WEBKIT_COMMON_FEATURE_POLICY_FEATURE_POLICY_FEATURE_H_
-#define THIRD_PARTY_WEBKIT_COMMON_FEATURE_POLICY_FEATURE_POLICY_FEATURE_H_
-
-namespace blink {
-
-// These values map to the features which can be controlled by Feature Policy.
-//
-// Features are defined in
-// https://github.com/WICG/feature-policy/blob/gh-pages/features.md. Many of
-// these are still under development in blink behind the
-// featurePolicyExperimentalFeatures flag.
-enum class FeaturePolicyFeature {
-  kNotFound = 0,
-  // Controls access to media autoplay.
-  kAutoplay,
-  // Controls access to video input devices.
-  kCamera,
-  // Controls whether navigator.requestMediaKeySystemAccess is allowed.
-  kEncryptedMedia,
-  // Controls whether Element.requestFullscreen is allowed.
-  kFullscreen,
-  // Controls access to Geolocation interface.
-  kGeolocation,
-  // Controls access to audio input devices.
-  kMicrophone,
-  // Controls access to requestMIDIAccess method.
-  kMidiFeature,
-  // Controls access to PaymentRequest interface.
-  kPayment,
-  // Controls access to audio output devices.
-  kSpeaker,
-  // Controls access to navigator.vibrate method.
-  kVibrate,
-  // Controls access to document.cookie attribute.
-  kDocumentCookie,
-  // Contols access to document.domain attribute.
-  kDocumentDomain,
-  // Controls access to document.write and document.writeln methods.
-  kDocumentWrite,
-  // Controls whether synchronous script elements will run.
-  kSyncScript,
-  // Controls use of synchronous XMLHTTPRequest API.
-  kSyncXHR,
-  // Controls access to the WebUSB API.
-  kUsb,
-  // Controls access to AOM event listeners.
-  kAccessibilityEvents,
-  // Controls use of WebVR API.
-  kWebVr,
-  // The following features control access to the corresponding sensor classes.
-  // Fusion sensor APIs (e.g. LinearAcceleration, OrientationSensor-based
-  // classes)require all of the features that are inputs into that API to be
-  // enabled for the feature to be allowed.
-  kAccelerometer,
-  kAmbientLightSensor,
-  kGyroscope,
-  kMagnetometer,
-  // Controls the layout size of intrinsically sized images and videos. When
-  // disabled, default size (300 x 150) is used to prevent relayout.
-  kUnsizedMedia,
-  // Controls access to Picture-in-Picture.
-  kPictureInPicture,
-  LAST_FEATURE = kPictureInPicture
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_WEBKIT_COMMON_FEATURE_POLICY_FEATURE_POLICY_FEATURE_H_
diff --git a/third_party/WebKit/common/feature_policy/feature_policy_struct_traits.h b/third_party/WebKit/common/feature_policy/feature_policy_struct_traits.h
index f11d15a..0abb66e 100644
--- a/third_party/WebKit/common/feature_policy/feature_policy_struct_traits.h
+++ b/third_party/WebKit/common/feature_policy/feature_policy_struct_traits.h
@@ -11,7 +11,6 @@
 #include "third_party/WebKit/common/common_export.h"
 #include "third_party/WebKit/common/feature_policy/feature_policy.h"
 #include "third_party/WebKit/common/feature_policy/feature_policy.mojom-shared.h"
-#include "third_party/WebKit/common/feature_policy/feature_policy_feature.h"
 #include "third_party/WebKit/common/sandbox_flags.h"
 
 namespace mojo {
@@ -20,56 +19,6 @@
   static_assert(static_cast<int>(a) == static_cast<int>(b), \
                 "mismatching enum : " #a)
 
-// TODO(crbug.com/789818) - Merge these 2 FeaturePolicyFeature enums.
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kNotFound,
-                   ::blink::mojom::FeaturePolicyFeature::kNotFound);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kAutoplay,
-                   ::blink::mojom::FeaturePolicyFeature::kAutoplay);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kCamera,
-                   ::blink::mojom::FeaturePolicyFeature::kCamera);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kEncryptedMedia,
-                   ::blink::mojom::FeaturePolicyFeature::kEncryptedMedia);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kFullscreen,
-                   ::blink::mojom::FeaturePolicyFeature::kFullscreen);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kGeolocation,
-                   ::blink::mojom::FeaturePolicyFeature::kGeolocation);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kMicrophone,
-                   ::blink::mojom::FeaturePolicyFeature::kMicrophone);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kMidiFeature,
-                   ::blink::mojom::FeaturePolicyFeature::kMidiFeature);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kPayment,
-                   ::blink::mojom::FeaturePolicyFeature::kPayment);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kSpeaker,
-                   ::blink::mojom::FeaturePolicyFeature::kSpeaker);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kVibrate,
-                   ::blink::mojom::FeaturePolicyFeature::kVibrate);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kDocumentCookie,
-                   ::blink::mojom::FeaturePolicyFeature::kDocumentCookie);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kDocumentDomain,
-                   ::blink::mojom::FeaturePolicyFeature::kDocumentDomain);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kDocumentWrite,
-                   ::blink::mojom::FeaturePolicyFeature::kDocumentWrite);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kSyncScript,
-                   ::blink::mojom::FeaturePolicyFeature::kSyncScript);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kSyncXHR,
-                   ::blink::mojom::FeaturePolicyFeature::kSyncXHR);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kUsb,
-                   ::blink::mojom::FeaturePolicyFeature::kUsb);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kWebVr,
-                   ::blink::mojom::FeaturePolicyFeature::kWebVr);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kAccelerometer,
-                   ::blink::mojom::FeaturePolicyFeature::kAccelerometer);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kAmbientLightSensor,
-                   ::blink::mojom::FeaturePolicyFeature::kAmbientLightSensor);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kGyroscope,
-                   ::blink::mojom::FeaturePolicyFeature::kGyroscope);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kMagnetometer,
-                   ::blink::mojom::FeaturePolicyFeature::kMagnetometer);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kUnsizedMedia,
-                   ::blink::mojom::FeaturePolicyFeature::kUnsizedMedia);
-STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kPictureInPicture,
-                   ::blink::mojom::FeaturePolicyFeature::kPictureInPicture);
-
 // TODO(crbug.com/789818) - Merge these 2 WebSandboxFlags enums.
 STATIC_ASSERT_ENUM(::blink::WebSandboxFlags::kNone,
                    ::blink::mojom::WebSandboxFlags::kNone);
@@ -122,25 +71,11 @@
 };
 
 template <>
-struct BLINK_COMMON_EXPORT EnumTraits<blink::mojom::FeaturePolicyFeature,
-                                      blink::FeaturePolicyFeature> {
-  static blink::mojom::FeaturePolicyFeature ToMojom(
-      blink::FeaturePolicyFeature feature) {
-    return static_cast<blink::mojom::FeaturePolicyFeature>(feature);
-  }
-  static bool FromMojom(blink::mojom::FeaturePolicyFeature in,
-                        blink::FeaturePolicyFeature* out) {
-    *out = static_cast<blink::FeaturePolicyFeature>(in);
-    return true;
-  }
-};
-
-template <>
 class BLINK_COMMON_EXPORT
     StructTraits<blink::mojom::ParsedFeaturePolicyDeclarationDataView,
                  blink::ParsedFeaturePolicyDeclaration> {
  public:
-  static blink::FeaturePolicyFeature feature(
+  static blink::mojom::FeaturePolicyFeature feature(
       const blink::ParsedFeaturePolicyDeclaration& policy) {
     return policy.feature;
   }
diff --git a/third_party/WebKit/common/feature_policy/feature_policy_unittest.cc b/third_party/WebKit/common/feature_policy/feature_policy_unittest.cc
index dbfca23..a962ab4 100644
--- a/third_party/WebKit/common/feature_policy/feature_policy_unittest.cc
+++ b/third_party/WebKit/common/feature_policy/feature_policy_unittest.cc
@@ -11,14 +11,17 @@
 
 namespace {
 
-FeaturePolicyFeature kDefaultOnFeature = static_cast<FeaturePolicyFeature>(
-    static_cast<int>(FeaturePolicyFeature::LAST_FEATURE) + 1);
+mojom::FeaturePolicyFeature kDefaultOnFeature =
+    static_cast<mojom::FeaturePolicyFeature>(
+        static_cast<int>(mojom::FeaturePolicyFeature::kLastFeature) + 1);
 
-FeaturePolicyFeature kDefaultSelfFeature = static_cast<FeaturePolicyFeature>(
-    static_cast<int>(FeaturePolicyFeature::LAST_FEATURE) + 2);
+mojom::FeaturePolicyFeature kDefaultSelfFeature =
+    static_cast<mojom::FeaturePolicyFeature>(
+        static_cast<int>(mojom::FeaturePolicyFeature::kLastFeature) + 2);
 
-FeaturePolicyFeature kDefaultOffFeature = static_cast<FeaturePolicyFeature>(
-    static_cast<int>(FeaturePolicyFeature::LAST_FEATURE) + 3);
+mojom::FeaturePolicyFeature kDefaultOffFeature =
+    static_cast<mojom::FeaturePolicyFeature>(
+        static_cast<int>(mojom::FeaturePolicyFeature::kLastFeature) + 3);
 
 }  // namespace
 
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn
index faf2520..3ec8112 100644
--- a/third_party/WebKit/public/BUILD.gn
+++ b/third_party/WebKit/public/BUILD.gn
@@ -149,7 +149,6 @@
     "platform/WebColor.h",
     "platform/WebCommon.h",
     "platform/WebCompositeAndReadbackAsyncCallback.h",
-    "platform/WebCompositorMutatorClient.h",
     "platform/WebCompositorSupport.h",
     "platform/WebComputedAXTree.h",
     "platform/WebConnectionType.h",
diff --git a/third_party/WebKit/public/platform/WebCompositorMutatorClient.h b/third_party/WebKit/public/platform/WebCompositorMutatorClient.h
deleted file mode 100644
index ae74495..0000000
--- a/third_party/WebKit/public/platform/WebCompositorMutatorClient.h
+++ /dev/null
@@ -1,23 +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.
-
-#ifndef WebCompositorMutatorClient_h
-#define WebCompositorMutatorClient_h
-
-#include "WebCommon.h"
-
-#include "cc/trees/layer_tree_mutator.h"
-
-namespace blink {
-
-// This is used by the compositor to invoke compositor worker callbacks.
-class BLINK_PLATFORM_EXPORT WebCompositorMutatorClient
-    : public cc::LayerTreeMutator {
- public:
-  ~WebCompositorMutatorClient() override = default;
-};
-
-}  // namespace blink
-
-#endif  // WebCompositorMutatorClient_h
diff --git a/third_party/WebKit/public/platform/WebLayerTreeView.h b/third_party/WebKit/public/platform/WebLayerTreeView.h
index 55ba358..ef5f653 100644
--- a/third_party/WebKit/public/platform/WebLayerTreeView.h
+++ b/third_party/WebKit/public/platform/WebLayerTreeView.h
@@ -29,13 +29,13 @@
 #include "WebBrowserControlsState.h"
 #include "WebColor.h"
 #include "WebCommon.h"
-#include "WebCompositorMutatorClient.h"
 #include "WebEventListenerProperties.h"
 #include "WebFloatPoint.h"
 #include "WebImageLayer.h"
 #include "WebOverscrollBehavior.h"
 #include "WebSize.h"
 #include "base/callback.h"
+#include "cc/trees/layer_tree_mutator.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
 
 #include "third_party/skia/include/core/SkImage.h"
@@ -179,7 +179,7 @@
   virtual void ClearSelection() {}
 
   // Mutations are plumbed back to the layer tree via the mutator client.
-  virtual void SetMutatorClient(std::unique_ptr<WebCompositorMutatorClient>) {}
+  virtual void SetMutatorClient(std::unique_ptr<cc::LayerTreeMutator>) {}
 
   // For when the embedder itself change scales on the page (e.g. devtools)
   // and wants all of the content at the new scale to be crisp.
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index 31760c4..bdf3802 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-9-18
-Revision: 036bdc0c9a4fb55b4fe5a7276e97b70b95c8a260
+Version: VER-2-9-20
+Revision: 4a03f17449ae45f0dacf4de4694ccd6e5e1b24d1
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
 License File: src/docs/FTL.TXT
diff --git a/third_party/freetype/include/freetype-custom-config/ftconfig.h b/third_party/freetype/include/freetype-custom-config/ftconfig.h
index 3ffd34bb..09199c1 100644
--- a/third_party/freetype/include/freetype-custom-config/ftconfig.h
+++ b/third_party/freetype/include/freetype-custom-config/ftconfig.h
@@ -422,9 +422,9 @@
 #endif /* !FT_BASE_DEF */
 
 
-  /*   When compiling FreeType as a DLL, some systems/compilers need a     */
-  /*   special attribute in front OR after the return type of function     */
-  /*   declarations.                                                       */
+  /*   When compiling FreeType as a DLL or DSO with hidden visibility      */
+  /*   some systems/compilers need a special attribute in front OR after   */
+  /*   the return type of function declarations.                           */
   /*                                                                       */
   /*   Two macros are used within the FreeType source code to define       */
   /*   exported library functions: FT_EXPORT and FT_EXPORT_DEF.            */
@@ -480,21 +480,28 @@
 
 #ifndef FT_EXPORT
 
-#ifdef __cplusplus
+#ifdef FT2_BUILD_LIBRARY
+
+#if defined( _WIN32 ) && ( defined( _DLL ) || defined( DLL_EXPORT ) )
+#define FT_EXPORT( x )  __declspec( dllexport )  x
+#elif defined( __GNUC__ ) && __GNUC__ >= 4
+#define FT_EXPORT( x )  __attribute__(( visibility( "default" ) ))  x
+#elif defined( __cplusplus )
 #define FT_EXPORT( x )  extern "C"  x
 #else
 #define FT_EXPORT( x )  extern  x
 #endif
 
-#ifdef _WIN32
-#if defined( FT2_BUILD_LIBRARY ) && \
-    ( defined( _DLL ) || defined( DLL_EXPORT ) )
-#undef FT_EXPORT
-#define FT_EXPORT( x )  __declspec( dllexport )  x
-#elif defined( FT2_DLLIMPORT )
-#undef FT_EXPORT
+#else
+
+#if defined( FT2_DLLIMPORT )
 #define FT_EXPORT( x )  __declspec( dllimport )  x
+#elif defined( __cplusplus )
+#define FT_EXPORT( x )  extern "C"  x
+#else
+#define FT_EXPORT( x )  extern  x
 #endif
+
 #endif
 
 #endif /* !FT_EXPORT */
diff --git a/third_party/tcmalloc/README.chromium b/third_party/tcmalloc/README.chromium
index 2e4fb29..f8c4d050 100644
--- a/third_party/tcmalloc/README.chromium
+++ b/third_party/tcmalloc/README.chromium
@@ -112,3 +112,4 @@
 - Remove superfluous size_t value >= 0 check.
 - Make kFooType in tcmalloc.cc truly const.
 - Added support for mips64el.
+- Pulled SuggestedDelayNS() implementation for 32bit architectures which do not support 64bit atomicity
diff --git a/third_party/tcmalloc/chromium/src/base/spinlock_internal.cc b/third_party/tcmalloc/chromium/src/base/spinlock_internal.cc
index b9fadde..4d7b6eb 100644
--- a/third_party/tcmalloc/chromium/src/base/spinlock_internal.cc
+++ b/third_party/tcmalloc/chromium/src/base/spinlock_internal.cc
@@ -78,6 +78,7 @@
 
 // Return a suggested delay in nanoseconds for iteration number "loop"
 static int SuggestedDelayNS(int loop) {
+#if defined(BASE_HAS_ATOMIC64)
   // Weak pseudo-random number generator to get some spread between threads
   // when many are spinning.
   static base::subtle::Atomic64 rand;
@@ -96,6 +97,24 @@
   // The futex path multiplies this by 16, since we expect explicit wakeups
   // almost always on that path.
   return r >> (44 - (loop >> 3));
+#else
+  static Atomic32 rand;
+  uint32 r = base::subtle::NoBarrier_Load(&rand);
+  r = 0x343fd * r + 0x269ec3;  // numbers from MSVC++
+  base::subtle::NoBarrier_Store(&rand, r);
+
+  r <<= 1;                      // 31-bit random number now in top 31-bits.
+  if (loop < 0 || loop > 32) {  // limit loop to 0..32
+    loop = 32;
+  }
+  // loop>>3 cannot exceed 4 because loop cannot exceed 32.
+  // Select top 20..24 bits of lower 31 bits,
+  // giving approximately 0ms to 16ms.
+  // Mean is exponential in loop for first 32 iterations, then 8ms.
+  // The futex path multiplies this by 16, since we expect explicit wakeups
+  // almost always on that path.
+  return r >> (12 - (loop >> 3));
+#endif
 }
 
 } // namespace internal
diff --git a/third_party/ub-uiautomator/BUILD.gn b/third_party/ub-uiautomator/BUILD.gn
index c222a19..cf60466 100644
--- a/third_party/ub-uiautomator/BUILD.gn
+++ b/third_party/ub-uiautomator/BUILD.gn
@@ -5,5 +5,6 @@
 import("//build/config/android/rules.gni")
 
 android_java_prebuilt("ub_uiautomator_java") {
+  testonly = true
   jar_path = "lib/ub-uiautomator.jar"
 }
diff --git a/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-client-protocol.h b/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-client-protocol.h
index bd18ed4..1baf11a2 100644
--- a/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-client-protocol.h
+++ b/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-client-protocol.h
@@ -196,6 +196,14 @@
 	 * resizing window state
 	 */
 	ZCR_REMOTE_SHELL_V1_STATE_TYPE_RESIZING = 8,
+	/**
+	 * left snapped window state
+	 */
+	ZCR_REMOTE_SHELL_V1_STATE_TYPE_LEFT_SNAPPED = 9,
+	/**
+	 * right snapped window state
+	 */
+	ZCR_REMOTE_SHELL_V1_STATE_TYPE_RIGHT_SNAPPED = 10,
 };
 #endif /* ZCR_REMOTE_SHELL_V1_STATE_TYPE_ENUM */
 
@@ -764,6 +772,8 @@
 #define ZCR_REMOTE_SURFACE_V1_UNSET_CAN_MAXIMIZE 30
 #define ZCR_REMOTE_SURFACE_V1_SET_MIN_SIZE 31
 #define ZCR_REMOTE_SURFACE_V1_SET_MAX_SIZE 32
+#define ZCR_REMOTE_SURFACE_V1_SET_SNAPPED_TO_LEFT 33
+#define ZCR_REMOTE_SURFACE_V1_SET_SNAPPED_TO_RIGHT 34
 
 /**
  * @ingroup iface_zcr_remote_surface_v1
@@ -926,6 +936,14 @@
  * @ingroup iface_zcr_remote_surface_v1
  */
 #define ZCR_REMOTE_SURFACE_V1_SET_MAX_SIZE_SINCE_VERSION 10
+/**
+ * @ingroup iface_zcr_remote_surface_v1
+ */
+#define ZCR_REMOTE_SURFACE_V1_SET_SNAPPED_TO_LEFT_SINCE_VERSION 11
+/**
+ * @ingroup iface_zcr_remote_surface_v1
+ */
+#define ZCR_REMOTE_SURFACE_V1_SET_SNAPPED_TO_RIGHT_SINCE_VERSION 11
 
 /** @ingroup iface_zcr_remote_surface_v1 */
 static inline void
@@ -1494,6 +1512,30 @@
 			 ZCR_REMOTE_SURFACE_V1_SET_MAX_SIZE, width, height);
 }
 
+/**
+ * @ingroup iface_zcr_remote_surface_v1
+ *
+ * Request that surface is snapped to left.
+ */
+static inline void
+zcr_remote_surface_v1_set_snapped_to_left(struct zcr_remote_surface_v1 *zcr_remote_surface_v1)
+{
+	wl_proxy_marshal((struct wl_proxy *) zcr_remote_surface_v1,
+			 ZCR_REMOTE_SURFACE_V1_SET_SNAPPED_TO_LEFT);
+}
+
+/**
+ * @ingroup iface_zcr_remote_surface_v1
+ *
+ * Request that surface is snapped to right.
+ */
+static inline void
+zcr_remote_surface_v1_set_snapped_to_right(struct zcr_remote_surface_v1 *zcr_remote_surface_v1)
+{
+	wl_proxy_marshal((struct wl_proxy *) zcr_remote_surface_v1,
+			 ZCR_REMOTE_SURFACE_V1_SET_SNAPPED_TO_RIGHT);
+}
+
 #define ZCR_NOTIFICATION_SURFACE_V1_DESTROY 0
 
 
diff --git a/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-server-protocol.h b/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-server-protocol.h
index 6c128b9d..dea9a90 100644
--- a/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-server-protocol.h
+++ b/third_party/wayland-protocols/include/protocol/remote-shell-unstable-v1-server-protocol.h
@@ -199,6 +199,14 @@
 	 * resizing window state
 	 */
 	ZCR_REMOTE_SHELL_V1_STATE_TYPE_RESIZING = 8,
+	/**
+	 * left snapped window state
+	 */
+	ZCR_REMOTE_SHELL_V1_STATE_TYPE_LEFT_SNAPPED = 9,
+	/**
+	 * right snapped window state
+	 */
+	ZCR_REMOTE_SHELL_V1_STATE_TYPE_RIGHT_SNAPPED = 10,
 };
 #endif /* ZCR_REMOTE_SHELL_V1_STATE_TYPE_ENUM */
 
@@ -974,6 +982,22 @@
 			     struct wl_resource *resource,
 			     int32_t width,
 			     int32_t height);
+	/**
+	 * set the surface to left snapped
+	 *
+	 * Request that surface is snapped to left.
+	 * @since 11
+	 */
+	void (*set_snapped_to_left)(struct wl_client *client,
+				    struct wl_resource *resource);
+	/**
+	 * set the surface to right snapped
+	 *
+	 * Request that surface is snapped to right.
+	 * @since 11
+	 */
+	void (*set_snapped_to_right)(struct wl_client *client,
+				     struct wl_resource *resource);
 };
 
 #define ZCR_REMOTE_SURFACE_V1_CLOSE 0
@@ -1145,6 +1169,14 @@
  * @ingroup iface_zcr_remote_surface_v1
  */
 #define ZCR_REMOTE_SURFACE_V1_SET_MAX_SIZE_SINCE_VERSION 10
+/**
+ * @ingroup iface_zcr_remote_surface_v1
+ */
+#define ZCR_REMOTE_SURFACE_V1_SET_SNAPPED_TO_LEFT_SINCE_VERSION 11
+/**
+ * @ingroup iface_zcr_remote_surface_v1
+ */
+#define ZCR_REMOTE_SURFACE_V1_SET_SNAPPED_TO_RIGHT_SINCE_VERSION 11
 
 /**
  * @ingroup iface_zcr_remote_surface_v1
diff --git a/third_party/wayland-protocols/protocol/remote-shell-protocol.c b/third_party/wayland-protocols/protocol/remote-shell-protocol.c
index d3ac990..c5a003b 100644
--- a/third_party/wayland-protocols/protocol/remote-shell-protocol.c
+++ b/third_party/wayland-protocols/protocol/remote-shell-protocol.c
@@ -70,7 +70,7 @@
 };
 
 WL_EXPORT const struct wl_interface zcr_remote_shell_v1_interface = {
-	"zcr_remote_shell_v1", 10,
+	"zcr_remote_shell_v1", 11,
 	3, zcr_remote_shell_v1_requests,
 	5, zcr_remote_shell_v1_events,
 };
@@ -109,6 +109,8 @@
 	{ "unset_can_maximize", "10", types + 0 },
 	{ "set_min_size", "10ii", types + 0 },
 	{ "set_max_size", "10ii", types + 0 },
+	{ "set_snapped_to_left", "11", types + 0 },
+	{ "set_snapped_to_right", "11", types + 0 },
 };
 
 static const struct wl_message zcr_remote_surface_v1_events[] = {
@@ -122,8 +124,8 @@
 };
 
 WL_EXPORT const struct wl_interface zcr_remote_surface_v1_interface = {
-	"zcr_remote_surface_v1", 10,
-	33, zcr_remote_surface_v1_requests,
+	"zcr_remote_surface_v1", 11,
+	35, zcr_remote_surface_v1_requests,
 	7, zcr_remote_surface_v1_events,
 };
 
diff --git a/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v1.xml b/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v1.xml
index 3005449..1640694 100644
--- a/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v1.xml
+++ b/third_party/wayland-protocols/unstable/remote-shell/remote-shell-unstable-v1.xml
@@ -38,7 +38,7 @@
     reset.
   </description>
 
-  <interface name="zcr_remote_shell_v1" version="10">
+  <interface name="zcr_remote_shell_v1" version="11">
     <description summary="remote_shell">
       The global interface that allows clients to turn a wl_surface into a
       "real window" which is remotely managed but can be stacked, activated
@@ -66,6 +66,8 @@
       <entry name="trusted_pinned" value="6" summary="trusted pinned window state"/>
       <entry name="moving" value="7" summary="moving window state"/>
       <entry name="resizing" value="8" summary="resizing window state"/>
+      <entry name="left_snapped" value="9" summary="left snapped window state"/>
+      <entry name="right_snapped" value="10" summary="right snapped window state"/>
     </enum>
 
     <enum name="error">
@@ -181,7 +183,7 @@
     </event>
   </interface>
 
-  <interface name="zcr_remote_surface_v1" version="10">
+  <interface name="zcr_remote_surface_v1" version="11">
     <description summary="A desktop window">
       An interface that may be implemented by a wl_surface, for
       implementations that provide a desktop-style user interface
@@ -758,6 +760,19 @@
       <arg name="height" type="int"/>
     </request>
 
+    <!-- Version 11 additions -->
+    <request name="set_snapped_to_left" since="11">
+      <description summary="set the surface to left snapped">
+        Request that surface is snapped to left.
+      </description>
+    </request>
+
+    <request name="set_snapped_to_right" since="11">
+      <description summary="set the surface to right snapped">
+        Request that surface is snapped to right.
+      </description>
+    </request>
+
   </interface>
 
   <interface name="zcr_notification_surface_v1" version="1">
diff --git a/third_party/zlib/BUILD.gn b/third_party/zlib/BUILD.gn
index 273e5f2..e545ae5 100644
--- a/third_party/zlib/BUILD.gn
+++ b/third_party/zlib/BUILD.gn
@@ -57,6 +57,10 @@
 config("zlib_inflate_chunk_simd_config") {
   if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
     defines = [ "INFLATE_CHUNK_SIMD_SSE2" ]
+
+    if (current_cpu == "x64") {
+      defines += [ "INFLATE_CHUNK_READ_64LE" ]
+    }
   }
 
   if (current_cpu == "arm" || current_cpu == "arm64") {
diff --git a/third_party/zlib/contrib/optimizations/chunkcopy.h b/third_party/zlib/contrib/optimizations/chunkcopy.h
index fe38be6..38ba0ed 100644
--- a/third_party/zlib/contrib/optimizations/chunkcopy.h
+++ b/third_party/zlib/contrib/optimizations/chunkcopy.h
@@ -3,7 +3,6 @@
  * 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 Chromium source repository LICENSE file.
- * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 #ifndef CHUNKCOPY_H
@@ -407,6 +406,37 @@
   return chunkcopy_lapped_relaxed(out, dist, len);
 }
 
+/*
+ * The chunk-copy code above deals with writing the decoded DEFLATE data to
+ * the output with SIMD methods to increase decode speed. Reading the input
+ * to the DEFLATE decoder with a wide, SIMD method can also increase decode
+ * speed. This option is supported on little endian machines, and reads the
+ * input data in 64-bit (8 byte) chunks.
+ */
+
+#ifdef INFLATE_CHUNK_READ_64LE
+/*
+ * Buffer the input in a uint64_t (8 bytes) in the wide input reading case.
+ */
+typedef uint64_t inflate_holder_t;
+
+/*
+ * Ask the compiler to perform a wide, unaligned load of a uint64_t using a
+ * machine instruction appropriate for the uint64_t type.
+ */
+static inline inflate_holder_t read64le(const unsigned char FAR *in) {
+    inflate_holder_t input;
+    Z_BUILTIN_MEMCPY(&input, in, sizeof(input));
+    return input;
+}
+#else
+/*
+ * Otherwise, buffer the input bits using zlib's default input buffer type.
+ */
+typedef unsigned long inflate_holder_t;
+
+#endif /* INFLATE_CHUNK_READ_64LE */
+
 #undef Z_STATIC_ASSERT
 #undef Z_RESTRICT
 #undef Z_BUILTIN_MEMCPY
diff --git a/third_party/zlib/contrib/optimizations/inffast_chunk.c b/third_party/zlib/contrib/optimizations/inffast_chunk.c
index c6dfbd2..4099edf 100644
--- a/third_party/zlib/contrib/optimizations/inffast_chunk.c
+++ b/third_party/zlib/contrib/optimizations/inffast_chunk.c
@@ -24,10 +24,11 @@
    Entry assumptions:
 
         state->mode == LEN
-        strm->avail_in >= INFLATE_FAST_MIN_INPUT (6 bytes)
+        strm->avail_in >= INFLATE_FAST_MIN_INPUT (6 or 8 bytes)
         strm->avail_out >= INFLATE_FAST_MIN_OUTPUT (258 bytes)
         start >= strm->avail_out
         state->bits < 8
+        (state->hold >> state->bits) == 0
         strm->next_out[0..strm->avail_out] does not overlap with
               strm->next_in[0..strm->avail_in]
         strm->state->window is allocated with an additional
@@ -41,7 +42,7 @@
 
    Notes:
 
-    INFLATE_FAST_MIN_INPUT 6 bytes
+    INFLATE_FAST_MIN_INPUT: 6 or 8 bytes
 
     - The maximum input bits used by a length/distance pair is 15 bits for the
       length code, 5 bits for the length extra, 15 bits for the distance code,
@@ -49,7 +50,21 @@
       Therefore if strm->avail_in >= 6, then there is enough input to avoid
       checking for available input while decoding.
 
-    INFLATE_FAST_MIN_OUTPUT 258 bytes
+    - The wide input data reading option reads 64 input bits at a time. Thus,
+      if strm->avail_in >= 8, then there is enough input to avoid checking for
+      available input while decoding. Reading consumes the input with:
+
+          hold |= read64le(in) << bits;
+          in += 6;
+          bits += 48;
+
+      reporting 6 bytes of new input because |bits| is 0..15 (2 bytes rounded
+      up, worst case) and 6 bytes is enough to decode as noted above. At exit,
+      hold &= (1U << bits) - 1 drops excess input to keep the invariant:
+
+          (state->hold >> state->bits) == 0
+
+    INFLATE_FAST_MIN_OUTPUT: 258 bytes
 
     - The maximum bytes that a single length/distance pair can output is 258
       bytes, which is the maximum length that can be coded.  inflate_fast()
@@ -74,7 +89,7 @@
     unsigned whave;             /* valid bytes in the window */
     unsigned wnext;             /* window write index */
     unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
-    unsigned long hold;         /* local strm->hold */
+    inflate_holder_t hold;      /* local strm->hold */
     unsigned bits;              /* local strm->bits */
     code const FAR *lcode;      /* local strm->lencode */
     code const FAR *dcode;      /* local strm->distcode */
@@ -113,10 +128,16 @@
        input data or output space */
     do {
         if (bits < 15) {
+#ifdef INFLATE_CHUNK_READ_64LE
+            hold |= read64le(in) << bits;
+            in += 6;
+            bits += 48;
+#else
             hold += (unsigned long)(*in++) << bits;
             bits += 8;
             hold += (unsigned long)(*in++) << bits;
             bits += 8;
+#endif
         }
         here = lcode[hold & lmask];
       dolen:
@@ -135,8 +156,14 @@
             op &= 15;                           /* number of extra bits */
             if (op) {
                 if (bits < op) {
+#ifdef INFLATE_CHUNK_READ_64LE
+                    hold |= read64le(in) << bits;
+                    in += 6;
+                    bits += 48;
+#else
                     hold += (unsigned long)(*in++) << bits;
                     bits += 8;
+#endif
                 }
                 len += (unsigned)hold & ((1U << op) - 1);
                 hold >>= op;
@@ -144,10 +171,16 @@
             }
             Tracevv((stderr, "inflate:         length %u\n", len));
             if (bits < 15) {
+#ifdef INFLATE_CHUNK_READ_64LE
+                hold |= read64le(in) << bits;
+                in += 6;
+                bits += 48;
+#else
                 hold += (unsigned long)(*in++) << bits;
                 bits += 8;
                 hold += (unsigned long)(*in++) << bits;
                 bits += 8;
+#endif
             }
             here = dcode[hold & dmask];
           dodist:
@@ -159,12 +192,18 @@
                 dist = (unsigned)(here.val);
                 op &= 15;                       /* number of extra bits */
                 if (bits < op) {
+#ifdef INFLATE_CHUNK_READ_64LE
+                    hold |= read64le(in) << bits;
+                    in += 6;
+                    bits += 48;
+#else
                     hold += (unsigned long)(*in++) << bits;
                     bits += 8;
                     if (bits < op) {
                         hold += (unsigned long)(*in++) << bits;
                         bits += 8;
                     }
+#endif
                 }
                 dist += (unsigned)hold & ((1U << op) - 1);
 #ifdef INFLATE_STRICT
@@ -298,6 +337,8 @@
         (INFLATE_FAST_MIN_OUTPUT - 1) - (out - end));
     state->hold = hold;
     state->bits = bits;
+
+    Assert((state->hold >> state->bits) == 0, "invalid input data state");
     return;
 }
 
diff --git a/third_party/zlib/contrib/optimizations/inffast_chunk.h b/third_party/zlib/contrib/optimizations/inffast_chunk.h
index 5cd1eac3..73e89d2 100644
--- a/third_party/zlib/contrib/optimizations/inffast_chunk.h
+++ b/third_party/zlib/contrib/optimizations/inffast_chunk.h
@@ -13,9 +13,14 @@
    we can safely call inflate_fast() with only one up-front bounds check. One
    length/distance code pair (15 bits for the length code, 5 bits for length
    extra, 15 bits for the distance code, 13 bits for distance extra) requires
-   reading up to 48 input bits (6 bytes).
+   reading up to 48 input bits (6 bytes). The wide input data reading option
+   requires a little endian machine, and reads 64 input bits (8 bytes).
 */
+#ifdef INFLATE_CHUNK_READ_64LE
+#define INFLATE_FAST_MIN_INPUT 8
+#else
 #define INFLATE_FAST_MIN_INPUT 6
+#endif
 
 /* INFLATE_FAST_MIN_OUTPUT: the minimum number of output bytes needed so that
    we can safely call inflate_fast() with only one up-front bounds check. One
diff --git a/tools/clang/traffic_annotation_extractor/CMakeLists.txt b/tools/clang/traffic_annotation_extractor/CMakeLists.txt
index f33d3ae7..32b154d 100644
--- a/tools/clang/traffic_annotation_extractor/CMakeLists.txt
+++ b/tools/clang/traffic_annotation_extractor/CMakeLists.txt
@@ -2,6 +2,8 @@
   BitReader
   MCParser
   Option
+  X86AsmParser
+  X86CodeGen
   )
 
 add_llvm_executable(traffic_annotation_extractor
diff --git a/tools/clang/traffic_annotation_extractor/traffic_annotation_extractor.cpp b/tools/clang/traffic_annotation_extractor/traffic_annotation_extractor.cpp
index 5015932..eed654a7 100644
--- a/tools/clang/traffic_annotation_extractor/traffic_annotation_extractor.cpp
+++ b/tools/clang/traffic_annotation_extractor/traffic_annotation_extractor.cpp
@@ -42,6 +42,7 @@
 #include "clang/Tooling/Refactoring.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/TargetSelect.h"
 
 using namespace clang::ast_matchers;
 
@@ -414,6 +415,8 @@
                                  options.getSourcePathList());
   Collector collector;
 
+  llvm::InitializeNativeTarget();
+  llvm::InitializeNativeTargetAsmParser();
   int result = RunMatchers(&tool, &collector);
 
   if (result != 0)
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index df7e0979c..e769e9e 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -2915,6 +2915,7 @@
   <int value="194" label="WCI_NEW_WIDGET_PROCESS_MISMATCH"/>
   <int value="195" label="AUTH_INVALID_EFFECTIVE_DOMAIN"/>
   <int value="196" label="AUTH_INVALID_RELYING_PARTY"/>
+  <int value="197" label="RWH_COPY_REQUEST_ATTEMPT"/>
 </enum>
 
 <enum name="BadMessageReasonExtensions">
@@ -32937,6 +32938,7 @@
   <int value="14" label="Invalid order - first paint / first image paint"/>
   <int value="15" label="Invalid order - first paint / first contentful paint"/>
   <int value="16" label="Invalid order - first paint / first meaningful paint"/>
+  <int value="17" label="Invalid order - first meaningful paint / interactive"/>
 </enum>
 
 <enum name="PageScaleFactorRange">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index e83aa60e..461d691 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -94933,6 +94933,14 @@
   </summary>
 </histogram>
 
+<histogram name="V8.GC.ParallelTaskLatencyMicroSeconds" units="microseconds">
+  <owner>gab@chromium.org</owner>
+  <summary>
+    Latency (post-to-schedule) of each parallel task posted during V8 garbage
+    collection.
+  </summary>
+</histogram>
+
 <histogram name="V8.GCBackgroundMarking" units="ms">
   <owner>ulan@chromium.org</owner>
   <summary>
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py
index 19e525c4..599d1a9d 100755
--- a/tools/perf/core/perf_data_generator.py
+++ b/tools/perf/core/perf_data_generator.py
@@ -532,7 +532,7 @@
       'expiration': 10 * 60 * 60, # 10 hour timeout
       'hard_timeout': swarming_timeout if swarming_timeout else 10800, # 3 hours
       'ignore_task_failure': ignore_task_failure,
-      'io_timeout': io_timeout if io_timeout else 600, # 10 minutes
+      'io_timeout': io_timeout if io_timeout else 1200, # 20 minutes
       'dimension_sets': swarming_dimensions,
       'upload_test_results': True,
     }
diff --git a/tools/perf/core/perf_data_generator_unittest.py b/tools/perf/core/perf_data_generator_unittest.py
index 8438c6b..3d9b24a 100644
--- a/tools/perf/core/perf_data_generator_unittest.py
+++ b/tools/perf/core/perf_data_generator_unittest.py
@@ -90,7 +90,7 @@
           'hard_timeout': 10800,
           'can_use_on_swarming_builders': True,
           'expiration': 36000,
-          'io_timeout': 600,
+          'io_timeout': 1200,
           'upload_test_results': True,
         },
         'name': 'speedometer',
@@ -114,7 +114,7 @@
           'hard_timeout': 10800,
           'can_use_on_swarming_builders': True,
           'expiration': 36000,
-          'io_timeout': 600,
+          'io_timeout': 1200,
           'upload_test_results': True,
         },
         'name': 'speedometer.reference',
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index 0d0380d..377c5d8 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -292,8 +292,6 @@
 # Benchmark: v8.browsing_desktop
 crbug.com/773084 [ Mac ] v8.browsing_desktop/browse:tools:maps [ Skip ]
 crbug.com/788796 [ Linux ] v8.browsing_desktop/browse:media:imgur [ Skip ]
-crbug.com/805922 [ Win ] v8.browsing_desktop/browse:media:imgur [ Skip ]
-crbug.com/805922 [ Mac ] v8.browsing_desktop/browse:media:imgur [ Skip ]
 crbug.com/806001 [ Linux ] v8.browsing_desktop/browse:media:tumblr [ Skip ]
 #crbug.com/676336 [ Win ] v8.browsing_desktop/browse:news:hackernews [ Skip ]
 crbug.com/676336 [ Mac ] v8.browsing_desktop/browse:news:hackernews [ Skip ]
@@ -304,8 +302,6 @@
 # Benchmark: v8.browsing_desktop-future
 crbug.com/773084 [ Mac ] v8.browsing_desktop-future/browse:tools:maps [ Skip ]
 crbug.com/788796 [ Linux ] v8.browsing_desktop-future/browse:media:imgur [ Skip ]
-crbug.com/805922 [ Win ] v8.browsing_desktop-future/browse:media:imgur [ Skip ]
-crbug.com/805922 [ Mac ] v8.browsing_desktop-future/browse:media:imgur [ Skip ]
 crbug.com/806001 [ Linux ] v8.browsing_desktop-future/browse:media:tumblr [ Skip ]
 crbug.com/676336 [ Win ] v8.browsing_desktop-future/browse:media:flickr_infinite_scroll [ Skip ]
 crbug.com/676336 [ Win ] v8.browsing_desktop-future/browse:news:hackernews [ Skip ]
diff --git a/tools/traffic_annotation/README.md b/tools/traffic_annotation/README.md
index a82b895..2e8f9ee 100644
--- a/tools/traffic_annotation/README.md
+++ b/tools/traffic_annotation/README.md
@@ -99,4 +99,4 @@
 re-enable the test.
 
 CLANG_REVISION = '321529'
-LASTCHANGE=71bf564b49fed01c39ac461efdff84b9c4973c9a-refs/heads/master@{#534339}
+LASTCHANGE=745b69e177ef4538a5fc92bb61882d37fa5c38b7-
diff --git a/tools/traffic_annotation/bin/linux64/traffic_annotation_extractor.sha1 b/tools/traffic_annotation/bin/linux64/traffic_annotation_extractor.sha1
index 07327322..1a5d4cc1 100644
--- a/tools/traffic_annotation/bin/linux64/traffic_annotation_extractor.sha1
+++ b/tools/traffic_annotation/bin/linux64/traffic_annotation_extractor.sha1
@@ -1 +1 @@
-e74930128c3608d67b93e882ebb9484423a08a25
\ No newline at end of file
+4cc69f7b5103f23d829020af44dabd3b1da6cfca
\ No newline at end of file
diff --git a/tools/traffic_annotation/bin/win32/traffic_annotation_extractor.exe.sha1 b/tools/traffic_annotation/bin/win32/traffic_annotation_extractor.exe.sha1
index 2147a07..7d1b871f1 100644
--- a/tools/traffic_annotation/bin/win32/traffic_annotation_extractor.exe.sha1
+++ b/tools/traffic_annotation/bin/win32/traffic_annotation_extractor.exe.sha1
@@ -1 +1 @@
-25d5732353ef266f3d08ad770b954e16eb34d094
\ No newline at end of file
+c318928a2767bbc822424fdb44ff6ee2f429d412
\ No newline at end of file
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 46547b0..37bf4515 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -208,8 +208,8 @@
  <item id="supervised_user_refresh_token_fetcher" hash_code="136117054" type="0" content_hash_code="101636136" os_list="linux,windows" file_path="chrome/browser/supervised_user/legacy/supervised_user_refresh_token_fetcher.cc"/>
  <item id="supervised_user_url_filter" hash_code="14257952" type="0" content_hash_code="30470003" os_list="linux,windows" file_path="chrome/browser/supervised_user/supervised_user_url_filter.cc"/>
  <item id="supervised_users_blacklist" hash_code="78544924" type="0" content_hash_code="10924669" os_list="linux,windows" file_path="chrome/browser/supervised_user/supervised_user_service.cc"/>
- <item id="sync_attachment_downloader" hash_code="26372521" type="0" content_hash_code="70097603" os_list="linux,windows" file_path="components/sync/engine_impl/attachments/attachment_downloader_impl.cc"/>
- <item id="sync_attachment_uploader" hash_code="132657055" type="0" content_hash_code="25152853" os_list="linux,windows" file_path="components/sync/engine_impl/attachments/attachment_uploader_impl.cc"/>
+ <item id="sync_attachment_downloader" hash_code="26372521" type="0" deprecated="2018-02-08" content_hash_code="70097603" file_path=""/>
+ <item id="sync_attachment_uploader" hash_code="132657055" type="0" deprecated="2018-02-08" content_hash_code="25152853" file_path=""/>
  <item id="sync_file_system" hash_code="102819690" type="0" content_hash_code="52153962" os_list="linux,windows" file_path="chrome/browser/sync_file_system/drive_backend/sync_engine.cc"/>
  <item id="sync_http_bridge" hash_code="57144960" type="0" content_hash_code="32868346" os_list="linux,windows" file_path="components/sync/engine/net/http_bridge.cc"/>
  <item id="sync_stop_reporter" hash_code="5021348" type="0" content_hash_code="56902850" os_list="linux,windows" file_path="components/sync/driver/sync_stopped_reporter.cc"/>
diff --git a/ui/message_center/views/message_view.h b/ui/message_center/views/message_view.h
index e728f99..51e73f8 100644
--- a/ui/message_center/views/message_view.h
+++ b/ui/message_center/views/message_view.h
@@ -116,6 +116,8 @@
     manually_expanded_or_collapsed_ = true;
   }
 
+  bool is_nested() const { return is_nested_; }
+
  private:
   std::string notification_id_;
   views::View* background_view_ = nullptr;  // Owned by views hierarchy.
diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc
index b7a0df9f..96a6346e 100644
--- a/ui/message_center/views/notification_view_md.cc
+++ b/ui/message_center/views/notification_view_md.cc
@@ -682,6 +682,16 @@
     action_buttons_row_->set_clip_path(path);
     inline_reply_->set_clip_path(path);
   }
+
+  // The animation is needed to run inside of the border, which is shown only
+  // when the notification is nested.
+  if (is_nested()) {
+    gfx::Rect ink_drop_bounds = GetLocalBounds();
+    ink_drop_bounds.Inset(gfx::Insets(kNotificationBorderThickness));
+    ink_drop_container_->SetBoundsRect(ink_drop_bounds);
+  } else {
+    ink_drop_container_->SetBoundsRect(GetLocalBounds());
+  }
 }
 
 void NotificationViewMD::OnFocus() {
@@ -1240,11 +1250,10 @@
 
   PreferredSizeChanged();
 
-  if (inline_settings_visible) {
+  if (inline_settings_visible)
     AddBackgroundAnimation(event);
-  } else {
+  else
     RemoveBackgroundAnimation();
-  }
 
   Layout();
   SchedulePaint();
@@ -1345,8 +1354,8 @@
 std::unique_ptr<views::InkDropRipple> NotificationViewMD::CreateInkDropRipple()
     const {
   return std::make_unique<views::FloodFillInkDropRipple>(
-      size(), GetInkDropCenterBasedOnLastEvent(), GetInkDropBaseColor(),
-      ink_drop_visible_opacity());
+      ink_drop_container_->size(), GetInkDropCenterBasedOnLastEvent(),
+      GetInkDropBaseColor(), ink_drop_visible_opacity());
 }
 
 SkColor NotificationViewMD::GetInkDropBaseColor() const {
diff --git a/ui/views/controls/webview/webview.cc b/ui/views/controls/webview/webview.cc
index 84b0514..e7f7503 100644
--- a/ui/views/controls/webview/webview.cc
+++ b/ui/views/controls/webview/webview.cc
@@ -54,11 +54,11 @@
 void WebView::SetWebContents(content::WebContents* replacement) {
   if (replacement == web_contents())
     return;
+  SetCrashedOverlayView(nullptr);
   DetachWebContents();
   WebContentsObserver::Observe(replacement);
   // web_contents() now returns |replacement| from here onwards.
-  SetFocusBehavior(web_contents() ? FocusBehavior::ALWAYS
-                                  : FocusBehavior::NEVER);
+  UpdateCrashedOverlayView();
   if (wc_owner_.get() != replacement)
     wc_owner_.reset();
   if (embed_fullscreen_widget_mode_enabled_) {
@@ -91,6 +91,25 @@
   holder_->set_resize_background_color(resize_background_color);
 }
 
+void WebView::SetCrashedOverlayView(View* crashed_overlay_view) {
+  if (crashed_overlay_view_ == crashed_overlay_view)
+    return;
+
+  if (crashed_overlay_view_) {
+    RemoveChildView(crashed_overlay_view_);
+    if (!crashed_overlay_view_->owned_by_client())
+      delete crashed_overlay_view_;
+  }
+
+  crashed_overlay_view_ = crashed_overlay_view;
+  if (crashed_overlay_view_) {
+    AddChildView(crashed_overlay_view_);
+    crashed_overlay_view_->SetBoundsRect(gfx::Rect(size()));
+  }
+
+  UpdateCrashedOverlayView();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // WebView, View overrides:
 
@@ -111,6 +130,9 @@
 }
 
 void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
+  if (crashed_overlay_view_)
+    crashed_overlay_view_->SetBoundsRect(gfx::Rect(size()));
+
   // In most cases, the holder is simply sized to fill this WebView's bounds.
   // Only WebContentses that are in fullscreen mode and being screen-captured
   // will engage the special layout/sizing behavior.
@@ -181,12 +203,12 @@
 }
 
 void WebView::OnFocus() {
-  if (web_contents())
+  if (web_contents() && !web_contents()->IsCrashed())
     web_contents()->Focus();
 }
 
 void WebView::AboutToRequestFocusFromTabTraversal(bool reverse) {
-  if (web_contents())
+  if (web_contents() && !web_contents()->IsCrashed())
     web_contents()->FocusThroughTabTraversal(reverse);
 }
 
@@ -195,7 +217,7 @@
 }
 
 gfx::NativeViewAccessible WebView::GetNativeViewAccessible() {
-  if (web_contents()) {
+  if (web_contents() && !web_contents()->IsCrashed()) {
     content::RenderWidgetHostView* host_view =
         web_contents()->GetRenderWidgetHostView();
     if (host_view)
@@ -216,10 +238,12 @@
 // WebView, content::WebContentsObserver implementation:
 
 void WebView::RenderViewReady() {
+  UpdateCrashedOverlayView();
   NotifyAccessibilityWebContentsChanged();
 }
 
 void WebView::RenderViewDeleted(content::RenderViewHost* render_view_host) {
+  UpdateCrashedOverlayView();
   NotifyAccessibilityWebContentsChanged();
 }
 
@@ -264,6 +288,7 @@
 }
 
 void WebView::RenderProcessGone(base::TerminationStatus status) {
+  UpdateCrashedOverlayView();
   NotifyAccessibilityWebContentsChanged();
 }
 
@@ -317,6 +342,22 @@
   NotifyAccessibilityWebContentsChanged();
 }
 
+void WebView::UpdateCrashedOverlayView() {
+  if (web_contents() && web_contents()->IsCrashed() && crashed_overlay_view_) {
+    SetFocusBehavior(FocusBehavior::NEVER);
+    holder_->SetVisible(false);
+    crashed_overlay_view_->SetVisible(true);
+    return;
+  }
+
+  SetFocusBehavior(web_contents() ? FocusBehavior::ALWAYS
+                                  : FocusBehavior::NEVER);
+
+  if (crashed_overlay_view_)
+    crashed_overlay_view_->SetVisible(false);
+  holder_->SetVisible(true);
+}
+
 void WebView::NotifyAccessibilityWebContentsChanged() {
   if (web_contents())
     NotifyAccessibilityEvent(ax::mojom::Event::kChildrenChanged, false);
diff --git a/ui/views/controls/webview/webview.h b/ui/views/controls/webview/webview.h
index 73ad929..afdd0a03 100644
--- a/ui/views/controls/webview/webview.h
+++ b/ui/views/controls/webview/webview.h
@@ -79,6 +79,11 @@
   // by default.
   void SetResizeBackgroundColor(SkColor resize_background_color);
 
+  // If provided, this View will be shown in place of the web contents
+  // when the web contents is in a crashed state. This is cleared automatically
+  // if the web contents is changed.
+  void SetCrashedOverlayView(View* crashed_overlay_view);
+
   // When used to host UI, we need to explicitly allow accelerators to be
   // processed. Default is false.
   void set_allow_accelerators(bool allow_accelerators) {
@@ -140,6 +145,7 @@
   void AttachWebContents();
   void DetachWebContents();
   void ReattachForFullscreenChange(bool enter_fullscreen);
+  void UpdateCrashedOverlayView();
   void NotifyAccessibilityWebContentsChanged();
 
   // Create a regular or test web contents (based on whether we're running
@@ -158,6 +164,7 @@
   bool is_embedding_fullscreen_widget_;
   content::BrowserContext* browser_context_;
   bool allow_accelerators_;
+  View* crashed_overlay_view_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(WebView);
 };
diff --git a/ui/views/controls/webview/webview_unittest.cc b/ui/views/controls/webview/webview_unittest.cc
index 2ca7683..686cf05 100644
--- a/ui/views/controls/webview/webview_unittest.cc
+++ b/ui/views/controls/webview/webview_unittest.cc
@@ -485,4 +485,52 @@
   webview.reset();
 }
 
+// Test that the specified crashed overlay view is shown when a WebContents
+// is in a crashed state.
+TEST_F(WebViewUnitTest, CrashedOverlayView) {
+  content::WebContents* web_contents = web_view()->GetWebContents();
+  View* crashed_overlay_view = new View();
+  web_view()->SetCrashedOverlayView(crashed_overlay_view);
+  EXPECT_FALSE(crashed_overlay_view->IsDrawn());
+
+  // Normally when a renderer crashes, the WebView will learn about it
+  // automatically via WebContentsObserver. Since this is a test
+  // WebContents, simulate that by calling SetIsCrashed and then
+  // explicitly calling RenderViewDeleted on the WebView to trigger it
+  // to swap in the crashed overlay view.
+  web_contents->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
+  EXPECT_TRUE(web_contents->IsCrashed());
+  static_cast<content::WebContentsObserver*>(web_view())
+      ->RenderViewDeleted(nullptr);
+  EXPECT_TRUE(crashed_overlay_view->IsDrawn());
+}
+
+// Test that a crashed overlay view isn't deleted if it's owned by client.
+TEST_F(WebViewUnitTest, CrashedOverlayViewOwnedbyClient) {
+  const std::unique_ptr<content::WebContents> web_contents(CreateWebContents());
+  std::unique_ptr<WebView> web_view(
+      new WebView(web_contents->GetBrowserContext()));
+  View* contents_view = top_level_widget()->GetContentsView();
+  contents_view->AddChildView(web_view.get());
+  web_view->SetWebContents(web_contents.get());
+
+  View* crashed_overlay_view = new View();
+  crashed_overlay_view->set_owned_by_client();
+  web_view->SetCrashedOverlayView(crashed_overlay_view);
+  EXPECT_FALSE(crashed_overlay_view->IsDrawn());
+
+  // Simulate a renderer crash (see above).
+  web_contents->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
+  EXPECT_TRUE(web_contents->IsCrashed());
+  static_cast<content::WebContentsObserver*>(web_view.get())
+      ->RenderViewDeleted(nullptr);
+  EXPECT_TRUE(crashed_overlay_view->IsDrawn());
+
+  web_view->SetCrashedOverlayView(nullptr);
+  web_view.reset();
+
+  // This shouldn't crash, we still own this.
+  delete crashed_overlay_view;
+}
+
 }  // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index 99b432f..cde45a41 100644
--- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -362,7 +362,7 @@
       View* view_for_activation = focus_manager->GetFocusedView()
                                       ? focus_manager->GetFocusedView()
                                       : focus_manager->GetStoredFocusView();
-      if (!view_for_activation) {
+      if (!view_for_activation || !view_for_activation->GetWidget()) {
         view_for_activation = GetWidget()->GetRootView();
       } else if (view_for_activation == focus_manager->GetStoredFocusView()) {
         // When desktop native widget has modal transient child, we don't