diff --git a/BUILD.gn b/BUILD.gn
index 478f28d..29915efe 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -948,6 +948,7 @@
     if (is_fuchsia) {
       data_deps += [
         "//content/shell:content_shell_fuchsia",
+        "//build/fuchsia/layout_test_proxy:layout_test_proxy_runner",
       ]
     }
 
diff --git a/DEPS b/DEPS
index fde7a2e..98eabc0 100644
--- a/DEPS
+++ b/DEPS
@@ -96,11 +96,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': '81f60ecd9cc0e7c507f9e1f05862bee6a19ee0c6',
+  'skia_revision': '4c2a34e4804e5affa8447b590578a359bad2caf8',
   # 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': '324a3e4449522dfec8ea9d9b23d7e33f16afe61a',
+  'v8_revision': '01433c15f792c4f18bef2b43592ed4b91551f496',
   # 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.
@@ -108,7 +108,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '01e83581864b153a21f0621a4500df7f2e99f524',
+  'angle_revision': '10e7e5013c41cdca8d6ab0ed4bc9bb3dedb537e7',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -120,7 +120,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': '473b4ae489e8c6d63b087693589eda03399f60f6',
+  'pdfium_revision': 'c3aa483e132526e5f5d150058fcdef9450ba3498',
   # 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.
@@ -144,7 +144,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling NaCl
   # and whatever else without interference from each other.
-  'nacl_revision': 'f9564e9d1b155097e5c88f292c01acbe1ddb21a4',
+  'nacl_revision': '93deff44b49fcbb4da0ee7961f21b6b93da194e9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -156,7 +156,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'a8692f3255c2bd61195a48f031de8d75995f81e6',
+  'catapult_revision': 'd8600ccc2ddeb2cc43ba6adccea9f687f5f1b2a9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -498,7 +498,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c8e4e795ed7527807910153dea581ee6ad9a2698',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '4dc1da47ad18caa822fd01f178ac32244474be7c',
       'condition': 'checkout_linux',
   },
 
@@ -523,7 +523,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'cbf0204555fe07fda96d20456e03f105e2922005',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '8de3800ce55ba459ffcbedcfa52ef5e6e59caab6',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -756,7 +756,7 @@
   },
 
   'src/third_party/libvpx/source/libvpx':
-    Var('chromium_git') + '/webm/libvpx.git' + '@' +  '28801f91c4c030da55d483840691582440f8f8f4',
+    Var('chromium_git') + '/webm/libvpx.git' + '@' +  'd99abe9a9ad78b765386d0ee62559de184ba581e',
 
   'src/third_party/libwebm/source':
     Var('chromium_git') + '/webm/libwebm.git' + '@' + 'af81f26025b7435fa9a14ad07c58b44cf9280430',
@@ -1002,7 +1002,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3136ebfa0a629e2906f6f2455f40490e95436baf',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b2cc1ab927d625c11e81a3235ceff244817fbc95',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index df8699ab..0843b6d7 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -652,6 +652,8 @@
     "system/network/network_row_title_view.h",
     "system/network/network_state_list_detailed_view.cc",
     "system/network/network_state_list_detailed_view.h",
+    "system/network/network_tray_view.cc",
+    "system/network/network_tray_view.h",
     "system/network/sms_observer.cc",
     "system/network/sms_observer.h",
     "system/network/tray_network.cc",
@@ -827,6 +829,7 @@
     "system/tray/time_to_click_recorder.h",
     "system/tray/tray_background_view.cc",
     "system/tray/tray_background_view.h",
+    "system/tray/tray_bubble_base.h",
     "system/tray/tray_bubble_wrapper.cc",
     "system/tray/tray_bubble_wrapper.h",
     "system/tray/tray_constants.cc",
@@ -897,6 +900,8 @@
     "system/unified/unified_system_tray_model.h",
     "system/unified/unified_system_tray_view.cc",
     "system/unified/unified_system_tray_view.h",
+    "system/unified/user_chooser_view.cc",
+    "system/unified/user_chooser_view.h",
     "system/update/tray_update.cc",
     "system/update/tray_update.h",
     "system/user/button_from_view.cc",
@@ -1322,6 +1327,7 @@
     "//ui/ozone",
     "//ui/platform_window",
     "//ui/platform_window/stub",
+    "//ui/snapshot",
     "//ui/wm/public",
     "//url",
   ]
@@ -1759,6 +1765,7 @@
     "system/unified/feature_pods_container_view_unittest.cc",
     "system/unified/top_shortcuts_view_unittest.cc",
     "system/unified/unified_system_info_view_unittest.cc",
+    "system/unified/unified_system_tray_controller_unittest.cc",
     "system/update/tray_update_unittest.cc",
     "system/user/tray_user_unittest.cc",
     "test/ash_test_helper_unittest.cc",
diff --git a/ash/assistant/assistant_controller.cc b/ash/assistant/assistant_controller.cc
index 7eaa7d9..eb7ac30 100644
--- a/ash/assistant/assistant_controller.cc
+++ b/ash/assistant/assistant_controller.cc
@@ -11,7 +11,10 @@
 #include "ash/session/session_controller.h"
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
+#include "base/bind.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/unguessable_token.h"
+#include "ui/snapshot/snapshot.h"
 
 namespace ash {
 
@@ -51,6 +54,24 @@
   assistant_card_renderer_ = std::move(assistant_card_renderer);
 }
 
+void AssistantController::RequestScreenshot(
+    const gfx::Rect& rect,
+    RequestScreenshotCallback callback) {
+  // TODO(muyuanli): handle multi-display when assistant's behavior is defined.
+  auto* root_window = Shell::GetPrimaryRootWindow();
+  gfx::Rect source_rect =
+      rect.IsEmpty() ? gfx::Rect(root_window->bounds().size()) : rect;
+  ui::GrabWindowSnapshotAsyncJPEG(
+      root_window, source_rect,
+      base::BindRepeating(
+          [](RequestScreenshotCallback callback,
+             scoped_refptr<base::RefCountedMemory> data) {
+            std::move(callback).Run(std::vector<uint8_t>(
+                data->front(), data->front() + data->size()));
+          },
+          base::Passed(&callback)));
+}
+
 void AssistantController::RenderCard(
     const base::UnguessableToken& id_token,
     mojom::AssistantCardParamsPtr params,
diff --git a/ash/assistant/assistant_controller.h b/ash/assistant/assistant_controller.h
index 6f19b1a9..1875c0b1 100644
--- a/ash/assistant/assistant_controller.h
+++ b/ash/assistant/assistant_controller.h
@@ -17,6 +17,7 @@
 #include "base/macros.h"
 #include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
+#include "ui/gfx/geometry/rect.h"
 
 namespace base {
 class UnguessableToken;
@@ -117,6 +118,8 @@
       chromeos::assistant::mojom::AssistantPtr assistant) override;
   void SetAssistantCardRenderer(
       mojom::AssistantCardRendererPtr assistant_card_renderer) override;
+  void RequestScreenshot(const gfx::Rect& rect,
+                         RequestScreenshotCallback callback) override;
 
  private:
   mojo::Binding<mojom::AssistantController> assistant_controller_binding_;
diff --git a/ash/assistant/ui/assistant_bubble_view.cc b/ash/assistant/ui/assistant_bubble_view.cc
index fa8a0a99..87c19ef3 100644
--- a/ash/assistant/ui/assistant_bubble_view.cc
+++ b/ash/assistant/ui/assistant_bubble_view.cc
@@ -14,6 +14,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/unguessable_token.h"
 #include "ui/app_list/views/suggestion_chip_view.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/chromeos/resources/grit/ui_chromeos_resources.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/render_text.h"
 #include "ui/views/background.h"
@@ -364,14 +366,24 @@
   }
 
   void AddSuggestions(const std::map<int, AssistantSuggestion*>& suggestions) {
-    // When adding a SuggestionChipView, we give the view the same id by which
-    // the interaction model identifies the corresponding suggestion. This
-    // allows us to look up the suggestion for the view during event handling.
     for (const std::pair<int, AssistantSuggestion*>& suggestion : suggestions) {
-      views::View* suggestion_chip_view = new app_list::SuggestionChipView(
-          base::UTF8ToUTF16(suggestion.second->text),
-          suggestion_chip_listener_);
+      app_list::SuggestionChipView::Params params;
+      params.text = base::UTF8ToUTF16(suggestion.second->text);
+
+      // TODO(dmblack): Here we are using a placeholder image for the suggestion
+      // chip icon but we need to handle the actual icon URL.
+      if (!suggestion.second->icon_url.is_empty())
+        params.icon = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
+            IDR_ASSISTANT_PLACEHOLDER_GREY300_20DP);
+
+      views::View* suggestion_chip_view =
+          new app_list::SuggestionChipView(params, suggestion_chip_listener_);
+
+      // When adding a SuggestionChipView, we give the view the same id by which
+      // the interaction model identifies the corresponding suggestion. This
+      // allows us to look up the suggestion for the view during event handling.
       suggestion_chip_view->set_id(suggestion.first);
+
       AddChildView(suggestion_chip_view);
     }
     PreferredSizeChanged();
diff --git a/ash/assistant/ui/dialog_plate/dialog_plate.cc b/ash/assistant/ui/dialog_plate/dialog_plate.cc
index eab3254..3497209 100644
--- a/ash/assistant/ui/dialog_plate/dialog_plate.cc
+++ b/ash/assistant/ui/dialog_plate/dialog_plate.cc
@@ -42,9 +42,15 @@
       textfield_(new views::Textfield()),
       action_view_(new ActionView(assistant_controller, this)) {
   InitLayout();
+
+  // The Assistant controller indirectly owns the view hierarchy to which
+  // DialogPlate belongs so is guaranteed to outlive it.
+  assistant_controller_->AddInteractionModelObserver(this);
 }
 
-DialogPlate::~DialogPlate() = default;
+DialogPlate::~DialogPlate() {
+  assistant_controller_->RemoveInteractionModelObserver(this);
+}
 
 gfx::Size DialogPlate::CalculatePreferredSize() const {
   return gfx::Size(INT_MAX, kPreferredHeightDip);
@@ -84,6 +90,14 @@
   AddChildView(action_view_);
 }
 
+void DialogPlate::OnInteractionStateChanged(
+    InteractionState interaction_state) {
+  // When the Assistant interaction becomes inactive we need to clear the
+  // dialog plate so that text does not persist across Assistant entries.
+  if (interaction_state == InteractionState::kInactive)
+    textfield_->SetText(base::string16());
+}
+
 void DialogPlate::OnActionPressed() {
   const base::StringPiece16& trimmed_text =
       base::TrimWhitespace(textfield_->text(), base::TrimPositions::TRIM_ALL);
diff --git a/ash/assistant/ui/dialog_plate/dialog_plate.h b/ash/assistant/ui/dialog_plate/dialog_plate.h
index c9ed1920..dd9c2e8 100644
--- a/ash/assistant/ui/dialog_plate/dialog_plate.h
+++ b/ash/assistant/ui/dialog_plate/dialog_plate.h
@@ -5,6 +5,7 @@
 #ifndef ASH_ASSISTANT_UI_DIALOG_PLATE_DIALOG_PLATE_H_
 #define ASH_ASSISTANT_UI_DIALOG_PLATE_DIALOG_PLATE_H_
 
+#include "ash/assistant/model/assistant_interaction_model_observer.h"
 #include "ash/assistant/ui/dialog_plate/action_view.h"
 #include "base/macros.h"
 #include "ui/views/controls/textfield/textfield_controller.h"
@@ -16,7 +17,8 @@
 
 class DialogPlate : public views::View,
                     public views::TextfieldController,
-                    public ActionViewListener {
+                    public ActionViewListener,
+                    public AssistantInteractionModelObserver {
  public:
   explicit DialogPlate(AssistantController* assistant_controller);
   ~DialogPlate() override;
@@ -34,6 +36,9 @@
   // ActionViewListener:
   void OnActionPressed() override;
 
+  // AssistantInteractionModelObserver:
+  void OnInteractionStateChanged(InteractionState interaction_state) override;
+
  private:
   void InitLayout();
   void UpdateIcon();
diff --git a/ash/keyboard/keyboard_ui.cc b/ash/keyboard/keyboard_ui.cc
index 3e99020a..16647e12 100644
--- a/ash/keyboard/keyboard_ui.cc
+++ b/ash/keyboard/keyboard_ui.cc
@@ -25,13 +25,13 @@
       Shell::Get()->accessibility_controller()->RemoveObserver(this);
   }
 
-  void ShowInDisplay(const int64_t display_id) override {
+  void ShowInDisplay(const display::Display& display) override {
     keyboard::KeyboardController* controller =
         keyboard::KeyboardController::GetInstance();
     // Controller may not exist if keyboard has been disabled. crbug.com/749989
     if (!controller)
       return;
-    controller->ShowKeyboardInDisplay(display_id);
+    controller->ShowKeyboardInDisplay(display);
   }
   void Hide() override {
     // Do nothing as this is called from ash::Shell, which also calls through
diff --git a/ash/keyboard/keyboard_ui.h b/ash/keyboard/keyboard_ui.h
index b86cd5e6..d3efe2d 100644
--- a/ash/keyboard/keyboard_ui.h
+++ b/ash/keyboard/keyboard_ui.h
@@ -11,6 +11,10 @@
 #include "base/macros.h"
 #include "base/observer_list.h"
 
+namespace display {
+class Display;
+}
+
 namespace ash {
 
 class KeyboardUIObserver;
@@ -23,7 +27,7 @@
 
   static std::unique_ptr<KeyboardUI> Create();
 
-  virtual void ShowInDisplay(const int64_t display_id) = 0;
+  virtual void ShowInDisplay(const display::Display& display) = 0;
   virtual void Hide() = 0;
 
   // Returns true if the keyboard is enabled.
diff --git a/ash/keyboard/keyboard_ui_mash.cc b/ash/keyboard/keyboard_ui_mash.cc
index 53ba9a0..9a232bb 100644
--- a/ash/keyboard/keyboard_ui_mash.cc
+++ b/ash/keyboard/keyboard_ui_mash.cc
@@ -30,7 +30,7 @@
     keyboard_->Hide();
 }
 
-void KeyboardUIMash::ShowInDisplay(const int64_t display_id) {
+void KeyboardUIMash::ShowInDisplay(const display::Display& display) {
   // TODO(yhanada): Send display id after adding a display_id argument to
   // |Keyboard::Show()| in keyboard.mojom. See crbug.com/585253.
   if (keyboard_)
diff --git a/ash/keyboard/keyboard_ui_mash.h b/ash/keyboard/keyboard_ui_mash.h
index 8d0cef6..c6337d6 100644
--- a/ash/keyboard/keyboard_ui_mash.h
+++ b/ash/keyboard/keyboard_ui_mash.h
@@ -17,6 +17,9 @@
 namespace service_manager {
 class Connector;
 }
+namespace display {
+class Display;
+}
 
 namespace ash {
 
@@ -32,7 +35,7 @@
 
   // KeyboardUI:
   void Hide() override;
-  void ShowInDisplay(const int64_t display_id) override;
+  void ShowInDisplay(const display::Display& display) override;
   bool IsEnabled() override;
 
   // keyboard::mojom::KeyboardObserver:
diff --git a/ash/public/interfaces/assistant_controller.mojom b/ash/public/interfaces/assistant_controller.mojom
index e228d2f..cd5143c 100644
--- a/ash/public/interfaces/assistant_controller.mojom
+++ b/ash/public/interfaces/assistant_controller.mojom
@@ -6,6 +6,7 @@
 
 import "ash/public/interfaces/assistant_card_renderer.mojom";
 import "chromeos/services/assistant/public/mojom/assistant.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
 
 // Interface for AssistantManagerService to communicate with
 // AssistantController.
@@ -16,4 +17,9 @@
   // Provides an interface to the |assistant_card_renderer| owned by
   // AssistantClient.
   SetAssistantCardRenderer(AssistantCardRenderer assistant_card_renderer);
+
+  // Requests screenshot of specified |rect| region and returns the screenshot
+  // encoded in JPEG format. If |rect| is empty, it returns fullscreen
+  // screenshot.
+  RequestScreenshot(gfx.mojom.Rect rect) => (array<uint8> screenshot);
 };
diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc
index 7df31c01..222bbc1 100644
--- a/ash/root_window_controller_unittest.cc
+++ b/ash/root_window_controller_unittest.cc
@@ -898,8 +898,7 @@
   ASSERT_TRUE(vk_container_in_primary->Contains(vk_window));
   ASSERT_FALSE(vk_container_in_secondary->Contains(vk_window));
 
-  const int64_t secondary_display_id = secondary_display.id();
-  controller->ShowKeyboardInDisplay(secondary_display_id);
+  controller->ShowKeyboardInDisplay(secondary_display);
 
   EXPECT_FALSE(vk_container_in_primary->Contains(vk_window));
   EXPECT_TRUE(vk_container_in_secondary->Contains(vk_window));
@@ -1109,7 +1108,7 @@
 
   // Move the keyboard into the secondary display and check that the keyboard
   // doesn't cover the window on the primary screen.
-  keyboard_controller->ShowKeyboardInDisplay(secondary_display_id);
+  keyboard_controller->ShowKeyboardInDisplay(GetSecondaryDisplay());
   contents_window->SetBounds(keyboard::KeyboardBoundsFromRootBounds(
       secondary_root_window->bounds(), keyboard_height));
 
diff --git a/ash/system/audio/unified_volume_slider_controller.h b/ash/system/audio/unified_volume_slider_controller.h
index b36af1de..093df023 100644
--- a/ash/system/audio/unified_volume_slider_controller.h
+++ b/ash/system/audio/unified_volume_slider_controller.h
@@ -27,7 +27,7 @@
                           views::SliderChangeReason reason) override;
 
  private:
-  UnifiedSliderView* slider_;
+  UnifiedSliderView* slider_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(UnifiedVolumeSliderController);
 };
diff --git a/ash/system/brightness/unified_brightness_slider_controller.h b/ash/system/brightness/unified_brightness_slider_controller.h
index e8c4896..1c822ebd 100644
--- a/ash/system/brightness/unified_brightness_slider_controller.h
+++ b/ash/system/brightness/unified_brightness_slider_controller.h
@@ -29,8 +29,8 @@
                           views::SliderChangeReason reason) override;
 
  private:
-  UnifiedSystemTrayModel* model_;
-  UnifiedSliderView* slider_;
+  UnifiedSystemTrayModel* const model_;
+  UnifiedSliderView* slider_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(UnifiedBrightnessSliderController);
 };
diff --git a/ash/system/network/network_tray_view.cc b/ash/system/network/network_tray_view.cc
new file mode 100644
index 0000000..adc2cd72
--- /dev/null
+++ b/ash/system/network/network_tray_view.cc
@@ -0,0 +1,123 @@
+// 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 "ash/system/network/network_tray_view.h"
+
+#include "ash/strings/grit/ash_strings.h"
+#include "ash/system/network/network_icon.h"
+#include "ash/system/network/network_icon_animation.h"
+#include "ash/system/network/tray_network.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "ui/accessibility/ax_node_data.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/views/controls/image_view.h"
+
+using chromeos::NetworkHandler;
+using chromeos::NetworkState;
+using chromeos::NetworkStateHandler;
+using chromeos::NetworkTypePattern;
+
+namespace ash {
+namespace tray {
+
+const NetworkState* GetConnectedNetwork() {
+  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
+  return handler->ConnectedNetworkByType(NetworkTypePattern::NonVirtual());
+}
+
+NetworkTrayView::NetworkTrayView(TrayNetwork* network_tray)
+    : TrayItemView(network_tray) {
+  CreateImageView();
+  UpdateNetworkStateHandlerIcon();
+  UpdateConnectionStatus(GetConnectedNetwork(), true /* notify_a11y */);
+}
+
+NetworkTrayView::~NetworkTrayView() {
+  network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
+}
+
+const char* NetworkTrayView::GetClassName() const {
+  return "NetworkTrayView";
+}
+
+void NetworkTrayView::UpdateNetworkStateHandlerIcon() {
+  gfx::ImageSkia image;
+  base::string16 name;
+  bool animating = false;
+  network_icon::GetDefaultNetworkImageAndLabel(network_icon::ICON_TYPE_TRAY,
+                                               &image, &name, &animating);
+  bool show_in_tray = !image.isNull();
+  UpdateIcon(show_in_tray, image);
+  if (animating)
+    network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
+  else
+    network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
+}
+
+void NetworkTrayView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
+  node_data->SetName(connection_status_string_);
+  node_data->role = ax::mojom::Role::kButton;
+}
+
+void NetworkTrayView::NetworkIconChanged() {
+  UpdateNetworkStateHandlerIcon();
+  UpdateConnectionStatus(GetConnectedNetwork(), false /* notify_a11y */);
+}
+
+void NetworkTrayView::UpdateConnectionStatus(
+    const NetworkState* connected_network,
+    bool notify_a11y) {
+  using SignalStrength = network_icon::SignalStrength;
+
+  base::string16 new_connection_status_string;
+  if (connected_network) {
+    new_connection_status_string = l10n_util::GetStringFUTF16(
+        IDS_ASH_STATUS_TRAY_NETWORK_CONNECTED,
+        base::UTF8ToUTF16(connected_network->name()));
+
+    // Retrieve the string describing the signal strength, if it is applicable
+    // to |connected_network|.
+    base::string16 signal_strength_string;
+    switch (network_icon::GetSignalStrengthForNetwork(connected_network)) {
+      case SignalStrength::NONE:
+      case SignalStrength::NOT_WIRELESS:
+        break;
+      case SignalStrength::WEAK:
+        signal_strength_string =
+            l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_SIGNAL_WEAK);
+        break;
+      case SignalStrength::MEDIUM:
+        signal_strength_string = l10n_util::GetStringUTF16(
+            IDS_ASH_STATUS_TRAY_NETWORK_SIGNAL_MEDIUM);
+        break;
+      case SignalStrength::STRONG:
+        signal_strength_string = l10n_util::GetStringUTF16(
+            IDS_ASH_STATUS_TRAY_NETWORK_SIGNAL_STRONG);
+        break;
+    }
+
+    if (!signal_strength_string.empty()) {
+      new_connection_status_string = l10n_util::GetStringFUTF16(
+          IDS_ASH_STATUS_TRAY_NETWORK_CONNECTED_ACCESSIBLE,
+          base::UTF8ToUTF16(connected_network->name()), signal_strength_string);
+    }
+  }
+  if (new_connection_status_string != connection_status_string_) {
+    connection_status_string_ = new_connection_status_string;
+    if (notify_a11y && !connection_status_string_.empty())
+      NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true);
+  }
+}
+
+void NetworkTrayView::UpdateIcon(bool tray_icon_visible,
+                                 const gfx::ImageSkia& image) {
+  image_view()->SetImage(image);
+  SetVisible(tray_icon_visible);
+  SchedulePaint();
+}
+
+}  // namespace tray
+}  // namespace ash
diff --git a/ash/system/network/network_tray_view.h b/ash/system/network/network_tray_view.h
new file mode 100644
index 0000000..ef4616b
--- /dev/null
+++ b/ash/system/network/network_tray_view.h
@@ -0,0 +1,56 @@
+// 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 ASH_SYSTEM_NETWORK_NETWORK_TRAY_VIEW_H_
+#define ASH_SYSTEM_NETWORK_NETWORK_TRAY_VIEW_H_
+
+#include "ash/system/network/network_icon_animation_observer.h"
+#include "ash/system/tray/tray_item_view.h"
+#include "base/macros.h"
+
+namespace chromeos {
+class NetworkState;
+}  // namespace chromeos
+
+namespace ash {
+class TrayNetwork;
+
+namespace tray {
+
+// Returns the connected, non-virtual (aka VPN), network.
+const chromeos::NetworkState* GetConnectedNetwork();
+
+class NetworkTrayView : public TrayItemView,
+                        public network_icon::AnimationObserver {
+ public:
+  explicit NetworkTrayView(TrayNetwork* network_tray);
+
+  ~NetworkTrayView() override;
+
+  const char* GetClassName() const override;
+
+  void UpdateNetworkStateHandlerIcon();
+
+  // views::View:
+  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
+
+  // network_icon::AnimationObserver:
+  void NetworkIconChanged() override;
+
+  // Updates connection status and notifies accessibility event when necessary.
+  void UpdateConnectionStatus(const chromeos::NetworkState* connected_network,
+                              bool notify_a11y);
+
+ private:
+  void UpdateIcon(bool tray_icon_visible, const gfx::ImageSkia& image);
+
+  base::string16 connection_status_string_;
+
+  DISALLOW_COPY_AND_ASSIGN(NetworkTrayView);
+};
+
+}  // namespace tray
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_NETWORK_NETWORK_TRAY_VIEW_H_
diff --git a/ash/system/network/tray_network.cc b/ash/system/network/tray_network.cc
index fdef5e8..03e551c 100644
--- a/ash/system/network/tray_network.cc
+++ b/ash/system/network/tray_network.cc
@@ -11,6 +11,7 @@
 #include "ash/system/network/network_icon_animation.h"
 #include "ash/system/network/network_icon_animation_observer.h"
 #include "ash/system/network/network_list.h"
+#include "ash/system/network/network_tray_view.h"
 #include "ash/system/network/tray_network_state_observer.h"
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_notifier.h"
@@ -33,123 +34,11 @@
 #include "ui/views/widget/widget.h"
 
 using chromeos::NetworkHandler;
-using chromeos::NetworkState;
-using chromeos::NetworkStateHandler;
 using chromeos::NetworkTypePattern;
 
 namespace ash {
 namespace tray {
 
-namespace {
-
-// Returns the connected, non-virtual (aka VPN), network.
-const NetworkState* GetConnectedNetwork() {
-  NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler();
-  return handler->ConnectedNetworkByType(NetworkTypePattern::NonVirtual());
-}
-
-}  // namespace
-
-class NetworkTrayView : public TrayItemView,
-                        public network_icon::AnimationObserver {
- public:
-  explicit NetworkTrayView(TrayNetwork* network_tray)
-      : TrayItemView(network_tray) {
-    CreateImageView();
-    UpdateNetworkStateHandlerIcon();
-    UpdateConnectionStatus(GetConnectedNetwork(), true /* notify_a11y */);
-  }
-
-  ~NetworkTrayView() override {
-    network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
-  }
-
-  const char* GetClassName() const override { return "NetworkTrayView"; }
-
-  void UpdateNetworkStateHandlerIcon() {
-    gfx::ImageSkia image;
-    base::string16 name;
-    bool animating = false;
-    network_icon::GetDefaultNetworkImageAndLabel(network_icon::ICON_TYPE_TRAY,
-                                                 &image, &name, &animating);
-    bool show_in_tray = !image.isNull();
-    UpdateIcon(show_in_tray, image);
-    if (animating)
-      network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this);
-    else
-      network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this);
-  }
-
-  // views::View:
-  void GetAccessibleNodeData(ui::AXNodeData* node_data) override {
-    node_data->SetName(connection_status_string_);
-    node_data->role = ax::mojom::Role::kButton;
-  }
-
-  // network_icon::AnimationObserver:
-  void NetworkIconChanged() override {
-    UpdateNetworkStateHandlerIcon();
-    UpdateConnectionStatus(GetConnectedNetwork(), false /* notify_a11y */);
-  }
-
-  // Updates connection status and notifies accessibility event when necessary.
-  void UpdateConnectionStatus(const NetworkState* connected_network,
-                              bool notify_a11y) {
-    using SignalStrength = network_icon::SignalStrength;
-
-    base::string16 new_connection_status_string;
-    if (connected_network) {
-      new_connection_status_string = l10n_util::GetStringFUTF16(
-          IDS_ASH_STATUS_TRAY_NETWORK_CONNECTED,
-          base::UTF8ToUTF16(connected_network->name()));
-
-      // Retrieve the string describing the signal strength, if it is applicable
-      // to |connected_network|.
-      base::string16 signal_strength_string;
-      switch (network_icon::GetSignalStrengthForNetwork(connected_network)) {
-        case SignalStrength::NONE:
-        case SignalStrength::NOT_WIRELESS:
-          break;
-        case SignalStrength::WEAK:
-          signal_strength_string = l10n_util::GetStringUTF16(
-              IDS_ASH_STATUS_TRAY_NETWORK_SIGNAL_WEAK);
-          break;
-        case SignalStrength::MEDIUM:
-          signal_strength_string = l10n_util::GetStringUTF16(
-              IDS_ASH_STATUS_TRAY_NETWORK_SIGNAL_MEDIUM);
-          break;
-        case SignalStrength::STRONG:
-          signal_strength_string = l10n_util::GetStringUTF16(
-              IDS_ASH_STATUS_TRAY_NETWORK_SIGNAL_STRONG);
-          break;
-      }
-
-      if (!signal_strength_string.empty()) {
-        new_connection_status_string = l10n_util::GetStringFUTF16(
-            IDS_ASH_STATUS_TRAY_NETWORK_CONNECTED_ACCESSIBLE,
-            base::UTF8ToUTF16(connected_network->name()),
-            signal_strength_string);
-      }
-    }
-    if (new_connection_status_string != connection_status_string_) {
-      connection_status_string_ = new_connection_status_string;
-      if (notify_a11y && !connection_status_string_.empty())
-        NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true);
-    }
-  }
-
- private:
-  void UpdateIcon(bool tray_icon_visible, const gfx::ImageSkia& image) {
-    image_view()->SetImage(image);
-    SetVisible(tray_icon_visible);
-    SchedulePaint();
-  }
-
-  base::string16 connection_status_string_;
-
-  DISALLOW_COPY_AND_ASSIGN(NetworkTrayView);
-};
-
 class NetworkDefaultView : public TrayItemMore,
                            public network_icon::AnimationObserver {
  public:
diff --git a/ash/system/status_area_widget_unittest.cc b/ash/system/status_area_widget_unittest.cc
index 6be80d7..9956c38 100644
--- a/ash/system/status_area_widget_unittest.cc
+++ b/ash/system/status_area_widget_unittest.cc
@@ -7,6 +7,7 @@
 #include "ash/focus_cycler.h"
 #include "ash/public/cpp/ash_features.h"
 #include "ash/public/cpp/ash_switches.h"
+#include "ash/public/cpp/config.h"
 #include "ash/session/session_controller.h"
 #include "ash/session/test_session_controller_client.h"
 #include "ash/shell.h"
@@ -23,6 +24,9 @@
 #include "ash/test/ash_test_base.h"
 #include "base/command_line.h"
 #include "base/test/scoped_feature_list.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/network/network_handler.h"
+#include "components/prefs/testing_pref_service.h"
 #include "components/session_manager/session_manager_types.h"
 
 using session_manager::SessionState;
@@ -215,11 +219,38 @@
   // AshTestBase:
   void SetUp() override {
     scoped_feature_list_.InitAndEnableFeature(features::kSystemTrayUnified);
+
+    chromeos::DBusThreadManager::Initialize();
+    // Initializing NetworkHandler before ash is more like production.
+    chromeos::NetworkHandler::Initialize();
     AshTestBase::SetUp();
+    // Mash doesn't do this yet, so don't do it in tests either.
+    // http://crbug.com/718072
+    if (Shell::GetAshConfig() != Config::MASH) {
+      chromeos::NetworkHandler::Get()->InitializePrefServices(&profile_prefs_,
+                                                              &local_state_);
+    }
+    // Networking stubs may have asynchronous initialization.
+    base::RunLoop().RunUntilIdle();
+  }
+
+  void TearDown() override {
+    // This roughly matches production shutdown order.
+    if (Shell::GetAshConfig() != Config::MASH) {
+      chromeos::NetworkHandler::Get()->ShutdownPrefServices();
+    }
+    AshTestBase::TearDown();
+    chromeos::NetworkHandler::Shutdown();
+    chromeos::DBusThreadManager::Shutdown();
   }
 
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
+
+  TestingPrefServiceSimple profile_prefs_;
+  TestingPrefServiceSimple local_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(UnifiedStatusAreaWidgetTest);
 };
 
 TEST_F(UnifiedStatusAreaWidgetTest, Basics) {
diff --git a/ash/system/tray/tray_bubble_base.h b/ash/system/tray/tray_bubble_base.h
new file mode 100644
index 0000000..6784c45
--- /dev/null
+++ b/ash/system/tray/tray_bubble_base.h
@@ -0,0 +1,35 @@
+// 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 ASH_SYSTEM_TRAY_TRAY_BUBBLE_BASE_H_
+#define ASH_SYSTEM_TRAY_TRAY_BUBBLE_BASE_H_
+
+#include "ash/ash_export.h"
+
+namespace views {
+class TrayBubbleView;
+class Widget;
+}  // namespace views
+
+namespace ash {
+class TrayBackgroundView;
+
+// Base class for tray bubbles registered to TrayEventFilter.
+class ASH_EXPORT TrayBubbleBase {
+ public:
+  virtual ~TrayBubbleBase() {}
+
+  // Returns the tray button instance.
+  virtual TrayBackgroundView* GetTray() const = 0;
+
+  // Returns the TrayBubbleView instance of the bubble.
+  virtual views::TrayBubbleView* GetBubbleView() const = 0;
+
+  // Returns the widget of the bubble.
+  virtual views::Widget* GetBubbleWidget() const = 0;
+};
+
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_TRAY_TRAY_BUBBLE_BASE_H_
diff --git a/ash/system/tray/tray_bubble_wrapper.cc b/ash/system/tray/tray_bubble_wrapper.cc
index e79879e..11a5d7bd 100644
--- a/ash/system/tray/tray_bubble_wrapper.cc
+++ b/ash/system/tray/tray_bubble_wrapper.cc
@@ -30,7 +30,7 @@
   tray_->UpdateBubbleViewArrow(bubble_view_);
   bubble_view_->InitializeAndShowBubble();
 
-  tray->tray_event_filter()->AddWrapper(this);
+  tray->tray_event_filter()->AddBubble(this);
 
   bubble_widget_->GetNativeWindow()->GetRootWindow()->AddObserver(this);
 
@@ -42,7 +42,7 @@
   if (!is_persistent_)
     Shell::Get()->activation_client()->RemoveObserver(this);
 
-  tray_->tray_event_filter()->RemoveWrapper(this);
+  tray_->tray_event_filter()->RemoveBubble(this);
   if (bubble_widget_) {
     auto* transient_manager = ::wm::TransientWindowManager::GetOrCreate(
         bubble_widget_->GetNativeWindow());
@@ -56,6 +56,18 @@
   }
 }
 
+TrayBackgroundView* TrayBubbleWrapper::GetTray() const {
+  return tray_;
+}
+
+views::TrayBubbleView* TrayBubbleWrapper::GetBubbleView() const {
+  return bubble_view_;
+}
+
+views::Widget* TrayBubbleWrapper::GetBubbleWidget() const {
+  return bubble_widget_;
+}
+
 void TrayBubbleWrapper::OnWidgetClosing(views::Widget* widget) {
   CHECK_EQ(bubble_widget_, widget);
   // Remove this from the observer list before the widget is closed and detached
diff --git a/ash/system/tray/tray_bubble_wrapper.h b/ash/system/tray/tray_bubble_wrapper.h
index 4ec7f171..e824c15 100644
--- a/ash/system/tray/tray_bubble_wrapper.h
+++ b/ash/system/tray/tray_bubble_wrapper.h
@@ -6,6 +6,7 @@
 #define ASH_SYSTEM_TRAY_TRAY_BUBBLE_WRAPPER_H_
 
 #include "ash/ash_export.h"
+#include "ash/system/tray/tray_bubble_base.h"
 #include "base/macros.h"
 #include "ui/aura/window_observer.h"
 #include "ui/views/widget/widget_observer.h"
@@ -19,8 +20,9 @@
 class TrayBackgroundView;
 
 // Creates and manages the Widget and EventFilter components of a bubble.
-
-class ASH_EXPORT TrayBubbleWrapper : public views::WidgetObserver,
+// TODO(tetsui): Remove this and use TrayBubbleBase for all bubbles.
+class ASH_EXPORT TrayBubbleWrapper : public TrayBubbleBase,
+                                     public views::WidgetObserver,
                                      public aura::WindowObserver,
                                      public ::wm::ActivationChangeObserver {
  public:
@@ -29,6 +31,11 @@
                     bool is_persistent);
   ~TrayBubbleWrapper() override;
 
+  // TrayBubbleBase overrides:
+  TrayBackgroundView* GetTray() const override;
+  views::TrayBubbleView* GetBubbleView() const override;
+  views::Widget* GetBubbleWidget() const override;
+
   // views::WidgetObserver overrides:
   void OnWidgetClosing(views::Widget* widget) override;
   void OnWidgetDestroying(views::Widget* widget) override;
@@ -46,12 +53,9 @@
                          aura::Window* gained_active,
                          aura::Window* lost_active) override;
 
-  const TrayBackgroundView* tray() const { return tray_; }
   TrayBackgroundView* tray() { return tray_; }
   views::TrayBubbleView* bubble_view() { return bubble_view_; }
-  const views::TrayBubbleView* bubble_view() const { return bubble_view_; }
   views::Widget* bubble_widget() { return bubble_widget_; }
-  const views::Widget* bubble_widget() const { return bubble_widget_; }
 
  private:
   TrayBackgroundView* tray_;
diff --git a/ash/system/tray/tray_event_filter.cc b/ash/system/tray/tray_event_filter.cc
index 0de13eea..97c454d 100644
--- a/ash/system/tray/tray_event_filter.cc
+++ b/ash/system/tray/tray_event_filter.cc
@@ -8,7 +8,7 @@
 #include "ash/shell.h"
 #include "ash/shell_port.h"
 #include "ash/system/tray/tray_background_view.h"
-#include "ash/system/tray/tray_bubble_wrapper.h"
+#include "ash/system/tray/tray_bubble_base.h"
 #include "ash/wm/container_finder.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "ui/aura/window.h"
@@ -20,21 +20,21 @@
 TrayEventFilter::TrayEventFilter() = default;
 
 TrayEventFilter::~TrayEventFilter() {
-  DCHECK(wrappers_.empty());
+  DCHECK(bubbles_.empty());
 }
 
-void TrayEventFilter::AddWrapper(TrayBubbleWrapper* wrapper) {
-  bool was_empty = wrappers_.empty();
-  wrappers_.insert(wrapper);
-  if (was_empty && !wrappers_.empty()) {
+void TrayEventFilter::AddBubble(TrayBubbleBase* bubble) {
+  bool was_empty = bubbles_.empty();
+  bubbles_.insert(bubble);
+  if (was_empty && !bubbles_.empty()) {
     ShellPort::Get()->AddPointerWatcher(this,
                                         views::PointerWatcherEventTypes::BASIC);
   }
 }
 
-void TrayEventFilter::RemoveWrapper(TrayBubbleWrapper* wrapper) {
-  wrappers_.erase(wrapper);
-  if (wrappers_.empty())
+void TrayEventFilter::RemoveBubble(TrayBubbleBase* bubble) {
+  bubbles_.erase(bubble);
+  if (bubbles_.empty())
     ShellPort::Get()->RemovePointerWatcher(this);
 }
 
@@ -73,17 +73,17 @@
   }
 
   std::set<TrayBackgroundView*> trays;
-  // Check the boundary for all wrappers, and do not handle the event if it
-  // happens inside of any of those wrappers.
-  for (std::set<TrayBubbleWrapper*>::const_iterator iter = wrappers_.begin();
-       iter != wrappers_.end(); ++iter) {
-    const TrayBubbleWrapper* wrapper = *iter;
-    const views::Widget* bubble_widget = wrapper->bubble_widget();
+  // Check the boundary for all bubbles, and do not handle the event if it
+  // happens inside of any of those bubbles.
+  for (std::set<TrayBubbleBase*>::const_iterator iter = bubbles_.begin();
+       iter != bubbles_.end(); ++iter) {
+    const TrayBubbleBase* bubble = *iter;
+    const views::Widget* bubble_widget = bubble->GetBubbleWidget();
     if (!bubble_widget)
       continue;
 
     gfx::Rect bounds = bubble_widget->GetWindowBoundsInScreen();
-    bounds.Inset(wrapper->bubble_view()->GetBorderInsets());
+    bounds.Inset(bubble->GetBubbleView()->GetBorderInsets());
     // System tray can be dragged to show the bubble if it is in tablet mode.
     // During the drag, the bubble's logical bounds can extend outside of the
     // work area, but its visual bounds are only within the work area. Restrict
@@ -99,14 +99,14 @@
     }
     if (bounds.Contains(location_in_screen))
       continue;
-    if (wrapper->tray()) {
+    if (bubble->GetTray()) {
       // If the user clicks on the parent tray, don't process the event here,
       // let the tray logic handle the event and determine show/hide behavior.
-      bounds = wrapper->tray()->GetBoundsInScreen();
+      bounds = bubble->GetTray()->GetBoundsInScreen();
       if (bounds.Contains(location_in_screen))
         continue;
     }
-    trays.insert((*iter)->tray());
+    trays.insert((*iter)->GetTray());
   }
 
   // Close all bubbles other than the one a user clicked on the tray
diff --git a/ash/system/tray/tray_event_filter.h b/ash/system/tray/tray_event_filter.h
index c2ddb43..f8f37ba 100644
--- a/ash/system/tray/tray_event_filter.h
+++ b/ash/system/tray/tray_event_filter.h
@@ -20,7 +20,7 @@
 }
 
 namespace ash {
-class TrayBubbleWrapper;
+class TrayBubbleBase;
 
 // Handles events for a tray bubble, e.g. to close the system tray bubble when
 // the user clicks outside it.
@@ -29,8 +29,8 @@
   TrayEventFilter();
   ~TrayEventFilter() override;
 
-  void AddWrapper(TrayBubbleWrapper* wrapper);
-  void RemoveWrapper(TrayBubbleWrapper* wrapper);
+  void AddBubble(TrayBubbleBase* bubble);
+  void RemoveBubble(TrayBubbleBase* bubble);
 
   // views::PointerWatcher:
   void OnPointerEventObserved(const ui::PointerEvent& event,
@@ -41,7 +41,7 @@
   void ProcessPressedEvent(const gfx::Point& location_in_screen,
                            gfx::NativeView target);
 
-  std::set<TrayBubbleWrapper*> wrappers_;
+  std::set<TrayBubbleBase*> bubbles_;
 
   DISALLOW_COPY_AND_ASSIGN(TrayEventFilter);
 };
diff --git a/ash/system/unified/top_shortcuts_view.cc b/ash/system/unified/top_shortcuts_view.cc
index 7ec23979..e53aa042 100644
--- a/ash/system/unified/top_shortcuts_view.cc
+++ b/ash/system/unified/top_shortcuts_view.cc
@@ -15,31 +15,28 @@
 #include "ash/system/unified/sign_out_button.h"
 #include "ash/system/unified/top_shortcut_button.h"
 #include "ash/system/unified/unified_system_tray_controller.h"
-#include "ash/system/user/rounded_image_view.h"
+#include "ash/system/unified/user_chooser_view.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/fill_layout.h"
 
 namespace ash {
 
 namespace {
 
-views::View* CreateUserAvatarView() {
-  DCHECK(Shell::Get());
-  const mojom::UserSession* const user_session =
-      Shell::Get()->session_controller()->GetUserSession(0);
-  DCHECK(user_session);
+class UserAvatarButton : public views::Button {
+ public:
+  UserAvatarButton(views::ButtonListener* listener);
+  ~UserAvatarButton() override = default;
 
-  auto* image_view = new tray::RoundedImageView(kTrayItemSize / 2);
-  if (user_session->user_info->type == user_manager::USER_TYPE_GUEST) {
-    gfx::ImageSkia icon =
-        gfx::CreateVectorIcon(kSystemMenuGuestIcon, kMenuIconColor);
-    image_view->SetImage(icon, icon.size());
-  } else {
-    image_view->SetImage(user_session->user_info->avatar->image,
-                         gfx::Size(kTrayItemSize, kTrayItemSize));
-  }
+ private:
+  DISALLOW_COPY_AND_ASSIGN(UserAvatarButton);
+};
 
-  return image_view;
+UserAvatarButton::UserAvatarButton(views::ButtonListener* listener)
+    : Button(listener) {
+  SetLayoutManager(std::make_unique<views::FillLayout>());
+  AddChildView(CreateUserAvatarView(0 /* user_index */));
 }
 
 }  // namespace
@@ -55,8 +52,8 @@
 
   if (Shell::Get()->session_controller()->login_status() !=
       LoginStatus::NOT_LOGGED_IN) {
-    user_avatar_view_ = CreateUserAvatarView();
-    AddChildView(user_avatar_view_);
+    user_avatar_button_ = new UserAvatarButton(this);
+    AddChildView(user_avatar_button_);
   }
 
   // Show the buttons in this row as disabled if the user is at the login
@@ -102,7 +99,9 @@
 
 void TopShortcutsView::ButtonPressed(views::Button* sender,
                                      const ui::Event& event) {
-  if (sender == sign_out_button_)
+  if (sender == user_avatar_button_)
+    controller_->ShowUserChooserWidget();
+  else if (sender == sign_out_button_)
     controller_->HandleSignOutAction();
   else if (sender == lock_button_)
     controller_->HandleLockAction();
diff --git a/ash/system/unified/top_shortcuts_view.h b/ash/system/unified/top_shortcuts_view.h
index fff29527..514df17 100644
--- a/ash/system/unified/top_shortcuts_view.h
+++ b/ash/system/unified/top_shortcuts_view.h
@@ -36,7 +36,7 @@
   UnifiedSystemTrayController* controller_;
 
   // Owned by views hierarchy.
-  views::View* user_avatar_view_ = nullptr;
+  views::Button* user_avatar_button_ = nullptr;
   SignOutButton* sign_out_button_ = nullptr;
   TopShortcutButton* lock_button_ = nullptr;
   TopShortcutButton* settings_button_ = nullptr;
diff --git a/ash/system/unified/top_shortcuts_view_unittest.cc b/ash/system/unified/top_shortcuts_view_unittest.cc
index 04ad3fb..0f67728 100644
--- a/ash/system/unified/top_shortcuts_view_unittest.cc
+++ b/ash/system/unified/top_shortcuts_view_unittest.cc
@@ -43,7 +43,7 @@
   }
 
   views::View* GetUserAvatar() {
-    return top_shortcuts_view_->user_avatar_view_;
+    return top_shortcuts_view_->user_avatar_button_;
   }
 
   views::Button* GetSignOutButton() {
diff --git a/ash/system/unified/unified_system_tray.cc b/ash/system/unified/unified_system_tray.cc
index 93c260b..2d1f033 100644
--- a/ash/system/unified/unified_system_tray.cc
+++ b/ash/system/unified/unified_system_tray.cc
@@ -8,6 +8,8 @@
 #include "ash/system/date/date_view.h"
 #include "ash/system/message_center/ash_popup_alignment_delegate.h"
 #include "ash/system/model/system_tray_model.h"
+#include "ash/system/network/network_tray_view.h"
+#include "ash/system/network/tray_network_state_observer.h"
 #include "ash/system/power/tray_power.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/tray/system_tray.h"
@@ -97,16 +99,53 @@
   return false;
 }
 
+class UnifiedSystemTray::NetworkStateDelegate
+    : public TrayNetworkStateObserver::Delegate {
+ public:
+  explicit NetworkStateDelegate(tray::NetworkTrayView* tray_view);
+  ~NetworkStateDelegate() override;
+
+  // TrayNetworkStateObserver::Delegate
+  void NetworkStateChanged(bool notify_a11y) override;
+
+ private:
+  tray::NetworkTrayView* const tray_view_;
+  const std::unique_ptr<TrayNetworkStateObserver> network_state_observer_;
+
+  DISALLOW_COPY_AND_ASSIGN(NetworkStateDelegate);
+};
+
+UnifiedSystemTray::NetworkStateDelegate::NetworkStateDelegate(
+    tray::NetworkTrayView* tray_view)
+    : tray_view_(tray_view),
+      network_state_observer_(
+          std::make_unique<TrayNetworkStateObserver>(this)) {}
+
+UnifiedSystemTray::NetworkStateDelegate::~NetworkStateDelegate() = default;
+
+void UnifiedSystemTray::NetworkStateDelegate::NetworkStateChanged(
+    bool notify_a11y) {
+  tray_view_->UpdateNetworkStateHandlerIcon();
+  tray_view_->UpdateConnectionStatus(tray::GetConnectedNetwork(), notify_a11y);
+}
+
 UnifiedSystemTray::UnifiedSystemTray(Shelf* shelf)
     : TrayBackgroundView(shelf),
       ui_delegate_(std::make_unique<UiDelegate>(this)),
       model_(std::make_unique<UnifiedSystemTrayModel>()) {
+  tray::NetworkTrayView* network_item = new tray::NetworkTrayView(nullptr);
+  network_state_delegate_ =
+      std::make_unique<NetworkStateDelegate>(network_item);
+  tray_container()->AddChildView(network_item);
+
   tray_container()->AddChildView(new tray::PowerTrayView(nullptr));
+
   TrayItemView* time_item = new TrayItemView(nullptr);
   time_item->AddChildView(
       new tray::TimeView(tray::TimeView::ClockLayout::HORIZONTAL_CLOCK,
                          Shell::Get()->system_tray_model()->clock()));
   tray_container()->AddChildView(time_item);
+
   SetInkDropMode(InkDropMode::ON);
   SetVisible(true);
 }
@@ -144,7 +183,9 @@
 void UnifiedSystemTray::HideBubbleWithView(
     const views::TrayBubbleView* bubble_view) {}
 
-void UnifiedSystemTray::ClickedOutsideBubble() {}
+void UnifiedSystemTray::ClickedOutsideBubble() {
+  CloseBubble();
+}
 
 void UnifiedSystemTray::ShowBubbleInternal(bool show_by_click) {
   bubble_ = std::make_unique<UnifiedSystemTrayBubble>(this, show_by_click);
diff --git a/ash/system/unified/unified_system_tray.h b/ash/system/unified/unified_system_tray.h
index 09aeacc..59d2c41 100644
--- a/ash/system/unified/unified_system_tray.h
+++ b/ash/system/unified/unified_system_tray.h
@@ -50,12 +50,17 @@
   // Private class implements message_center::UiDelegate.
   class UiDelegate;
 
+  // Private class implements TrayNetworkStateObserver::Delegate.
+  class NetworkStateDelegate;
+
   // Forwarded from UiDelegate.
   void ShowBubbleInternal(bool show_by_click);
   void HideBubbleInternal();
 
   std::unique_ptr<UiDelegate> ui_delegate_;
 
+  std::unique_ptr<NetworkStateDelegate> network_state_delegate_;
+
   std::unique_ptr<UnifiedSystemTrayBubble> bubble_;
 
   // Model class that stores UnifiedSystemTray's UI specific variables.
diff --git a/ash/system/unified/unified_system_tray_bubble.cc b/ash/system/unified/unified_system_tray_bubble.cc
index 17f6948..90d0798 100644
--- a/ash/system/unified/unified_system_tray_bubble.cc
+++ b/ash/system/unified/unified_system_tray_bubble.cc
@@ -7,6 +7,7 @@
 #include "ash/public/cpp/app_list/app_list_features.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/tray/tray_constants.h"
+#include "ash/system/tray/tray_event_filter.h"
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/system/unified/unified_system_tray_controller.h"
 #include "ash/system/unified/unified_system_tray_view.h"
@@ -40,43 +41,58 @@
   init_params.corner_radius = kUnifiedTrayCornerRadius;
   init_params.has_shadow = false;
 
-  auto* bubble_view = new views::TrayBubbleView(init_params);
+  bubble_view_ = new views::TrayBubbleView(init_params);
   int max_height = tray->shelf()->GetUserWorkAreaBounds().height() -
                    kPaddingFromScreenTop -
-                   bubble_view->GetBorderInsets().height();
+                   bubble_view_->GetBorderInsets().height();
   auto* unified_view = controller_->CreateView();
   time_to_click_recorder_ =
       std::make_unique<TimeToClickRecorder>(this, unified_view);
   unified_view->SetMaxHeight(max_height);
-  bubble_view->SetMaxHeight(max_height);
-  bubble_view->AddChildView(unified_view);
-  bubble_view->set_anchor_view_insets(
+  bubble_view_->SetMaxHeight(max_height);
+  bubble_view_->AddChildView(unified_view);
+  bubble_view_->set_anchor_view_insets(
       tray->shelf()->GetSystemTrayAnchor()->GetBubbleAnchorInsets());
-  bubble_view->set_color(SK_ColorTRANSPARENT);
-  bubble_view->layer()->SetFillsBoundsOpaquely(false);
+  bubble_view_->set_color(SK_ColorTRANSPARENT);
+  bubble_view_->layer()->SetFillsBoundsOpaquely(false);
 
-  bubble_widget_ = views::BubbleDialogDelegateView::CreateBubble(bubble_view);
+  bubble_widget_ = views::BubbleDialogDelegateView::CreateBubble(bubble_view_);
   bubble_widget_->AddObserver(this);
 
   TrayBackgroundView::InitializeBubbleAnimations(bubble_widget_);
-  bubble_view->InitializeAndShowBubble();
+  bubble_view_->InitializeAndShowBubble();
   if (app_list::features::IsBackgroundBlurEnabled()) {
     // ClientView's layer (See TrayBubbleView::InitializeAndShowBubble())
-    bubble_view->layer()->parent()->SetBackgroundBlur(
+    bubble_view_->layer()->parent()->SetBackgroundBlur(
         kUnifiedMenuBackgroundBlur);
   }
 
   bubble_widget_->widget_delegate()->set_can_activate(true);
   bubble_widget_->Activate();
+
+  tray->tray_event_filter()->AddBubble(this);
 }
 
 UnifiedSystemTrayBubble::~UnifiedSystemTrayBubble() {
+  tray_->tray_event_filter()->RemoveBubble(this);
   if (bubble_widget_) {
     bubble_widget_->RemoveObserver(this);
     bubble_widget_->Close();
   }
 }
 
+TrayBackgroundView* UnifiedSystemTrayBubble::GetTray() const {
+  return tray_;
+}
+
+views::TrayBubbleView* UnifiedSystemTrayBubble::GetBubbleView() const {
+  return bubble_view_;
+}
+
+views::Widget* UnifiedSystemTrayBubble::GetBubbleWidget() const {
+  return bubble_widget_;
+}
+
 void UnifiedSystemTrayBubble::OnWidgetDestroying(views::Widget* widget) {
   CHECK_EQ(bubble_widget_, widget);
   bubble_widget_->RemoveObserver(this);
diff --git a/ash/system/unified/unified_system_tray_bubble.h b/ash/system/unified/unified_system_tray_bubble.h
index 82fff38..fa32d5a 100644
--- a/ash/system/unified/unified_system_tray_bubble.h
+++ b/ash/system/unified/unified_system_tray_bubble.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "ash/system/tray/time_to_click_recorder.h"
+#include "ash/system/tray/tray_bubble_base.h"
 #include "base/macros.h"
 #include "base/optional.h"
 #include "base/time/time.h"
@@ -26,12 +27,18 @@
 // Shows the bubble on the constructor, and closes the bubble on the destructor.
 // It is possible that the bubble widget is closed on deactivation. In such
 // case, this class calls UnifiedSystemTray::CloseBubble() to delete itself.
-class UnifiedSystemTrayBubble : public views::WidgetObserver,
+class UnifiedSystemTrayBubble : public TrayBubbleBase,
+                                public views::WidgetObserver,
                                 public TimeToClickRecorder::Delegate {
  public:
   explicit UnifiedSystemTrayBubble(UnifiedSystemTray* tray, bool show_by_click);
   ~UnifiedSystemTrayBubble() override;
 
+  // TrayBubbleBase:
+  TrayBackgroundView* GetTray() const override;
+  views::TrayBubbleView* GetBubbleView() const override;
+  views::Widget* GetBubbleWidget() const override;
+
   // views::WidgetObserver:
   void OnWidgetDestroying(views::Widget* widget) override;
 
@@ -60,6 +67,8 @@
   // click (|show_by_click| in ctor is false), it is not set.
   base::Optional<base::TimeTicks> time_shown_by_click_;
 
+  views::TrayBubbleView* bubble_view_ = nullptr;
+
   DISALLOW_COPY_AND_ASSIGN(UnifiedSystemTrayBubble);
 };
 
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc
index 2179a07..c886f92 100644
--- a/ash/system/unified/unified_system_tray_controller.cc
+++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -6,6 +6,7 @@
 
 #include "ash/metrics/user_metrics_action.h"
 #include "ash/metrics/user_metrics_recorder.h"
+#include "ash/multi_profile_uma.h"
 #include "ash/session/session_controller.h"
 #include "ash/shell.h"
 #include "ash/system/audio/unified_volume_slider_controller.h"
@@ -30,6 +31,7 @@
 #include "ash/system/unified/quiet_mode_feature_pod_controller.h"
 #include "ash/system/unified/unified_system_tray_model.h"
 #include "ash/system/unified/unified_system_tray_view.h"
+#include "ash/system/unified/user_chooser_view.h"
 #include "ash/wm/lock_state_controller.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/ranges.h"
@@ -79,6 +81,29 @@
   return unified_view_;
 }
 
+void UnifiedSystemTrayController::HandleUserSwitch(int user_index) {
+  // Do not switch users when the log screen is presented.
+  SessionController* controller = Shell::Get()->session_controller();
+  if (controller->IsUserSessionBlocked())
+    return;
+
+  // |user_index| must be in range (0, number_of_user). Note 0 is excluded
+  // because it represents the active user and SwitchUser should not be called
+  // for such case.
+  DCHECK_GT(user_index, 0);
+  DCHECK_LT(user_index, controller->NumberOfLoggedInUsers());
+
+  MultiProfileUMA::RecordSwitchActiveUser(
+      MultiProfileUMA::SWITCH_ACTIVE_USER_BY_TRAY);
+  controller->SwitchActiveUser(
+      controller->GetUserSession(user_index)->user_info->account_id);
+}
+
+void UnifiedSystemTrayController::HandleAddUserAction() {
+  MultiProfileUMA::RecordSigninUser(MultiProfileUMA::SIGNIN_USER_BY_TRAY);
+  Shell::Get()->session_controller()->ShowMultiProfileLogin();
+}
+
 void UnifiedSystemTrayController::HandleSignOutAction() {
   Shell::Get()->metrics()->RecordUserMetricsAction(UMA_STATUS_AREA_SIGN_OUT);
   Shell::Get()->session_controller()->RequestSignOut();
@@ -141,6 +166,25 @@
   }
 }
 
+void UnifiedSystemTrayController::ShowUserChooserWidget() {
+  // Don't allow user add or switch when CancelCastingDialog is open.
+  // See http://crrev.com/291276 and http://crbug.com/353170.
+  if (Shell::IsSystemModalWindowOpen())
+    return;
+
+  // Don't allow at login, lock or when adding a multi-profile user.
+  SessionController* session = Shell::Get()->session_controller();
+  if (session->IsUserSessionBlocked())
+    return;
+
+  // Don't show if we cannot add or switch users.
+  if (session->GetAddUserPolicy() != AddUserSessionPolicy::ALLOWED &&
+      session->NumberOfLoggedInUsers() <= 1)
+    return;
+
+  unified_view_->SetDetailedView(new UserChooserView(this));
+}
+
 void UnifiedSystemTrayController::ShowNetworkDetailedView() {
   // TODO(tetsui): Implement UnifiedSystemTray's Network detailed view.
   ShowSystemTrayDetailedView(system_tray_->GetTrayNetwork());
diff --git a/ash/system/unified/unified_system_tray_controller.h b/ash/system/unified/unified_system_tray_controller.h
index fd68d71..00729721 100644
--- a/ash/system/unified/unified_system_tray_controller.h
+++ b/ash/system/unified/unified_system_tray_controller.h
@@ -39,6 +39,10 @@
   // Create the view. The created view is unowned.
   UnifiedSystemTrayView* CreateView();
 
+  // Switch the active user to |user_index|. Called from the view.
+  void HandleUserSwitch(int user_index);
+  // Show multi profile login UI. Called from the view.
+  void HandleAddUserAction();
   // Sign out from the current user. Called from the view.
   void HandleSignOutAction();
   // Show lock screen which asks the user password. Called from the view.
@@ -55,6 +59,8 @@
   void UpdateDrag(const gfx::Point& location);
   void EndDrag(const gfx::Point& location);
 
+  // Show user selector popup widget. Called from the view.
+  void ShowUserChooserWidget();
   // Show the detailed view of network. Called from the view.
   void ShowNetworkDetailedView();
   // Show the detailed view of bluetooth. Called from the view.
@@ -76,6 +82,8 @@
   UnifiedSystemTrayModel* model() { return model_; }
 
  private:
+  friend class UnifiedSystemTrayControllerTest;
+
   // How the expanded state is toggled. The enum is used to back an UMA
   // histogram and should be treated as append-only.
   enum ToggleExpandedType {
diff --git a/ash/system/unified/unified_system_tray_controller_unittest.cc b/ash/system/unified/unified_system_tray_controller_unittest.cc
new file mode 100644
index 0000000..530cf1e
--- /dev/null
+++ b/ash/system/unified/unified_system_tray_controller_unittest.cc
@@ -0,0 +1,106 @@
+// 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 "ash/system/unified/unified_system_tray_controller.h"
+
+#include "ash/public/cpp/config.h"
+#include "ash/shell.h"
+#include "ash/system/unified/unified_system_tray_model.h"
+#include "ash/system/unified/unified_system_tray_view.h"
+#include "ash/test/ash_test_base.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/network/network_handler.h"
+#include "components/prefs/testing_pref_service.h"
+#include "ui/compositor/scoped_animation_duration_scale_mode.h"
+#include "ui/gfx/animation/slide_animation.h"
+#include "ui/views/view_observer.h"
+
+namespace ash {
+
+class UnifiedSystemTrayControllerTest : public AshTestBase,
+                                        public views::ViewObserver {
+ public:
+  UnifiedSystemTrayControllerTest() = default;
+  ~UnifiedSystemTrayControllerTest() override = default;
+
+  // testing::Test:
+  void SetUp() override {
+    chromeos::DBusThreadManager::Initialize();
+    // Initializing NetworkHandler before ash is more like production.
+    chromeos::NetworkHandler::Initialize();
+    AshTestBase::SetUp();
+    // Mash doesn't do this yet, so don't do it in tests either.
+    // http://crbug.com/718072
+    if (Shell::GetAshConfig() != Config::MASH) {
+      chromeos::NetworkHandler::Get()->InitializePrefServices(&profile_prefs_,
+                                                              &local_state_);
+    }
+    // Networking stubs may have asynchronous initialization.
+    base::RunLoop().RunUntilIdle();
+
+    model_ = std::make_unique<UnifiedSystemTrayModel>();
+    controller_ = std::make_unique<UnifiedSystemTrayController>(
+        model(), nullptr /* system_tray */);
+    view_.reset(controller_->CreateView());
+
+    view_->AddObserver(this);
+    OnViewPreferredSizeChanged(view());
+  }
+
+  void TearDown() override {
+    view_->RemoveObserver(this);
+
+    view_.reset();
+    controller_.reset();
+    model_.reset();
+
+    // This roughly matches production shutdown order.
+    if (Shell::GetAshConfig() != Config::MASH) {
+      chromeos::NetworkHandler::Get()->ShutdownPrefServices();
+    }
+    AshTestBase::TearDown();
+    chromeos::NetworkHandler::Shutdown();
+    chromeos::DBusThreadManager::Shutdown();
+  }
+
+  // views::ViewObserver:
+  void OnViewPreferredSizeChanged(views::View* observed_view) override {
+    view_->SetBoundsRect(gfx::Rect(view_->GetPreferredSize()));
+    view_->Layout();
+  }
+
+ protected:
+  void WaitForAnimation() {
+    while (controller()->animation_->is_animating())
+      base::RunLoop().RunUntilIdle();
+  }
+
+  UnifiedSystemTrayModel* model() { return model_.get(); }
+  UnifiedSystemTrayController* controller() { return controller_.get(); }
+  UnifiedSystemTrayView* view() { return view_.get(); }
+
+ private:
+  std::unique_ptr<UnifiedSystemTrayModel> model_;
+  std::unique_ptr<UnifiedSystemTrayController> controller_;
+  std::unique_ptr<UnifiedSystemTrayView> view_;
+
+  TestingPrefServiceSimple profile_prefs_;
+  TestingPrefServiceSimple local_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(UnifiedSystemTrayControllerTest);
+};
+
+TEST_F(UnifiedSystemTrayControllerTest, ToggleExpanded) {
+  EXPECT_TRUE(model()->expanded_on_open());
+  const int expanded_height = view()->GetPreferredSize().height();
+
+  controller()->ToggleExpanded();
+  WaitForAnimation();
+
+  const int collapsed_height = view()->GetPreferredSize().height();
+  EXPECT_LT(collapsed_height, expanded_height);
+  EXPECT_FALSE(model()->expanded_on_open());
+}
+
+}  // namespace ash
diff --git a/ash/system/unified/user_chooser_view.cc b/ash/system/unified/user_chooser_view.cc
new file mode 100644
index 0000000..eafab86
--- /dev/null
+++ b/ash/system/unified/user_chooser_view.cc
@@ -0,0 +1,156 @@
+// 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 "ash/system/unified/user_chooser_view.h"
+
+#include "ash/public/cpp/shell_window_ids.h"
+#include "ash/resources/vector_icons/vector_icons.h"
+#include "ash/session/session_controller.h"
+#include "ash/shell.h"
+#include "ash/strings/grit/ash_strings.h"
+#include "ash/system/tray/tray_constants.h"
+#include "ash/system/unified/top_shortcuts_view.h"
+#include "ash/system/unified/unified_system_tray_controller.h"
+#include "ash/system/user/rounded_image_view.h"
+#include "base/strings/utf_string_conversions.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/paint_vector_icon.h"
+#include "ui/views/controls/button/label_button.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/widget/widget.h"
+
+namespace ash {
+
+views::View* CreateUserAvatarView(int user_index) {
+  DCHECK(Shell::Get());
+  const mojom::UserSession* const user_session =
+      Shell::Get()->session_controller()->GetUserSession(user_index);
+  DCHECK(user_session);
+
+  auto* image_view = new tray::RoundedImageView(kTrayItemSize / 2);
+  if (user_session->user_info->type == user_manager::USER_TYPE_GUEST) {
+    gfx::ImageSkia icon =
+        gfx::CreateVectorIcon(kSystemMenuGuestIcon, kMenuIconColor);
+    image_view->SetImage(icon, icon.size());
+  } else {
+    image_view->SetImage(user_session->user_info->avatar->image,
+                         gfx::Size(kTrayItemSize, kTrayItemSize));
+  }
+  return image_view;
+}
+
+namespace {
+
+// A button item of a switchable user.
+class UserItemButton : public views::Button, public views::ButtonListener {
+ public:
+  UserItemButton(int user_index, UnifiedSystemTrayController* controller);
+  ~UserItemButton() override = default;
+
+  // views::ButtonListener:
+  void ButtonPressed(views::Button* sender, const ui::Event& event) override;
+
+ private:
+  int user_index_;
+  UnifiedSystemTrayController* const controller_;
+
+  DISALLOW_COPY_AND_ASSIGN(UserItemButton);
+};
+
+UserItemButton::UserItemButton(int user_index,
+                               UnifiedSystemTrayController* controller)
+    : Button(this), user_index_(user_index), controller_(controller) {
+  SetLayoutManager(std::make_unique<views::BoxLayout>(
+      views::BoxLayout::kHorizontal, gfx::Insets(kUnifiedTopShortcutSpacing),
+      kUnifiedTopShortcutSpacing));
+  AddChildView(CreateUserAvatarView(user_index));
+
+  views::View* vertical_labels = new views::View;
+  auto* layout = vertical_labels->SetLayoutManager(
+      std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical));
+  layout->set_cross_axis_alignment(
+      views::BoxLayout::CROSS_AXIS_ALIGNMENT_START);
+
+  const mojom::UserSession* const user_session =
+      Shell::Get()->session_controller()->GetUserSession(user_index);
+
+  auto* name = new views::Label(
+      base::UTF8ToUTF16(user_session->user_info->display_name));
+  name->SetEnabledColor(kUnifiedMenuTextColor);
+  name->SetAutoColorReadabilityEnabled(false);
+  name->SetSubpixelRenderingEnabled(false);
+  vertical_labels->AddChildView(name);
+
+  auto* email = new views::Label(
+      base::UTF8ToUTF16(user_session->user_info->display_email));
+  email->SetEnabledColor(kUnifiedMenuSecondaryTextColor);
+  email->SetAutoColorReadabilityEnabled(false);
+  email->SetSubpixelRenderingEnabled(false);
+  vertical_labels->AddChildView(email);
+
+  AddChildView(vertical_labels);
+}
+
+void UserItemButton::ButtonPressed(views::Button* sender,
+                                   const ui::Event& event) {
+  controller_->HandleUserSwitch(user_index_);
+}
+
+// A button that will transition to multi profile login UI.
+class AddUserButton : public views::Button, public views::ButtonListener {
+ public:
+  explicit AddUserButton(UnifiedSystemTrayController* controller);
+  ~AddUserButton() override = default;
+
+  // views::ButtonListener:
+  void ButtonPressed(views::Button* sender, const ui::Event& event) override;
+
+ private:
+  UnifiedSystemTrayController* const controller_;
+
+  DISALLOW_COPY_AND_ASSIGN(AddUserButton);
+};
+
+AddUserButton::AddUserButton(UnifiedSystemTrayController* controller)
+    : Button(this), controller_(controller) {
+  SetLayoutManager(std::make_unique<views::BoxLayout>(
+      views::BoxLayout::kHorizontal, gfx::Insets(kUnifiedTopShortcutSpacing),
+      kUnifiedTopShortcutSpacing));
+
+  auto* icon = new views::ImageView;
+  icon->SetImage(
+      gfx::CreateVectorIcon(kSystemMenuNewUserIcon, kUnifiedMenuIconColor));
+  AddChildView(icon);
+
+  auto* label = new views::Label(
+      l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT));
+  label->SetEnabledColor(kUnifiedMenuTextColor);
+  label->SetAutoColorReadabilityEnabled(false);
+  label->SetSubpixelRenderingEnabled(false);
+  AddChildView(label);
+}
+
+void AddUserButton::ButtonPressed(views::Button* sender,
+                                  const ui::Event& event) {
+  controller_->HandleAddUserAction();
+}
+
+}  // namespace
+
+UserChooserView::UserChooserView(UnifiedSystemTrayController* controller) {
+  SetLayoutManager(
+      std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical));
+  const int num_users =
+      Shell::Get()->session_controller()->NumberOfLoggedInUsers();
+  for (int i = 0; i < num_users; ++i)
+    AddChildView(new UserItemButton(i, controller));
+  if (Shell::Get()->session_controller()->GetAddUserPolicy() ==
+      AddUserSessionPolicy::ALLOWED) {
+    AddChildView(new AddUserButton(controller));
+  }
+}
+
+UserChooserView::~UserChooserView() = default;
+
+}  // namespace ash
diff --git a/ash/system/unified/user_chooser_view.h b/ash/system/unified/user_chooser_view.h
new file mode 100644
index 0000000..c42f89b
--- /dev/null
+++ b/ash/system/unified/user_chooser_view.h
@@ -0,0 +1,29 @@
+// 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 ASH_SYSTEM_UNIFIED_USER_CHOOSER_VIEW_H_
+#define ASH_SYSTEM_UNIFIED_USER_CHOOSER_VIEW_H_
+
+#include "ui/views/view.h"
+
+namespace ash {
+
+class UnifiedSystemTrayController;
+
+// Circular image view with user's icon of |user_index|.
+views::View* CreateUserAvatarView(int user_index);
+
+// A detailed view of user chooser.
+class UserChooserView : public views::View {
+ public:
+  UserChooserView(UnifiedSystemTrayController* controller);
+  ~UserChooserView() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(UserChooserView);
+};
+
+}  // namespace ash
+
+#endif  // ASH_SYSTEM_UNIFIED_UNIFIED_SYSTEM_TRAY_VIEW_H_
diff --git a/ash/system/virtual_keyboard/virtual_keyboard_tray.cc b/ash/system/virtual_keyboard/virtual_keyboard_tray.cc
index a727171..1d368f64 100644
--- a/ash/system/virtual_keyboard/virtual_keyboard_tray.cc
+++ b/ash/system/virtual_keyboard/virtual_keyboard_tray.cc
@@ -70,10 +70,9 @@
 bool VirtualKeyboardTray::PerformAction(const ui::Event& event) {
   UserMetricsRecorder::RecordUserClickOnTray(
       LoginMetricsRecorder::TrayClickTarget::kVirtualKeyboardTray);
-  const int64_t display_id = display::Screen::GetScreen()
-                                 ->GetDisplayNearestWindow(shelf_->GetWindow())
-                                 .id();
-  Shell::Get()->keyboard_ui()->ShowInDisplay(display_id);
+  Shell::Get()->keyboard_ui()->ShowInDisplay(
+      display::Screen::GetScreen()->GetDisplayNearestWindow(
+          shelf_->GetWindow()));
   // Normally, active status is set when virtual keyboard is shown/hidden,
   // however, showing virtual keyboard happens asynchronously and, especially
   // the first time, takes some time. We need to set active status here to
diff --git a/base/run_loop.cc b/base/run_loop.cc
index 496e858f..1385a8631 100644
--- a/base/run_loop.cc
+++ b/base/run_loop.cc
@@ -239,6 +239,11 @@
   tls_delegate.Get().Get()->active_run_loops_.top()->QuitWhenIdle();
 }
 
+// static
+Closure RunLoop::QuitCurrentWhenIdleClosureDeprecated() {
+  return Bind(&RunLoop::QuitCurrentWhenIdleDeprecated);
+}
+
 #if DCHECK_IS_ON()
 RunLoop::ScopedDisallowRunningForTesting::ScopedDisallowRunningForTesting()
     : current_delegate_(tls_delegate.Get().Get()),
diff --git a/base/run_loop.h b/base/run_loop.h
index d3858fce..53c42d0 100644
--- a/base/run_loop.h
+++ b/base/run_loop.h
@@ -234,12 +234,13 @@
 
   // Quits the active RunLoop (when idle) -- there must be one. These were
   // introduced as prefered temporary replacements to the long deprecated
-  // MessageLoop::Quit(WhenIdle) methods. Callers should properly plumb a
-  // reference to the appropriate RunLoop instance (or its QuitClosure) instead
-  // of using these in order to link Run()/Quit() to a single RunLoop instance
-  // and increase readability.
+  // MessageLoop::Quit(WhenIdle)(Closure) methods. Callers should properly plumb
+  // a reference to the appropriate RunLoop instance (or its QuitClosure)
+  // instead of using these in order to link Run()/Quit() to a single RunLoop
+  // instance and increase readability.
   static void QuitCurrentDeprecated();
   static void QuitCurrentWhenIdleDeprecated();
+  static Closure QuitCurrentWhenIdleClosureDeprecated();
 
   // Run() will DCHECK if called while there's a ScopedDisallowRunningForTesting
   // in scope on its thread. This is useful to add safety to some test
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java
index ce898611..258984e 100644
--- a/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java
+++ b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java
@@ -24,6 +24,7 @@
 
 import org.chromium.base.BuildConfig;
 import org.chromium.base.Log;
+import org.chromium.base.annotations.MainDex;
 import org.chromium.base.multidex.ChromiumMultiDexInstaller;
 
 import java.io.IOException;
@@ -40,6 +41,7 @@
  * TODO(yolandyan): remove this class after all tests are converted to JUnit4. Use class runner
  * for test listing.
  */
+@MainDex
 public class BaseChromiumAndroidJUnitRunner extends AndroidJUnitRunner {
     private static final String LIST_ALL_TESTS_FLAG =
             "org.chromium.base.test.BaseChromiumAndroidJUnitRunner.TestList";
diff --git a/build/android/pylib/local/device/local_device_gtest_run.py b/build/android/pylib/local/device/local_device_gtest_run.py
index 9856017..ca52fb3 100644
--- a/build/android/pylib/local/device/local_device_gtest_run.py
+++ b/build/android/pylib/local/device/local_device_gtest_run.py
@@ -391,11 +391,19 @@
       retries = 1
       if self._test_instance.wait_for_java_debugger:
         timeout = None
+
+      flags = list(self._test_instance.flags)
+      flags.append('--gtest_list_tests')
+
       # TODO(crbug.com/726880): Remove retries when no longer necessary.
       for i in range(0, retries+1):
+        logging.info('flags:')
+        for f in flags:
+          logging.info('  %s', f)
+
         raw_test_list = crash_handler.RetryOnSystemCrash(
             lambda d: self._delegate.Run(
-                None, d, flags='--gtest_list_tests', timeout=timeout),
+                None, d, flags=' '.join(flags), timeout=timeout),
             device=dev)
         tests = gtest_test_instance.ParseGTestListTests(raw_test_list)
         if not tests:
diff --git a/build/chromeos/run_vm_test.py b/build/chromeos/run_vm_test.py
index 5da39bd0..ce6e651 100755
--- a/build/chromeos/run_vm_test.py
+++ b/build/chromeos/run_vm_test.py
@@ -6,6 +6,7 @@
 
 import argparse
 import contextlib
+import json
 import logging
 import os
 import re
@@ -16,6 +17,13 @@
 
 CHROMIUM_SRC_PATH = os.path.abspath(os.path.join(
     os.path.dirname(__file__), '..', '..'))
+
+# Use the android test-runner's gtest results support library for generating
+# output json ourselves.
+sys.path.insert(0, os.path.join(CHROMIUM_SRC_PATH, 'build', 'android'))
+from pylib.base import base_test_result
+from pylib.results import json_results
+
 CHROMITE_PATH = os.path.abspath(os.path.join(
     CHROMIUM_SRC_PATH, 'third_party', 'chromite'))
 # cros_vm is a tool for managing VMs.
@@ -152,9 +160,24 @@
   if not env_copy.get('GN_ARGS'):
     env_copy['GN_ARGS'] = 'is_chromeos = true'
   env_copy['PATH'] = env_copy['PATH'] + ':' + os.path.join(CHROMITE_PATH, 'bin')
-  return subprocess.call(
+  rc = subprocess.call(
       cros_run_vm_test_cmd, stdout=sys.stdout, stderr=sys.stderr, env=env_copy)
 
+  # Create a simple json results file for the sanity test if needed. The results
+  # will contain only one test ('cros_vm_sanity_test'), and will either be a
+  # PASS or FAIL depending on the return code of cros_run_vm_test above.
+  if args.test_launcher_summary_output and is_sanity_test:
+    result = (base_test_result.ResultType.FAIL if rc else
+                  base_test_result.ResultType.PASS)
+    sanity_test_result = base_test_result.BaseTestResult(
+        'cros_vm_sanity_test', result)
+    run_results = base_test_result.TestRunResults()
+    run_results.AddResult(sanity_test_result)
+    with open(args.test_launcher_summary_output, 'w') as f:
+      json.dump(json_results.GenerateResultsDict([run_results]), f)
+
+  return rc
+
 
 def main():
   parser = argparse.ArgumentParser()
diff --git a/build/config/chromeos/rules.gni b/build/config/chromeos/rules.gni
index b36d118..5f1ece8 100644
--- a/build/config/chromeos/rules.gni
+++ b/build/config/chromeos/rules.gni
@@ -29,6 +29,11 @@
     ]
 
     data = [
+      # We use android test-runner's results libs to construct gtest output
+      # json.
+      "//build/android/pylib/__init__.py",
+      "//build/android/pylib/base/",
+      "//build/android/pylib/results/",
       invoker.generated_script,
       "//build/chromeos/",
       "//build/cros_cache/chrome-sdk/misc/",
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
index 625904a..79838c0 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -162,12 +162,12 @@
   # Linux or Fuchsia.
   # TODO(pcc): Enable lld on more architectures on Linux. E.g. we probably need
   # to fix some of crbug.com/742655 to enable it on ARM.
-  use_lld =
-      is_clang &&
-      (is_win || is_fuchsia || (use_thin_lto && target_os != "chromeos") ||
-       (is_linux && current_cpu == "x64" && target_os != "chromeos") ||
-       (is_android && (current_cpu != "arm" || arm_version >= 7) &&
-        current_cpu != "mipsel" && current_cpu != "mips64el"))
+  use_lld = is_clang &&
+            ((is_win && host_os != "win") || is_fuchsia ||
+             (use_thin_lto && target_os != "chromeos") ||
+             (is_linux && current_cpu == "x64" && target_os != "chromeos") ||
+             (is_android && (current_cpu != "arm" || arm_version >= 7) &&
+              current_cpu != "mipsel" && current_cpu != "mips64el"))
 }
 
 declare_args() {
diff --git a/build/fuchsia/layout_test_proxy/BUILD.gn b/build/fuchsia/layout_test_proxy/BUILD.gn
new file mode 100644
index 0000000..43ed152
--- /dev/null
+++ b/build/fuchsia/layout_test_proxy/BUILD.gn
@@ -0,0 +1,27 @@
+# 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.
+
+assert(is_fuchsia)
+
+import("//testing/test.gni")
+
+# Binary used to proxy TCP connections from a Fuchsia process. Potentially SSH
+# can be used to forward TCP, but this feature is currently broken on Fuchsia,
+# see ZX-1555. layout_test_proxy can be removed once that issue with sshd is
+# fixed and layout tests are updated to use SSH.
+executable("layout_test_proxy") {
+  testonly = true
+  sources = [
+    "layout_test_proxy.cc",
+  ]
+  deps = [
+    "//net",
+    "//net:test_support",
+  ]
+}
+
+fuchsia_executable_runner("layout_test_proxy_runner") {
+  testonly = true
+  exe_target = ":layout_test_proxy"
+}
diff --git a/build/fuchsia/layout_test_proxy/DEPS b/build/fuchsia/layout_test_proxy/DEPS
new file mode 100644
index 0000000..b2f6f8e
--- /dev/null
+++ b/build/fuchsia/layout_test_proxy/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+net",
+]
\ No newline at end of file
diff --git a/build/fuchsia/layout_test_proxy/layout_test_proxy.cc b/build/fuchsia/layout_test_proxy/layout_test_proxy.cc
new file mode 100644
index 0000000..1d14df99
--- /dev/null
+++ b/build/fuchsia/layout_test_proxy/layout_test_proxy.cc
@@ -0,0 +1,78 @@
+// 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/command_line.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "net/base/ip_endpoint.h"
+#include "net/test/tcp_socket_proxy.h"
+
+const char kPortsSwitch[] = "ports";
+const char kRemoteAddressSwitch[] = "remote-address";
+
+int main(int argc, char** argv) {
+  base::CommandLine::Init(argc, argv);
+
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+
+  if (!command_line->HasSwitch(kPortsSwitch)) {
+    LOG(ERROR) << "--" << kPortsSwitch << " was not specified.";
+    return 1;
+  }
+
+  std::vector<std::string> ports_strings =
+      base::SplitString(command_line->GetSwitchValueASCII(kPortsSwitch), ",",
+                        base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+  if (ports_strings.empty()) {
+    LOG(ERROR) << "At least one port must be specified with --" << kPortsSwitch;
+    return 1;
+  }
+
+  std::vector<int> ports;
+  for (auto& port_string : ports_strings) {
+    int port;
+    if (!base::StringToInt(port_string, &port) || port <= 0 || port > 65535) {
+      LOG(ERROR) << "Invalid value specified for --" << kPortsSwitch << ": "
+                 << port_string;
+      return 1;
+    }
+    ports.push_back(port);
+  }
+
+  if (!command_line->HasSwitch(kRemoteAddressSwitch)) {
+    LOG(ERROR) << "--" << kRemoteAddressSwitch << " was not specified.";
+    return 1;
+  }
+
+  std::string remote_address_str =
+      command_line->GetSwitchValueASCII(kRemoteAddressSwitch);
+  net::IPAddress remote_address;
+  if (!remote_address.AssignFromIPLiteral(remote_address_str)) {
+    LOG(ERROR) << "Invalid value specified for --" << kRemoteAddressSwitch
+               << ": " << remote_address_str;
+    return 1;
+  }
+
+  base::MessageLoopForIO message_loop;
+
+  std::vector<std::unique_ptr<net::TcpSocketProxy>> proxies;
+
+  for (int port : ports) {
+    auto test_server_proxy =
+        std::make_unique<net::TcpSocketProxy>(message_loop.task_runner());
+    if (!test_server_proxy->Initialize(port)) {
+      LOG(ERROR) << "Can't bind proxy to port " << port;
+      return 1;
+    }
+    LOG(INFO) << "Listening on port " << test_server_proxy->local_port();
+    test_server_proxy->Start(net::IPEndPoint(remote_address, port));
+    proxies.push_back(std::move(test_server_proxy));
+  }
+
+  // Run the message loop indefinitely.
+  base::RunLoop().Run();
+
+  return 0;
+}
\ No newline at end of file
diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc
index ce60d89e..cce06a5 100644
--- a/cc/test/fake_tile_manager.cc
+++ b/cc/test/fake_tile_manager.cc
@@ -42,7 +42,6 @@
       image_decode_cache_(
           kN32_SkColorType,
           LayerTreeSettings().decoded_image_working_set_budget_bytes) {
-  SetDecodedImageTracker(&decoded_image_tracker_);
   SetResources(resource_pool, &image_decode_cache_, GetGlobalTaskGraphRunner(),
                GetGlobalRasterBufferProvider(),
                false /* use_gpu_rasterization */);
diff --git a/cc/test/fake_tile_manager.h b/cc/test/fake_tile_manager.h
index 562e154..1b39674 100644
--- a/cc/test/fake_tile_manager.h
+++ b/cc/test/fake_tile_manager.h
@@ -27,7 +27,6 @@
 
  private:
   SoftwareImageDecodeCache image_decode_cache_;
-  DecodedImageTracker decoded_image_tracker_;
 };
 
 }  // namespace cc
diff --git a/cc/tiles/decoded_image_tracker.cc b/cc/tiles/decoded_image_tracker.cc
index 0f8f0dd..cd2d1ee 100644
--- a/cc/tiles/decoded_image_tracker.cc
+++ b/cc/tiles/decoded_image_tracker.cc
@@ -10,7 +10,11 @@
 const int kNumFramesToLock = 2;
 }  // namespace
 
-DecodedImageTracker::DecodedImageTracker() = default;
+DecodedImageTracker::DecodedImageTracker(ImageController* controller)
+    : image_controller_(controller) {
+  DCHECK(image_controller_);
+}
+
 DecodedImageTracker::~DecodedImageTracker() {
   for (auto& pair : locked_images_)
     image_controller_->UnlockImageDecode(pair.first);
diff --git a/cc/tiles/decoded_image_tracker.h b/cc/tiles/decoded_image_tracker.h
index 4b9417f..4321a02 100644
--- a/cc/tiles/decoded_image_tracker.h
+++ b/cc/tiles/decoded_image_tracker.h
@@ -24,7 +24,7 @@
 // are silently ignored.
 class CC_EXPORT DecodedImageTracker {
  public:
-  DecodedImageTracker();
+  explicit DecodedImageTracker(ImageController* controller);
   ~DecodedImageTracker();
 
   // Request that the given image be decoded. This issues a callback upon
@@ -36,18 +36,13 @@
   void NotifyFrameFinished();
 
  private:
-  friend class TileManager;
   friend class DecodedImageTrackerTest;
 
-  void set_image_controller(ImageController* controller) {
-    image_controller_ = controller;
-  }
-
   void ImageDecodeFinished(const base::Callback<void(bool)>& callback,
                            ImageController::ImageDecodeRequestId id,
                            ImageController::ImageDecodeResult result);
 
-  ImageController* image_controller_ = nullptr;
+  ImageController* image_controller_;
   std::vector<std::pair<ImageController::ImageDecodeRequestId, int>>
       locked_images_;
 
diff --git a/cc/tiles/decoded_image_tracker_unittest.cc b/cc/tiles/decoded_image_tracker_unittest.cc
index f5bb5a37..365f93b6 100644
--- a/cc/tiles/decoded_image_tracker_unittest.cc
+++ b/cc/tiles/decoded_image_tracker_unittest.cc
@@ -63,9 +63,7 @@
 
 class DecodedImageTrackerTest : public testing::Test {
  public:
-  void SetUp() override {
-    decoded_image_tracker_.set_image_controller(image_controller());
-  }
+  DecodedImageTrackerTest() : decoded_image_tracker_(&image_controller_) {}
 
   TestImageController* image_controller() { return &image_controller_; }
   DecodedImageTracker* decoded_image_tracker() {
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc
index f9d395d37..dfebdf4 100644
--- a/cc/tiles/tile_manager.cc
+++ b/cc/tiles/tile_manager.cc
@@ -359,6 +359,7 @@
       did_oom_on_last_assign_(false),
       image_controller_(origin_task_runner,
                         std::move(image_worker_task_runner)),
+      decoded_image_tracker_(&image_controller_),
       checker_image_tracker_(&image_controller_,
                              this,
                              tile_manager_settings_.enable_checker_imaging,
@@ -1283,13 +1284,6 @@
   }
 }
 
-void TileManager::SetDecodedImageTracker(
-    DecodedImageTracker* decoded_image_tracker) {
-  // TODO(vmpstr): If the tile manager needs to request out-of-raster decodes,
-  // it should retain and use |decoded_image_tracker| here.
-  decoded_image_tracker->set_image_controller(&image_controller_);
-}
-
 std::unique_ptr<Tile> TileManager::CreateTile(const Tile::CreateInfo& info,
                                               int layer_id,
                                               int source_frame_number,
diff --git a/cc/tiles/tile_manager.h b/cc/tiles/tile_manager.h
index c0359a36..2b79c93 100644
--- a/cc/tiles/tile_manager.h
+++ b/cc/tiles/tile_manager.h
@@ -260,8 +260,6 @@
                              ResourcePool::InUsePoolResource resource,
                              bool was_canceled);
 
-  void SetDecodedImageTracker(DecodedImageTracker* decoded_image_tracker);
-
   // CheckerImageTrackerClient implementation.
   void NeedsInvalidationForCheckerImagedTiles() override;
 
@@ -278,6 +276,9 @@
   CheckerImageTracker& checker_image_tracker() {
     return checker_image_tracker_;
   }
+  DecodedImageTracker& decoded_image_tracker() {
+    return decoded_image_tracker_;
+  }
 
   const std::vector<DrawImage>& decode_tasks_for_testing(Tile::Id id) {
     return scheduled_draw_images_[id];
@@ -414,6 +415,7 @@
   bool did_oom_on_last_assign_;
 
   ImageController image_controller_;
+  DecodedImageTracker decoded_image_tracker_;
   CheckerImageTracker checker_image_tracker_;
 
   RasterTaskCompletionStats raster_task_completion_stats_;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 96a6134..fcf2dd11 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -341,8 +341,6 @@
   browser_controls_offset_manager_ = BrowserControlsOffsetManager::Create(
       this, settings.top_controls_show_threshold,
       settings.top_controls_hide_threshold);
-
-  tile_manager_.SetDecodedImageTracker(&decoded_image_tracker_);
 }
 
 LayerTreeHostImpl::~LayerTreeHostImpl() {
@@ -2329,7 +2327,7 @@
 void LayerTreeHostImpl::DidFinishImplFrame() {
   impl_thread_phase_ = ImplThreadPhase::IDLE;
   current_begin_frame_tracker_.Finish();
-  decoded_image_tracker_.NotifyFrameFinished();
+  tile_manager_.decoded_image_tracker().NotifyFrameFinished();
 }
 
 void LayerTreeHostImpl::DidNotProduceFrame(const viz::BeginFrameAck& ack) {
@@ -2807,7 +2805,7 @@
                image.GetKeyForFrame(image.frame_index()).ToString());
   // Optimistically specify the current raster color space, since we assume that
   // it won't change.
-  decoded_image_tracker_.QueueImageDecode(
+  tile_manager_.decoded_image_tracker().QueueImageDecode(
       image, GetRasterColorSpace().color_space,
       base::Bind(&LayerTreeHostImpl::ImageDecodeFinished,
                  base::Unretained(this), request_id));
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 1dff5795..483d743 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -924,7 +924,6 @@
 
   const bool is_synchronous_single_threaded_;
   TileManager tile_manager_;
-  DecodedImageTracker decoded_image_tracker_;
 
   gfx::Vector2dF accumulated_root_overscroll_;
 
diff --git a/chrome/VERSION b/chrome/VERSION
index a2ee50e..cfaf4466 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=68
 MINOR=0
-BUILD=3432
+BUILD=3433
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 72621a5..7b7ceed8 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -858,6 +858,7 @@
     ":chrome_jni_for_test_registration($default_toolchain)",
     "//base/test:test_support",
     "//components/heap_profiling:test_support",
+    "//content/public/test/android:content_native_test_support",
   ]
 }
 
@@ -1123,6 +1124,7 @@
   }
   deps = [
     "//components/heap_profiling:heap_profiling_java_test_support",
+    "//content/public/test/android:content_java_test_support",
   ]
 }
 
diff --git a/chrome/android/java/DEPS b/chrome/android/java/DEPS
index 259e4e3..7c71480c 100644
--- a/chrome/android/java/DEPS
+++ b/chrome/android/java/DEPS
@@ -26,7 +26,6 @@
   "!content/public/android/java/src/org/chromium/content/browser/DeviceUtils.java",
   "!content/public/android/java/src/org/chromium/content/browser/MotionEventSynthesizer.java",
   "!content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProvider.java",
-  "!content/public/android/java/src/org/chromium/content/browser/SpeechRecognition.java",
   "!content/public/android/java/src/org/chromium/content/common/ContentSwitches.java",
 
   "+device/gamepad/android/java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
index f92f090c..44b62ac 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
@@ -47,7 +47,7 @@
 import org.chromium.components.crash.browser.CrashDumpManager;
 import org.chromium.content.browser.BrowserStartupController;
 import org.chromium.content.browser.DeviceUtils;
-import org.chromium.content.browser.SpeechRecognition;
+import org.chromium.content_public.browser.SpeechRecognition;
 import org.chromium.net.NetworkChangeNotifier;
 import org.chromium.policy.CombinedPolicyProvider;
 
diff --git a/chrome/android/javatests/DEPS b/chrome/android/javatests/DEPS
index 901f115..bc9cb0a 100644
--- a/chrome/android/javatests/DEPS
+++ b/chrome/android/javatests/DEPS
@@ -24,7 +24,6 @@
   "+content/public/android/java/src/org/chromium/content_public",
   "!content/public/android/java/src/org/chromium/content/browser/BindingManager.java",
   "!content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java",
-  "!content/public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java",
   "!content/public/android/java/src/org/chromium/content/common/ContentSwitches.java",
 
   "-content/public/android/javatests",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java
index 6435c86..494e0bf 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/BrandColorTest.java
@@ -34,7 +34,7 @@
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.util.DisableInTabbedMode;
-import org.chromium.content.browser.InterstitialPageDelegateAndroid;
+import org.chromium.content.browser.test.InterstitialPageDelegateAndroid;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.ui.test.util.UiRestriction;
@@ -249,10 +249,7 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                mActivityTestRule.getActivity()
-                        .getActivityTab()
-                        .getWebContents()
-                        .showInterstitialPage(brandColorUrl, delegate.getNative());
+                delegate.showInterstitialPage(brandColorUrl, mActivityTestRule.getWebContents());
             }
         });
         CriteriaHelper.pollUiThread(new Criteria() {
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 547979b..f74ac277 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-68.0.3431.0_rc-r2.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-68.0.3432.0_rc-r1.afdo.bz2
\ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index f34da02..7711bc2d 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -1365,8 +1365,8 @@
     <message name="IDS_SETTINGS_DOWNLOADS_SMB_SHARES_ADD_SHARE" desc="In SMB shares settings subpage, text for the link to add a new SMB share.">
       Add File Share
     </message>
-    <message name="IDS_SETTINGS_DOWNLOADS_ADD_SHARE_URL" desc="Title for the input that lets users specify the name of an SMB Url.">
-      File Share Url
+    <message name="IDS_SETTINGS_DOWNLOADS_ADD_SHARE_URL" desc="Title for the input that lets users specify the name of an SMB URL.">
+      File Share URL
     </message>
     <message name="IDS_SETTINGS_DOWNLOADS_ADD_SHARE_USERNAME" desc="Title for the input that lets users specify their username for an SMB share.">
       Username
@@ -1374,6 +1374,12 @@
     <message name="IDS_SETTINGS_DOWNLOADS_ADD_SHARE_PASSWORD" desc="Title for the input that lets users specify their password for an SMB Share.">
       Password
     </message>
+    <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_SUCCESS_MESSAGE" desc="The message shown when a new SMB share is successfully mounted.">
+      Share mounted successfully.
+    </message>
+    <message name="IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_ERROR_MESSAGE" desc="The message shown when mounting a new SMB share fails.">
+      Error mounting share. Check the file share URL and try again.
+    </message>
 
     <!-- Date/Time Page -->
     <message name="IDS_SETTINGS_DATE_TIME" desc="Name of the settings page which displays date and time preferences.">
diff --git a/chrome/browser/background_fetch/background_fetch_delegate_impl.cc b/chrome/browser/background_fetch/background_fetch_delegate_impl.cc
index 441c088..6b5a8e12 100644
--- a/chrome/browser/background_fetch/background_fetch_delegate_impl.cc
+++ b/chrome/browser/background_fetch/background_fetch_delegate_impl.cc
@@ -192,7 +192,6 @@
 
   JobDetails& job_details = job_details_iter->second;
   job_details.cancelled = true;
-  UpdateOfflineItemAndUpdateObservers(&job_details);
 
   for (const auto& download_guid : job_details.current_download_guids) {
     download_service_->CancelDownload(download_guid);
@@ -395,21 +394,10 @@
 
 void BackgroundFetchDelegateImpl::CancelDownload(
     const offline_items_collection::ContentId& id) {
-  auto job_details_iter = job_details_map_.find(id.id);
-  if (job_details_iter == job_details_map_.end())
-    return;
-
-  JobDetails& job_details = job_details_iter->second;
-
-  for (auto& download_guid : job_details.current_download_guids) {
-    download_service_->CancelDownload(download_guid);
-    download_job_unique_id_map_.erase(download_guid);
-  }
+  Abort(id.id);
 
   if (client())
     client()->OnJobCancelled(id.id);
-
-  job_details_map_.erase(job_details_iter);
 }
 
 void BackgroundFetchDelegateImpl::PauseDownload(
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 1570c66..20a8ed0 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1573,6 +1573,8 @@
     "smb_client/discovery/network_scanner.h",
     "smb_client/smb_constants.cc",
     "smb_client/smb_constants.h",
+    "smb_client/smb_errors.cc",
+    "smb_client/smb_errors.h",
     "smb_client/smb_file_system.cc",
     "smb_client/smb_file_system.h",
     "smb_client/smb_file_system_id.cc",
@@ -2086,6 +2088,7 @@
     "smb_client/discovery/in_memory_host_locator_unittest.cc",
     "smb_client/discovery/mdns_host_locator_unittest.cc",
     "smb_client/discovery/network_scanner_unittest.cc",
+    "smb_client/smb_errors_unittest.cc",
     "smb_client/smb_file_system_id_test.cc",
     "smb_client/smb_service_helper_unittest.cc",
     "smb_client/smb_service_unittest.cc",
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index 5edfce0..4baebb7 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -88,6 +88,10 @@
 
 // FileManager browser test class for tests that rely on deprecated event
 // dispatch that send tests.
+// TODO(noel): get rid of this class, move what it needs into the
+// FileManagerBrowserTest class.  Add a |group_name| to TestCase to allow
+// detection of tests that need legacy event dispatch by loooking at their
+// group name.
 class FileManagerBrowserTestWithLegacyEventDispatch
     : public FileManagerBrowserTest {
  public:
@@ -108,18 +112,16 @@
   StartTest();
 }
 
-// Unlike TEST/TEST_F, which are macros that expand to further macros,
-// INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that
-// stringizes the arguments. As a result, macros passed as parameters (such as
-// prefix or test_case_name) will not be expanded by the preprocessor. To work
-// around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the
-// pre-processor will expand macros such as MAYBE_test_name before
-// instantiating the test.
-#define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
-  INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator)
+// INSTANTIATE_TEST_CASE_P expands to code that stringizes the arguments. Thus
+// macro parameters such as |prefix| and |test_class| won't be expanded by the
+// macro pre-processor. To work around this, indirect INSTANTIATE_TEST_CASE_P,
+// as WRAPPED_INSTANTIATE_TEST_CASE_P here, so the pre-processor expand macros
+// like MAYBE_prefix used to disable tests.
+#define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_class, generator) \
+  INSTANTIATE_TEST_CASE_P(prefix, test_class, generator)
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    FileDisplay,
+    FileDisplay,  /* file_display.js */
     FileManagerBrowserTest,
     ::testing::Values(TestCase("fileDisplayDownloads"),
                       TestCase("fileDisplayDownloads").InGuestMode(),
@@ -130,7 +132,7 @@
                       TestCase("fileSearchNotFound")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    OpenVideoFiles,
+    OpenVideoFiles,  /* open_video_files.js */
     FileManagerBrowserTest,
     ::testing::Values(TestCase("videoOpenDownloads").InGuestMode(),
                       TestCase("videoOpenDownloads"),
@@ -143,7 +145,7 @@
 #define MAYBE_OpenAudioFiles OpenAudioFiles
 #endif
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    MAYBE_OpenAudioFiles,
+    MAYBE_OpenAudioFiles, /* open_audio_files.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("audioOpenDownloads").InGuestMode(),
@@ -164,14 +166,14 @@
 #define MAYBE_OpenImageFiles OpenImageFiles
 #endif
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    MAYBE_OpenImageFiles,
+    MAYBE_OpenImageFiles, /* open_image_files.js */
     FileManagerBrowserTest,
     ::testing::Values(TestCase("imageOpenDownloads").InGuestMode(),
                       TestCase("imageOpenDownloads"),
                       TestCase("imageOpenDrive")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    CreateNewFolder,
+    CreateNewFolder, /* create_new_folder.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("selectCreateFolderDownloads"),
@@ -180,7 +182,7 @@
         TestCase("createFolderDrive")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    KeyboardOperations,
+    KeyboardOperations, /* keyboard_operations.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("keyboardDeleteDownloads").InGuestMode(),
@@ -197,20 +199,20 @@
         TestCase("renameNewFolderDrive")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    Delete,
+    Delete, /* delete.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("deleteMenuItemNoEntrySelected"),
         TestCase("deleteEntryWithToolbar")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    QuickView,
+    QuickView, /* quick_view.js */
     FileManagerBrowserTest,
     ::testing::Values(TestCase("openQuickView"),
                       TestCase("closeQuickView")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    DirectoryTreeContextMenu,
+    DirectoryTreeContextMenu, /* directory_tree_context_menu.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("dirCopyWithContextMenu"),
@@ -240,7 +242,7 @@
         TestCase("dirCreateWithoutChangingCurrent")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    DriveSpecific,
+    DriveSpecific, /* drive_specific.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("driveOpenSidebarOffline"),
@@ -251,7 +253,7 @@
         TestCase("drivePressEnterToSearch")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    Transfer,
+    Transfer, /* transfer.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("transferFromDriveToDownloads"),
@@ -262,7 +264,7 @@
         TestCase("transferFromOfflineToDrive")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    RestorePrefs,
+    RestorePrefs, /* restore_prefs.js */
     FileManagerBrowserTest,
     ::testing::Values(TestCase("restoreSortColumn").InGuestMode(),
                       TestCase("restoreSortColumn"),
@@ -270,44 +272,44 @@
                       TestCase("restoreCurrentView")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    ShareDialog,
-    FileManagerBrowserTest,
-    ::testing::Values(TestCase("shareFile"),
-                      TestCase("shareDirectory")));
-
-WRAPPED_INSTANTIATE_TEST_CASE_P(
-    RestoreGeometry,
+    RestoreGeometry, /* restore_geometry.js */
     FileManagerBrowserTest,
     ::testing::Values(TestCase("restoreGeometry"),
                       TestCase("restoreGeometry").InGuestMode(),
                       TestCase("restoreGeometryMaximized")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    Traverse,
+    ShareDialog, /* share_dialog.js */
+    FileManagerBrowserTest,
+    ::testing::Values(TestCase("shareFile"),
+                      TestCase("shareDirectory")));
+
+WRAPPED_INSTANTIATE_TEST_CASE_P(
+    SuggestAppDialog, /* suggest_app_dialog.js */
+    FileManagerBrowserTest,
+    ::testing::Values(TestCase("suggestAppDialog")));
+
+WRAPPED_INSTANTIATE_TEST_CASE_P(
+    Traverse, /* traverse.js */
     FileManagerBrowserTest,
     ::testing::Values(TestCase("traverseDownloads").InGuestMode(),
                       TestCase("traverseDownloads"),
                       TestCase("traverseDrive")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    SuggestAppDialog,
-    FileManagerBrowserTest,
-    ::testing::Values(TestCase("suggestAppDialog")));
-
-WRAPPED_INSTANTIATE_TEST_CASE_P(
-    ExecuteDefaultTaskOnDownloads,
+    ExecuteDefaultTaskOnDownloads, /* tasks.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("executeDefaultTaskDownloads"),
         TestCase("executeDefaultTaskDownloads").InGuestMode()));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    ExecuteDefaultTaskOnDrive,
+    ExecuteDefaultTaskOnDrive, /* tasks.js */
     FileManagerBrowserTest,
     ::testing::Values(TestCase("executeDefaultTaskDrive")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    DefaultTaskDialog,
+    DefaultTaskDialog, /* tasks.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("defaultTaskDialogDownloads"),
@@ -315,49 +317,49 @@
         TestCase("defaultTaskDialogDrive")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    GenericTask,
+    GenericTask, /* tasks.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("genericTaskIsNotExecuted"),
         TestCase("genericTaskAndNonGenericTask")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    FolderShortcuts,
+    FolderShortcuts, /* folder_shortcuts.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("traverseFolderShortcuts"),
         TestCase("addRemoveFolderShortcuts")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    SortColumns,
+    SortColumns, /* sort_columns.js */
     FileManagerBrowserTest,
     ::testing::Values(TestCase("sortColumns"),
                       TestCase("sortColumns").InGuestMode()));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    TabIndex,
+    TabIndex, /* tab_index.js */
     FileManagerBrowserTestWithLegacyEventDispatch,
     ::testing::Values(
         TestCase("tabindexSearchBoxFocus")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    TabindexFocus,
+    TabindexFocus, /* tab_index.js */
     FileManagerBrowserTestWithLegacyEventDispatch,
     ::testing::Values(TestCase("tabindexFocus")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    TabindexFocusDownloads,
+    TabindexFocusDownloads, /* tab_index.js */
     FileManagerBrowserTestWithLegacyEventDispatch,
     ::testing::Values(TestCase("tabindexFocusDownloads"),
                       TestCase("tabindexFocusDownloads").InGuestMode()));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    TabindexFocusDirectorySelected,
+    TabindexFocusDirectorySelected, /* tab_index.js */
     FileManagerBrowserTestWithLegacyEventDispatch,
     ::testing::Values(TestCase("tabindexFocusDirectorySelected")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    TabindexOpenDialog,
+    TabindexOpenDialog, /* tab_index.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("tabindexOpenDialogDrive"),
@@ -365,7 +367,7 @@
         TestCase("tabindexOpenDialogDownloads").InGuestMode()));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    TabindexSaveFileDialog,
+    TabindexSaveFileDialog, /* tab_index.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("tabindexSaveFileDialogDrive"),
@@ -373,7 +375,7 @@
         TestCase("tabindexSaveFileDialogDownloads").InGuestMode()));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    OpenFileDialog,
+    OpenFileDialog, /* file_dialog.js */
     FileManagerBrowserTest,
     ::testing::Values(TestCase("openFileDialogDownloads"),
                       TestCase("openFileDialogDownloads").InGuestMode(),
@@ -384,7 +386,7 @@
 
 // Test does too much? Flaky on all bots: http://crbug.com/500966
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    DISABLED_CopyBetweenWindows,
+    DISABLED_CopyBetweenWindows, /* copy_between_windows.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("copyBetweenWindowsLocalToDrive"),
@@ -395,14 +397,14 @@
         TestCase("copyBetweenWindowsUsbToLocal")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    ShowGridView,
+    ShowGridView, /* grid_view.js */
     FileManagerBrowserTest,
     ::testing::Values(TestCase("showGridViewDownloads"),
                       TestCase("showGridViewDownloads").InGuestMode(),
                       TestCase("showGridViewDrive")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    Providers,
+    Providers, /* providers.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("requestMount"),
@@ -411,7 +413,7 @@
         TestCase("requestMountSourceFile")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
-    GearMenu,
+    GearMenu, /* gear_menu.js */
     FileManagerBrowserTest,
     ::testing::Values(
         TestCase("showHiddenFilesDownloads"),
diff --git a/chrome/browser/chromeos/smb_client/smb_errors.cc b/chrome/browser/chromeos/smb_client/smb_errors.cc
new file mode 100644
index 0000000..73f7397
--- /dev/null
+++ b/chrome/browser/chromeos/smb_client/smb_errors.cc
@@ -0,0 +1,61 @@
+// 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/chromeos/smb_client/smb_errors.h"
+
+namespace chromeos {
+namespace smb_client {
+
+base::File::Error TranslateToFileError(smbprovider::ErrorType error) {
+  DCHECK_NE(smbprovider::ERROR_NONE, error);
+
+  switch (error) {
+    case smbprovider::ERROR_OK:
+      return base::File::FILE_OK;
+    case smbprovider::ERROR_FAILED:
+      return base::File::FILE_ERROR_FAILED;
+    case smbprovider::ERROR_IN_USE:
+      return base::File::FILE_ERROR_IN_USE;
+    case smbprovider::ERROR_EXISTS:
+      return base::File::FILE_ERROR_EXISTS;
+    case smbprovider::ERROR_NOT_FOUND:
+      return base::File::FILE_ERROR_NOT_FOUND;
+    case smbprovider::ERROR_ACCESS_DENIED:
+      return base::File::FILE_ERROR_ACCESS_DENIED;
+    case smbprovider::ERROR_TOO_MANY_OPENED:
+      return base::File::FILE_ERROR_TOO_MANY_OPENED;
+    case smbprovider::ERROR_NO_MEMORY:
+      return base::File::FILE_ERROR_NO_MEMORY;
+    case smbprovider::ERROR_NO_SPACE:
+      return base::File::FILE_ERROR_NO_SPACE;
+    case smbprovider::ERROR_NOT_A_DIRECTORY:
+      return base::File::FILE_ERROR_NOT_A_DIRECTORY;
+    case smbprovider::ERROR_INVALID_OPERATION:
+      return base::File::FILE_ERROR_INVALID_OPERATION;
+    case smbprovider::ERROR_SECURITY:
+      return base::File::FILE_ERROR_SECURITY;
+    case smbprovider::ERROR_ABORT:
+      return base::File::FILE_ERROR_ABORT;
+    case smbprovider::ERROR_NOT_A_FILE:
+      return base::File::FILE_ERROR_NOT_A_FILE;
+    case smbprovider::ERROR_NOT_EMPTY:
+      return base::File::FILE_ERROR_NOT_EMPTY;
+    case smbprovider::ERROR_INVALID_URL:
+      return base::File::FILE_ERROR_INVALID_URL;
+    case smbprovider::ERROR_IO:
+      return base::File::FILE_ERROR_IO;
+    case smbprovider::ERROR_DBUS_PARSE_FAILED:
+      // DBUS_PARSE_FAILED maps to generic ERROR_FAILED
+      LOG(ERROR) << "DBUS PARSE FAILED";
+      return base::File::FILE_ERROR_FAILED;
+    default:
+      break;
+  }
+
+  NOTREACHED();
+  return base::File::FILE_ERROR_FAILED;
+}
+
+}  // namespace smb_client
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/smb_client/smb_errors.h b/chrome/browser/chromeos/smb_client/smb_errors.h
new file mode 100644
index 0000000..cc7baa4
--- /dev/null
+++ b/chrome/browser/chromeos/smb_client/smb_errors.h
@@ -0,0 +1,22 @@
+// 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_CHROMEOS_SMB_CLIENT_SMB_ERRORS_H_
+#define CHROME_BROWSER_CHROMEOS_SMB_CLIENT_SMB_ERRORS_H_
+
+#include "base/files/file.h"
+#include "chromeos/dbus/smb_provider_client.h"
+
+namespace chromeos {
+namespace smb_client {
+
+// Translates an smbprovider::ErrorType to a base::File::Error. Since
+// smbprovider::ErrorType is a superset of base::File::Error, errors that do not
+// map directly are logged and mapped to the generic failed error.
+base::File::Error TranslateToFileError(smbprovider::ErrorType error);
+
+}  // namespace smb_client
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_SMB_CLIENT_SMB_ERRORS_H_
diff --git a/chrome/browser/chromeos/smb_client/smb_errors_unittest.cc b/chrome/browser/chromeos/smb_client/smb_errors_unittest.cc
new file mode 100644
index 0000000..22bf1c44a
--- /dev/null
+++ b/chrome/browser/chromeos/smb_client/smb_errors_unittest.cc
@@ -0,0 +1,63 @@
+// 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/chromeos/smb_client/smb_errors.h"
+
+#include "base/files/file.h"
+#include "chromeos/dbus/smbprovider/directory_entry.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace smb_client {
+
+class SmbErrorsTest : public ::testing::Test {
+ public:
+  SmbErrorsTest() = default;
+  ~SmbErrorsTest() override = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SmbErrorsTest);
+};
+
+TEST_F(SmbErrorsTest, SmbErrorToFileError) {
+  EXPECT_EQ(base::File::FILE_OK, TranslateToFileError(smbprovider::ERROR_OK));
+  EXPECT_EQ(base::File::FILE_ERROR_FAILED,
+            TranslateToFileError(smbprovider::ERROR_FAILED));
+  EXPECT_EQ(base::File::FILE_ERROR_IN_USE,
+            TranslateToFileError(smbprovider::ERROR_IN_USE));
+  EXPECT_EQ(base::File::FILE_ERROR_EXISTS,
+            TranslateToFileError(smbprovider::ERROR_EXISTS));
+  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
+            TranslateToFileError(smbprovider::ERROR_NOT_FOUND));
+  EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED,
+            TranslateToFileError(smbprovider::ERROR_ACCESS_DENIED));
+  EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED,
+            TranslateToFileError(smbprovider::ERROR_TOO_MANY_OPENED));
+  EXPECT_EQ(base::File::FILE_ERROR_NO_MEMORY,
+            TranslateToFileError(smbprovider::ERROR_NO_MEMORY));
+  EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE,
+            TranslateToFileError(smbprovider::ERROR_NO_SPACE));
+  EXPECT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY,
+            TranslateToFileError(smbprovider::ERROR_NOT_A_DIRECTORY));
+  EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION,
+            TranslateToFileError(smbprovider::ERROR_INVALID_OPERATION));
+  EXPECT_EQ(base::File::FILE_ERROR_SECURITY,
+            TranslateToFileError(smbprovider::ERROR_SECURITY));
+  EXPECT_EQ(base::File::FILE_ERROR_ABORT,
+            TranslateToFileError(smbprovider::ERROR_ABORT));
+  EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE,
+            TranslateToFileError(smbprovider::ERROR_NOT_A_FILE));
+  EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY,
+            TranslateToFileError(smbprovider::ERROR_NOT_EMPTY));
+  EXPECT_EQ(base::File::FILE_ERROR_INVALID_URL,
+            TranslateToFileError(smbprovider::ERROR_INVALID_URL));
+  EXPECT_EQ(base::File::FILE_ERROR_IO,
+            TranslateToFileError(smbprovider::ERROR_IO));
+
+  EXPECT_EQ(base::File::FILE_ERROR_FAILED,
+            TranslateToFileError(smbprovider::ERROR_DBUS_PARSE_FAILED));
+}
+
+}  // namespace smb_client
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/smb_client/smb_file_system.cc b/chrome/browser/chromeos/smb_client/smb_file_system.cc
index 06dd005..47717ee4 100644
--- a/chrome/browser/chromeos/smb_client/smb_file_system.cc
+++ b/chrome/browser/chromeos/smb_client/smb_file_system.cc
@@ -11,6 +11,7 @@
 #include "base/posix/eintr_wrapper.h"
 #include "base/task_scheduler/post_task.h"
 #include "chrome/browser/chromeos/file_system_provider/service.h"
+#include "chrome/browser/chromeos/smb_client/smb_errors.h"
 #include "chrome/browser/chromeos/smb_client/smb_file_system_id.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/smb_provider_client.h"
@@ -91,57 +92,6 @@
 
 SmbFileSystem::~SmbFileSystem() {}
 
-// static
-base::File::Error SmbFileSystem::TranslateError(smbprovider::ErrorType error) {
-  DCHECK_NE(smbprovider::ERROR_NONE, error);
-
-  switch (error) {
-    case smbprovider::ERROR_OK:
-      return base::File::FILE_OK;
-    case smbprovider::ERROR_FAILED:
-      return base::File::FILE_ERROR_FAILED;
-    case smbprovider::ERROR_IN_USE:
-      return base::File::FILE_ERROR_IN_USE;
-    case smbprovider::ERROR_EXISTS:
-      return base::File::FILE_ERROR_EXISTS;
-    case smbprovider::ERROR_NOT_FOUND:
-      return base::File::FILE_ERROR_NOT_FOUND;
-    case smbprovider::ERROR_ACCESS_DENIED:
-      return base::File::FILE_ERROR_ACCESS_DENIED;
-    case smbprovider::ERROR_TOO_MANY_OPENED:
-      return base::File::FILE_ERROR_TOO_MANY_OPENED;
-    case smbprovider::ERROR_NO_MEMORY:
-      return base::File::FILE_ERROR_NO_MEMORY;
-    case smbprovider::ERROR_NO_SPACE:
-      return base::File::FILE_ERROR_NO_SPACE;
-    case smbprovider::ERROR_NOT_A_DIRECTORY:
-      return base::File::FILE_ERROR_NOT_A_DIRECTORY;
-    case smbprovider::ERROR_INVALID_OPERATION:
-      return base::File::FILE_ERROR_INVALID_OPERATION;
-    case smbprovider::ERROR_SECURITY:
-      return base::File::FILE_ERROR_SECURITY;
-    case smbprovider::ERROR_ABORT:
-      return base::File::FILE_ERROR_ABORT;
-    case smbprovider::ERROR_NOT_A_FILE:
-      return base::File::FILE_ERROR_NOT_A_FILE;
-    case smbprovider::ERROR_NOT_EMPTY:
-      return base::File::FILE_ERROR_NOT_EMPTY;
-    case smbprovider::ERROR_INVALID_URL:
-      return base::File::FILE_ERROR_INVALID_URL;
-    case smbprovider::ERROR_IO:
-      return base::File::FILE_ERROR_IO;
-    case smbprovider::ERROR_DBUS_PARSE_FAILED:
-      // DBUS_PARSE_FAILED maps to generic ERROR_FAILED
-      LOG(ERROR) << "DBUS PARSE FAILED";
-      return base::File::FILE_ERROR_FAILED;
-    default:
-      break;
-  }
-
-  NOTREACHED();
-  return base::File::FILE_ERROR_FAILED;
-}
-
 int32_t SmbFileSystem::GetMountId() const {
   return GetMountIdFromFileSystemId(file_system_info_.file_system_id());
 }
@@ -197,7 +147,7 @@
     storage::AsyncFileUtil::StatusCallback callback,
     smbprovider::ErrorType error) {
   task_queue_.TaskFinished();
-  base::File::Error result = TranslateError(error);
+  base::File::Error result = TranslateToFileError(error);
   if (result == base::File::FILE_OK) {
     result =
         RunUnmountCallback(file_system_info_.file_system_id(),
@@ -270,7 +220,7 @@
     smbprovider::ErrorType error,
     int32_t file_id) const {
   task_queue_.TaskFinished();
-  callback.Run(file_id, TranslateError(error));
+  callback.Run(file_id, TranslateToFileError(error));
 }
 
 AbortCallback SmbFileSystem::CloseFile(
@@ -529,7 +479,7 @@
     }
   }
 
-  callback.Run(TranslateError(error), entry_list, false /* has_more */);
+  callback.Run(TranslateToFileError(error), entry_list, false /* has_more */);
 }
 
 void SmbFileSystem::HandleGetDeleteListCallback(
@@ -541,7 +491,7 @@
   if (delete_list.entries_size() == 0) {
     // There are no entries to delete.
     DCHECK_NE(smbprovider::ERROR_OK, list_error);
-    std::move(callback).Run(TranslateError(list_error));
+    std::move(callback).Run(TranslateToFileError(list_error));
     return;
   }
 
@@ -572,7 +522,7 @@
     if (list_error != smbprovider::ERROR_OK) {
       delete_error = list_error;
     }
-    std::move(callback).Run(TranslateError(delete_error));
+    std::move(callback).Run(TranslateToFileError(delete_error));
   }
 }
 
@@ -583,7 +533,7 @@
     const smbprovider::DirectoryEntryProto& entry) const {
   task_queue_.TaskFinished();
   if (error != smbprovider::ERROR_OK) {
-    std::move(callback).Run(nullptr, TranslateError(error));
+    std::move(callback).Run(nullptr, TranslateToFileError(error));
     return;
   }
   std::unique_ptr<file_system_provider::EntryMetadata> metadata =
@@ -626,7 +576,7 @@
 
   if (error != smbprovider::ERROR_OK) {
     callback.Run(0 /* chunk_length */, false /* has_more */,
-                 TranslateError(error));
+                 TranslateToFileError(error));
     return;
   }
 
@@ -655,7 +605,7 @@
     smbprovider::ErrorType error) const {
   task_queue_.TaskFinished();
 
-  std::move(callback).Run(TranslateError(error));
+  std::move(callback).Run(TranslateToFileError(error));
 }
 
 void SmbFileSystem::InitTempFileManager() {
diff --git a/chrome/browser/chromeos/smb_client/smb_file_system.h b/chrome/browser/chromeos/smb_client/smb_file_system.h
index 2f8dea6..2e4e3b4 100644
--- a/chrome/browser/chromeos/smb_client/smb_file_system.h
+++ b/chrome/browser/chromeos/smb_client/smb_file_system.h
@@ -54,8 +54,6 @@
       UnmountCallback unmount_callback);
   ~SmbFileSystem() override;
 
-  static base::File::Error TranslateError(smbprovider::ErrorType);
-
   // ProvidedFileSystemInterface overrides.
   file_system_provider::AbortCallback RequestUnmount(
       storage::AsyncFileUtil::StatusCallback callback) override;
diff --git a/chrome/browser/chromeos/smb_client/smb_service.cc b/chrome/browser/chromeos/smb_client/smb_service.cc
index d6d19a63..66d42842 100644
--- a/chrome/browser/chromeos/smb_client/smb_service.cc
+++ b/chrome/browser/chromeos/smb_client/smb_service.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/smb_client/smb_constants.h"
+#include "chrome/browser/chromeos/smb_client/smb_errors.h"
 #include "chrome/browser/chromeos/smb_client/smb_file_system.h"
 #include "chrome/browser/chromeos/smb_client/smb_file_system_id.h"
 #include "chrome/browser/chromeos/smb_client/smb_provider.h"
@@ -134,7 +135,7 @@
     smbprovider::ErrorType error,
     int32_t mount_id) {
   if (error != smbprovider::ERROR_OK) {
-    std::move(callback).Run(SmbFileSystem::TranslateError(error));
+    std::move(callback).Run(TranslateToFileError(error));
     return;
   }
 
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc
index 849602a..a163e77 100644
--- a/chrome/browser/extensions/api/debugger/debugger_api.cc
+++ b/chrome/browser/extensions/api/debugger/debugger_api.cc
@@ -368,7 +368,7 @@
     if (result && web_contents) {
       // TODO(rdevlin.cronin) This should definitely be GetLastCommittedURL().
       GURL url = web_contents->GetVisibleURL();
-      if (PermissionsData::IsRestrictedUrl(url, extension(), &error_))
+      if (extension()->permissions_data()->IsRestrictedUrl(url, &error_))
         return false;
       agent_host_ = DevToolsAgentHost::GetOrCreateFor(web_contents);
     }
@@ -377,9 +377,8 @@
         ProcessManager::Get(GetProfile())
             ->GetBackgroundHostForExtension(*debuggee_.extension_id);
     if (extension_host) {
-      if (PermissionsData::IsRestrictedUrl(extension_host->GetURL(),
-                                           extension(),
-                                           &error_)) {
+      if (extension()->permissions_data()->IsRestrictedUrl(
+              extension_host->GetURL(), &error_)) {
         return false;
       }
       agent_host_ =
@@ -388,9 +387,8 @@
   } else if (debuggee_.target_id) {
     agent_host_ = DevToolsAgentHost::GetForId(*debuggee_.target_id);
     if (agent_host_.get()) {
-      if (PermissionsData::IsRestrictedUrl(agent_host_->GetURL(),
-                                           extension(),
-                                           &error_)) {
+      if (extension()->permissions_data()->IsRestrictedUrl(
+              agent_host_->GetURL(), &error_)) {
         agent_host_ = nullptr;
         return false;
       }
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
index 0897e22..69f4f6de 100644
--- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
+++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
@@ -1485,17 +1485,11 @@
         {"block_websocket.com", 7, {"websocket"}, {}},
         {"block_image_and_stylesheet.com", 8, {"image", "stylesheet"}, {}},
         {"block_subframe_and_xhr.com", 11, {"sub_frame", "xmlhttprequest"}, {}},
-        // With renderer side navigation, the main frame origin serves as the
-        // initiator for main frame page loads. Hence to ensure that the main
-        // frame page load is not blocked, also exclude the "other" resource
-        // type, which is used for main frame requests currently.
-        // TODO(crbug.com/696822): Change "other" to "main_frame" once it is
-        // implemented.
-        {"block_all.com", 9, {}, {"other"}},
+        {"block_all.com", 9, {}, {}},
         {"block_all_but_xhr_and_script.com",
          10,
          {},
-         {"xmlhttprequest", "script", "other"}},
+         {"xmlhttprequest", "script"}},
     };
 
     std::vector<TestRule> rules;
diff --git a/chrome/browser/extensions/api/history/history_api.cc b/chrome/browser/extensions/api/history/history_api.cc
index c83fcd8..9e23c409 100644
--- a/chrome/browser/extensions/api/history/history_api.cc
+++ b/chrome/browser/extensions/api/history/history_api.cc
@@ -149,16 +149,14 @@
                 api::history::OnVisited::kEventName, std::move(args));
 }
 
-void HistoryEventRouter::OnURLsDeleted(history::HistoryService* history_service,
-                                       bool all_history,
-                                       bool expired,
-                                       const history::URLRows& deleted_rows,
-                                       const std::set<GURL>& favicon_urls) {
+void HistoryEventRouter::OnURLsDeleted(
+    history::HistoryService* history_service,
+    const history::DeletionInfo& deletion_info) {
   OnVisitRemoved::Removed removed;
-  removed.all_history = all_history;
+  removed.all_history = deletion_info.IsAllHistory();
 
   std::vector<std::string>* urls = new std::vector<std::string>();
-  for (const auto& row : deleted_rows)
+  for (const auto& row : deletion_info.deleted_rows())
     urls->push_back(row.url().spec());
   removed.urls.reset(urls);
 
diff --git a/chrome/browser/extensions/api/history/history_api.h b/chrome/browser/extensions/api/history/history_api.h
index f6b74f7..36d12ac 100644
--- a/chrome/browser/extensions/api/history/history_api.h
+++ b/chrome/browser/extensions/api/history/history_api.h
@@ -46,10 +46,7 @@
                     const history::RedirectList& redirects,
                     base::Time visit_time) override;
   void OnURLsDeleted(history::HistoryService* history_service,
-                     bool all_history,
-                     bool expired,
-                     const history::URLRows& deleted_rows,
-                     const std::set<GURL>& favicon_urls) override;
+                     const history::DeletionInfo& deletion_info) override;
 
   void DispatchEvent(Profile* profile,
                      events::HistogramValue histogram_value,
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index 8b849bf..e58532c 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -1367,8 +1367,9 @@
 
   if (params->update_properties.auto_discardable.get()) {
     bool state = *params->update_properties.auto_discardable;
-    g_browser_process->GetTabManager()->SetTabAutoDiscardableState(contents,
-                                                                   state);
+    resource_coordinator::TabLifecycleUnitExternal::FromWebContents(
+        web_contents_)
+        ->SetAutoDiscardable(state);
   }
 
   if (!is_async) {
@@ -2089,7 +2090,7 @@
     return false;
 
   GURL url(web_contents->GetVisibleURL());
-  if (PermissionsData::IsRestrictedUrl(url, extension(), &error_))
+  if (extension()->permissions_data()->IsRestrictedUrl(url, &error_))
     return false;
 
   ZoomController* zoom_controller =
@@ -2141,7 +2142,7 @@
     return false;
 
   GURL url(web_contents->GetVisibleURL());
-  if (PermissionsData::IsRestrictedUrl(url, extension(), &error_))
+  if (extension()->permissions_data()->IsRestrictedUrl(url, &error_))
     return false;
 
   // "per-origin" scope is only available in "automatic" mode.
diff --git a/chrome/browser/extensions/extension_sync_data.cc b/chrome/browser/extensions/extension_sync_data.cc
index 2b24159..3d43bab2 100644
--- a/chrome/browser/extensions/extension_sync_data.cc
+++ b/chrome/browser/extensions/extension_sync_data.cc
@@ -232,6 +232,7 @@
   for (const auto& linked_icon : linked_icons_) {
     sync_pb::LinkedAppIconInfo* linked_app_icon_info =
         specifics->add_linked_app_icons();
+    DCHECK(linked_icon.url.is_valid());
     linked_app_icon_info->set_url(linked_icon.url.spec());
     linked_app_icon_info->set_size(linked_icon.size);
   }
diff --git a/chrome/browser/metrics/chromeos_metrics_provider.cc b/chrome/browser/metrics/chromeos_metrics_provider.cc
index 4d092f3..65ee42a 100644
--- a/chrome/browser/metrics/chromeos_metrics_provider.cc
+++ b/chrome/browser/metrics/chromeos_metrics_provider.cc
@@ -89,17 +89,11 @@
                                      base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Called on a background thread to load hardware class information.
-std::string GetHardwareClassOnBackgroundThread() {
-  // If short hardware class feature is enabled, the hardware class should be
-  // getting set synchronously, so this shouldn't be getting called.
-  // TODO(asvitkine): Get rid of the background thread logic after M67 goes to
-  // stable when the new logic has fully rolled out.
-  DCHECK(!base::FeatureList::IsEnabled(kUmaShortHWClass));
-
-  std::string hardware_class;
+std::string GetFullHardwareClassOnBackgroundThread() {
+  std::string full_hardware_class;
   chromeos::system::StatisticsProvider::GetInstance()->GetMachineStatistic(
-      "hardware_class", &hardware_class);
-  return hardware_class;
+      "hardware_class", &full_hardware_class);
+  return full_hardware_class;
 }
 
 }  // namespace
@@ -107,8 +101,7 @@
 ChromeOSMetricsProvider::ChromeOSMetricsProvider()
     : registered_user_count_at_log_initialization_(false),
       user_count_at_log_initialization_(0),
-      weak_ptr_factory_(this) {
-}
+      weak_ptr_factory_(this) {}
 
 ChromeOSMetricsProvider::~ChromeOSMetricsProvider() {
 }
@@ -182,8 +175,8 @@
       {base::MayBlock(), base::WithBaseSyncPrimitives(),
        base::TaskPriority::BACKGROUND,
        base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
-      base::BindOnce(&GetHardwareClassOnBackgroundThread),
-      base::BindOnce(&ChromeOSMetricsProvider::SetHardwareClass,
+      base::BindOnce(&GetFullHardwareClassOnBackgroundThread),
+      base::BindOnce(&ChromeOSMetricsProvider::SetFullHardwareClass,
                      weak_ptr_factory_.GetWeakPtr(), callback));
 }
 
@@ -202,6 +195,7 @@
   metrics::SystemProfileProto::Hardware* hardware =
       system_profile_proto->mutable_hardware();
   hardware->set_hardware_class(hardware_class_);
+  hardware->set_full_hardware_class(full_hardware_class_);
   display::Display::TouchSupport has_touch =
       ui::GetInternalDisplayTouchSupport();
   if (has_touch == display::Display::TouchSupport::AVAILABLE)
@@ -337,9 +331,14 @@
   callback.Run();
 }
 
-void ChromeOSMetricsProvider::SetHardwareClass(base::Closure callback,
-                                               std::string hardware_class) {
-  hardware_class_ = hardware_class;
+void ChromeOSMetricsProvider::SetFullHardwareClass(
+    base::Closure callback,
+    std::string full_hardware_class) {
+  if (!base::FeatureList::IsEnabled(kUmaShortHWClass)) {
+    DCHECK(hardware_class_.empty());
+    hardware_class_ = full_hardware_class;
+  }
+  full_hardware_class_ = full_hardware_class;
   callback.Run();
 }
 
diff --git a/chrome/browser/metrics/chromeos_metrics_provider.h b/chrome/browser/metrics/chromeos_metrics_provider.h
index 2550b32..4d22514 100644
--- a/chrome/browser/metrics/chromeos_metrics_provider.h
+++ b/chrome/browser/metrics/chromeos_metrics_provider.h
@@ -79,8 +79,9 @@
   void SetBluetoothAdapter(base::Closure callback,
                            scoped_refptr<device::BluetoothAdapter> adapter);
 
-  // Sets the hardware class, then calls the callback.
-  void SetHardwareClass(base::Closure callback, std::string hardware_class);
+  // Sets the full hardware class, then calls the callback.
+  void SetFullHardwareClass(base::Closure callback,
+                            std::string full_hardware_class);
 
   // Writes info about paired Bluetooth devices on this system.
   void WriteBluetoothProto(metrics::SystemProfileProto* system_profile_proto);
@@ -105,10 +106,13 @@
   // true.
   uint64_t user_count_at_log_initialization_;
 
-  // Hardware class (e.g., hardware qualification ID). This class identifies
-  // the configured system components such as CPU, WiFi adapter, etc.
+  // Short Hardware class. This value identifies the board of the hardware.
   std::string hardware_class_;
 
+  // Hardware class (e.g., hardware qualification ID). This value identifies
+  // the configured system components such as CPU, WiFi adapter, etc.
+  std::string full_hardware_class_;
+
   base::WeakPtrFactory<ChromeOSMetricsProvider> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ChromeOSMetricsProvider);
diff --git a/chrome/browser/permissions/PERMISSIONS_OWNERS b/chrome/browser/permissions/PERMISSIONS_OWNERS
index 778a059..3cf4dd0f8 100644
--- a/chrome/browser/permissions/PERMISSIONS_OWNERS
+++ b/chrome/browser/permissions/PERMISSIONS_OWNERS
@@ -1,6 +1,3 @@
-# PermissionContext subclasses require a Security UX review by one of the
-# following:
-
 benwells@chromium.org
 dominickn@chromium.org
 raymes@chromium.org
diff --git a/chrome/browser/predictors/loading_predictor_config.cc b/chrome/browser/predictors/loading_predictor_config.cc
index c9253363..08cb2fab 100644
--- a/chrome/browser/predictors/loading_predictor_config.cc
+++ b/chrome/browser/predictors/loading_predictor_config.cc
@@ -39,7 +39,15 @@
 const char kNoPreconnectMode[] = "no-preconnect";
 
 const base::Feature kSpeculativePreconnectFeature{
-    kSpeculativePreconnectFeatureName, base::FEATURE_DISABLED_BY_DEFAULT};
+  kSpeculativePreconnectFeatureName,
+// TODO(https://crbug.com/839886): Enable the feature on ChromeOS after disk I/O
+// flakes are fixed.
+#if defined(OS_CHROMEOS)
+      base::FEATURE_DISABLED_BY_DEFAULT
+#else
+      base::FEATURE_ENABLED_BY_DEFAULT
+#endif
+};
 
 bool MaybeEnableSpeculativePreconnect(LoadingPredictorConfig* config) {
   if (!base::FeatureList::IsEnabled(kSpeculativePreconnectFeature))
@@ -47,6 +55,9 @@
 
   std::string mode_value = base::GetFieldTrialParamValueByFeature(
       kSpeculativePreconnectFeature, kModeParamName);
+  if (mode_value.empty())
+    mode_value = kPreconnectMode;
+
   if (mode_value == kLearningMode) {
     if (config) {
       config->mode |= LoadingPredictorConfig::LEARNING;
diff --git a/chrome/browser/predictors/loading_predictor_config_unittest.cc b/chrome/browser/predictors/loading_predictor_config_unittest.cc
index bf9b5066..4e8b685a 100644
--- a/chrome/browser/predictors/loading_predictor_config_unittest.cc
+++ b/chrome/browser/predictors/loading_predictor_config_unittest.cc
@@ -6,6 +6,7 @@
 #include <string>
 
 #include "base/memory/ptr_util.h"
+#include "base/test/scoped_feature_list.h"
 #include "chrome/browser/net/prediction_options.h"
 #include "chrome/browser/net/predictor.h"
 #include "chrome/browser/predictors/loading_predictor_config.h"
@@ -66,11 +67,29 @@
 LoadingPredictorConfigTest::LoadingPredictorConfigTest()
     : profile_(new TestingProfile()) {}
 
-TEST_F(LoadingPredictorConfigTest, IsDisabledByDefault) {
+TEST_F(LoadingPredictorConfigTest, Enabled) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(predictors::kSpeculativePreconnectFeature);
+
+  LoadingPredictorConfig config;
+  EXPECT_TRUE(MaybeEnableSpeculativePreconnect(&config));
+
+  EXPECT_TRUE(config.IsLearningEnabled());
+  EXPECT_TRUE(config.should_disable_other_preconnects);
+  EXPECT_FALSE(IsNetPredictorEnabled());
+  EXPECT_TRUE(config.IsPreconnectEnabledForSomeOrigin(profile_.get()));
+}
+
+TEST_F(LoadingPredictorConfigTest, Disabled) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndDisableFeature(predictors::kSpeculativePreconnectFeature);
+
   LoadingPredictorConfig config;
   EXPECT_FALSE(MaybeEnableSpeculativePreconnect(&config));
 
   EXPECT_FALSE(config.IsLearningEnabled());
+  EXPECT_FALSE(config.should_disable_other_preconnects);
+  EXPECT_TRUE(IsNetPredictorEnabled());
   EXPECT_FALSE(config.IsPreconnectEnabledForSomeOrigin(profile_.get()));
 }
 
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc
index 4f9a660..2821a54 100644
--- a/chrome/browser/resource_coordinator/tab_manager.cc
+++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -316,25 +316,6 @@
   TabLifecycleUnitExternal::RemoveTabLifecycleObserver(observer);
 }
 
-void TabManager::SetTabAutoDiscardableState(int32_t tab_id, bool state) {
-  for (LifecycleUnit* lifecycle_unit : lifecycle_units_) {
-    if (lifecycle_unit->GetID() == tab_id) {
-      TabLifecycleUnitExternal* tab_lifecycle_unit_external =
-          lifecycle_unit->AsTabLifecycleUnitExternal();
-      // For now, all LifecycleUnits are TabLifecycleUnitExternals.
-      DCHECK(tab_lifecycle_unit_external);
-      tab_lifecycle_unit_external->SetAutoDiscardable(state);
-      return;
-    }
-  }
-}
-
-void TabManager::SetTabAutoDiscardableState(content::WebContents* contents,
-                                            bool state) {
-  TabLifecycleUnitExternal::FromWebContents(contents)->SetAutoDiscardable(
-      state);
-}
-
 bool TabManager::CanPurgeBackgroundedRenderer(int render_process_id) const {
   for (LifecycleUnit* lifecycle_unit : lifecycle_units_) {
     TabLifecycleUnitExternal* tab_lifecycle_unit_external =
diff --git a/chrome/browser/resource_coordinator/tab_manager.h b/chrome/browser/resource_coordinator/tab_manager.h
index 856d4133..8169070 100644
--- a/chrome/browser/resource_coordinator/tab_manager.h
+++ b/chrome/browser/resource_coordinator/tab_manager.h
@@ -126,10 +126,6 @@
   void AddObserver(TabLifecycleObserver* observer);
   void RemoveObserver(TabLifecycleObserver* observer);
 
-  // Sets/clears the auto-discardable state of the tab.
-  void SetTabAutoDiscardableState(int32_t tab_id, bool state);
-  void SetTabAutoDiscardableState(content::WebContents* contents, bool state);
-
   // Returns true when a given renderer can be purged if the specified
   // renderer is eligible for purging.
   bool CanPurgeBackgroundedRenderer(int render_process_id) const;
diff --git a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
index bee2070c..aa04ef15 100644
--- a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
@@ -464,13 +464,15 @@
   ASSERT_EQ(2, tsm->count());
 
   // Set the auto-discardable state of the first tab to false.
-  tab_manager->SetTabAutoDiscardableState(tsm->GetWebContentsAt(0), false);
+  TabLifecycleUnitExternal::FromWebContents(tsm->GetWebContentsAt(0))
+      ->SetAutoDiscardable(false);
 
   // Shouldn't discard the tab, since auto-discardable is deactivated.
   EXPECT_FALSE(tab_manager->DiscardTabImpl(DiscardReason::kProactive));
 
   // Reset auto-discardable state to true.
-  tab_manager->SetTabAutoDiscardableState(tsm->GetWebContentsAt(0), true);
+  TabLifecycleUnitExternal::FromWebContents(tsm->GetWebContentsAt(0))
+      ->SetAutoDiscardable(true);
 
   // Now it should be able to discard the tab.
   EXPECT_TRUE(tab_manager->DiscardTabImpl(DiscardReason::kProactive));
diff --git a/chrome/browser/resources/md_downloads/item.html b/chrome/browser/resources/md_downloads/item.html
index f24d0bd9..e3981a49 100644
--- a/chrome/browser/resources/md_downloads/item.html
+++ b/chrome/browser/resources/md_downloads/item.html
@@ -220,15 +220,6 @@
         width: 32px;
       }
 
-      /* TODO(hcarmona): Move this to its parent after updating
-         paper-icon-button-light to have:
-         :host ::slotted(button) {
-           font-size: inherit;
-         } */
-      #remove-wrapper > paper-icon-button-light > button {
-        font-size: 16px;
-      }
-
       #incognito {
         bottom: 20px;
         content: -webkit-image-set(
@@ -315,12 +306,12 @@
       </div>
 
       <div id="remove-wrapper" class="icon-wrapper ">
-        <paper-icon-button-light
+        <paper-icon-button-light class="icon-clear"
             style$="[[computeRemoveStyle_(isDangerous_, showCancel_)]]">
           <button id="remove"
               title="$i18n{controlRemoveFromList}"
               aria-label="$i18n{controlRemoveFromList}"
-              on-click="onRemoveTap_">&#x2715;</button>
+              on-click="onRemoveTap_"></button>
         </paper-icon-button-light>
       </div>
 
diff --git a/chrome/browser/resources/settings/downloads_page/BUILD.gn b/chrome/browser/resources/settings/downloads_page/BUILD.gn
index 302be1b1..77ad172 100644
--- a/chrome/browser/resources/settings/downloads_page/BUILD.gn
+++ b/chrome/browser/resources/settings/downloads_page/BUILD.gn
@@ -24,6 +24,7 @@
 js_library("smb_shares_page") {
   deps = [
     ":add_smb_share_dialog",
+    "//ui/webui/resources/js:web_ui_listener_behavior",
   ]
 }
 
diff --git a/chrome/browser/resources/settings/downloads_page/smb_shares_page.html b/chrome/browser/resources/settings/downloads_page/smb_shares_page.html
index 617d4cd4..2e1ac593 100644
--- a/chrome/browser/resources/settings/downloads_page/smb_shares_page.html
+++ b/chrome/browser/resources/settings/downloads_page/smb_shares_page.html
@@ -1,8 +1,10 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 
+<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html">
 <link rel="import" href="chrome://resources/html/action_link.html">
 <link rel="import" href="chrome://resources/html/action_link_css.html">
 <link rel="import" href="chrome://resources/html/assert.html">
+<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
 <link rel="import" href="chrome://resources/html/md_select_css.html">
 <link rel="import" href="../settings_shared_css.html">
@@ -31,6 +33,11 @@
       <settings-add-smb-share-dialog on-close="onAddSmbDialogClosed_">
       </settings-add-smb-share-dialog>
     </template>
+
+    <cr-toast id="errorToast" duration="3000">
+      <div class="error-message" id="addShareDoneMessage">
+      </div>
+    </cr-toast>
   </template>
   <script src="smb_shares_page.js"></script>
 </dom-module>
diff --git a/chrome/browser/resources/settings/downloads_page/smb_shares_page.js b/chrome/browser/resources/settings/downloads_page/smb_shares_page.js
index 09d58992..319c7dd8 100644
--- a/chrome/browser/resources/settings/downloads_page/smb_shares_page.js
+++ b/chrome/browser/resources/settings/downloads_page/smb_shares_page.js
@@ -5,11 +5,18 @@
 Polymer({
   is: 'settings-smb-shares-page',
 
+  behaviors: [WebUIListenerBehavior],
+
   properties: {
     /** @private */
     showAddSmbDialog_: Boolean,
   },
 
+  /** @override */
+  attached: function() {
+    this.addWebUIListener('on-add-smb-share', this.onAddShare_.bind(this));
+  },
+
   /** @private */
   onAddShareTap_: function() {
     this.showAddSmbDialog_ = true;
@@ -20,4 +27,15 @@
     this.showAddSmbDialog_ = false;
   },
 
+  /**
+   * @param {string} error_status
+   * @private
+   */
+  onAddShare_: function(error_status) {
+    this.$.addShareDoneMessage.textContent = error_status == 'success' ?
+        loadTimeData.getString('smbShareAddedSuccessfulMessage') :
+        loadTimeData.getString('smbShareAddedErrorMessage');
+    this.$.errorToast.show();
+  },
+
 });
diff --git a/chrome/browser/resources/settings/printing_page/cups_printers.html b/chrome/browser/resources/settings/printing_page/cups_printers.html
index f11afc6..13b2968 100644
--- a/chrome/browser/resources/settings/printing_page/cups_printers.html
+++ b/chrome/browser/resources/settings/printing_page/cups_printers.html
@@ -79,14 +79,9 @@
     </div>
 
     <cr-toast id="errorToast" duration="3000">
-      <div class="error-message" id="addPrinterDoneMessage" hidden>
-          $i18n{printerAddedSuccessfulMessage}
-        </div>
-        <div class="error-message" id="addPrinterErrorMessage">
-          <span id="addPrinterFailedMessage" hidden>
-            $i18n{printerAddedFailedMessage}
-          </span>
-        </div>
+      <div class="error-message" id="addPrinterDoneMessage">
+        [[addPrinterResultText_]]
+      </div>
     </cr-toast>
   </template>
   <script src="cups_printers.js"></script>
diff --git a/chrome/browser/resources/settings/printing_page/cups_printers.js b/chrome/browser/resources/settings/printing_page/cups_printers.js
index 71bb918b..cf2233ae 100644
--- a/chrome/browser/resources/settings/printing_page/cups_printers.js
+++ b/chrome/browser/resources/settings/printing_page/cups_printers.js
@@ -38,6 +38,9 @@
 
     /** @private */
     showCupsEditPrinterDialog_: Boolean,
+
+    /**@private */
+    addPrinterResultText_: String,
   },
 
   listeners: {
@@ -104,59 +107,54 @@
    * @private
    */
   onAddPrinter_: function(result_code, printerName) {
-    let message;
     if (result_code == PrinterSetupResult.SUCCESS) {
       this.updateCupsPrintersList_();
-      message = this.$.addPrinterDoneMessage;
-      message.textContent =
+      this.addPrinterResultText_ =
           loadTimeData.getStringF('printerAddedSuccessfulMessage', printerName);
     } else {
-      message = this.$.addPrinterErrorMessage;
-      const messageText = this.$.addPrinterFailedMessage;
       switch (result_code) {
         case PrinterSetupResult.FATAL_ERROR:
-          messageText.textContent =
+          this.addPrinterResultText_ =
               loadTimeData.getString('printerAddedFatalErrorMessage');
           break;
         case PrinterSetupResult.PRINTER_UNREACHABLE:
-          messageText.textContent =
+          this.addPrinterResultText_ =
               loadTimeData.getString('printerAddedUnreachableMessage');
           break;
         case PrinterSetupResult.DBUS_ERROR:
           // Simply display a generic error message as this error should only
           // occur when a call to Dbus fails which isn't meaningful to the user.
-          messageText.textContent =
+          this.addPrinterResultText_ =
               loadTimeData.getString('printerAddedFailedmMessage');
           break;
         case PrinterSetupResult.NATIVE_PRINTERS_NOT_ALLOWED:
-          messageText.textContent = loadTimeData.getString(
+          this.addPrinterResultText_ = loadTimeData.getString(
               'printerAddedNativePrintersNotAllowedMessage');
           break;
         case PrinterSetupResult.INVALID_PRINTER_UPDATE:
-          messageText.textContent =
+          this.addPrinterResultText_ =
               loadTimeData.getString('editPrinterInvalidPrinterUpdate');
           break;
         case PrinterSetupResult.PPD_TOO_LARGE:
-          messageText.textContent =
+          this.addPrinterResultText_ =
               loadTimeData.getString('printerAddedPpdTooLargeMessage');
           break;
         case PrinterSetupResult.INVALID_PPD:
-          messageText.textContent =
+          this.addPrinterResultText_ =
               loadTimeData.getString('printerAddedInvalidPpdMessage');
           break;
         case PrinterSetupResult.PPD_NOT_FOUND:
-          messageText.textContent =
+          this.addPrinterResultText_ =
               loadTimeData.getString('printerAddedPpdNotFoundMessage');
           break;
         case PrinterSetupResult.PPD_UNRETRIEVABLE:
-          messageText.textContent =
+          this.addPrinterResultText_ =
               loadTimeData.getString('printerAddedPpdUnretrievableMessage');
           break;
       }
     }
 
     this.$.errorToast.show();
-    message.hidden = false;
   },
 
   /** @private */
diff --git a/chrome/browser/resources/settings/settings_shared_css.html b/chrome/browser/resources/settings/settings_shared_css.html
index a47b3fa..eea8a09 100644
--- a/chrome/browser/resources/settings/settings_shared_css.html
+++ b/chrome/browser/resources/settings/settings_shared_css.html
@@ -330,6 +330,7 @@
         padding-bottom: 15px;
         padding-top: 15px;
         text-align: center;
+        white-space: normal;
       }
     </style>
   </template>
diff --git a/chrome/browser/tracing/chrome_tracing_delegate.cc b/chrome/browser/tracing/chrome_tracing_delegate.cc
index ca8cab3..dce3d85 100644
--- a/chrome/browser/tracing/chrome_tracing_delegate.cc
+++ b/chrome/browser/tracing/chrome_tracing_delegate.cc
@@ -29,6 +29,11 @@
 #include "content/public/browser/background_tracing_config.h"
 #include "content/public/browser/browser_thread.h"
 
+#if defined(OS_ANDROID)
+#include "chrome/browser/ui/android/tab_model/tab_model.h"
+#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
+#endif
+
 namespace {
 
 const int kMinDaysUntilNextUpload = 7;
@@ -43,6 +48,8 @@
   CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 #if !defined(OS_ANDROID)
   BrowserList::AddObserver(this);
+#else
+  TabModelList::AddObserver(this);
 #endif
 }
 
@@ -50,15 +57,29 @@
   CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 #if !defined(OS_ANDROID)
   BrowserList::RemoveObserver(this);
+#else
+  TabModelList::RemoveObserver(this);
 #endif
 }
 
+#if defined(OS_ANDROID)
+void ChromeTracingDelegate::OnTabModelAdded() {
+  for (TabModelList::const_iterator i = TabModelList::begin();
+       i != TabModelList::end(); i++) {
+    if ((*i)->IsOffTheRecord())
+      incognito_launched_ = true;
+  }
+}
+
+void ChromeTracingDelegate::OnTabModelRemoved() {}
+
+#else
+
 void ChromeTracingDelegate::OnBrowserAdded(Browser* browser) {
-#if !defined(OS_ANDROID)
   if (browser->profile()->IsOffTheRecord())
     incognito_launched_ = true;
-#endif
 }
+#endif  // defined(OS_ANDROID)
 
 std::unique_ptr<content::TraceUploader> ChromeTracingDelegate::GetTraceUploader(
     net::URLRequestContextGetter* request_context) {
diff --git a/chrome/browser/tracing/chrome_tracing_delegate.h b/chrome/browser/tracing/chrome_tracing_delegate.h
index 4e3c0c82..c052326b 100644
--- a/chrome/browser/tracing/chrome_tracing_delegate.h
+++ b/chrome/browser/tracing/chrome_tracing_delegate.h
@@ -7,13 +7,24 @@
 
 #include <memory>
 
-#include "chrome/browser/ui/browser_list_observer.h"
+#include "build/build_config.h"
 #include "content/public/browser/tracing_delegate.h"
 
+#if defined(OS_ANDROID)
+#include "chrome/browser/ui/android/tab_model/tab_model_list_observer.h"
+#else
+#include "chrome/browser/ui/browser_list_observer.h"
+#endif
+
 class PrefRegistrySimple;
 
 class ChromeTracingDelegate : public content::TracingDelegate,
-                              public BrowserListObserver {
+#if defined(OS_ANDROID)
+                              public TabModelListObserver
+#else
+                              public BrowserListObserver
+#endif
+{
  public:
   ChromeTracingDelegate();
   ~ChromeTracingDelegate() override;
@@ -38,8 +49,14 @@
   content::MetadataFilterPredicate GetMetadataFilterPredicate() override;
 
  private:
+#if defined(OS_ANDROID)
+  // TabModelListObserver implementation.
+  void OnTabModelAdded() override;
+  void OnTabModelRemoved() override;
+#else
   // BrowserListObserver implementation.
   void OnBrowserAdded(Browser* browser) override;
+#endif
 
   bool incognito_launched_;
 };
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index d907022..c4afba7 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -3149,8 +3149,6 @@
         "views/load_complete_listener.h",
         "views/location_bar/background_with_1_px_border.cc",
         "views/location_bar/background_with_1_px_border.h",
-        "views/location_bar/bubble_icon_view.cc",
-        "views/location_bar/bubble_icon_view.h",
         "views/location_bar/content_setting_image_view.cc",
         "views/location_bar/content_setting_image_view.h",
         "views/location_bar/find_bar_icon.cc",
@@ -3202,6 +3200,8 @@
         "views/omnibox/rounded_omnibox_results_frame.h",
         "views/page_action/page_action_icon_container_view.cc",
         "views/page_action/page_action_icon_container_view.h",
+        "views/page_action/page_action_icon_view.cc",
+        "views/page_action/page_action_icon_view.h",
         "views/passwords/manage_passwords_icon_views.cc",
         "views/passwords/manage_passwords_icon_views.h",
         "views/permission_bubble/chooser_bubble_ui_views.cc",
diff --git a/chrome/browser/ui/app_list/crostini/crostini_app_item.cc b/chrome/browser/ui/app_list/crostini/crostini_app_item.cc
index 3df1be5..315f4d2 100644
--- a/chrome/browser/ui/app_list/crostini/crostini_app_item.cc
+++ b/chrome/browser/ui/app_list/crostini/crostini_app_item.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/chromeos/crostini/crostini_util.h"
 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
 #include "chrome/browser/ui/app_list/crostini/crostini_app_context_menu.h"
+#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
 #include "content/public/browser/browser_thread.h"
 
 // static
@@ -46,7 +47,8 @@
 }
 
 void CrostiniAppItem::Activate(int event_flags) {
-  LaunchCrostiniApp(profile(), id());
+  ChromeLauncherController::instance()->ActivateApp(
+      id(), ash::LAUNCH_FROM_APP_LIST, event_flags);
 
   // TODO(timloh): Launching Crostini apps can take a few seconds if the
   // container is not currently running. Hiding the launcher at least provides
diff --git a/chrome/browser/ui/app_list/search/crostini_app_result.cc b/chrome/browser/ui/app_list/search/crostini_app_result.cc
index 4ed97bf..15f3d10 100644
--- a/chrome/browser/ui/app_list/search/crostini_app_result.cc
+++ b/chrome/browser/ui/app_list/search/crostini_app_result.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/crostini/crostini_app_context_menu.h"
 #include "chrome/browser/ui/app_list/crostini/crostini_app_icon_loader.h"
+#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
 
 namespace app_list {
 
@@ -29,7 +30,8 @@
 CrostiniAppResult::~CrostiniAppResult() = default;
 
 void CrostiniAppResult::Open(int event_flags) {
-  LaunchCrostiniApp(profile(), app_id());
+  ChromeLauncherController::instance()->ActivateApp(
+      id(), ash::LAUNCH_FROM_APP_LIST_SEARCH, event_flags);
 }
 
 void CrostiniAppResult::GetContextMenuModel(GetMenuModelCallback callback) {
diff --git a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc
index c8ee3597..c0a5f726 100644
--- a/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc
+++ b/chrome/browser/ui/ash/launcher/crostini_app_window_shelf_controller.cc
@@ -66,10 +66,9 @@
                                                    std::move(controller));
       owner()->SetItemStatus(shelf_id, ash::STATUS_RUNNING);
     }
-    window->SetProperty(ash::kShelfIDKey,
-                        new std::string(shelf_id.Serialize()));
   }
 
+  window->SetProperty(ash::kShelfIDKey, new std::string(shelf_id.Serialize()));
   item_controller->AddWindow(app_window);
   app_window->SetController(item_controller);
 }
diff --git a/chrome/browser/ui/ash/launcher/crostini_shelf_context_menu.cc b/chrome/browser/ui/ash/launcher/crostini_shelf_context_menu.cc
index 5bc1cb1d..c1a11e0 100644
--- a/chrome/browser/ui/ash/launcher/crostini_shelf_context_menu.cc
+++ b/chrome/browser/ui/ash/launcher/crostini_shelf_context_menu.cc
@@ -10,6 +10,7 @@
 #include "ash/public/cpp/shelf_item.h"
 #include "chrome/browser/chromeos/crostini/crostini_registry_service.h"
 #include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h"
+#include "chrome/browser/chromeos/crostini/crostini_util.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
 #include "chrome/grit/generated_resources.h"
 #include "ui/base/ui_base_features.h"
@@ -37,6 +38,8 @@
   if (registration)
     AddPinMenu(menu_model);
 
+  menu_model->AddItemWithStringId(MENU_NEW_WINDOW, IDS_APP_LIST_NEW_WINDOW);
+
   if (controller()->IsOpen(item().id)) {
     menu_model->AddItemWithStringId(MENU_CLOSE,
                                     IDS_LAUNCHER_CONTEXT_MENU_CLOSE);
@@ -48,3 +51,14 @@
   if (!features::IsTouchableAppContextMenuEnabled())
     menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
 }
+
+void CrostiniShelfContextMenu::ExecuteCommand(int command_id, int event_flags) {
+  if (ExecuteCommonCommand(command_id, event_flags))
+    return;
+
+  if (command_id == MENU_NEW_WINDOW) {
+    LaunchCrostiniApp(controller()->profile(), item().id.app_id);
+    return;
+  }
+  NOTREACHED();
+}
diff --git a/chrome/browser/ui/ash/launcher/crostini_shelf_context_menu.h b/chrome/browser/ui/ash/launcher/crostini_shelf_context_menu.h
index 6d6928c..744e7ca 100644
--- a/chrome/browser/ui/ash/launcher/crostini_shelf_context_menu.h
+++ b/chrome/browser/ui/ash/launcher/crostini_shelf_context_menu.h
@@ -18,6 +18,7 @@
 
   // LauncherContextMenu:
   void GetMenuModel(GetMenuModelCallback callback) override;
+  void ExecuteCommand(int command_id, int event_flags) override;
 
  private:
   void BuildMenu(ui::SimpleMenuModel* menu_model);
diff --git a/chrome/browser/ui/views/autofill/save_card_icon_view.cc b/chrome/browser/ui/views/autofill/save_card_icon_view.cc
index fe1c048a..fce4807 100644
--- a/chrome/browser/ui/views/autofill/save_card_icon_view.cc
+++ b/chrome/browser/ui/views/autofill/save_card_icon_view.cc
@@ -12,7 +12,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/view_ids.h"
 #include "chrome/browser/ui/views/autofill/save_card_bubble_views.h"
-#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
 #include "chrome/grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -20,8 +19,10 @@
 
 SaveCardIconView::SaveCardIconView(CommandUpdater* command_updater,
                                    Browser* browser,
-                                   BubbleIconView::Delegate* delegate)
-    : BubbleIconView(command_updater, IDC_SAVE_CREDIT_CARD_FOR_PAGE, delegate),
+                                   PageActionIconView::Delegate* delegate)
+    : PageActionIconView(command_updater,
+                         IDC_SAVE_CREDIT_CARD_FOR_PAGE,
+                         delegate),
       browser_(browser) {
   DCHECK(delegate);
   set_id(VIEW_ID_SAVE_CREDIT_CARD_BUTTON);
@@ -54,7 +55,7 @@
 }
 
 void SaveCardIconView::OnExecuting(
-    BubbleIconView::ExecuteSource execute_source) {}
+    PageActionIconView::ExecuteSource execute_source) {}
 
 const gfx::VectorIcon& SaveCardIconView::GetVectorIcon() const {
   return kCreditCardIcon;
diff --git a/chrome/browser/ui/views/autofill/save_card_icon_view.h b/chrome/browser/ui/views/autofill/save_card_icon_view.h
index 2184685..e40a509 100644
--- a/chrome/browser/ui/views/autofill/save_card_icon_view.h
+++ b/chrome/browser/ui/views/autofill/save_card_icon_view.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_VIEWS_AUTOFILL_SAVE_CARD_ICON_VIEW_H_
 
 #include "base/macros.h"
-#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
+#include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 
 class Browser;
 class CommandUpdater;
@@ -18,21 +18,21 @@
 // The location bar icon to show the Save Credit Card bubble where the user can
 // choose to save the credit card info to use again later without re-entering
 // it.
-class SaveCardIconView : public BubbleIconView {
+class SaveCardIconView : public PageActionIconView {
  public:
   SaveCardIconView(CommandUpdater* command_updater,
                    Browser* browser,
-                   BubbleIconView::Delegate* delegate);
+                   PageActionIconView::Delegate* delegate);
   ~SaveCardIconView() override;
 
-  // BubbleIconView:
+  // PageActionIconView:
   views::BubbleDialogDelegateView* GetBubble() const override;
   bool Refresh() override;
   base::string16 GetTextForTooltipAndAccessibleName() const override;
 
  protected:
-  // BubbleIconView:
-  void OnExecuting(BubbleIconView::ExecuteSource execute_source) override;
+  // PageActionIconView:
+  void OnExecuting(PageActionIconView::ExecuteSource execute_source) override;
   const gfx::VectorIcon& GetVectorIcon() const override;
 
  private:
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index c17842ed..20013ff 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1192,7 +1192,7 @@
     autofill::SaveCardBubbleController* controller,
     bool user_gesture) {
   LocationBarView* location_bar = GetLocationBarView();
-  BubbleIconView* card_view = location_bar->save_credit_card_icon_view();
+  PageActionIconView* card_view = location_bar->save_credit_card_icon_view();
 
   views::View* anchor_view = location_bar;
   if (!ui::MaterialDesignController::IsSecondaryUiMaterial()) {
diff --git a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.cc b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.cc
index aca54c16..0345049 100644
--- a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.cc
+++ b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.cc
@@ -65,13 +65,7 @@
     ExclusiveAccessContext* exclusive_access_context,
     ExclusiveAccessBubbleViewsContext* bubble_views_context)
     : exclusive_access_context_(exclusive_access_context),
-      bubble_views_context_(bubble_views_context),
-      fullscreen_control_popup_(
-          bubble_views_context->GetBubbleParentView(),
-          base::BindRepeating(&ExclusiveAccessContext::ExitFullscreen,
-                              base::Unretained(exclusive_access_context)),
-          base::BindRepeating(&FullscreenControlHost::OnVisibilityChanged,
-                              base::Unretained(this))) {}
+      bubble_views_context_(bubble_views_context) {}
 
 FullscreenControlHost::~FullscreenControlHost() = default;
 
@@ -141,8 +135,7 @@
 }
 
 void FullscreenControlHost::OnMouseEvent(ui::MouseEvent* event) {
-  if (event->type() != ui::ET_MOUSE_MOVED ||
-      fullscreen_control_popup_.IsAnimating() ||
+  if (event->type() != ui::ET_MOUSE_MOVED || IsAnimating() ||
       (input_entry_method_ != InputEntryMethod::NOT_ACTIVE &&
        input_entry_method_ != InputEntryMethod::MOUSE)) {
     return;
@@ -176,8 +169,7 @@
 
   // Hide the popup if the popup is showing and the user touches outside of the
   // popup.
-  if (event->type() == ui::ET_TOUCH_PRESSED &&
-      !fullscreen_control_popup_.IsAnimating()) {
+  if (event->type() == ui::ET_TOUCH_PRESSED && !IsAnimating()) {
     Hide(true);
   } else if (event->type() == ui::ET_TOUCH_RELEASED) {
     StartPopupTimeout(InputEntryMethod::TOUCH);
@@ -192,11 +184,33 @@
 }
 
 void FullscreenControlHost::Hide(bool animate) {
-  fullscreen_control_popup_.Hide(animate);
+  if (IsPopupCreated()) {
+    GetPopup()->Hide(animate);
+  }
 }
 
 bool FullscreenControlHost::IsVisible() const {
-  return fullscreen_control_popup_.IsVisible();
+  return IsPopupCreated() && fullscreen_control_popup_->IsVisible();
+}
+
+FullscreenControlPopup* FullscreenControlHost::GetPopup() {
+  if (!IsPopupCreated()) {
+    fullscreen_control_popup_ = std::make_unique<FullscreenControlPopup>(
+        bubble_views_context_->GetBubbleParentView(),
+        base::BindRepeating(&ExclusiveAccessContext::ExitFullscreen,
+                            base::Unretained(exclusive_access_context_)),
+        base::BindRepeating(&FullscreenControlHost::OnVisibilityChanged,
+                            base::Unretained(this)));
+  }
+  return fullscreen_control_popup_.get();
+}
+
+bool FullscreenControlHost::IsPopupCreated() const {
+  return fullscreen_control_popup_.get() != nullptr;
+}
+
+bool FullscreenControlHost::IsAnimating() const {
+  return IsPopupCreated() && fullscreen_control_popup_->IsAnimating();
 }
 
 void FullscreenControlHost::ShowForInputEntryMethod(
@@ -205,8 +219,7 @@
   auto* bubble = exclusive_access_context_->GetExclusiveAccessBubble();
   if (bubble)
     bubble->HideImmediately();
-  fullscreen_control_popup_.Show(
-      bubble_views_context_->GetClientAreaBoundsInScreen());
+  GetPopup()->Show(bubble_views_context_->GetClientAreaBoundsInScreen());
 
   // Exit cooldown mode in case the exit UI is triggered by a different method.
   in_mouse_cooldown_mode_ = false;
@@ -234,11 +247,11 @@
 
 void FullscreenControlHost::OnPopupTimeout(
     InputEntryMethod expected_input_method) {
-  if (IsVisible() && !fullscreen_control_popup_.IsAnimating() &&
+  if (IsVisible() && !IsAnimating() &&
       input_entry_method_ == expected_input_method) {
     if (input_entry_method_ == InputEntryMethod::MOUSE)
       in_mouse_cooldown_mode_ = true;
-    fullscreen_control_popup_.Hide(true);
+    Hide(true);
   }
 }
 
diff --git a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h
index c96a9a49..a512b02d 100644
--- a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h
+++ b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h
@@ -13,7 +13,6 @@
 
 class ExclusiveAccessContext;
 class ExclusiveAccessBubbleViewsContext;
-class FullscreenControlView;
 
 namespace ui {
 class GestureEvent;
@@ -46,10 +45,6 @@
 
   bool IsVisible() const;
 
-  FullscreenControlView* fullscreen_control_view() {
-    return fullscreen_control_popup_.control_view();
-  }
-
  private:
   friend class FullscreenControlViewTest;
 
@@ -62,6 +57,9 @@
     TOUCH,       // A touch event caused the view to show.
   };
 
+  FullscreenControlPopup* GetPopup();
+  bool IsPopupCreated() const;
+  bool IsAnimating() const;
   void ShowForInputEntryMethod(InputEntryMethod input_entry_method);
   void OnVisibilityChanged();
   void StartPopupTimeout(InputEntryMethod expected_input_method);
@@ -76,7 +74,8 @@
   ExclusiveAccessContext* const exclusive_access_context_;
   ExclusiveAccessBubbleViewsContext* const bubble_views_context_;
 
-  FullscreenControlPopup fullscreen_control_popup_;
+  std::unique_ptr<FullscreenControlPopup> fullscreen_control_popup_;
+
   base::OneShotTimer popup_timeout_timer_;
   base::OneShotTimer key_press_delay_timer_;
 
diff --git a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_view_interactive_uitest.cc b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_view_interactive_uitest.cc
index 8d05333..c44ed2c 100644
--- a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_view_interactive_uitest.cc
@@ -16,17 +16,24 @@
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "chrome/test/views/scoped_macviews_browser_mode.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_features.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/web/web_fullscreen_options.h"
+#include "ui/base/ui_base_features.h"
 #include "ui/events/base_event_utils.h"
 #include "ui/events/event.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/view.h"
 #include "url/gurl.h"
 
+#if defined(USE_AURA)
+#include "ui/aura/test/test_cursor_client.h"
+#include "ui/aura/window.h"
+#endif
+
 namespace {
 
 constexpr base::TimeDelta kPopupEventTimeout = base::TimeDelta::FromSeconds(5);
@@ -56,6 +63,25 @@
     InProcessBrowserTest::SetUp();
   }
 
+  void SetUpOnMainThread() override {
+#if defined(USE_AURA)
+    // This code prevents WindowEventDispatcher from synthesizing mouse move
+    // events when views get refreshed, so that they won't interfere with the
+    // tests. Note that new mouse move events directly coming from the real
+    // device will still pass through.
+    auto* root_window = browser()->window()->GetNativeWindow()->GetRootWindow();
+    cursor_client_ =
+        std::make_unique<aura::test::TestCursorClient>(root_window);
+    cursor_client_->DisableMouseEvents();
+#endif
+  }
+
+  void TearDownOnMainThread() override {
+#if defined(USE_AURA)
+    cursor_client_.reset();
+#endif
+  }
+
  protected:
   FullscreenControlHost* GetFullscreenControlHost() {
     BrowserView* browser_view =
@@ -64,7 +90,7 @@
   }
 
   FullscreenControlView* GetFullscreenControlView() {
-    return GetFullscreenControlHost()->fullscreen_control_view();
+    return GetFullscreenControlHost()->GetPopup()->control_view();
   }
 
   views::Button* GetFullscreenExitButton() {
@@ -83,6 +109,8 @@
     return browser()->tab_strip_model()->GetActiveWebContents();
   }
 
+  bool IsPopupCreated() { return GetFullscreenControlHost()->IsPopupCreated(); }
+
   void EnterActiveTabFullscreen() {
     FullscreenNotificationObserver fullscreen_observer;
     content::WebContentsDelegate* delegate =
@@ -121,10 +149,27 @@
 
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
+  test::ScopedMacViewsBrowserMode views_mode_{true};
+
+#if defined(USE_AURA)
+  std::unique_ptr<aura::test::TestCursorClient> cursor_client_;
+#endif
 
   DISALLOW_COPY_AND_ASSIGN(FullscreenControlViewTest);
 };
 
+// Creating the popup on Mac increases the memory use by ~2MB so it should be
+// lazily loaded only when necessary. This test verifies that the popup is not
+// immediately created when FullscreenControlHost is created.
+IN_PROC_BROWSER_TEST_F(FullscreenControlViewTest,
+                       NoFullscreenPopupOnBrowserFullscreen) {
+  EnterActiveTabFullscreen();
+  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
+  DCHECK(browser_view);
+  ASSERT_TRUE(browser_view->IsFullscreen());
+  ASSERT_FALSE(IsPopupCreated());
+}
+
 #if defined(OS_MACOSX)
 // Entering fullscreen is flaky on Mac: http://crbug.com/824517
 #define MAYBE_MouseExitFullscreen DISABLED_MouseExitFullscreen
@@ -392,10 +437,6 @@
 #endif
 IN_PROC_BROWSER_TEST_F(FullscreenControlViewTest,
                        MAYBE_KeyboardPopupInteraction) {
-  // TODO(yuweih): Test will fail if the cursor is at the top of the screen.
-  // That's because random mouse move events may pass from the browser to the
-  // host and interfere with the InputEntryMethod tracking. Consider fixing
-  // this.
   EnterActiveTabFullscreen();
   BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
   ASSERT_TRUE(browser_view->IsFullscreen());
diff --git a/chrome/browser/ui/views/location_bar/find_bar_icon.cc b/chrome/browser/ui/views/location_bar/find_bar_icon.cc
index e46fb4d..22608d8 100644
--- a/chrome/browser/ui/views/location_bar/find_bar_icon.cc
+++ b/chrome/browser/ui/views/location_bar/find_bar_icon.cc
@@ -8,8 +8,8 @@
 #include "components/toolbar/vector_icons.h"
 #include "ui/base/l10n/l10n_util.h"
 
-FindBarIcon::FindBarIcon(BubbleIconView::Delegate* delegate)
-    : BubbleIconView(nullptr, 0, delegate) {}
+FindBarIcon::FindBarIcon(PageActionIconView::Delegate* delegate)
+    : PageActionIconView(nullptr, 0, delegate) {}
 
 FindBarIcon::~FindBarIcon() {}
 
diff --git a/chrome/browser/ui/views/location_bar/find_bar_icon.h b/chrome/browser/ui/views/location_bar/find_bar_icon.h
index 7af0dc9f..dfdefb3 100644
--- a/chrome/browser/ui/views/location_bar/find_bar_icon.h
+++ b/chrome/browser/ui/views/location_bar/find_bar_icon.h
@@ -6,18 +6,18 @@
 #define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_FIND_BAR_ICON_H_
 
 #include "base/macros.h"
-#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
+#include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 
 // The find icon to show when the find bar is visible.
-class FindBarIcon : public BubbleIconView {
+class FindBarIcon : public PageActionIconView {
  public:
-  explicit FindBarIcon(BubbleIconView::Delegate* delegate);
+  explicit FindBarIcon(PageActionIconView::Delegate* delegate);
   ~FindBarIcon() override;
 
   void SetActive(bool activate, bool should_animate);
 
  protected:
-  // BubbleIconView:
+  // PageActionIconView:
   void OnExecuting(ExecuteSource execute_source) override;
   views::BubbleDialogDelegateView* GetBubble() const override;
   const gfx::VectorIcon& GetVectorIcon() const override;
diff --git a/chrome/browser/ui/views/location_bar/intent_picker_view.cc b/chrome/browser/ui/views/location_bar/intent_picker_view.cc
index c476d57..0adda3de 100644
--- a/chrome/browser/ui/views/location_bar/intent_picker_view.cc
+++ b/chrome/browser/ui/views/location_bar/intent_picker_view.cc
@@ -20,8 +20,8 @@
 }
 
 IntentPickerView::IntentPickerView(Browser* browser,
-                                   BubbleIconView::Delegate* delegate)
-    : BubbleIconView(nullptr, 0, delegate), browser_(browser) {
+                                   PageActionIconView::Delegate* delegate)
+    : PageActionIconView(nullptr, 0, delegate), browser_(browser) {
   if (browser_) {
     intent_picker_controller_ =
         std::make_unique<arc::IntentPickerController>(browser_);
@@ -36,11 +36,11 @@
   if (!visible)
     IntentPickerBubbleView::CloseCurrentBubble();
 
-  BubbleIconView::SetVisible(visible);
+  PageActionIconView::SetVisible(visible);
 }
 
 void IntentPickerView::OnExecuting(
-    BubbleIconView::ExecuteSource execute_source) {
+    PageActionIconView::ExecuteSource execute_source) {
   if (browser_ && !browser_->profile()->IsGuestSession() &&
       !IsIncognitoMode()) {
     SetVisible(true);
diff --git a/chrome/browser/ui/views/location_bar/intent_picker_view.h b/chrome/browser/ui/views/location_bar/intent_picker_view.h
index e01549c8..60adf1d 100644
--- a/chrome/browser/ui/views/location_bar/intent_picker_view.h
+++ b/chrome/browser/ui/views/location_bar/intent_picker_view.h
@@ -8,7 +8,7 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
+#include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 
 namespace arc {
 class IntentPickerController;
@@ -17,17 +17,17 @@
 class Browser;
 
 // The entry point for the intent picker.
-class IntentPickerView : public BubbleIconView {
+class IntentPickerView : public PageActionIconView {
  public:
-  IntentPickerView(Browser* browser, BubbleIconView::Delegate* delegate);
+  IntentPickerView(Browser* browser, PageActionIconView::Delegate* delegate);
   ~IntentPickerView() override;
 
-  // BubbleIconView:
+  // PageActionIconView:
   void SetVisible(bool visible) override;
 
  protected:
-  // BubbleIconView:
-  void OnExecuting(BubbleIconView::ExecuteSource execute_source) override;
+  // PageActionIconView:
+  void OnExecuting(PageActionIconView::ExecuteSource execute_source) override;
   views::BubbleDialogDelegateView* GetBubble() const override;
   const gfx::VectorIcon& GetVectorIcon() const override;
   base::string16 GetTextForTooltipAndAccessibleName() const override;
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index abb5a9ff..d6f1959 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -46,7 +46,6 @@
 #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/harmony/chrome_typography.h"
 #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h"
-#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
 #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h"
 #include "chrome/browser/ui/views/location_bar/find_bar_icon.h"
 #include "chrome/browser/ui/views/location_bar/keyword_hint_view.h"
@@ -57,6 +56,7 @@
 #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h"
 #include "chrome/browser/ui/views/location_bar/zoom_view.h"
 #include "chrome/browser/ui/views/page_action/page_action_icon_container_view.h"
+#include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_bubble_view.h"
 #include "chrome/browser/ui/views/passwords/manage_passwords_icon_views.h"
 #include "chrome/browser/ui/views/translate/translate_bubble_view.h"
@@ -245,32 +245,32 @@
   }
 
   zoom_view_ = new ZoomView(delegate_, this);
-  bubble_icons_.push_back(zoom_view_);
+  page_action_icons_.push_back(zoom_view_);
   manage_passwords_icon_view_ =
       new ManagePasswordsIconViews(command_updater(), this);
-  bubble_icons_.push_back(manage_passwords_icon_view_);
+  page_action_icons_.push_back(manage_passwords_icon_view_);
 
   if (browser_) {
     save_credit_card_icon_view_ =
         new autofill::SaveCardIconView(command_updater(), browser_, this);
-    bubble_icons_.push_back(save_credit_card_icon_view_);
+    page_action_icons_.push_back(save_credit_card_icon_view_);
   }
   translate_icon_view_ = new TranslateIconView(command_updater(), this);
-  bubble_icons_.push_back(translate_icon_view_);
+  page_action_icons_.push_back(translate_icon_view_);
 
 #if defined(OS_CHROMEOS)
   if (browser_)
-    bubble_icons_.push_back(intent_picker_view_ =
-                                new IntentPickerView(browser_, this));
+    page_action_icons_.push_back(intent_picker_view_ =
+                                     new IntentPickerView(browser_, this));
 #endif
-  bubble_icons_.push_back(find_bar_icon_ = new FindBarIcon(this));
+  page_action_icons_.push_back(find_bar_icon_ = new FindBarIcon(this));
   if (browser_) {
-    bubble_icons_.push_back(
+    page_action_icons_.push_back(
         star_view_ = new StarView(command_updater(), browser_, this));
   }
 
-  std::for_each(bubble_icons_.begin(), bubble_icons_.end(),
-                [this](BubbleIconView* icon_view) -> void {
+  std::for_each(page_action_icons_.begin(), page_action_icons_.end(),
+                [this](PageActionIconView* icon_view) -> void {
                   icon_view->Init();
                   icon_view->SetVisible(false);
                   AddChildView(icon_view);
@@ -649,16 +649,16 @@
 void LocationBarView::Update(const WebContents* contents) {
   RefreshContentSettingViews();
 
-  // TODO(calamity): Refactor Update to use BubbleIconView::Refresh.
+  // TODO(calamity): Refactor Update to use PageActionIconView::Refresh.
   RefreshZoomView();
 
-  RefreshBubbleIconViews();
+  RefreshPageActionIconViews();
 
-  // TODO(calamity): Refactor Update to use BubbleIconView::Refresh.
+  // TODO(calamity): Refactor Update to use PageActionIconView::Refresh.
   RefreshFindBarIcon();
 
   if (star_view_) {
-    // TODO(calamity): Refactor Update to use BubbleIconView::Refresh.
+    // TODO(calamity): Refactor Update to use PageActionIconView::Refresh.
     UpdateBookmarkStarVisibility();
   }
 
@@ -680,7 +680,8 @@
 
 bool LocationBarView::ActivateFirstInactiveBubbleForAccessibility() {
   auto result = std::find_if(
-      bubble_icons_.begin(), bubble_icons_.end(), [](BubbleIconView* view) {
+      page_action_icons_.begin(), page_action_icons_.end(),
+      [](PageActionIconView* view) {
         if (!view || !view->visible() || !view->GetBubble())
           return false;
 
@@ -688,10 +689,10 @@
         return widget && widget->IsVisible() && !widget->IsActive();
       });
 
-  if (result != bubble_icons_.end())
+  if (result != page_action_icons_.end())
     (*result)->GetBubble()->GetWidget()->Show();
 
-  return result != bubble_icons_.end();
+  return result != page_action_icons_.end();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -722,8 +723,8 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// LocationBarView, public BubbleIconView::Delegate implementation:
-WebContents* LocationBarView::GetWebContentsForBubbleIconView() {
+// LocationBarView, public PageActionIconView::Delegate implementation:
+WebContents* LocationBarView::GetWebContentsForPageActionIconView() {
   return GetWebContents();
 }
 
@@ -880,7 +881,7 @@
   return visibility_changed;
 }
 
-bool LocationBarView::RefreshBubbleIconViews() {
+bool LocationBarView::RefreshPageActionIconViews() {
   if (extensions::HostedAppBrowserController::IsForExperimentalHostedAppBrowser(
           browser_)) {
     // For hosted apps, the location bar is normally hidden and icons appear in
@@ -889,7 +890,7 @@
   }
 
   bool visibility_changed = false;
-  for (auto* v : bubble_icons_) {
+  for (auto* v : page_action_icons_) {
     visibility_changed |= v->Refresh();
   }
   return visibility_changed;
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h
index 4e65c681..db73135 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.h
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -21,9 +21,9 @@
 #include "chrome/browser/ui/views/dropdown_bar_host.h"
 #include "chrome/browser/ui/views/dropdown_bar_host_delegate.h"
 #include "chrome/browser/ui/views/extensions/extension_popup.h"
-#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
 #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h"
 #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
+#include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 #include "components/prefs/pref_member.h"
 #include "components/security_state/core/security_state.h"
 #include "components/zoom/zoom_event_manager_observer.h"
@@ -80,7 +80,7 @@
                         public zoom::ZoomEventManagerObserver,
                         public views::ButtonListener,
                         public ContentSettingImageView::Delegate,
-                        public BubbleIconView::Delegate {
+                        public PageActionIconView::Delegate {
  public:
   class Delegate {
    public:
@@ -303,11 +303,10 @@
   // of at least one of the views in |content_setting_views_| changed.
   bool RefreshContentSettingViews();
 
-  // Updates the visibility state of the BubbleIconView (page action) icons
-  // to reflect what actions are available on the current page.
-  // Returns true if the visibility of at least one of the views in
-  // |bubble_icons_| changed.
-  bool RefreshBubbleIconViews();
+  // Updates the visibility state of the PageActionIconViews to reflect what
+  // actions are available on the current page. Returns true if the visibility
+  // of at least one of the views in |page_action_icons_| changed.
+  bool RefreshPageActionIconViews();
 
   // Updates the view for the zoom icon based on the current tab's zoom. Returns
   // true if the visibility of the view changed.
@@ -377,8 +376,8 @@
                            const gfx::Point& press_pt,
                            const gfx::Point& p) override;
 
-  // BubbleIconView::Delegate:
-  content::WebContents* GetWebContentsForBubbleIconView() override;
+  // PageActionIconView::Delegate:
+  content::WebContents* GetWebContentsForPageActionIconView() override;
   OmniboxTint GetTint() override;
 
   // gfx::AnimationDelegate:
@@ -480,8 +479,8 @@
   // Tracks this preference to determine whether bookmark editing is allowed.
   BooleanPrefMember edit_bookmarks_enabled_;
 
-  // A list of all bubble descendants ordered by focus.
-  std::vector<BubbleIconView*> bubble_icons_;
+  // A list of all page action icons ordered by focus.
+  std::vector<PageActionIconView*> page_action_icons_;
 
   PageActionIconContainerView* page_action_icon_container_view_ = nullptr;
 
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc b/chrome/browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc
index e44c8572..61deb85e 100644
--- a/chrome/browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/location_bar/location_icon_view_interactive_uitest.cc
@@ -88,7 +88,7 @@
                                     translate::TRANSLATE_STEP_AFTER_TRANSLATE,
                                     translate::TranslateErrors::NONE, true);
 
-  BubbleIconView* icon_view = location_bar_view->translate_icon_view();
+  PageActionIconView* icon_view = location_bar_view->translate_icon_view();
   ASSERT_TRUE(icon_view);
   EXPECT_TRUE(icon_view->visible());
 
diff --git a/chrome/browser/ui/views/location_bar/star_view.cc b/chrome/browser/ui/views/location_bar/star_view.cc
index 48fca38..7e0fceb 100644
--- a/chrome/browser/ui/views/location_bar/star_view.cc
+++ b/chrome/browser/ui/views/location_bar/star_view.cc
@@ -22,8 +22,8 @@
 
 StarView::StarView(CommandUpdater* command_updater,
                    Browser* browser,
-                   BubbleIconView::Delegate* delegate)
-    : BubbleIconView(command_updater, IDC_BOOKMARK_PAGE, delegate),
+                   PageActionIconView::Delegate* delegate)
+    : PageActionIconView(command_updater, IDC_BOOKMARK_PAGE, delegate),
       browser_(browser),
       bookmark_promo_observer_(this) {
   set_id(VIEW_ID_STAR_BUTTON);
@@ -33,7 +33,7 @@
 StarView::~StarView() {}
 
 void StarView::SetToggled(bool on) {
-  BubbleIconView::SetActiveInternal(on);
+  PageActionIconView::SetActiveInternal(on);
 }
 
 void StarView::ShowPromo() {
@@ -49,8 +49,7 @@
   }
 }
 
-void StarView::OnExecuting(
-    BubbleIconView::ExecuteSource execute_source) {
+void StarView::OnExecuting(PageActionIconView::ExecuteSource execute_source) {
   BookmarkEntryPoint entry_point = BOOKMARK_ENTRY_POINT_STAR_MOUSE;
   switch (execute_source) {
     case EXECUTE_SOURCE_MOUSE:
@@ -73,7 +72,7 @@
     OnExecuting(source);
     chrome::BookmarkCurrentPageIgnoringExtensionOverrides(browser_);
   } else {
-    BubbleIconView::ExecuteCommand(source);
+    PageActionIconView::ExecuteCommand(source);
   }
 }
 
@@ -94,7 +93,7 @@
   return bookmark_promo_observer_.IsObservingSources()
              ? GetNativeTheme()->GetSystemColor(
                    ui::NativeTheme::kColorId_ProminentButtonColor)
-             : BubbleIconView::GetInkDropBaseColor();
+             : PageActionIconView::GetInkDropBaseColor();
 }
 
 void StarView::OnWidgetDestroying(views::Widget* widget) {
diff --git a/chrome/browser/ui/views/location_bar/star_view.h b/chrome/browser/ui/views/location_bar/star_view.h
index 1d4d86fe..b4c6002 100644
--- a/chrome/browser/ui/views/location_bar/star_view.h
+++ b/chrome/browser/ui/views/location_bar/star_view.h
@@ -7,17 +7,17 @@
 
 #include "base/macros.h"
 #include "base/scoped_observer.h"
-#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
+#include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 
 class Browser;
 class CommandUpdater;
 
 // The star icon to show a bookmark bubble.
-class StarView : public BubbleIconView, public views::WidgetObserver {
+class StarView : public PageActionIconView, public views::WidgetObserver {
  public:
   StarView(CommandUpdater* command_updater,
            Browser* browser,
-           BubbleIconView::Delegate* delegate);
+           PageActionIconView::Delegate* delegate);
   ~StarView() override;
 
   // Toggles the star on or off.
@@ -27,8 +27,8 @@
   void ShowPromo();
 
  protected:
-  // BubbleIconView:
-  void OnExecuting(BubbleIconView::ExecuteSource execute_source) override;
+  // PageActionIconView:
+  void OnExecuting(PageActionIconView::ExecuteSource execute_source) override;
   void ExecuteCommand(ExecuteSource source) override;
   views::BubbleDialogDelegateView* GetBubble() const override;
   SkColor GetInkDropBaseColor() const override;
diff --git a/chrome/browser/ui/views/location_bar/zoom_view.cc b/chrome/browser/ui/views/location_bar/zoom_view.cc
index 0b1fc03..6db74f8 100644
--- a/chrome/browser/ui/views/location_bar/zoom_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_view.cc
@@ -17,8 +17,8 @@
 #include "ui/gfx/geometry/size.h"
 
 ZoomView::ZoomView(LocationBarView::Delegate* location_bar_delegate,
-                   BubbleIconView::Delegate* delegate)
-    : BubbleIconView(nullptr, 0, delegate),
+                   PageActionIconView::Delegate* delegate)
+    : PageActionIconView(nullptr, 0, delegate),
       location_bar_delegate_(location_bar_delegate),
       icon_(&kZoomMinusIcon) {
   Update(nullptr);
@@ -50,7 +50,7 @@
   SetVisible(true);
 }
 
-void ZoomView::OnExecuting(BubbleIconView::ExecuteSource source) {
+void ZoomView::OnExecuting(PageActionIconView::ExecuteSource source) {
   ZoomBubbleView::ShowBubble(location_bar_delegate_->GetWebContents(),
                              gfx::Point(), ZoomBubbleView::USER_GESTURE);
 }
diff --git a/chrome/browser/ui/views/location_bar/zoom_view.h b/chrome/browser/ui/views/location_bar/zoom_view.h
index 20694ca..c7f2154 100644
--- a/chrome/browser/ui/views/location_bar/zoom_view.h
+++ b/chrome/browser/ui/views/location_bar/zoom_view.h
@@ -6,22 +6,22 @@
 #define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_VIEW_H_
 
 #include "base/macros.h"
-#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
+#include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 
 namespace zoom {
 class ZoomController;
 }
 
 // View for the zoom icon in the Omnibox.
-class ZoomView : public BubbleIconView {
+class ZoomView : public PageActionIconView {
  public:
   // Clicking on the ZoomView shows a ZoomBubbleView, which requires the current
   // WebContents. Because the current WebContents changes as the user switches
   // tabs, a LocationBarView::Delegate is supplied to queried for the current
   // WebContents when needed.
   ZoomView(LocationBarView::Delegate* location_bar_delegate,
-           BubbleIconView::Delegate* delegate);
+           PageActionIconView::Delegate* delegate);
   ~ZoomView() override;
 
   // Updates the image and its tooltip appropriately, hiding or showing the icon
@@ -29,8 +29,8 @@
   void Update(zoom::ZoomController* zoom_controller);
 
  protected:
-  // BubbleIconView:
-  void OnExecuting(BubbleIconView::ExecuteSource source) override;
+  // PageActionIconView:
+  void OnExecuting(PageActionIconView::ExecuteSource source) override;
   views::BubbleDialogDelegateView* GetBubble() const override;
   const gfx::VectorIcon& GetVectorIcon() const override;
   base::string16 GetTextForTooltipAndAccessibleName() const override;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
index 1c4b2e0..eaf51960 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -128,8 +128,7 @@
   }
 
   Invalidate();
-  if (GetWidget())
-    Layout();
+  Layout();
 }
 
 void OmniboxResultView::ShowKeyword(bool show_keyword) {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
index 2f51073..2bafe8a 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -576,9 +576,8 @@
   if (IsSelectAll() && !home_key_pressed)
     return false;
 
-  model()->SetInputInProgress(true);
-
-  base::string16 full_url = model()->GetCurrentPermanentUrlText();
+  base::string16 full_url =
+      controller()->GetToolbarModel()->GetFormattedFullURL();
   size_t start, end;
   GetSelectionBounds(&start, &end);
 
@@ -597,6 +596,7 @@
 
   // Update the text to the full unelided URL. The caret is positioned at 0, as
   // otherwise we will spuriously scroll the text to the end of the new string.
+  model()->SetUserText(full_url);
   SetWindowTextAndCaretPos(full_url, 0, false, false);
   SelectRange(gfx::Range(start, end));
   return true;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
index aa1e7731..1fc784f 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
@@ -442,6 +442,7 @@
 class OmniboxViewViewsSteadyStateElisionsTest : public OmniboxViewViewsTest {
  protected:
   const int kCharacterWidth = 10;
+  const base::string16 kFullUrl = base::ASCIIToUTF16("https://www.example.com");
 
   void SetUp() override {
     scoped_feature_list_.InitAndEnableFeature(
@@ -453,8 +454,7 @@
     clock_.Advance(base::TimeDelta::FromSeconds(5));
     ui::SetEventTickClockForTesting(&clock_);
 
-    toolbar_model()->set_formatted_full_url(
-        base::ASCIIToUTF16("https://example.com"));
+    toolbar_model()->set_formatted_full_url(kFullUrl);
     toolbar_model()->set_url_for_display(base::ASCIIToUTF16("example.com"));
 
     gfx::test::RenderTextTestApi render_text_test_api(
@@ -476,10 +476,14 @@
     ASSERT_FALSE(omnibox_view()->HasFocus());
   }
 
-  bool IsFullUrlDisplayed() {
-    return omnibox_view()->text() ==
-               base::ASCIIToUTF16("https://example.com") &&
-           omnibox_view()->model()->user_input_in_progress();
+  void ExpectFullUrlDisplayed() {
+    EXPECT_EQ(kFullUrl, omnibox_view()->text());
+    EXPECT_TRUE(omnibox_view()->model()->user_input_in_progress());
+
+    // We test the user text stored in the model has been updated as well. The
+    // model user text is used to populate the text in the Omnibox after some
+    // state transitions, such as the ZeroSuggest popup opening.
+    EXPECT_EQ(kFullUrl, omnibox_view()->model()->GetUserTextForTesting());
   }
 
   bool IsElidedUrlDisplayed() {
@@ -527,11 +531,11 @@
   // Right key should unelide and move the cursor to the end.
   omnibox_textfield_view()->OnKeyPressed(
       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RIGHT, 0));
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
   size_t start, end;
   omnibox_view()->GetSelectionBounds(&start, &end);
-  EXPECT_EQ(19U, start);
-  EXPECT_EQ(19U, end);
+  EXPECT_EQ(23U, start);
+  EXPECT_EQ(23U, end);
 
   // Blur to restore the elided URL, then click on the Omnibox again to refocus.
   BlurOmnibox();
@@ -541,10 +545,10 @@
   // part.
   omnibox_textfield_view()->OnKeyPressed(
       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_LEFT, 0));
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
   omnibox_view()->GetSelectionBounds(&start, &end);
-  EXPECT_EQ(8U, start);
-  EXPECT_EQ(8U, end);
+  EXPECT_EQ(12U, start);
+  EXPECT_EQ(12U, end);
 }
 
 TEST_F(OmniboxViewViewsSteadyStateElisionsTest, UnelideOnHomeKey) {
@@ -554,7 +558,7 @@
   // unelided URL.
   omnibox_textfield_view()->OnKeyPressed(
       ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_HOME, 0));
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
   size_t start, end;
   omnibox_view()->GetSelectionBounds(&start, &end);
   EXPECT_EQ(0U, start);
@@ -577,7 +581,7 @@
 
   // Unelide on second tap (cursor placement).
   omnibox_textfield_view()->OnGestureEvent(&tap);
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
 }
 
 TEST_F(OmniboxViewViewsSteadyStateElisionsTest, FirstMouseClickFocusesOnly) {
@@ -622,15 +626,15 @@
   EXPECT_TRUE(IsElidedUrlDisplayed());
   omnibox_view()->OnMouseReleased(CreateMouseEvent(
       ui::ET_MOUSE_RELEASED, GetPointInTextAtXOffset(2 * kCharacterWidth)));
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
 
-  // Verify the cursor position is https://ex|ample.com. It should be between
-  // 'x' and 'a', because the click was after the second character of the
-  // unelided text "example.com".
+  // Verify the cursor position is https://www.ex|ample.com. It should be
+  // between 'x' and 'a', because the click was after the second character of
+  // the unelided text "example.com".
   size_t start, end;
   omnibox_view()->GetSelectionBounds(&start, &end);
-  EXPECT_EQ(10U, start);
-  EXPECT_EQ(10U, end);
+  EXPECT_EQ(14U, start);
+  EXPECT_EQ(14U, end);
 }
 
 TEST_F(OmniboxViewViewsSteadyStateElisionsTest, MouseDoubleClick) {
@@ -640,14 +644,14 @@
   // should do a single word selection and unelide the text on mousedown.
   omnibox_view()->OnMousePressed(CreateMouseEvent(
       ui::ET_MOUSE_PRESSED, GetPointInTextAtXOffset(4 * kCharacterWidth)));
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
 
-  // Verify that the selection is https://|example|.com, since the double-click
-  // after the fourth character of the unelided text "example.com".
+  // Verify that the selection is https://www.|example|.com, since the
+  // double-click after the fourth character of the unelided text "example.com".
   size_t start, end;
   omnibox_view()->GetSelectionBounds(&start, &end);
-  EXPECT_EQ(8U, start);
-  EXPECT_EQ(15U, end);
+  EXPECT_EQ(12U, start);
+  EXPECT_EQ(19U, end);
 }
 
 TEST_F(OmniboxViewViewsSteadyStateElisionsTest, MouseTripleClick) {
@@ -655,14 +659,14 @@
   SendMouseClick(4 * kCharacterWidth);
   SendMouseClick(4 * kCharacterWidth);
 
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
 
   // Verify that the whole full URL is selected.
   EXPECT_TRUE(omnibox_view()->IsSelectAll());
   size_t start, end;
   omnibox_view()->GetSelectionBounds(&start, &end);
   EXPECT_EQ(0U, start);
-  EXPECT_EQ(19U, end);
+  EXPECT_EQ(23U, end);
 }
 
 TEST_F(OmniboxViewViewsSteadyStateElisionsTest, MouseClickDrag) {
@@ -675,7 +679,7 @@
       ui::ET_MOUSE_DRAGGED, GetPointInTextAtXOffset(4 * kCharacterWidth)));
   EXPECT_TRUE(IsElidedUrlDisplayed());
 
-  // Expect that ex|am|ple.com is the drag selected portion.
+  // Expect that ex|am|ple.com is the drag selected portion while dragging.
   size_t start, end;
   omnibox_view()->GetSelectionBounds(&start, &end);
   EXPECT_EQ(2U, start);
@@ -683,43 +687,45 @@
 
   omnibox_view()->OnMouseReleased(CreateMouseEvent(
       ui::ET_MOUSE_RELEASED, GetPointInTextAtXOffset(4 * kCharacterWidth)));
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
 
-  // Expect that https://ex|am|ple.com is the drag selected portion.
+  // Expect that https://www.ex|am|ple.com is the selected portion after the
+  // user releases the mouse.
   omnibox_view()->GetSelectionBounds(&start, &end);
-  EXPECT_EQ(10U, start);
-  EXPECT_EQ(12U, end);
+  EXPECT_EQ(14U, start);
+  EXPECT_EQ(16U, end);
 }
 
 TEST_F(OmniboxViewViewsSteadyStateElisionsTest, MouseDoubleClickDrag) {
   // Expect that after a double-click after the third character of the elided
-  // text, the text is unelided, and https://|example|.com is selected.
+  // text, the text is unelided, and https://www.|example|.com is selected.
   SendMouseClick(4 * kCharacterWidth);
   omnibox_view()->OnMousePressed(CreateMouseEvent(
       ui::ET_MOUSE_PRESSED, GetPointInTextAtXOffset(4 * kCharacterWidth)));
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
   size_t start, end;
   omnibox_view()->GetSelectionBounds(&start, &end);
-  EXPECT_EQ(8U, start);
-  EXPECT_EQ(15U, end);
+  EXPECT_EQ(12U, start);
+  EXPECT_EQ(19U, end);
 
   // Expect that dragging to the fourth character of the full URL (between the
-  // the 'p' and the 's' of https), will word-select the scheme and domain, so
-  // the new selection will be |https://example|.com. The expected selection is
-  // backwards, since we are dragging the mouse from the domain to the scheme.
+  // the 'p' and the 's' of https), will word-select the scheme, subdomain, and
+  // domain, so the new selection will be |https://www.example|.com. The
+  // expected selection is backwards, since we are dragging the mouse from the
+  // domain to the scheme.
   omnibox_view()->OnMouseDragged(CreateMouseEvent(
       ui::ET_MOUSE_DRAGGED, GetPointInTextAtXOffset(2 * kCharacterWidth)));
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
   omnibox_view()->GetSelectionBounds(&start, &end);
-  EXPECT_EQ(15U, start);
+  EXPECT_EQ(19U, start);
   EXPECT_EQ(0U, end);
 
   // Expect the selection to stay the same after mouse-release.
   omnibox_view()->OnMouseReleased(CreateMouseEvent(
       ui::ET_MOUSE_RELEASED, GetPointInTextAtXOffset(2 * kCharacterWidth)));
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
   omnibox_view()->GetSelectionBounds(&start, &end);
-  EXPECT_EQ(15U, start);
+  EXPECT_EQ(19U, start);
   EXPECT_EQ(0U, end);
 }
 
@@ -727,7 +733,7 @@
   // Double-click should unelide the URL by making a partial selection.
   SendMouseClick(4 * kCharacterWidth);
   SendMouseClick(4 * kCharacterWidth);
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
 
   BlurOmnibox();
   EXPECT_TRUE(IsElidedUrlDisplayed());
@@ -737,19 +743,19 @@
   // Double-click should unelide the URL by making a partial selection.
   SendMouseClick(4 * kCharacterWidth);
   SendMouseClick(4 * kCharacterWidth);
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
 
   // Since the domain word is selected, pressing 'a' should replace the domain.
   ui::KeyEvent char_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::DomCode::US_A, 0,
                           ui::DomKey::FromCharacter('a'),
                           ui::EventTimeForNow());
   omnibox_textfield()->InsertChar(char_event);
-  EXPECT_EQ(base::ASCIIToUTF16("https://a.com"), omnibox_view()->text());
+  EXPECT_EQ(base::ASCIIToUTF16("https://www.a.com"), omnibox_view()->text());
   EXPECT_TRUE(omnibox_view()->model()->user_input_in_progress());
 
   // Now that we've edited the text, blurring should not re-elide the URL.
   BlurOmnibox();
-  EXPECT_EQ(base::ASCIIToUTF16("https://a.com"), omnibox_view()->text());
+  EXPECT_EQ(base::ASCIIToUTF16("https://www.a.com"), omnibox_view()->text());
   EXPECT_TRUE(omnibox_view()->model()->user_input_in_progress());
 }
 
@@ -757,7 +763,7 @@
        DontReelideOnBlurIfWidgetDeactivated) {
   SendMouseClick(0);
   SendMouseClick(0);
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
 
   // Create a different Widget that will take focus away from the test widget
   // containing our test Omnibox.
@@ -768,10 +774,10 @@
   params.bounds = gfx::Rect(0, 0, 100, 100);
   other_widget->Init(params);
   other_widget->Show();
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
 
   omnibox_view()->GetWidget()->Activate();
-  EXPECT_TRUE(IsFullUrlDisplayed());
+  ExpectFullUrlDisplayed();
 }
 
 TEST_F(OmniboxViewViewsSteadyStateElisionsTest, SaveSelectAllOnBlurAndRefocus) {
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc
index a4d66a53..a2861d1 100644
--- a/chrome/browser/ui/views/overlay/overlay_window_views.cc
+++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -42,7 +42,7 @@
 // OverlayWindow implementation of NonClientFrameView.
 class OverlayWindowFrameView : public views::NonClientFrameView {
  public:
-  OverlayWindowFrameView() = default;
+  explicit OverlayWindowFrameView(views::Widget* widget) : widget_(widget) {}
   ~OverlayWindowFrameView() override = default;
 
   // views::NonClientFrameView:
@@ -56,14 +56,18 @@
     if (!bounds().Contains(point))
       return HTNOWHERE;
 
-    // Allow dragging the border of the window to resize. Within the bounds of
-    // the window, allow interaction with the media controls on the window.
-    // TODO(apacible): Return correct hit test value to enable drag.
-    // http://crbug.com/840540
-    int window_component = GetHTComponentForFrame(
-        point, kBorderThickness, kBorderThickness, kResizeAreaCornerSize,
-        kResizeAreaCornerSize, GetWidget()->widget_delegate()->CanResize());
-    return window_component;
+    // Allow dragging the border of the window to resize when interacting with
+    // the window outside the control icons.
+    OverlayWindowViews* window = static_cast<OverlayWindowViews*>(widget_);
+    if (!window->GetCloseControlsBounds().Contains(point) &&
+        !window->GetPlayPauseControlsBounds().Contains(point))
+      return HTCAPTION;
+
+    // The areas left to interact with are media controls. These should take
+    // and handle user interaction.
+    return GetHTComponentForFrame(point, kBorderThickness, kBorderThickness,
+                                  kResizeAreaCornerSize, kResizeAreaCornerSize,
+                                  GetWidget()->widget_delegate()->CanResize());
   }
   void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override {}
   void ResetWindowControls() override {}
@@ -72,6 +76,8 @@
   void SizeConstraintsChanged() override {}
 
  private:
+  views::Widget* widget_;
+
   DISALLOW_COPY_AND_ASSIGN(OverlayWindowFrameView);
 };
 
@@ -98,7 +104,7 @@
   const views::Widget* GetWidget() const override { return widget_; }
   views::NonClientFrameView* CreateNonClientFrameView(
       views::Widget* widget) override {
-    return new OverlayWindowFrameView();
+    return new OverlayWindowFrameView(widget);
   }
 
  private:
diff --git a/chrome/browser/ui/views/page_action/OWNERS b/chrome/browser/ui/views/page_action/OWNERS
new file mode 100644
index 0000000..ec19d21
--- /dev/null
+++ b/chrome/browser/ui/views/page_action/OWNERS
@@ -0,0 +1,4 @@
+alancutter@chromium.org
+calamity@chromium.org
+
+# COMPONENT: UI>Browser>Bubbles
\ No newline at end of file
diff --git a/chrome/browser/ui/views/location_bar/bubble_icon_view.cc b/chrome/browser/ui/views/page_action/page_action_icon_view.cc
similarity index 72%
rename from chrome/browser/ui/views/location_bar/bubble_icon_view.cc
rename to chrome/browser/ui/views/page_action/page_action_icon_view.cc
index 4630f97..61336e23 100644
--- a/chrome/browser/ui/views/location_bar/bubble_icon_view.cc
+++ b/chrome/browser/ui/views/page_action/page_action_icon_view.cc
@@ -2,7 +2,7 @@
 // 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/location_bar/bubble_icon_view.h"
+#include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/ui/layout_constants.h"
@@ -23,7 +23,7 @@
 #include "ui/views/animation/ink_drop_mask.h"
 #include "ui/views/bubble/bubble_dialog_delegate.h"
 
-void BubbleIconView::Init() {
+void PageActionIconView::Init() {
   AddChildView(image_);
   image_->set_can_process_events_within_subtree(false);
   image_->EnableCanvasFlippingForRTLUI(true);
@@ -31,9 +31,9 @@
   SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
 }
 
-BubbleIconView::BubbleIconView(CommandUpdater* command_updater,
-                               int command_id,
-                               BubbleIconView::Delegate* delegate)
+PageActionIconView::PageActionIconView(CommandUpdater* command_updater,
+                                       int command_id,
+                                       PageActionIconView::Delegate* delegate)
     : widget_observer_(this),
       image_(new views::ImageView()),
       command_updater_(command_updater),
@@ -50,69 +50,69 @@
   }
 }
 
-BubbleIconView::~BubbleIconView() {}
+PageActionIconView::~PageActionIconView() {}
 
-bool BubbleIconView::IsBubbleShowing() const {
+bool PageActionIconView::IsBubbleShowing() const {
   // If the bubble is being destroyed, it's considered showing though it may be
   // already invisible currently.
   return GetBubble() != nullptr;
 }
 
-bool BubbleIconView::SetCommandEnabled(bool enabled) const {
+bool PageActionIconView::SetCommandEnabled(bool enabled) const {
   DCHECK(command_updater_);
   command_updater_->UpdateCommandEnabled(command_id_, enabled);
   return command_updater_->IsCommandEnabled(command_id_);
 }
 
-void BubbleIconView::SetImage(const gfx::ImageSkia* image_skia) {
+void PageActionIconView::SetImage(const gfx::ImageSkia* image_skia) {
   image_->SetImage(image_skia);
 }
 
-const gfx::ImageSkia& BubbleIconView::GetImage() const {
+const gfx::ImageSkia& PageActionIconView::GetImage() const {
   return image_->GetImage();
 }
 
-void BubbleIconView::SetHighlighted(bool bubble_visible) {
+void PageActionIconView::SetHighlighted(bool bubble_visible) {
   AnimateInkDrop(bubble_visible ? views::InkDropState::ACTIVATED
                                 : views::InkDropState::DEACTIVATED,
                  nullptr);
 }
 
-void BubbleIconView::OnBubbleWidgetCreated(views::Widget* bubble_widget) {
+void PageActionIconView::OnBubbleWidgetCreated(views::Widget* bubble_widget) {
   widget_observer_.SetWidget(bubble_widget);
 
   if (bubble_widget->IsVisible())
     SetHighlighted(true);
 }
 
-bool BubbleIconView::Refresh() {
+bool PageActionIconView::Refresh() {
   return false;
 }
 
-void BubbleIconView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
+void PageActionIconView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
   node_data->role = ax::mojom::Role::kButton;
   node_data->SetName(GetTextForTooltipAndAccessibleName());
 }
 
-bool BubbleIconView::GetTooltipText(const gfx::Point& p,
-                                    base::string16* tooltip) const {
+bool PageActionIconView::GetTooltipText(const gfx::Point& p,
+                                        base::string16* tooltip) const {
   if (IsBubbleShowing())
     return false;
   *tooltip = GetTextForTooltipAndAccessibleName();
   return true;
 }
 
-gfx::Size BubbleIconView::CalculatePreferredSize() const {
+gfx::Size PageActionIconView::CalculatePreferredSize() const {
   gfx::Size image_rect(image_->GetPreferredSize());
   image_rect.Enlarge(GetInsets().width(), GetInsets().height());
   return image_rect;
 }
 
-void BubbleIconView::Layout() {
+void PageActionIconView::Layout() {
   image_->SetBoundsRect(GetContentsBounds());
 }
 
-bool BubbleIconView::OnMousePressed(const ui::MouseEvent& event) {
+bool PageActionIconView::OnMousePressed(const ui::MouseEvent& event) {
   // If the bubble is showing then don't reshow it when the mouse is released.
   suppress_mouse_released_action_ = IsBubbleShowing();
   if (!suppress_mouse_released_action_ && event.IsOnlyLeftMouseButton())
@@ -123,7 +123,7 @@
   return true;
 }
 
-void BubbleIconView::OnMouseReleased(const ui::MouseEvent& event) {
+void PageActionIconView::OnMouseReleased(const ui::MouseEvent& event) {
   // If this is the second click on this view then the bubble was showing on the
   // mouse pressed event and is hidden now. Prevent the bubble from reshowing by
   // doing nothing here.
@@ -144,7 +144,7 @@
   OnPressed(activated);
 }
 
-bool BubbleIconView::OnKeyPressed(const ui::KeyEvent& event) {
+bool PageActionIconView::OnKeyPressed(const ui::KeyEvent& event) {
   if (event.key_code() != ui::VKEY_RETURN && event.key_code() != ui::VKEY_SPACE)
     return false;
 
@@ -156,7 +156,7 @@
   return true;
 }
 
-bool BubbleIconView::OnKeyReleased(const ui::KeyEvent& event) {
+bool PageActionIconView::OnKeyReleased(const ui::KeyEvent& event) {
   if (event.key_code() != ui::VKEY_SPACE)
     return false;
 
@@ -164,40 +164,40 @@
   return true;
 }
 
-void BubbleIconView::ViewHierarchyChanged(
+void PageActionIconView::ViewHierarchyChanged(
     const ViewHierarchyChangedDetails& details) {
   View::ViewHierarchyChanged(details);
   if (details.is_add && GetNativeTheme())
     UpdateIcon();
 }
 
-void BubbleIconView::OnNativeThemeChanged(const ui::NativeTheme* theme) {
+void PageActionIconView::OnNativeThemeChanged(const ui::NativeTheme* theme) {
   UpdateIcon();
 }
 
-void BubbleIconView::OnThemeChanged() {
+void PageActionIconView::OnThemeChanged() {
   UpdateIcon();
 }
 
-void BubbleIconView::AddInkDropLayer(ui::Layer* ink_drop_layer) {
+void PageActionIconView::AddInkDropLayer(ui::Layer* ink_drop_layer) {
   image_->SetPaintToLayer();
   image_->layer()->SetFillsBoundsOpaquely(false);
   views::InkDropHostView::AddInkDropLayer(ink_drop_layer);
 }
 
-void BubbleIconView::RemoveInkDropLayer(ui::Layer* ink_drop_layer) {
+void PageActionIconView::RemoveInkDropLayer(ui::Layer* ink_drop_layer) {
   views::InkDropHostView::RemoveInkDropLayer(ink_drop_layer);
   image_->DestroyLayer();
 }
 
-std::unique_ptr<views::InkDrop> BubbleIconView::CreateInkDrop() {
+std::unique_ptr<views::InkDrop> PageActionIconView::CreateInkDrop() {
   std::unique_ptr<views::InkDropImpl> ink_drop =
       CreateDefaultFloodFillInkDropImpl();
   ink_drop->SetShowHighlightOnFocus(true);
   return std::move(ink_drop);
 }
 
-std::unique_ptr<views::InkDropRipple> BubbleIconView::CreateInkDropRipple()
+std::unique_ptr<views::InkDropRipple> PageActionIconView::CreateInkDropRipple()
     const {
   return std::make_unique<views::FloodFillInkDropRipple>(
       size(), GetInkDropCenterBasedOnLastEvent(), GetInkDropBaseColor(),
@@ -205,7 +205,7 @@
 }
 
 std::unique_ptr<views::InkDropHighlight>
-BubbleIconView::CreateInkDropHighlight() const {
+PageActionIconView::CreateInkDropHighlight() const {
   std::unique_ptr<views::InkDropHighlight> highlight =
       CreateDefaultInkDropHighlight(
           gfx::RectF(GetMirroredRect(GetContentsBounds())).CenterPoint(),
@@ -217,7 +217,7 @@
   return highlight;
 }
 
-SkColor BubbleIconView::GetInkDropBaseColor() const {
+SkColor PageActionIconView::GetInkDropBaseColor() const {
   const SkColor ink_color_opaque = GetNativeTheme()->GetSystemColor(
       ui::NativeTheme::kColorId_TextfieldDefaultColor);
   if (ui::MaterialDesignController::IsNewerMaterialUi()) {
@@ -227,14 +227,15 @@
   return color_utils::DeriveDefaultIconColor(ink_color_opaque);
 }
 
-std::unique_ptr<views::InkDropMask> BubbleIconView::CreateInkDropMask() const {
+std::unique_ptr<views::InkDropMask> PageActionIconView::CreateInkDropMask()
+    const {
   if (!LocationBarView::IsRounded())
     return nullptr;
   return std::make_unique<views::RoundRectInkDropMask>(size(), gfx::Insets(),
                                                        height() / 2.f);
 }
 
-void BubbleIconView::OnGestureEvent(ui::GestureEvent* event) {
+void PageActionIconView::OnGestureEvent(ui::GestureEvent* event) {
   if (event->type() == ui::ET_GESTURE_TAP) {
     AnimateInkDrop(views::InkDropState::ACTIVATED, event);
     ExecuteCommand(EXECUTE_SOURCE_GESTURE);
@@ -242,20 +243,20 @@
   }
 }
 
-void BubbleIconView::ExecuteCommand(ExecuteSource source) {
+void PageActionIconView::ExecuteCommand(ExecuteSource source) {
   OnExecuting(source);
   if (command_updater_)
     command_updater_->ExecuteCommand(command_id_);
 }
 
-void BubbleIconView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
+void PageActionIconView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
   views::BubbleDialogDelegateView* bubble = GetBubble();
   if (bubble)
     bubble->OnAnchorBoundsChanged();
   InkDropHostView::OnBoundsChanged(previous_bounds);
 }
 
-void BubbleIconView::UpdateIcon() {
+void PageActionIconView::UpdateIcon() {
   const ui::NativeTheme* theme = GetNativeTheme();
   SkColor icon_color =
       active_ ? theme->GetSystemColor(
@@ -267,32 +268,33 @@
       GetVectorIcon(), GetLayoutConstant(LOCATION_BAR_ICON_SIZE), icon_color));
 }
 
-void BubbleIconView::SetActiveInternal(bool active) {
+void PageActionIconView::SetActiveInternal(bool active) {
   if (active_ == active)
     return;
   active_ = active;
   UpdateIcon();
 }
 
-content::WebContents* BubbleIconView::GetWebContents() const {
-  return delegate_->GetWebContentsForBubbleIconView();
+content::WebContents* PageActionIconView::GetWebContents() const {
+  return delegate_->GetWebContentsForPageActionIconView();
 }
 
-BubbleIconView::WidgetObserver::WidgetObserver(BubbleIconView* parent)
+PageActionIconView::WidgetObserver::WidgetObserver(PageActionIconView* parent)
     : parent_(parent), scoped_observer_(this) {}
 
-BubbleIconView::WidgetObserver::~WidgetObserver() = default;
+PageActionIconView::WidgetObserver::~WidgetObserver() = default;
 
-void BubbleIconView::WidgetObserver::SetWidget(views::Widget* widget) {
+void PageActionIconView::WidgetObserver::SetWidget(views::Widget* widget) {
   scoped_observer_.RemoveAll();
   scoped_observer_.Add(widget);
 }
 
-void BubbleIconView::WidgetObserver::OnWidgetDestroying(views::Widget* widget) {
+void PageActionIconView::WidgetObserver::OnWidgetDestroying(
+    views::Widget* widget) {
   scoped_observer_.Remove(widget);
 }
 
-void BubbleIconView::WidgetObserver::OnWidgetVisibilityChanged(
+void PageActionIconView::WidgetObserver::OnWidgetVisibilityChanged(
     views::Widget* widget,
     bool visible) {
   // |widget| is a bubble that has just got shown / hidden.
diff --git a/chrome/browser/ui/views/location_bar/bubble_icon_view.h b/chrome/browser/ui/views/page_action/page_action_icon_view.h
similarity index 85%
rename from chrome/browser/ui/views/location_bar/bubble_icon_view.h
rename to chrome/browser/ui/views/page_action/page_action_icon_view.h
index e95e2bc..3c7a819c 100644
--- a/chrome/browser/ui/views/location_bar/bubble_icon_view.h
+++ b/chrome/browser/ui/views/page_action/page_action_icon_view.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_BUBBLE_ICON_VIEW_H_
-#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_BUBBLE_ICON_VIEW_H_
+#ifndef CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_ICON_VIEW_H_
+#define CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_ICON_VIEW_H_
 
 #include <memory>
 
@@ -29,20 +29,21 @@
 class BubbleDialogDelegateView;
 }
 
-// Represents an icon on the omnibox that shows a bubble when clicked.
+// Represents an inbuilt (as opposed to an extension) page action icon that
+// shows a bubble when clicked.
 // TODO(spqchan): Convert this to subclass Button.
-class BubbleIconView : public views::InkDropHostView {
+class PageActionIconView : public views::InkDropHostView {
  public:
   class Delegate {
    public:
-    virtual content::WebContents* GetWebContentsForBubbleIconView() = 0;
+    virtual content::WebContents* GetWebContentsForPageActionIconView() = 0;
     virtual OmniboxTint GetTint() = 0;
   };
 
   void Init();
 
-  // Invoked when a bubble for this icon is created. The BubbleIconView changes
-  // highlights based on this widget's visibility.
+  // Invoked when a bubble for this icon is created. The PageActionIconView
+  // changes highlights based on this widget's visibility.
   void OnBubbleWidgetCreated(views::Widget* bubble_widget);
 
   // Returns the bubble instance for the icon.
@@ -59,10 +60,10 @@
     EXECUTE_SOURCE_GESTURE,
   };
 
-  BubbleIconView(CommandUpdater* command_updater,
-                 int command_id,
-                 Delegate* delegate);
-  ~BubbleIconView() override;
+  PageActionIconView(CommandUpdater* command_updater,
+                     int command_id,
+                     Delegate* delegate);
+  ~PageActionIconView() override;
 
   // Returns true if a related bubble is showing.
   bool IsBubbleShowing() const;
@@ -141,7 +142,7 @@
  private:
   class WidgetObserver : public views::WidgetObserver {
    public:
-    explicit WidgetObserver(BubbleIconView* parent);
+    explicit WidgetObserver(PageActionIconView* parent);
     ~WidgetObserver() override;
 
     void SetWidget(views::Widget* widget);
@@ -152,7 +153,7 @@
     void OnWidgetVisibilityChanged(views::Widget* widget,
                                    bool visible) override;
 
-    BubbleIconView* const parent_;
+    PageActionIconView* const parent_;
     ScopedObserver<views::Widget, views::WidgetObserver> scoped_observer_;
     DISALLOW_COPY_AND_ASSIGN(WidgetObserver);
   };
@@ -185,7 +186,7 @@
   // prevent the bubble from reshowing.
   bool suppress_mouse_released_action_;
 
-  DISALLOW_COPY_AND_ASSIGN(BubbleIconView);
+  DISALLOW_COPY_AND_ASSIGN(PageActionIconView);
 };
 
-#endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_BUBBLE_ICON_VIEW_H_
+#endif  // CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_ICON_VIEW_H_
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
index aa78c014..7ff5190 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
@@ -16,8 +16,8 @@
 
 ManagePasswordsIconViews::ManagePasswordsIconViews(
     CommandUpdater* updater,
-    BubbleIconView::Delegate* delegate)
-    : BubbleIconView(updater, IDC_MANAGE_PASSWORDS_FOR_PAGE, delegate),
+    PageActionIconView::Delegate* delegate)
+    : PageActionIconView(updater, IDC_MANAGE_PASSWORDS_FOR_PAGE, delegate),
       state_(password_manager::ui::INACTIVE_STATE) {
   DCHECK(delegate);
 #if defined(OS_MACOSX)
@@ -69,10 +69,10 @@
 }
 
 void ManagePasswordsIconViews::OnExecuting(
-    BubbleIconView::ExecuteSource source) {}
+    PageActionIconView::ExecuteSource source) {}
 
 bool ManagePasswordsIconViews::OnMousePressed(const ui::MouseEvent& event) {
-  bool result = BubbleIconView::OnMousePressed(event);
+  bool result = PageActionIconView::OnMousePressed(event);
   PasswordBubbleViewBase::CloseCurrentBubble();
   return result;
 }
@@ -88,7 +88,7 @@
     // If it still somehow got this key event, the bubble shouldn't be reopened.
     return true;
   }
-  return BubbleIconView::OnKeyPressed(event);
+  return PageActionIconView::OnKeyPressed(event);
 }
 
 const gfx::VectorIcon& ManagePasswordsIconViews::GetVectorIcon() const {
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h
index cc8eee1..010f3c6 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h
+++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.h
@@ -8,27 +8,27 @@
 #include "base/macros.h"
 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h"
 #include "chrome/browser/ui/passwords/manage_passwords_icon_view.h"
-#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
+#include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 #include "ui/views/controls/image_view.h"
 
 class CommandUpdater;
 
 // View for the password icon in the Omnibox.
 class ManagePasswordsIconViews : public ManagePasswordsIconView,
-                                 public BubbleIconView {
+                                 public PageActionIconView {
  public:
   ManagePasswordsIconViews(CommandUpdater* updater,
-                           BubbleIconView::Delegate* delegate);
+                           PageActionIconView::Delegate* delegate);
   ~ManagePasswordsIconViews() override;
 
   // ManagePasswordsIconView:
   void SetState(password_manager::ui::State state) override;
 
-  // BubbleIconView:
+  // PageActionIconView:
   views::BubbleDialogDelegateView* GetBubble() const override;
   bool Refresh() override;
-  void OnExecuting(BubbleIconView::ExecuteSource source) override;
+  void OnExecuting(PageActionIconView::ExecuteSource source) override;
   bool OnMousePressed(const ui::MouseEvent& event) override;
   bool OnKeyPressed(const ui::KeyEvent& event) override;
   const gfx::VectorIcon& GetVectorIcon() const override;
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc
index 96107c8e..01312d19 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -299,7 +299,7 @@
     bool already_bookmarked,
     bookmarks::BookmarkBubbleObserver* observer) {
   views::View* anchor_view = location_bar();
-  BubbleIconView* const star_view = location_bar()->star_view();
+  PageActionIconView* const star_view = location_bar()->star_view();
   if (!ui::MaterialDesignController::IsSecondaryUiMaterial()) {
     if (star_view && star_view->visible())
       anchor_view = star_view;
@@ -322,7 +322,8 @@
     translate::TranslateErrors::Type error_type,
     bool is_user_gesture) {
   views::View* anchor_view = location_bar();
-  BubbleIconView* translate_icon_view = location_bar()->translate_icon_view();
+  PageActionIconView* translate_icon_view =
+      location_bar()->translate_icon_view();
   if (!ui::MaterialDesignController::IsSecondaryUiMaterial()) {
     if (translate_icon_view && translate_icon_view->visible())
       anchor_view = translate_icon_view;
diff --git a/chrome/browser/ui/views/translate/translate_icon_view.cc b/chrome/browser/ui/views/translate/translate_icon_view.cc
index b3c641e..171afca 100644
--- a/chrome/browser/ui/views/translate/translate_icon_view.cc
+++ b/chrome/browser/ui/views/translate/translate_icon_view.cc
@@ -19,8 +19,8 @@
 #include "ui/base/resource/resource_bundle.h"
 
 TranslateIconView::TranslateIconView(CommandUpdater* command_updater,
-                                     BubbleIconView::Delegate* delegate)
-    : BubbleIconView(command_updater, IDC_TRANSLATE_PAGE, delegate) {
+                                     PageActionIconView::Delegate* delegate)
+    : PageActionIconView(command_updater, IDC_TRANSLATE_PAGE, delegate) {
   DCHECK(delegate);
   set_id(VIEW_ID_TRANSLATE_BUTTON);
 }
@@ -51,7 +51,7 @@
 }
 
 void TranslateIconView::OnExecuting(
-    BubbleIconView::ExecuteSource execute_source) {}
+    PageActionIconView::ExecuteSource execute_source) {}
 
 void TranslateIconView::OnPressed(bool activated) {
   translate::ReportUiAction(activated
diff --git a/chrome/browser/ui/views/translate/translate_icon_view.h b/chrome/browser/ui/views/translate/translate_icon_view.h
index c86dde0..8d3d1e9 100644
--- a/chrome/browser/ui/views/translate/translate_icon_view.h
+++ b/chrome/browser/ui/views/translate/translate_icon_view.h
@@ -6,25 +6,25 @@
 #define CHROME_BROWSER_UI_VIEWS_TRANSLATE_TRANSLATE_ICON_VIEW_H_
 
 #include "base/macros.h"
-#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h"
+#include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 
 class CommandUpdater;
 
 // The location bar icon to show the Translate bubble where the user can have
 // the page translated.
-class TranslateIconView : public BubbleIconView {
+class TranslateIconView : public PageActionIconView {
  public:
   TranslateIconView(CommandUpdater* command_updater,
-                    BubbleIconView::Delegate* delegate);
+                    PageActionIconView::Delegate* delegate);
   ~TranslateIconView() override;
 
-  // BubbleIconView:
+  // PageActionIconView:
   views::BubbleDialogDelegateView* GetBubble() const override;
   bool Refresh() override;
 
  protected:
-  // BubbleIconView:
-  void OnExecuting(BubbleIconView::ExecuteSource execute_source) override;
+  // PageActionIconView:
+  void OnExecuting(PageActionIconView::ExecuteSource execute_source) override;
   void OnPressed(bool activated) override;
   const gfx::VectorIcon& GetVectorIcon() const override;
   base::string16 GetTextForTooltipAndAccessibleName() const override;
diff --git a/chrome/browser/ui/webui/settings/chromeos/smb_handler.cc b/chrome/browser/ui/webui/settings/chromeos/smb_handler.cc
index 849d6d5..2145e31 100644
--- a/chrome/browser/ui/webui/settings/chromeos/smb_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/smb_handler.cc
@@ -12,17 +12,13 @@
 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
 #include "chrome/browser/chromeos/smb_client/smb_service.h"
 #include "chrome/browser/profiles/profile.h"
-
-namespace {
-void DoNothingCallback(base::File::Error error) {
-  return;
-}
-}  // namespace
+#include "content/public/browser/web_ui_message_handler.h"
 
 namespace chromeos {
 namespace settings {
 
-SmbHandler::SmbHandler(Profile* profile) : profile_(profile) {}
+SmbHandler::SmbHandler(Profile* profile)
+    : profile_(profile), weak_ptr_factory_(this) {}
 
 SmbHandler::~SmbHandler() = default;
 
@@ -49,7 +45,15 @@
   mo.writable = true;
 
   service->Mount(mo, base::FilePath(mountUrl), username, password,
-                 base::BindOnce(&DoNothingCallback));
+                 base::BindOnce(&SmbHandler::HandleSmbMountResponse,
+                                weak_ptr_factory_.GetWeakPtr()));
+}
+
+void SmbHandler::HandleSmbMountResponse(base::File::Error error) {
+  std::string result = error == base::File::FILE_OK ? "success" : "failure";
+
+  AllowJavascript();
+  FireWebUIListener("on-add-smb-share", base::Value(result));
 }
 
 }  // namespace settings
diff --git a/chrome/browser/ui/webui/settings/chromeos/smb_handler.h b/chrome/browser/ui/webui/settings/chromeos/smb_handler.h
index fc7e1463..4bd6a951 100644
--- a/chrome/browser/ui/webui/settings/chromeos/smb_handler.h
+++ b/chrome/browser/ui/webui/settings/chromeos/smb_handler.h
@@ -5,7 +5,9 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SMB_HANDLER_H_
 #define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_SMB_HANDLER_H_
 
+#include "base/files/file.h"
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
 
 class Profile;
@@ -26,7 +28,11 @@
   // WebUI call to mount an Smb Filesystem.
   void HandleSmbMount(const base::ListValue* args);
 
+  // Callback handler for SmbMount.
+  void HandleSmbMountResponse(base::File::Error error);
+
   Profile* const profile_;
+  base::WeakPtrFactory<SmbHandler> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SmbHandler);
 };
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index af0463d..e93d704 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -810,6 +810,10 @@
     {"smbShareUrl", IDS_SETTINGS_DOWNLOADS_ADD_SHARE_URL},
     {"smbShareUsername", IDS_SETTINGS_DOWNLOADS_ADD_SHARE_USERNAME},
     {"smbSharePassword", IDS_SETTINGS_DOWNLOADS_ADD_SHARE_PASSWORD},
+    {"smbShareAddedSuccessfulMessage",
+     IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_SUCCESS_MESSAGE},
+    {"smbShareAddedErrorMessage",
+     IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_ERROR_MESSAGE},
 #endif
   };
   AddLocalizedStringsBulk(html_source, localized_strings,
diff --git a/chrome/common/extensions/docs/server2/integration_test.py b/chrome/common/extensions/docs/server2/integration_test.py
index 6faabe1a..1711b939 100755
--- a/chrome/common/extensions/docs/server2/integration_test.py
+++ b/chrome/common/extensions/docs/server2/integration_test.py
@@ -166,15 +166,23 @@
           path = path_without_ext
 
         def check_result(response):
+          is_ok = response.status == 200;
+          is_redirect = response.status == 302;
           # TODO(dbertoni@chromium.org): Explore following redirects and/or
           # keeping an explicit list of files that expect 200 vs. 302.
-          self.assertTrue(response.status == 200 or response.status == 302,
+          self.assertTrue(is_ok or is_redirect,
                           'Got %s when rendering %s' % (response.status, path))
 
+          self.assertTrue(is_redirect or len(response.content),
+              'Rendered content length was 0 when rendering %s' % path)
+
           # This is reaaaaally rough since usually these will be tiny templates
-          # that render large files. At least it'll catch zero-length responses.
-          self.assertTrue(len(response.content) >= len(content) or
-                          response.status == 302,
+          # that render large files.
+          self.assertTrue(is_redirect or
+                          len(response.content) >= len(content) or
+                          # Zip files may be served differently than stored
+                          # locally.
+                          path.endswith('.zip'),
               'Rendered content length was %s vs template content length %s '
               'when rendering %s' % (len(response.content), len(content), path))
 
diff --git a/chrome/common/extensions/permissions/permissions_data_unittest.cc b/chrome/common/extensions/permissions/permissions_data_unittest.cc
index 1708231f..0d6fcdd 100644
--- a/chrome/common/extensions/permissions/permissions_data_unittest.cc
+++ b/chrome/common/extensions/permissions/permissions_data_unittest.cc
@@ -89,22 +89,18 @@
   const GURL invalid_url("chrome-debugger://foo/bar.html");
 
   std::string error;
-  EXPECT_EQ(block_chrome_urls,
-            PermissionsData::IsRestrictedUrl(
-                chrome_settings_url,
-                extension,
-                &error)) << name;
+  EXPECT_EQ(block_chrome_urls, extension->permissions_data()->IsRestrictedUrl(
+                                   chrome_settings_url, &error))
+      << name;
   if (block_chrome_urls)
     EXPECT_EQ(manifest_errors::kCannotAccessChromeUrl, error) << name;
   else
     EXPECT_TRUE(error.empty()) << name;
 
   error.clear();
-  EXPECT_EQ(block_chrome_urls,
-            PermissionsData::IsRestrictedUrl(
-                chrome_extension_url,
-                extension,
-                &error)) << name;
+  EXPECT_EQ(block_chrome_urls, extension->permissions_data()->IsRestrictedUrl(
+                                   chrome_extension_url, &error))
+      << name;
   if (block_chrome_urls)
     EXPECT_EQ(manifest_errors::kCannotAccessExtensionUrl, error) << name;
   else
@@ -112,14 +108,15 @@
 
   // Google should never be a restricted url.
   error.clear();
-  EXPECT_FALSE(PermissionsData::IsRestrictedUrl(
-      google_url, extension, &error)) << name;
+  EXPECT_FALSE(
+      extension->permissions_data()->IsRestrictedUrl(google_url, &error))
+      << name;
   EXPECT_TRUE(error.empty()) << name;
 
   // We should always be able to access our own extension pages.
   error.clear();
-  EXPECT_FALSE(PermissionsData::IsRestrictedUrl(
-      self_url, extension, &error)) << name;
+  EXPECT_FALSE(extension->permissions_data()->IsRestrictedUrl(self_url, &error))
+      << name;
   EXPECT_TRUE(error.empty()) << name;
 
   // We should only allow other schemes for extensions when it's a whitelisted
@@ -128,8 +125,8 @@
   bool allow_on_other_schemes = PermissionsData::CanExecuteScriptEverywhere(
       extension->id(), extension->location());
   EXPECT_EQ(!allow_on_other_schemes,
-            PermissionsData::IsRestrictedUrl(
-                invalid_url, extension, &error)) << name;
+            extension->permissions_data()->IsRestrictedUrl(invalid_url, &error))
+      << name;
   if (!allow_on_other_schemes) {
     EXPECT_EQ(ErrorUtils::FormatErrorMessage(
                   manifest_errors::kCannotAccessPage,
diff --git a/chrome/installer/linux/rpm/build.sh b/chrome/installer/linux/rpm/build.sh
index d2d40ea..0bcd868 100755
--- a/chrome/installer/linux/rpm/build.sh
+++ b/chrome/installer/linux/rpm/build.sh
@@ -253,6 +253,7 @@
 case "$TARGETARCH" in
   arm )
     export ARCHITECTURE="armhf"
+    stage_install_rpm
     ;;
   ia32 )
     export ARCHITECTURE="i386"
diff --git a/chrome/test/data/webui/.eslintrc.js b/chrome/test/data/webui/.eslintrc.js
index 8938c0e..f28d0056c 100644
--- a/chrome/test/data/webui/.eslintrc.js
+++ b/chrome/test/data/webui/.eslintrc.js
@@ -3,10 +3,7 @@
 // found in the LICENSE file.
 
 module.exports = {
-  'env': {
-    'browser': true,
-    'es6': true
-  },
+  'env': {'browser': true, 'es6': true},
   'rules': {
     'no-restricted-properties': 'off',
   },
diff --git a/chrome/test/data/webui/PRESUBMIT.py b/chrome/test/data/webui/PRESUBMIT.py
index ed60fbe2..badd377 100644
--- a/chrome/test/data/webui/PRESUBMIT.py
+++ b/chrome/test/data/webui/PRESUBMIT.py
@@ -15,6 +15,8 @@
         input_api, output_api)
   finally:
     sys.path = old_sys_path
+  results += input_api.canned_checks.CheckPatchFormatted(input_api, output_api,
+                                                         check_js=True)
   return results
 
 
diff --git a/chrome/test/data/webui/a11y/accessibility_test.js b/chrome/test/data/webui/a11y/accessibility_test.js
index 5729d7ea..5678d4d6 100644
--- a/chrome/test/data/webui/a11y/accessibility_test.js
+++ b/chrome/test/data/webui/a11y/accessibility_test.js
@@ -95,8 +95,7 @@
   for (let violation of violations) {
     if (violation.id in filter) {
       let exclusionRule = filter[violation.id];
-      violation.nodes = violation.nodes.filter(
-          (node) => !exclusionRule(node));
+      violation.nodes = violation.nodes.filter((node) => !exclusionRule(node));
     }
 
     if (violation.nodes.length > 0) {
@@ -120,8 +119,8 @@
   testDef.setup = testDef.setup || (() => {});
 
   // Define a test for each audit rule separately.
-  let rules = axeOptions.runOnly ?
-      axeOptions.runOnly.values : AccessibilityTest.ruleIds;
+  let rules = axeOptions.runOnly ? axeOptions.runOnly.values :
+                                   AccessibilityTest.ruleIds;
   rules.forEach((ruleId) => {
     // Skip rules disabled in axeOptions.
     if (axeOptions.rules && ruleId in axeOptions.rules &&
@@ -134,18 +133,16 @@
     // Replace hyphens, which break the build.
     newTestDef.name = newTestDef.name.replace(new RegExp('-', 'g'), '_');
     newTestDef.axeOptions = Object.assign({}, axeOptions);
-    newTestDef.axeOptions.runOnly = {
-      type: 'rule',
-      values: [ruleId]
-    };
+    newTestDef.axeOptions.runOnly = {type: 'rule', values: [ruleId]};
 
     TEST_F(testFixture, newTestDef.name, () => {
       // Define the mocha tests
       suite(newTestDef.name, () => {
         setup(newTestDef.setup.bind(newTestDef));
         for (let testMember in newTestDef.tests) {
-          test(testMember, AccessibilityTest.getMochaTest_(
-              testMember, newTestDef));
+          test(
+              testMember,
+              AccessibilityTest.getMochaTest_(testMember, newTestDef));
         }
       });
       mocha.grep(newTestDef.name).run();
diff --git a/chrome/test/data/webui/about_invalidations_browsertest.js b/chrome/test/data/webui/about_invalidations_browsertest.js
index cb4c36f4..36524e10 100644
--- a/chrome/test/data/webui/about_invalidations_browsertest.js
+++ b/chrome/test/data/webui/about_invalidations_browsertest.js
@@ -23,16 +23,15 @@
 // Test that registering an invalidations appears properly on the textarea.
 TEST_F('InvalidationsWebUITest', 'testRegisteringNewInvalidation', function() {
   var invalidationsLog = $('invalidations-log');
-  var invalidation = [{
-    isUnknownVersion: 'true',
-    objectId: {name: 'EXTENSIONS', source: 1004}
-  }];
+  var invalidation = [
+    {isUnknownVersion: 'true', objectId: {name: 'EXTENSIONS', source: 1004}}
+  ];
   invalidationsLog.value = '';
   chrome.invalidations.logInvalidations(invalidation);
   var isContained =
-    invalidationsLog.value.indexOf(
-      'Received Invalidation with type ' +
-      '"EXTENSIONS" version "Unknown" with payload "undefined"') != -1;
+      invalidationsLog.value.indexOf(
+          'Received Invalidation with type ' +
+          '"EXTENSIONS" version "Unknown" with payload "undefined"') != -1;
   expectTrue(isContained, 'Actual log is:' + invalidationsLog.value);
 
 });
@@ -46,27 +45,26 @@
   var newNewState = 'TRANSIENT_INVALIDATION_ERROR';
 
   chrome.invalidations.updateInvalidatorState(newState);
-  var isContainedState = invalidationsState.textContent.indexOf(
-      'INVALIDATIONS_ENABLED') != -1;
+  var isContainedState =
+      invalidationsState.textContent.indexOf('INVALIDATIONS_ENABLED') != -1;
   expectTrue(isContainedState, 'could not change the invalidations text');
 
   invalidationsLog.value = '';
   chrome.invalidations.updateInvalidatorState(newNewState);
   var isContainedState2 = invalidationsState.textContent.indexOf(
-      'TRANSIENT_INVALIDATION_ERROR') != -1;
+                              'TRANSIENT_INVALIDATION_ERROR') != -1;
   expectTrue(isContainedState2, 'could not change the invalidations text');
-  var isContainedLog =
-    invalidationsLog.value.indexOf(
-      'Invalidations service state changed to ' +
-      '"TRANSIENT_INVALIDATION_ERROR"') != -1;
+  var isContainedLog = invalidationsLog.value.indexOf(
+                           'Invalidations service state changed to ' +
+                           '"TRANSIENT_INVALIDATION_ERROR"') != -1;
   expectTrue(isContainedLog, 'Actual log is:' + invalidationsLog.value);
 });
 
 // Test that objects ids appear on the table.
 TEST_F('InvalidationsWebUITest', 'testRegisteringNewIds', function() {
   var newDataType = [
-    { name: 'EXTENSIONS', source: 1004, totalCount: 0},
-    { name: 'FAVICON_IMAGE', source: 1004, totalCount: 0}
+    {name: 'EXTENSIONS', source: 1004, totalCount: 0},
+    {name: 'FAVICON_IMAGE', source: 1004, totalCount: 0}
   ];
   var pattern1 = ['Fake', '1004', 'EXTENSIONS', '0', '0', '', '', ''];
   var pattern2 = ['Fake', '1004', 'FAVICON_IMAGE', '0', '0', '', '', ''];
@@ -84,10 +82,10 @@
     var pattern1Test = true;
     var pattern2Test = true;
     for (var cell = 0; cell < oidTable.rows[row].cells.length; cell++) {
-      pattern1Test = pattern1Test
-          && (pattern1[cell] == oidTable.rows[row].cells[cell].textContent);
-      pattern2Test = pattern2Test
-          && (pattern2[cell] == oidTable.rows[row].cells[cell].textContent);
+      pattern1Test = pattern1Test &&
+          (pattern1[cell] == oidTable.rows[row].cells[cell].textContent);
+      pattern2Test = pattern2Test &&
+          (pattern2[cell] == oidTable.rows[row].cells[cell].textContent);
     }
     if (pattern1Test)
       expectEquals('greyed', oidTable.rows[row].className);
@@ -99,12 +97,14 @@
     if (foundPattern2)
       expectTrue(foundPattern1, 'The entries were not ordererd');
   }
-  expectTrue(foundPattern1 && foundPattern2, "couldn't find both objects ids");
+  expectTrue(foundPattern1 && foundPattern2, 'couldn\'t find both objects ids');
 });
 
 // Test that registering new handlers appear on the website.
 TEST_F('InvalidationsWebUITest', 'testUpdatingRegisteredHandlers', function() {
-  function text() { return $('registered-handlers').textContent; }
+  function text() {
+    return $('registered-handlers').textContent;
+  }
   chrome.invalidations.updateHandlers(['FakeApi', 'FakeClient']);
   expectNotEquals(text().indexOf('FakeApi'), -1);
   expectNotEquals(text().indexOf('FakeClient'), -1);
@@ -118,5 +118,5 @@
 TEST_F('InvalidationsWebUITest', 'testUpdatingInternalDisplay', function() {
   var newDetailedStatus = {MessagesSent: 1};
   chrome.invalidations.updateDetailedStatus(newDetailedStatus);
-  expectEquals( $('internal-display').value, '{\n  \"MessagesSent\": 1\n}');
+  expectEquals($('internal-display').value, '{\n  \"MessagesSent\": 1\n}');
 });
diff --git a/chrome/test/data/webui/accessibility_audit_browsertest.js b/chrome/test/data/webui/accessibility_audit_browsertest.js
index 38905258..f988a07 100644
--- a/chrome/test/data/webui/accessibility_audit_browsertest.js
+++ b/chrome/test/data/webui/accessibility_audit_browsertest.js
@@ -43,9 +43,8 @@
   /** @override */
   setUp: function() {
     this.accessibilityAuditConfig.auditRulesToIgnore = [];
-    this.accessibilityAuditConfig.auditRulesToRun = ['lowContrastElements',
-                                                     'badAriaRole',
-                                                     'controlsWithoutLabel'];
+    this.accessibilityAuditConfig.auditRulesToRun =
+        ['lowContrastElements', 'badAriaRole', 'controlsWithoutLabel'];
   },
 
   tearDown: function() {
@@ -90,7 +89,7 @@
   // Contrast ratio
   var style = document.createElement('style');
   style.innerText = 'body { background-color: #ffff }\n' +
-                    'p { color: #ffffff }';
+      'p { color: #ffffff }';
   document.head.appendChild(style);
 
   // Bad ARIA role
@@ -166,36 +165,37 @@
 
 // Test that an audit failure causes a test failure, if both
 // |runAccessibilityChecks| and |accessibilityIssuesAreErrors| are true.
-TEST_F('WebUIAccessibilityAuditBrowserTest_ShouldFail', 'testWithAuditFailures',
-       function() {
-  expectAuditWillRun(1, this.accessibilityAuditConfig);
-  addAuditFailures();
-});
+TEST_F(
+    'WebUIAccessibilityAuditBrowserTest_ShouldFail', 'testWithAuditFailures',
+    function() {
+      expectAuditWillRun(1, this.accessibilityAuditConfig);
+      addAuditFailures();
+    });
 
 // Test that the accessibility audit does not run if |runAccessibilityChecks|
 // is false.
-TEST_F('WebUIAccessibilityAuditBrowserTest',
-       'testWithAuditFailures_a11yChecksDisabled',
-       function() {
-  expectAuditWillNotRun();
-  this.disableAccessibilityChecks();
-  addAuditFailures();
-});
+TEST_F(
+    'WebUIAccessibilityAuditBrowserTest',
+    'testWithAuditFailures_a11yChecksDisabled', function() {
+      expectAuditWillNotRun();
+      this.disableAccessibilityChecks();
+      addAuditFailures();
+    });
 
 // Tests that the accessibility audit will run but not cause a test failure when
 // accessibilityIssuesAreErrors(false) is called in the test function
-TEST_F('WebUIAccessibilityAuditBrowserTest',
-       'testWithAuditFailures_a11yIssuesAreWarnings',
-        function() {
-  this.accessibilityIssuesAreErrors = false;
-  expectAuditWillRun(1, this.accessibilityAuditConfig);
-  expectReportConsoleWarning();
+TEST_F(
+    'WebUIAccessibilityAuditBrowserTest',
+    'testWithAuditFailures_a11yIssuesAreWarnings', function() {
+      this.accessibilityIssuesAreErrors = false;
+      expectAuditWillRun(1, this.accessibilityAuditConfig);
+      expectReportConsoleWarning();
 
-  this.expectedWarnings = 1;
-  this.expectedErrors = 2;
-  this.enableAccessibilityChecks();
-  addAuditFailures();
-});
+      this.expectedWarnings = 1;
+      this.expectedErrors = 2;
+      this.enableAccessibilityChecks();
+      addAuditFailures();
+    });
 
 /**
  * Test fixture with |runAccessibilityChecks| set to false.
@@ -217,11 +217,11 @@
  * @constructor
  * @extends {WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture}
  */
-function WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture_ShouldFail()
-{}
+function
+WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture_ShouldFail() {}
 
-WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture_ShouldFail.prototype =
-{
+WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture_ShouldFail
+    .prototype = {
   __proto__:
       WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture.prototype,
 
@@ -232,50 +232,51 @@
 
 // Test that the accessibility audit does not run when |runAccessibilityChecks|
 // is set to false in the test fixture.
-TEST_F('WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture',
-       'testWithAuditFailures_a11yChecksNotEnabled',
-       function() {
-  expectAuditWillNotRun();
-  addAuditFailures();
-});
+TEST_F(
+    'WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture',
+    'testWithAuditFailures_a11yChecksNotEnabled', function() {
+      expectAuditWillNotRun();
+      addAuditFailures();
+    });
 
 // Test that the accessibility audit does run if the enableAccessibilityChecks()
 // method is called in the test function.
-TEST_F('WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture_ShouldFail',
-       'testWithAuditFailures',
-       function() {
-  expectAuditWillRun(1, this.accessibilityAuditConfig);
-  this.enableAccessibilityChecks();
-  addAuditFailures();
-});
+TEST_F(
+    'WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture_ShouldFail',
+    'testWithAuditFailures', function() {
+      expectAuditWillRun(1, this.accessibilityAuditConfig);
+      this.enableAccessibilityChecks();
+      addAuditFailures();
+    });
 
 // Test that the accessibility audit runs when the expectAccessibilityOk()
 // method is called.
-TEST_F('WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture',
-       'testRunningAuditManually_noErrors',
-       function() {
-  expectAuditWillRun(1, this.accessibilityAuditConfig);
-  expectAccessibilityOk();
-});
+TEST_F(
+    'WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture',
+    'testRunningAuditManually_noErrors', function() {
+      expectAuditWillRun(1, this.accessibilityAuditConfig);
+      expectAccessibilityOk();
+    });
 
 // Test that calling expectAccessibilityOk() when there are accessibility issues
 // on the page causes the test to fail.
-TEST_F('WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture_ShouldFail',
-       'testRunningAuditManually_withErrors',
-       function() {
-  expectAuditWillRun(1, this.accessibilityAuditConfig);
-  addAuditFailures();
-  expectAccessibilityOk();
-});
+TEST_F(
+    'WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture_ShouldFail',
+    'testRunningAuditManually_withErrors', function() {
+      expectAuditWillRun(1, this.accessibilityAuditConfig);
+      addAuditFailures();
+      expectAccessibilityOk();
+    });
 
 // Test that calling expectAccessibilityOk() multiple times will cause the
 // accessibility audit to run multiple times.
-TEST_F('WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture',
-       'testRunningAuditManuallySeveralTimes', function() {
-  expectAuditWillRun(2, this.accessibilityAuditConfig);
-  expectAccessibilityOk();
-  expectAccessibilityOk();
-});
+TEST_F(
+    'WebUIAccessibilityAuditBrowserTest_TestsDisabledInFixture',
+    'testRunningAuditManuallySeveralTimes', function() {
+      expectAuditWillRun(2, this.accessibilityAuditConfig);
+      expectAccessibilityOk();
+      expectAccessibilityOk();
+    });
 
 /**
  * Test fixture with |accessibilityIssuesAreErrors| set to false.
@@ -307,75 +308,75 @@
 
 // Tests that the accessibility audit will run but not cause a test failure when
 // |accessibilityIssuesAreErrors| is false in the test fixture.
-TEST_F('WebUIAccessibilityAuditBrowserTest_IssuesAreWarnings',
-       'testWithAuditFailures',
-        function() {
-  expectAuditWillRun(1, this.accessibilityAuditConfig);
-  expectReportConsoleWarning();
-  this.expectedWarnings = 1;
-  this.expectedErrors = 2;
+TEST_F(
+    'WebUIAccessibilityAuditBrowserTest_IssuesAreWarnings',
+    'testWithAuditFailures', function() {
+      expectAuditWillRun(1, this.accessibilityAuditConfig);
+      expectReportConsoleWarning();
+      this.expectedWarnings = 1;
+      this.expectedErrors = 2;
 
-  this.enableAccessibilityChecks();
-  addAuditFailures();
-});
+      this.enableAccessibilityChecks();
+      addAuditFailures();
+    });
 
 // Tests that the accessibility audit will run and call a test failure when
 // accessibilityIssuesAreErrors(true) is called in the test function.
-TEST_F('WebUIAccessibilityAuditBrowserTest_IssuesAreWarnings_ShouldFail',
-       'testWithAuditFailuresAndIssuesAreErrors',
-        function() {
-  expectAuditWillRun(1, this.accessibilityAuditConfig);
-  this.expectedWarnings = 1;
-  this.expectedErrors = 2;
+TEST_F(
+    'WebUIAccessibilityAuditBrowserTest_IssuesAreWarnings_ShouldFail',
+    'testWithAuditFailuresAndIssuesAreErrors', function() {
+      expectAuditWillRun(1, this.accessibilityAuditConfig);
+      this.expectedWarnings = 1;
+      this.expectedErrors = 2;
 
-  this.accessibilityIssuesAreErrors = true;
-  this.enableAccessibilityChecks();
+      this.accessibilityIssuesAreErrors = true;
+      this.enableAccessibilityChecks();
 
-  addAuditFailures();
-});
+      addAuditFailures();
+    });
 
 // Tests that the accessibility audit will run twice if expectAccessibilityOk()
 // is called during the test function and |runAccessibilityChecks| is true in
 // the test fixture.
-TEST_F('WebUIAccessibilityAuditBrowserTest_IssuesAreWarnings',
-       'testWithAuditFailuresAndExpectA11yOk',
-        function() {
-  expectAuditWillRun(2, this.accessibilityAuditConfig);
+TEST_F(
+    'WebUIAccessibilityAuditBrowserTest_IssuesAreWarnings',
+    'testWithAuditFailuresAndExpectA11yOk', function() {
+      expectAuditWillRun(2, this.accessibilityAuditConfig);
 
-  expectAccessibilityOk();
+      expectAccessibilityOk();
 
-  this.expectedWarnings = 1;
-  this.expectedErrors = 2;
-  expectReportConsoleWarning();
+      this.expectedWarnings = 1;
+      this.expectedErrors = 2;
+      expectReportConsoleWarning();
 
-  this.enableAccessibilityChecks();
+      this.enableAccessibilityChecks();
 
-  addAuditFailures();
-});
+      addAuditFailures();
+    });
 
 // Tests that parts of the page can be ignored on a per-audit rule basis.
-TEST_F('WebUIAccessibilityAuditBrowserTest_IssuesAreWarnings',
-       'testCanIgnoreSelectors',
-        function() {
-  this.disableAccessibilityChecks();
-  addAuditFailures();
-  var accessibilityResults = [];
-  try {
-    assertAccessibilityOk(accessibilityResults);
-  } catch (e) {
-    // Expected error from assertion
-  }
-  expectEquals(3, accessibilityResults.length);
+TEST_F(
+    'WebUIAccessibilityAuditBrowserTest_IssuesAreWarnings',
+    'testCanIgnoreSelectors', function() {
+      this.disableAccessibilityChecks();
+      addAuditFailures();
+      var accessibilityResults = [];
+      try {
+        assertAccessibilityOk(accessibilityResults);
+      } catch (e) {
+        // Expected error from assertion
+      }
+      expectEquals(3, accessibilityResults.length);
 
-  accessibilityResults.length = 0;
-  this.accessibilityAuditConfig.ignoreSelectors('lowContrastElements', '*');
-  try {
-    assertAccessibilityOk(accessibilityResults);
-  } catch (e) {
-    // Expected error from assertion
-  }
-  expectEquals(2, accessibilityResults.length);
-  for (var i = 0; i < accessibilityResults.length; i++) {
-    expectFalse(accessibilityResults[i].rule.name == 'lowContrastElements');
-  }
-});
+      accessibilityResults.length = 0;
+      this.accessibilityAuditConfig.ignoreSelectors('lowContrastElements', '*');
+      try {
+        assertAccessibilityOk(accessibilityResults);
+      } catch (e) {
+        // Expected error from assertion
+      }
+      expectEquals(2, accessibilityResults.length);
+      for (var i = 0; i < accessibilityResults.length; i++) {
+        expectFalse(accessibilityResults[i].rule.name == 'lowContrastElements');
+      }
+    });
diff --git a/chrome/test/data/webui/assertions.js b/chrome/test/data/webui/assertions.js
index cd7bc9b..6ffca4428 100644
--- a/chrome/test/data/webui/assertions.js
+++ b/chrome/test/data/webui/assertions.js
@@ -27,17 +27,15 @@
   }, []);
   resetTestState();
   assertFalse(result[0]);
-  assertEquals(2, result[1].match(
-      /message1: expected false to be true/g).length);
+  assertEquals(
+      2, result[1].match(/message1: expected false to be true/g).length);
 });
 
 TEST_F('WebUIAssertionsTest', 'testConstructedMessage', function() {
   var message = 'myErrorMessage';
-  var result = runTestFunction(
-      'testConstructMessage',
-      function() {
-        assertTrue(false, message);
-      }, []);
+  var result = runTestFunction('testConstructMessage', function() {
+    assertTrue(false, message);
+  }, []);
   resetTestState();
   assertNotEquals(
       -1, result[1].indexOf(message + ': expected false to be true'));
diff --git a/chrome/test/data/webui/async_gen.js b/chrome/test/data/webui/async_gen.js
index d842800..dc08b3c 100644
--- a/chrome/test/data/webui/async_gen.js
+++ b/chrome/test/data/webui/async_gen.js
@@ -71,8 +71,8 @@
 var continueTest2;
 
 TEST_F('WebUIBrowserAsyncGenTest', 'TestPreloadOnceOnNavigate', function() {
-  window.addEventListener('hashchange', this.continueTest(
-      WhenTestDone.DEFAULT, function() {
+  window.addEventListener(
+      'hashchange', this.continueTest(WhenTestDone.DEFAULT, function() {
         testDone();
       }));
   window.location = DUMMY_URL + '#anchor';
@@ -106,47 +106,47 @@
 // Test that runAllActionsAsync can be called with multiple functions, and with
 // bound, saved, or mixed arguments.
 TEST_F('WebUIBrowserAsyncGenTest', 'TestRunAllActionsAsyncMock', function() {
-  this.makeAndRegisterMockHandler(['testBoundArgs',
-                                   'testSavedArgs',
-                                   'testMixedArgs',
-                                   ]);
+  this.makeAndRegisterMockHandler([
+    'testBoundArgs',
+    'testSavedArgs',
+    'testMixedArgs',
+  ]);
   // Bind some arguments.
   var var1, var2;
-  this.mockHandler.expects(once()).testBoundArgs().
-      will(runAllActionsAsync(WhenTestDone.DEFAULT,
-                              callFunction(function(args) {
-                                var1 = args[0];
-                              }, ['val1']),
-                              callFunction(function(args) {
-                                var2 = args[0];
-                              }, ['val2'])));
+  this.mockHandler.expects(once()).testBoundArgs().will(
+      runAllActionsAsync(WhenTestDone.DEFAULT, callFunction(function(args) {
+                           var1 = args[0];
+                         }, ['val1']), callFunction(function(args) {
+                           var2 = args[0];
+                         }, ['val2'])));
 
   // Receive some saved arguments.
   var var3, var4;
   var savedArgs = new SaveMockArguments();
   var savedArgs2 = new SaveMockArguments();
-  this.mockHandler.expects(once()).testSavedArgs(
-      savedArgs.match(savedArgs2.match(eq(['passedVal1'])))).
-      will(runAllActionsAsync(
+  this.mockHandler.expects(once())
+      .testSavedArgs(savedArgs.match(savedArgs2.match(eq(['passedVal1']))))
+      .will(runAllActionsAsync(
           WhenTestDone.DEFAULT,
           callFunctionWithSavedArgs(savedArgs, function(args) {
             var3 = args[0];
-          }),
-          callFunctionWithSavedArgs(savedArgs2, function(args) {
+          }), callFunctionWithSavedArgs(savedArgs2, function(args) {
             var4 = args[0];
           })));
 
   // Receive some saved arguments and some bound arguments.
   var var5, var6, var7, var8;
-  this.mockHandler.expects(once()).testMixedArgs(
-      savedArgs.match(savedArgs2.match(eq('passedVal2')))).
-      will(runAllActionsAsync(
+  this.mockHandler.expects(once())
+      .testMixedArgs(savedArgs.match(savedArgs2.match(eq('passedVal2'))))
+      .will(runAllActionsAsync(
           WhenTestDone.DEFAULT,
           callFunctionWithSavedArgs(
-              savedArgs, function(passedArgs, boundArgs) {
+              savedArgs,
+              function(passedArgs, boundArgs) {
                 var5 = passedArgs[0];
                 var6 = boundArgs[0];
-              }, ['val6']),
+              },
+              ['val6']),
           callFunctionWithSavedArgs(
               savedArgs2, function(passedArgs, boundArgs) {
                 var7 = passedArgs[0];
@@ -194,13 +194,11 @@
   this.makeAndRegisterMockGlobals(['setTestRanTrue']);
 
   // Mock the setTestRanTrue global function.
-  this.mockGlobals.expects(once()).setTestRanTrue().
-      will(runAllActionsAsync(
-          WhenTestDone.ALWAYS,
-          callGlobalWithSavedArgs(null, 'setTestRanTrue'),
-          callFunction(function() {
-            assertTrue(testRan);
-          })));
+  this.mockGlobals.expects(once()).setTestRanTrue().will(runAllActionsAsync(
+      WhenTestDone.ALWAYS, callGlobalWithSavedArgs(null, 'setTestRanTrue'),
+      callFunction(function() {
+        assertTrue(testRan);
+      })));
 
   // Cause setTestRanTrue to be invoked asynchronously.
   chrome.send('callJS', ['setTestRanTrue']);
@@ -272,19 +270,18 @@
   /** @inheritDoc */
   setUp: function() {
     this.makeAndRegisterMockGlobals(['setTestRanTrue']);
-    this.mockGlobals.expects(once()).setTestRanTrue().
-        will(runAllActionsAsync(
-            WhenTestDone.ALWAYS,
-            callGlobalWithSavedArgs(null, 'setTestRanTrue'),
-            callFunction(deferRunTest)));
+    this.mockGlobals.expects(once()).setTestRanTrue().will(runAllActionsAsync(
+        WhenTestDone.ALWAYS, callGlobalWithSavedArgs(null, 'setTestRanTrue'),
+        callFunction(deferRunTest)));
 
     // Cause setTestRanTrue to be invoked asynchronously.
     chrome.send('callJS', ['setTestRanTrue']);
   },
 };
 
-TEST_F('WebUIBrowserAsyncGenDeferredToGlobalTest', 'TestDeferRunTestToGlobal',
-       function() {
-  this.ranTest_ = true;
-  assertTrue(testRan);
-});
+TEST_F(
+    'WebUIBrowserAsyncGenDeferredToGlobalTest', 'TestDeferRunTestToGlobal',
+    function() {
+      this.ranTest_ = true;
+      assertTrue(testRan);
+    });
diff --git a/chrome/test/data/webui/bidichecker_tests.js b/chrome/test/data/webui/bidichecker_tests.js
index 5f7466a..4b908fd 100644
--- a/chrome/test/data/webui/bidichecker_tests.js
+++ b/chrome/test/data/webui/bidichecker_tests.js
@@ -18,17 +18,17 @@
   // TODO(ofri): Link to more comprehensive documentation when available.
   var filters = {
     // Page filters
-    "chrome://history" : {
+    'chrome://history': {
       // Filters for LTR UI
-      "LTR" : [
+      'LTR': [
         // BUG: http://crbug.com/80791
-        bidichecker.FilterFactory.atText("בדיקה")
+        bidichecker.FilterFactory.atText('בדיקה')
       ],
       // Filters for RTL UI
-      "RTL" : [
+      'RTL': [
         // BUG: http://crbug.com/80791
-        bidichecker.FilterFactory.atText("Google"),
-        bidichecker.FilterFactory.atText("www.google.com"),
+        bidichecker.FilterFactory.atText('Google'),
+        bidichecker.FilterFactory.atText('www.google.com'),
         // The following two are probably false positives since we can't
         // completely change the environment to RTL on Linux.
         // TODO(ofri): Verify that it's indeed a false positive.
@@ -36,75 +36,73 @@
         bidichecker.FilterFactory.locationClass('time')
       ]
     },
-    "chrome://settings/autofill" : {
-      "LTR" : [
+    'chrome://settings/autofill': {
+      'LTR': [
         // BUG: http://crbug.com/82267
-        bidichecker.FilterFactory.atText("משה ב כהן, דרך מנחם בגין")
+        bidichecker.FilterFactory.atText('משה ב כהן, דרך מנחם בגין')
       ],
-      "RTL" : [
+      'RTL': [
         // BUG: http://crbug.com/90322
         bidichecker.FilterFactory.atText(
-            "Milton C. Waddams, 4120 Freidrich Lane")
+            'Milton C. Waddams, 4120 Freidrich Lane')
       ]
     },
-    "chrome://plugins" : {
-      "RTL" : [
+    'chrome://plugins': {
+      'RTL': [
         // False positive
         bidichecker.FilterFactory.atText('x'),
         // Apparently also a false positive
-        bidichecker.FilterFactory.atText("undefined\n      undefined"),
+        bidichecker.FilterFactory.atText('undefined\n      undefined'),
         bidichecker.FilterFactory.locationClass('plugin-text')
       ]
     },
-    "chrome://newtab" : {
-      "RTL" : [
+    'chrome://newtab': {
+      'RTL': [
         // BUG: http://crbug.com/93339
-        bidichecker.FilterFactory.atText("Chrome Web Store"),
-        bidichecker.FilterFactory.atText("File Manager"),
-        bidichecker.FilterFactory.atText("Chrome Apps Debugger")
+        bidichecker.FilterFactory.atText('Chrome Web Store'),
+        bidichecker.FilterFactory.atText('File Manager'),
+        bidichecker.FilterFactory.atText('Chrome Apps Debugger')
       ]
     },
-    "chrome://feedback#0?description=%D7%91%D7%93%D7%99%D7%A7%D7%94" :
-    {
-      "LTR" : [
+    'chrome://feedback#0?description=%D7%91%D7%93%D7%99%D7%A7%D7%94': {
+      'LTR': [
         // BUG: http://crbug.com/90835
-        bidichecker.FilterFactory.atText("בדיקה")
+        bidichecker.FilterFactory.atText('בדיקה')
       ]
     },
-    "chrome://feedback#0?description=test" : {
-      "RTL" : [
+    'chrome://feedback#0?description=test': {
+      'RTL': [
         // BUG: http://crbug.com/90835
-        bidichecker.FilterFactory.atText("test"),
-        bidichecker.FilterFactory.atText("stub-user@example.com")
+        bidichecker.FilterFactory.atText('test'),
+        bidichecker.FilterFactory.atText('stub-user@example.com')
       ]
     },
-    "chrome://settings/browser" : {
-      "LTR" : [
+    'chrome://settings/browser': {
+      'LTR': [
         // BUG: http://crbug.com/93702
-        bidichecker.FilterFactory.atText(
-            "חדשות תוכן ועדכונים - ידיעות אחרונות")
+        bidichecker.FilterFactory.atText('חדשות תוכן ועדכונים - ידיעות אחרונות')
       ]
     },
-    "chrome://history-frame" : {
-      "LTR" : [
+    'chrome://history-frame': {
+      'LTR': [
         // BUG: http://crbug.com/119595
-        bidichecker.FilterFactory.atText("בדיקה")
+        bidichecker.FilterFactory.atText('בדיקה')
       ],
-      "RTL" : [
+      'RTL': [
         // BUG: http://crbug.com/119595
-        bidichecker.FilterFactory.atText("Google"),
-        bidichecker.FilterFactory.atText("www.google.com")
+        bidichecker.FilterFactory.atText('Google'),
+        bidichecker.FilterFactory.atText('www.google.com')
       ],
     },
   };
   var globalFilters = {
-    "RTL" : [
+    'RTL': [
       // BUG: http://crbug/158750
-      bidichecker.FilterFactory.locationId("timezone-select")
+      bidichecker.FilterFactory.locationId('timezone-select')
     ]
   };
 
-  var dir = isRTL ? "RTL" : "LTR";
+  var dir = isRTL ? 'RTL' : 'LTR';
   if (!filters.hasOwnProperty(pageName))
     pageName += '/';
   if (!filters.hasOwnProperty(pageName)) {
diff --git a/chrome/test/data/webui/bluetooth_internals_browsertest.js b/chrome/test/data/webui/bluetooth_internals_browsertest.js
index 6cdfcb8..ca41490 100644
--- a/chrome/test/data/webui/bluetooth_internals_browsertest.js
+++ b/chrome/test/data/webui/bluetooth_internals_browsertest.js
@@ -56,8 +56,8 @@
 
         this.binding = new mojo.Binding(mojom.BluetoothInternalsHandler, this);
         this.adapter = new TestAdapterProxy();
-        this.adapterBinding_ = new mojo.Binding(bluetooth.mojom.Adapter,
-                                                this.adapter);
+        this.adapterBinding_ =
+            new mojo.Binding(bluetooth.mojom.Adapter, this.adapter);
       }
 
       getAdapter() {
@@ -92,8 +92,8 @@
 
         return Promise.resolve({
           result: this.connectResult_,
-          device: this.deviceProxyMap.get(
-              address).binding.createInterfacePtrAndBind(),
+          device: this.deviceProxyMap.get(address)
+                      .binding.createInterfacePtrAndBind(),
         });
       }
 
@@ -122,8 +122,7 @@
       setTestDevices(devices) {
         this.devices_ = devices;
         this.devices_.forEach(function(device) {
-          this.deviceProxyMap.set(
-              device.address, new TestDeviceProxy(device));
+          this.deviceProxyMap.set(device.address, new TestDeviceProxy(device));
         }, this);
       }
     }
@@ -166,8 +165,8 @@
     }
 
     window.setupFn = () => {
-      this.bluetoothInternalsHandlerInterceptor = new MojoInterfaceInterceptor(
-          mojom.BluetoothInternalsHandler.name);
+      this.bluetoothInternalsHandlerInterceptor =
+          new MojoInterfaceInterceptor(mojom.BluetoothInternalsHandler.name);
       this.bluetoothInternalsHandlerInterceptor.oninterfacerequest = (e) => {
         this.adapterFactory = new TestAdapterFactoryProxy();
         this.adapterFactory.binding.bind(e.handle);
@@ -176,11 +175,10 @@
           this.fakeDeviceInfo1(),
           this.fakeDeviceInfo2(),
         ]);
-        this.adapterFactory.adapter.setTestAdapter(
-            this.fakeAdapterInfo());
+        this.adapterFactory.adapter.setTestAdapter(this.fakeAdapterInfo());
 
-        this.adapterFactory.adapter.deviceProxyMap.forEach(
-            function(deviceProxy) {
+        this.adapterFactory.adapter.deviceProxyMap
+            .forEach(function(deviceProxy) {
               deviceProxy.setTestServices([
                 this.fakeServiceInfo1(),
                 this.fakeServiceInfo2(),
@@ -215,9 +213,9 @@
    */
   fakeDeviceInfo1: function() {
     return {
-      address: "AA:AA:84:96:92:84",
-      name: "AAA",
-      nameForDisplay: "AAA",
+      address: 'AA:AA:84:96:92:84',
+      name: 'AAA',
+      nameForDisplay: 'AAA',
       rssi: {value: -40},
       services: [],
     };
@@ -229,9 +227,9 @@
    */
   fakeDeviceInfo2: function() {
     return {
-      address: "BB:BB:84:96:92:84",
-      name: "BBB",
-      nameForDisplay: "BBB",
+      address: 'BB:BB:84:96:92:84',
+      name: 'BBB',
+      nameForDisplay: 'BBB',
       rssi: null,
       services: [],
     };
@@ -244,9 +242,9 @@
    */
   fakeDeviceInfo3: function() {
     return {
-      address: "CC:CC:84:96:92:84",
-      name: "CCC",
-      nameForDisplay: "CCC",
+      address: 'CC:CC:84:96:92:84',
+      name: 'CCC',
+      nameForDisplay: 'CCC',
     };
   },
 
@@ -290,8 +288,7 @@
   },
 };
 
-TEST_F('BluetoothInternalsTest', 'Startup_BluetoothInternals',
-    function() {
+TEST_F('BluetoothInternalsTest', 'Startup_BluetoothInternals', function() {
   /** @const */ var PageManager = cr.ui.pageManager.PageManager;
 
   var adapterFactory = null;
@@ -363,8 +360,8 @@
      * @param {!device_collection.DeviceInfo} deviceInfo
      */
     function changeDevice(deviceInfo) {
-      var deviceRow = deviceTable.querySelector('#' + escapeDeviceAddress(
-          deviceInfo.address));
+      var deviceRow = deviceTable.querySelector(
+          '#' + escapeDeviceAddress(deviceInfo.address));
       var nameForDisplayColumn = deviceRow.children[0];
       var addressColumn = deviceRow.children[1];
       var rssiColumn = deviceRow.children[2];
@@ -377,8 +374,7 @@
 
       adapterBroker.adapterClient_.deviceChanged(deviceInfo);
 
-      expectEquals(deviceInfo.nameForDisplay,
-                   nameForDisplayColumn.textContent);
+      expectEquals(deviceInfo.nameForDisplay, nameForDisplayColumn.textContent);
       expectEquals(deviceInfo.address, addressColumn.textContent);
 
       if (deviceInfo.rssi) {
@@ -386,8 +382,8 @@
       }
 
       if (deviceInfo.services) {
-        expectEquals(String(deviceInfo.services.length),
-                     servicesColumn.textContent);
+        expectEquals(
+            String(deviceInfo.services.length), servicesColumn.textContent);
       } else {
         expectEquals('Unknown', servicesColumn.textContent);
       }
@@ -407,8 +403,8 @@
      * @param {boolean} expectRemoved
      */
     function expectDeviceRemoved(address, expectRemoved) {
-      var removedRow = deviceTable.querySelector(
-          '#' + escapeDeviceAddress(address));
+      var removedRow =
+          deviceTable.querySelector('#' + escapeDeviceAddress(address));
 
       expectEquals(expectRemoved, removedRow.classList.contains('removed'));
     }
@@ -458,7 +454,7 @@
       // Copy device info because device collection will not copy this object.
       var newDeviceInfo = fakeDeviceInfo1();
       newDeviceInfo.nameForDisplay = 'DDDD';
-      newDeviceInfo.rssi = { value: -20 };
+      newDeviceInfo.rssi = {value: -20};
       newDeviceInfo.services = ['service1', 'service2', 'service3'];
 
       changeDevice(newDeviceInfo);
@@ -477,7 +473,7 @@
 
       var newDeviceInfo = fakeDeviceInfo3();
       newDeviceInfo.nameForDisplay = 'DDDD';
-      newDeviceInfo.rssi = { value: -20 };
+      newDeviceInfo.rssi = {value: -20};
       newDeviceInfo.services = ['service1', 'service2', 'service3'];
 
       changeDevice(newDeviceInfo);
@@ -498,8 +494,8 @@
       var newDeviceInfo = fakeDeviceInfo3();
       adapterBroker.adapterClient_.deviceAdded(newDeviceInfo);
 
-      var deviceRow = deviceTable.querySelector('#' + escapeDeviceAddress(
-          newDeviceInfo.address));
+      var deviceRow = deviceTable.querySelector(
+          '#' + escapeDeviceAddress(newDeviceInfo.address));
       var rssiColumn = deviceRow.children[2];
       expectEquals('Unknown', rssiColumn.textContent);
 
@@ -522,8 +518,8 @@
 
     /* Sidebar Tests */
     test('Sidebar_Setup', function() {
-      var sidebarItems = Array.from(
-          sidebarNode.querySelectorAll('.sidebar-content li'));
+      var sidebarItems =
+          Array.from(sidebarNode.querySelectorAll('.sidebar-content li'));
 
       pageNames.forEach(function(pageName) {
         expectTrue(sidebarItems.some(function(item) {
@@ -604,9 +600,11 @@
       var snackbar1 = snackbar.Snackbar.show('Message 1');
       assertEquals(1, $('snackbar-container').children.length);
 
-      return whenSnackbarShows(snackbar1).then(function() {
-        return snackbar.Snackbar.dismiss();
-      }).then(finishSnackbarTest);
+      return whenSnackbarShows(snackbar1)
+          .then(function() {
+            return snackbar.Snackbar.dismiss();
+          })
+          .then(finishSnackbarTest);
     });
 
     test('Snackbar_QueueThreeDismiss', function() {
@@ -627,9 +625,12 @@
 
       whenSnackbarShows(snackbar1).then(next);
       whenSnackbarShows(snackbar2).then(next);
-      return whenSnackbarShows(snackbar3).then(next).then(function() {
-        expectEquals(expectedCalls, actualCalls);
-      }).then(finishSnackbarTest);
+      return whenSnackbarShows(snackbar3)
+          .then(next)
+          .then(function() {
+            expectEquals(expectedCalls, actualCalls);
+          })
+          .then(finishSnackbarTest);
     });
 
     test('Snackbar_QueueThreeDismissAll', function() {
@@ -652,19 +653,22 @@
       whenSnackbarShows(snackbar3).then(next);
       snackbar3.addEventListener('dismissed', next);
 
-      return whenSnackbarShows(snackbar1).then(function() {
-        return snackbar.Snackbar.dismiss(true);
-      }).then(function() {
-        expectEquals(0, snackbar.Snackbar.queue_.length);
-        expectFalse(!!snackbar.Snackbar.current_);
-      }).then(finishSnackbarTest);
+      return whenSnackbarShows(snackbar1)
+          .then(function() {
+            return snackbar.Snackbar.dismiss(true);
+          })
+          .then(function() {
+            expectEquals(0, snackbar.Snackbar.queue_.length);
+            expectFalse(!!snackbar.Snackbar.current_);
+          })
+          .then(finishSnackbarTest);
     });
 
     /* AdapterPage Tests */
     function checkAdapterFieldSet(adapterInfo) {
       for (var propName in adapterInfo) {
-        var valueCell = adapterFieldSet.querySelector(
-            '[data-field="' + propName + '"]');
+        var valueCell =
+            adapterFieldSet.querySelector('[data-field="' + propName + '"]');
         var value = adapterInfo[propName];
 
         if (typeof(value) === 'boolean') {
@@ -717,13 +721,8 @@
      * @param {!Object} deviceInfo
      */
     function checkDeviceDetailsFieldSet(detailsPage, deviceInfo) {
-      [
-        'name',
-        'address',
-        'isGattConnected',
-        'rssi.value',
-        'services.length',
-      ].forEach(function(propName){
+      ['name', 'address', 'isGattConnected', 'rssi.value', 'services.length',
+      ].forEach(function(propName) {
         var valueCell = detailsPage.querySelector(
             'fieldset [data-field="' + propName + '"]');
 
@@ -751,19 +750,20 @@
     test('DeviceDetailsPage_NewDelete', function() {
       var device = devices.item(0);
 
-      var deviceInspectLink = $(device.address).querySelector(
-          '[is="action-link"]');
+      var deviceInspectLink =
+          $(device.address).querySelector('[is="action-link"]');
 
       var deviceDetailsPageId = 'devices/' + device.address.toLowerCase();
 
       deviceInspectLink.click();
-      expectEquals("#" + deviceDetailsPageId, window.location.hash);
+      expectEquals('#' + deviceDetailsPageId, window.location.hash);
 
       var detailsPage = $(deviceDetailsPageId);
       assertTrue(!!detailsPage);
 
-      return adapterFactory.adapter.deviceProxyMap.get(
-          device.address).whenCalled('getServices').then(function() {
+      return adapterFactory.adapter.deviceProxyMap.get(device.address)
+          .whenCalled('getServices')
+          .then(function() {
             // At this point, the device details page should be fully loaded.
             checkDeviceDetailsFieldSet(detailsPage, device);
 
@@ -778,18 +778,19 @@
       var device = devices.item(0);
       var deviceDetailsPageId = 'devices/' + device.address.toLowerCase();
 
-      var deviceLinks = $(device.address).querySelectorAll(
-          '[is="action-link"]');
+      var deviceLinks =
+          $(device.address).querySelectorAll('[is="action-link"]');
 
       // First link is 'Inspect'.
       deviceLinks[0].click();
-      expectEquals("#" + deviceDetailsPageId, window.location.hash);
+      expectEquals('#' + deviceDetailsPageId, window.location.hash);
 
       var detailsPage = $(deviceDetailsPageId);
       assertTrue(!!detailsPage);
 
-      return adapterFactory.adapter.deviceProxyMap.get(
-          device.address).whenCalled('getServices').then(function() {
+      return adapterFactory.adapter.deviceProxyMap.get(device.address)
+          .whenCalled('getServices')
+          .then(function() {
             // At this point, the device details page should be fully loaded.
             checkDeviceDetailsFieldSet(detailsPage, device);
 
diff --git a/chrome/test/data/webui/certificate_viewer_dialog_test.js b/chrome/test/data/webui/certificate_viewer_dialog_test.js
index 5d7e4e8..afe1b53 100644
--- a/chrome/test/data/webui/certificate_viewer_dialog_test.js
+++ b/chrome/test/data/webui/certificate_viewer_dialog_test.js
@@ -54,22 +54,23 @@
     // Override the receive certificate function to catch when fields are
     // loaded.
     var getCertificateFields = cert_viewer.getCertificateFields;
-    cert_viewer.getCertificateFields = this.continueTest(WhenTestDone.ALWAYS,
-        function(certFieldDetails) {
-      getCertificateFields(certFieldDetails);
-      cert_viewer.getCertificateFields = getCertificateFields;
-      assertLT(0, certFields.childNodes.length);
+    cert_viewer.getCertificateFields =
+        this.continueTest(WhenTestDone.ALWAYS, function(certFieldDetails) {
+          getCertificateFields(certFieldDetails);
+          cert_viewer.getCertificateFields = getCertificateFields;
+          assertLT(0, certFields.childNodes.length);
 
-      // Test that a field can be selected to see the details for that field.
-      var item = getElementWithValue(certFields);
-      assertNotEquals(null, item);
-      certFields.selectedItem = item;
-      assertEquals(item.detail.payload.val, certFieldVal.textContent);
+          // Test that a field can be selected to see the details for that
+          // field.
+          var item = getElementWithValue(certFields);
+          assertNotEquals(null, item);
+          certFields.selectedItem = item;
+          assertEquals(item.detail.payload.val, certFieldVal.textContent);
 
-      // Test that selecting an item without a value empties the field.
-      certFields.selectedItem = certFields.childNodes[0];
-      assertEquals('', certFieldVal.textContent);
-    });
+          // Test that selecting an item without a value empties the field.
+          certFields.selectedItem = certFields.childNodes[0];
+          assertEquals('', certFieldVal.textContent);
+        });
     certHierarchy.selectedItem = certHierarchy.childNodes[0];
   }
 };
diff --git a/chrome/test/data/webui/chrome_send_browsertest.js b/chrome/test/data/webui/chrome_send_browsertest.js
index 582e30e..037b80ce 100644
--- a/chrome/test/data/webui/chrome_send_browsertest.js
+++ b/chrome/test/data/webui/chrome_send_browsertest.js
@@ -55,9 +55,8 @@
 
 // Test that the mocked chrome.send can call the original.
 TEST_F('ChromeSendPassthroughWebUITest', 'CanCallOriginal', function() {
-  this.mockHandler.expects(once()).checkSend().
-      will(callFunction(function() {
-                          chrome.originalSend('checkSend');
-                        }));
+  this.mockHandler.expects(once()).checkSend().will(callFunction(function() {
+    chrome.originalSend('checkSend');
+  }));
   chrome.send('checkSend');
 });
diff --git a/chrome/test/data/webui/cr_elements/cr_action_menu_test.js b/chrome/test/data/webui/cr_elements/cr_action_menu_test.js
index 1fa8e561..78a8800c 100644
--- a/chrome/test/data/webui/cr_elements/cr_action_menu_test.js
+++ b/chrome/test/data/webui/cr_elements/cr_action_menu_test.js
@@ -211,15 +211,17 @@
     items[1].setAttribute('role', 'checkbox');
     menu.showAt(dots);
 
-    return PolymerTest.flushTasks().then(() => {
-      assertEquals('menuitem', items[0].getAttribute('role'));
-      assertEquals('checkbox', items[1].getAttribute('role'));
+    return PolymerTest.flushTasks()
+        .then(() => {
+          assertEquals('menuitem', items[0].getAttribute('role'));
+          assertEquals('checkbox', items[1].getAttribute('role'));
 
-      menu.insertBefore(newItem, items[0]);
-      return PolymerTest.flushTasks();
-    }).then(() => {
-      assertEquals('menuitem', newItem.getAttribute('role'));
-    });
+          menu.insertBefore(newItem, items[0]);
+          return PolymerTest.flushTasks();
+        })
+        .then(() => {
+          assertEquals('menuitem', newItem.getAttribute('role'));
+        });
   });
 
   test('positioning', function() {
diff --git a/chrome/test/data/webui/cr_elements/cr_drawer_tests.js b/chrome/test/data/webui/cr_elements/cr_drawer_tests.js
index 478d8c4..859acf4 100644
--- a/chrome/test/data/webui/cr_elements/cr_drawer_tests.js
+++ b/chrome/test/data/webui/cr_elements/cr_drawer_tests.js
@@ -22,25 +22,27 @@
     const drawer = createDrawer('ltr');
     drawer.openDrawer();
 
-    return test_util.eventToPromise('transitionend', drawer).then(() => {
-      assertTrue(drawer.open);
+    return test_util.eventToPromise('transitionend', drawer)
+        .then(() => {
+          assertTrue(drawer.open);
 
-      // Clicking the content does not close the drawer.
-      MockInteractions.tap(document.querySelector('.drawer-content'));
-      assertFalse(drawer.classList.contains('closing'));
+          // Clicking the content does not close the drawer.
+          MockInteractions.tap(document.querySelector('.drawer-content'));
+          assertFalse(drawer.classList.contains('closing'));
 
-      const whenClosed = test_util.eventToPromise('close', drawer);
-      drawer.$.dialog.dispatchEvent(new MouseEvent('click', {
-        bubbles: true,
-        cancelable: true,
-        clientX: 300,  // Must be larger than the drawer width (256px).
-        clientY: 300,
-      }));
+          const whenClosed = test_util.eventToPromise('close', drawer);
+          drawer.$.dialog.dispatchEvent(new MouseEvent('click', {
+            bubbles: true,
+            cancelable: true,
+            clientX: 300,  // Must be larger than the drawer width (256px).
+            clientY: 300,
+          }));
 
-      return whenClosed;
-    }).then(() => {
-      assertFalse(drawer.open);
-    });
+          return whenClosed;
+        })
+        .then(() => {
+          assertFalse(drawer.open);
+        });
   });
 
   test('opened event', function() {
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
index d683718..18e4217 100644
--- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
+++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
@@ -58,9 +58,8 @@
       'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html',
 
   /** @override */
-  extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([
-    'cr_lazy_render_tests.js'
-  ]),
+  extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat(
+      ['cr_lazy_render_tests.js']),
 };
 
 TEST_F('CrElementsLazyRenderTest', 'All', function() {
@@ -77,8 +76,7 @@
   __proto__: CrElementsBrowserTest.prototype,
 
   /** @override */
-  browsePreload:
-      'chrome://resources/cr_elements/cr_profile_avatar_selector/' +
+  browsePreload: 'chrome://resources/cr_elements/cr_profile_avatar_selector/' +
       'cr_profile_avatar_selector.html',
 
   /** @override */
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js b/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js
index 80e4538..aa3fd6a 100644
--- a/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js
+++ b/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js
@@ -43,8 +43,7 @@
   __proto__: CrElementsFocusTest.prototype,
 
   /** @override */
-  browsePreload:
-      'chrome://resources/cr_elements/cr_profile_avatar_selector/' +
+  browsePreload: 'chrome://resources/cr_elements/cr_profile_avatar_selector/' +
       'cr_profile_avatar_selector.html',
 
   extraLibraries: CrElementsFocusTest.prototype.extraLibraries.concat([
diff --git a/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.js b/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.js
index c6d7031..015c987 100644
--- a/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.js
+++ b/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.js
@@ -18,10 +18,11 @@
       function createElement() {
         const avatarSelector =
             document.createElement('cr-profile-avatar-selector');
-        avatarSelector.avatars =
-            [{url: 'chrome://avatar1.png', label: 'avatar1'},
-             {url: 'chrome://avatar2.png', label: 'avatar2'},
-             {url: 'chrome://avatar3.png', label: 'avatar3'}];
+        avatarSelector.avatars = [
+          {url: 'chrome://avatar1.png', label: 'avatar1'},
+          {url: 'chrome://avatar2.png', label: 'avatar2'},
+          {url: 'chrome://avatar3.png', label: 'avatar3'}
+        ];
         return avatarSelector;
       }
 
diff --git a/chrome/test/data/webui/cr_elements/cr_toggle_test.js b/chrome/test/data/webui/cr_elements/cr_toggle_test.js
index a0bb7c1..21e98e4 100644
--- a/chrome/test/data/webui/cr_elements/cr_toggle_test.js
+++ b/chrome/test/data/webui/cr_elements/cr_toggle_test.js
@@ -72,16 +72,16 @@
     // Need to provide a valid |pointerId| for setPointerCapture() to not throw
     // an error.
     const xStart = 100;
-    toggle.dispatchEvent(new PointerEvent(
-        'pointerdown', {pointerId: 1, clientX: xStart}));
+    toggle.dispatchEvent(
+        new PointerEvent('pointerdown', {pointerId: 1, clientX: xStart}));
     let xEnd = xStart;
     if (moveDirection) {
       xEnd = moveDirection > 0 ? xStart + diff : xStart - diff;
-      toggle.dispatchEvent(new PointerEvent(
-          'pointermove', {pointerId: 1, clientX: xEnd}));
+      toggle.dispatchEvent(
+          new PointerEvent('pointermove', {pointerId: 1, clientX: xEnd}));
     }
-    toggle.dispatchEvent(new PointerEvent(
-        'pointerup', {pointerId: 1, clientX: xEnd}));
+    toggle.dispatchEvent(
+        new PointerEvent('pointerup', {pointerId: 1, clientX: xEnd}));
     MockInteractions.tap(toggle);
   }
 
@@ -106,14 +106,16 @@
   test('ToggleByPointerTap', function() {
     let whenChanged = test_util.eventToPromise('change', toggle);
     triggerPointerDownMoveUpTapSequence(0 /* no pointermove */);
-    return whenChanged.then(function() {
-      assertChecked();
-      whenChanged = test_util.eventToPromise('change', toggle);
-      triggerPointerDownMoveUpTapSequence(0 /* no pointermove */);
-      return whenChanged;
-    }).then(function() {
-      assertNotChecked();
-    });
+    return whenChanged
+        .then(function() {
+          assertChecked();
+          whenChanged = test_util.eventToPromise('change', toggle);
+          triggerPointerDownMoveUpTapSequence(0 /* no pointermove */);
+          return whenChanged;
+        })
+        .then(function() {
+          assertNotChecked();
+        });
   });
 
   // Test that the control is toggled if the user moves the pointer by a
@@ -122,15 +124,17 @@
     let whenChanged = test_util.eventToPromise('change', toggle);
     triggerPointerDownMoveUpTapSequence(
         1 /* right */, toggle.MOVE_THRESHOLD_PX - 1);
-    return whenChanged.then(function() {
-      assertChecked();
-      whenChanged = test_util.eventToPromise('change', toggle);
-      triggerPointerDownMoveUpTapSequence(
-          1 /* right */, toggle.MOVE_THRESHOLD_PX - 1);
-      return whenChanged;
-    }).then(function() {
-      assertNotChecked();
-    });
+    return whenChanged
+        .then(function() {
+          assertChecked();
+          whenChanged = test_util.eventToPromise('change', toggle);
+          triggerPointerDownMoveUpTapSequence(
+              1 /* right */, toggle.MOVE_THRESHOLD_PX - 1);
+          return whenChanged;
+        })
+        .then(function() {
+          assertNotChecked();
+        });
   });
 
   // Test that the control is toggled when the user moves the pointer while
@@ -139,22 +143,25 @@
     let whenChanged = test_util.eventToPromise('change', toggle);
     triggerPointerDownMoveUpTapSequence(
         1 /* right */, toggle.MOVE_THRESHOLD_PX);
-    return whenChanged.then(function() {
-      assertChecked();
-      whenChanged = test_util.eventToPromise('change', toggle);
-      triggerPointerDownMoveUpTapSequence(
-          -1 /* left */, toggle.MOVE_THRESHOLD_PX);
-      return whenChanged;
-    }).then(function() {
-      assertNotChecked();
-      whenChanged = test_util.eventToPromise('change', toggle);
+    return whenChanged
+        .then(function() {
+          assertChecked();
+          whenChanged = test_util.eventToPromise('change', toggle);
+          triggerPointerDownMoveUpTapSequence(
+              -1 /* left */, toggle.MOVE_THRESHOLD_PX);
+          return whenChanged;
+        })
+        .then(function() {
+          assertNotChecked();
+          whenChanged = test_util.eventToPromise('change', toggle);
 
-      // Test simple tapping after having dragged.
-      triggerPointerDownMoveUpTapSequence(0 /* no pointermove */);
-      return whenChanged;
-    }).then(function() {
-      assertChecked();
-    });
+          // Test simple tapping after having dragged.
+          triggerPointerDownMoveUpTapSequence(0 /* no pointermove */);
+          return whenChanged;
+        })
+        .then(function() {
+          assertChecked();
+        });
   });
 
   // Test that the control is toggled when the user presses the 'Enter' or
diff --git a/chrome/test/data/webui/cr_elements/cr_toolbar_search_field_tests.js b/chrome/test/data/webui/cr_elements/cr_toolbar_search_field_tests.js
index dd68801..1eb7496 100644
--- a/chrome/test/data/webui/cr_elements/cr_toolbar_search_field_tests.js
+++ b/chrome/test/data/webui/cr_elements/cr_toolbar_search_field_tests.js
@@ -39,7 +39,9 @@
       // construction and initialization of the cr-toolbar-search-field element.
       test('no initial search-changed event', function() {
         let didFire = false;
-        const onSearchChanged = function () { didFire = true; };
+        const onSearchChanged = function() {
+          didFire = true;
+        };
 
         // Need to attach listener event before the element is created, to catch
         // the unnecessary initial event.
diff --git a/chrome/test/data/webui/discards/discards_browsertest.js b/chrome/test/data/webui/discards/discards_browsertest.js
index 44162206..48465dc 100644
--- a/chrome/test/data/webui/discards/discards_browsertest.js
+++ b/chrome/test/data/webui/discards/discards_browsertest.js
@@ -43,45 +43,37 @@
   };
 
   ['title', 'tabUrl', 'visibility', 'isMedia', 'isFrozen', 'isDiscarded',
-      'isAutoDiscardable', 'discardCount', 'utilityRank', 'lastActiveSeconds']
+   'isAutoDiscardable', 'discardCount', 'utilityRank', 'lastActiveSeconds']
       .forEach((sortKey) => {
-    assertTrue(
-        discards.compareTabDiscardsInfos(sortKey, dummy1, dummy2) < 0);
-    assertTrue(
-        discards.compareTabDiscardsInfos(sortKey, dummy2, dummy1) > 0);
-    assertTrue(
-        discards.compareTabDiscardsInfos(sortKey, dummy1, dummy1) == 0);
-    assertTrue(
-        discards.compareTabDiscardsInfos(sortKey, dummy2, dummy2) == 0);
-  });
+        assertTrue(
+            discards.compareTabDiscardsInfos(sortKey, dummy1, dummy2) < 0);
+        assertTrue(
+            discards.compareTabDiscardsInfos(sortKey, dummy2, dummy1) > 0);
+        assertTrue(
+            discards.compareTabDiscardsInfos(sortKey, dummy1, dummy1) == 0);
+        assertTrue(
+            discards.compareTabDiscardsInfos(sortKey, dummy2, dummy2) == 0);
+      });
 });
 
 TEST_F('DiscardsTest', 'LastActiveToString', function() {
   // Test cases have the form [ 'expected output', input_in_seconds ].
-  [
-    [ 'just now', 0 ],
-    [ 'just now', 10 ],
-    [ 'just now', 59 ],
-    [ '1 minute ago', 60 ],
-    [ '10 minutes ago', 10 * 60 + 30 ],
-    [ '59 minutes ago', 59 * 60 + 59 ],
-    [ '1 hour ago', 60 * 60 ],
-    [ '1 hour and 1 minute ago', 61 * 60 ],
-    [ '1 hour and 10 minutes ago', 70 * 60 + 30 ],
-    [ '1 day ago', 24 * 60 * 60 ],
-    [ '2 days ago', 2.5 * 24 * 60 * 60 ],
-    [ '6 days ago', 6.9 * 24 * 60 * 60 ],
-    [ 'over 1 week ago', 7 * 24 * 60 * 60 ],
-    [ 'over 2 weeks ago', 2.5 * 7 * 24 * 60 * 60 ],
-    [ 'over 4 weeks ago', 30 * 24 * 60 * 60 ],
-    [ 'over 1 month ago', 30.5 * 24 * 60 * 60 ],
-    [ 'over 2 months ago', 2.5 * 30.5 * 24 * 60 * 60 ],
-    [ 'over 11 months ago', 364 * 24 * 60 * 60 ],
-    [ 'over 1 year ago', 365 * 24 * 60 * 60 ],
-    [ 'over 2 years ago', 2.3 * 365 * 24 * 60 * 60 ]
-  ].forEach((data) => {
-    assertEquals(data[0], discards.lastActiveToString(data[1]));
-  });
+  [['just now', 0], ['just now', 10], ['just now', 59], ['1 minute ago', 60],
+   ['10 minutes ago', 10 * 60 + 30], ['59 minutes ago', 59 * 60 + 59],
+   ['1 hour ago', 60 * 60], ['1 hour and 1 minute ago', 61 * 60],
+   ['1 hour and 10 minutes ago', 70 * 60 + 30], ['1 day ago', 24 * 60 * 60],
+   ['2 days ago', 2.5 * 24 * 60 * 60], ['6 days ago', 6.9 * 24 * 60 * 60],
+   ['over 1 week ago', 7 * 24 * 60 * 60],
+   ['over 2 weeks ago', 2.5 * 7 * 24 * 60 * 60],
+   ['over 4 weeks ago', 30 * 24 * 60 * 60],
+   ['over 1 month ago', 30.5 * 24 * 60 * 60],
+   ['over 2 months ago', 2.5 * 30.5 * 24 * 60 * 60],
+   ['over 11 months ago', 364 * 24 * 60 * 60],
+   ['over 1 year ago', 365 * 24 * 60 * 60],
+   ['over 2 years ago', 2.3 * 365 * 24 * 60 * 60]]
+      .forEach((data) => {
+        assertEquals(data[0], discards.lastActiveToString(data[1]));
+      });
 });
 
 TEST_F('DiscardsTest', 'MaybeMakePlural', function() {
diff --git a/chrome/test/data/webui/draganddroptoinput.js b/chrome/test/data/webui/draganddroptoinput.js
index 65550a0..1be13ba 100644
--- a/chrome/test/data/webui/draganddroptoinput.js
+++ b/chrome/test/data/webui/draganddroptoinput.js
@@ -5,7 +5,7 @@
 console.log('start guest js');
 
 var embedder = null;
-window.addEventListener('message', function (e) {
+window.addEventListener('message', function(e) {
   var data = JSON.parse(e.data)[0];
   window.console.log('guest gets message ' + data);
   if (data == 'create-channel') {
@@ -14,7 +14,7 @@
   }
 });
 
-var doPostMessage = function (msg) {
+var doPostMessage = function(msg) {
   window.console.log('guest posts message: ' + msg);
   embedder.postMessage(JSON.stringify([msg]), '*');
 };
@@ -25,7 +25,7 @@
 
 var destNode = document.getElementById('dest');
 var testStep = 0;
-destNode.addEventListener('dragenter', function (e) {
+destNode.addEventListener('dragenter', function(e) {
   console.log('node drag enter');
   if (testStep == 0) {
     doPostMessage('Step1: destNode gets dragenter');
@@ -33,14 +33,14 @@
   }
 });
 
-destNode.addEventListener('dragover', function (e) {
+destNode.addEventListener('dragover', function(e) {
   if (testStep == 1) {
     doPostMessage('Step2: destNode gets dragover');
     testStep = 2;
   }
 });
 
-destNode.addEventListener('drop', function (e) {
+destNode.addEventListener('drop', function(e) {
   if (testStep == 2) {
     doPostMessage('Step3: destNode gets drop');
     testStep = 3;
diff --git a/chrome/test/data/webui/extensions/a11y/extensions_a11y_test.js b/chrome/test/data/webui/extensions/a11y/extensions_a11y_test.js
index 8eba99c..4afcb538 100644
--- a/chrome/test/data/webui/extensions/a11y/extensions_a11y_test.js
+++ b/chrome/test/data/webui/extensions/a11y/extensions_a11y_test.js
@@ -105,8 +105,7 @@
   /** @override */
   tests: {
     'Accessible with No Extensions': function() {
-      let list =
-          document.querySelector('* /deep/ #items-list');
+      let list = document.querySelector('* /deep/ #items-list');
       assertEquals(list.extensions.length, 0);
       assertEquals(list.apps.length, 0);
     }
@@ -137,8 +136,7 @@
   /** @override */
   tests: {
     'Accessible with Extensions and Apps': function() {
-      let list =
-          document.querySelector('* /deep/ #items-list');
+      let list = document.querySelector('* /deep/ #items-list');
       assertEquals(list.extensions.length, 1);
       assertEquals(list.apps.length, 3);
     },
@@ -166,8 +164,8 @@
   /** @override */
   tests: {
     'Accessible with No Extensions or Apps': function() {
-      let list = document.querySelector(
-          '* /deep/ extensions-keyboard-shortcuts');
+      let list =
+          document.querySelector('* /deep/ extensions-keyboard-shortcuts');
       assertEquals(list.items.length, 0);
     },
   },
@@ -194,8 +192,8 @@
   /** @override */
   tests: {
     'Accessible with Extensions': function() {
-      let list = document.querySelector(
-          '* /deep/ extensions-keyboard-shortcuts');
+      let list =
+          document.querySelector('* /deep/ extensions-keyboard-shortcuts');
       assertEquals(list.items.length, 1);
     },
   },
diff --git a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js
index 98658554..cc8b1b3 100644
--- a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js
+++ b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js
@@ -8,8 +8,8 @@
 var ROOT_PATH = '../../../../../';
 
 // Polymer BrowserTest fixture.
-GEN_INCLUDE([
-    ROOT_PATH + 'chrome/test/data/webui/polymer_browser_test_base.js']);
+GEN_INCLUDE(
+    [ROOT_PATH + 'chrome/test/data/webui/polymer_browser_test_base.js']);
 GEN('#include "chrome/browser/ui/webui/extensions/' +
     'extension_settings_browsertest.h"');
 GEN('#include "chrome/common/chrome_features.h"');
@@ -226,11 +226,9 @@
   this.runMochaTest(extension_detail_view_tests.TestNames.LayoutSource);
 });
 
-TEST_F(
-    'CrExtensionsDetailViewTest', 'ClickableElements', function() {
-      this.runMochaTest(
-          extension_detail_view_tests.TestNames.ClickableElements);
-    });
+TEST_F('CrExtensionsDetailViewTest', 'ClickableElements', function() {
+  this.runMochaTest(extension_detail_view_tests.TestNames.ClickableElements);
+});
 
 TEST_F('CrExtensionsDetailViewTest', 'IndicatorTest', function() {
   this.runMochaTest(extension_detail_view_tests.TestNames.Indicator);
diff --git a/chrome/test/data/webui/extensions/extension_detail_view_test.js b/chrome/test/data/webui/extensions/extension_detail_view_test.js
index 1a8a6cc..37eb53d2 100644
--- a/chrome/test/data/webui/extensions/extension_detail_view_test.js
+++ b/chrome/test/data/webui/extensions/extension_detail_view_test.js
@@ -207,12 +207,10 @@
       mockDelegate.testClickingCalls(
           item.$$('#remove-extension'), 'deleteItem', [extensionData.id]);
       mockDelegate.testClickingCalls(
-          item.$$('#load-path > a[is=\'action-link\']'),
-          'showInFolder', [extensionData.id]);
+          item.$$('#load-path > a[is=\'action-link\']'), 'showInFolder',
+          [extensionData.id]);
       mockDelegate.testClickingCalls(
-          item.$$('#reload-button'),
-          'reloadItem',
-          [extensionData.id],
+          item.$$('#reload-button'), 'reloadItem', [extensionData.id],
           Promise.resolve());
     });
 
diff --git a/chrome/test/data/webui/extensions/extension_error_page_test.js b/chrome/test/data/webui/extensions/extension_error_page_test.js
index 6d547440..9bf5ae6a 100644
--- a/chrome/test/data/webui/extensions/extension_error_page_test.js
+++ b/chrome/test/data/webui/extensions/extension_error_page_test.js
@@ -168,7 +168,8 @@
       errorPage.push('data.runtimeErrors', nextRuntimeError);
       Polymer.dom.flush();
 
-      var errorElements = errorPage.querySelectorAll('* /deep/ .error-item .start');
+      var errorElements =
+          errorPage.querySelectorAll('* /deep/ .error-item .start');
       var ironCollapses = errorPage.querySelectorAll('* /deep/ iron-collapse');
       expectEquals(2, errorElements.length);
       expectEquals(2, ironCollapses.length);
@@ -198,7 +199,8 @@
       expectFalse(ironCollapses[0].opened);
 
       // Tapping the button sends the right parameter to open dev tool.
-      expectTrue(ironCollapses[1].querySelector('li').classList.contains('selected'));
+      expectTrue(
+          ironCollapses[1].querySelector('li').classList.contains('selected'));
       MockInteractions.tap(ironCollapses[1].querySelector('paper-button'));
       expectDeepEquals(mockDelegate.openDevToolsArgs, {
         renderProcessId: 111,
diff --git a/chrome/test/data/webui/extensions/extension_item_test.js b/chrome/test/data/webui/extensions/extension_item_test.js
index f573754..d1441261 100644
--- a/chrome/test/data/webui/extensions/extension_item_test.js
+++ b/chrome/test/data/webui/extensions/extension_item_test.js
@@ -26,8 +26,10 @@
     {selector: '#extension-id', text: `ID: ${extensionData.id}`},
     {selector: '#inspect-views'},
     {selector: '#inspect-views a[is="action-link"]', text: 'foo.html,'},
-    {selector: '#inspect-views a[is="action-link"]:nth-of-type(2)',
-     text: '1 more…'},
+    {
+      selector: '#inspect-views a[is="action-link"]:nth-of-type(2)',
+      text: '1 more…'
+    },
   ];
 
   /**
@@ -192,7 +194,9 @@
       // This is a bit of a pain to verify because the promises finish
       // asynchronously, so we have to use setTimeout()s.
       var firedLoadError = false;
-      item.addEventListener('load-error', () => { firedLoadError = true; });
+      item.addEventListener('load-error', () => {
+        firedLoadError = true;
+      });
 
       // This is easier to test with a TestBrowserProxy-style delegate.
       var proxyDelegate = new extensions.TestService();
@@ -208,18 +212,21 @@
       };
 
       MockInteractions.tap(item.$$('#dev-reload-button'));
-      return proxyDelegate.whenCalled('reloadItem').then(function(id) {
-        expectEquals(item.data.id, id);
-        return verifyEventPromise(false);
-      }).then(function() {
-        proxyDelegate.resetResolver('reloadItem');
-        proxyDelegate.setForceReloadItemError(true);
-        MockInteractions.tap(item.$$('#dev-reload-button'));
-        return proxyDelegate.whenCalled('reloadItem');
-      }).then(function(id) {
-        expectEquals(item.data.id, id);
-        return verifyEventPromise(true);
-      });
+      return proxyDelegate.whenCalled('reloadItem')
+          .then(function(id) {
+            expectEquals(item.data.id, id);
+            return verifyEventPromise(false);
+          })
+          .then(function() {
+            proxyDelegate.resetResolver('reloadItem');
+            proxyDelegate.setForceReloadItemError(true);
+            MockInteractions.tap(item.$$('#dev-reload-button'));
+            return proxyDelegate.whenCalled('reloadItem');
+          })
+          .then(function(id) {
+            expectEquals(item.data.id, id);
+            return verifyEventPromise(true);
+          });
     });
 
     test(assert(TestNames.Warnings), function() {
diff --git a/chrome/test/data/webui/extensions/extension_manager_test.js b/chrome/test/data/webui/extensions/extension_manager_test.js
index 4a8ce1c5..d98f1702 100644
--- a/chrome/test/data/webui/extensions/extension_manager_test.js
+++ b/chrome/test/data/webui/extensions/extension_manager_test.js
@@ -13,7 +13,9 @@
   };
 
   function getDataByName(list, name) {
-    return assert(list.find(function(el) { return el.name == name; }));
+    return assert(list.find(function(el) {
+      return el.name == name;
+    }));
   }
 
   var suiteName = 'ExtensionManagerTest';
diff --git a/chrome/test/data/webui/extensions/extension_manager_unit_test.js b/chrome/test/data/webui/extensions/extension_manager_unit_test.js
index 9a0664b..129f9e56 100644
--- a/chrome/test/data/webui/extensions/extension_manager_unit_test.js
+++ b/chrome/test/data/webui/extensions/extension_manager_unit_test.js
@@ -115,12 +115,12 @@
       const oldDescription = 'old description';
       const newDescription = 'new description';
 
-      const extension = extension_test_util.createExtensionInfo({
-        description: oldDescription
-      });
+      const extension = extension_test_util.createExtensionInfo(
+          {description: oldDescription});
       simulateExtensionInstall(extension);
       const secondExtension = extension_test_util.createExtensionInfo({
-        description: 'irrelevant', id: 'b'.repeat(32),
+        description: 'irrelevant',
+        id: 'b'.repeat(32),
       });
       simulateExtensionInstall(secondExtension);
 
diff --git a/chrome/test/data/webui/extensions/extension_navigation_helper_test.js b/chrome/test/data/webui/extensions/extension_navigation_helper_test.js
index 8933c82..cd0f2a0 100644
--- a/chrome/test/data/webui/extensions/extension_navigation_helper_test.js
+++ b/chrome/test/data/webui/extensions/extension_navigation_helper_test.js
@@ -48,8 +48,7 @@
       expectDeepEquals({page: Page.LIST}, navigationHelper.getCurrentPage());
 
       var currentLength = history.length;
-      navigationHelper.updateHistory(
-          {page: Page.DETAILS, extensionId: id});
+      navigationHelper.updateHistory({page: Page.DETAILS, extensionId: id});
       expectEquals(++currentLength, history.length);
 
       navigationHelper.updateHistory({page: Page.ERRORS, extensionId: id});
@@ -105,8 +104,7 @@
       for (let key in stateUrlPairs) {
         let entry = stateUrlPairs[key];
         history.pushState({}, '', entry.url);
-        expectDeepEquals(
-            entry.state, navigationHelper.getCurrentPage(), key);
+        expectDeepEquals(entry.state, navigationHelper.getCurrentPage(), key);
       }
 
       // Test state -> url.
@@ -127,8 +125,7 @@
       var expectedLength = history.length;
 
       // Navigating to a new page pushes new state.
-      navigationHelper.updateHistory(
-          {page: Page.DETAILS, extensionId: id1});
+      navigationHelper.updateHistory({page: Page.DETAILS, extensionId: id1});
       expectEquals(++expectedLength, history.length);
 
       // Navigating to a subpage (like the options page) just opens a dialog,
@@ -139,8 +136,7 @@
 
       // Navigating away from a subpage also shouldn't push state (it just
       // closes the dialog).
-      navigationHelper.updateHistory(
-          {page: Page.DETAILS, extensionId: id1});
+      navigationHelper.updateHistory({page: Page.DETAILS, extensionId: id1});
       expectEquals(expectedLength, history.length);
 
       // Navigating away should push new state.
@@ -154,8 +150,7 @@
 
       // Navigating away from a subpage to a page for a different item should
       // push state.
-      navigationHelper.updateHistory(
-          {page: Page.DETAILS, extensionId: id2});
+      navigationHelper.updateHistory({page: Page.DETAILS, extensionId: id2});
       expectEquals(++expectedLength, history.length);
 
       // Using replaceWith, which passes true for replaceState should not push
diff --git a/chrome/test/data/webui/extensions/extension_options_dialog_test.js b/chrome/test/data/webui/extensions/extension_options_dialog_test.js
index d51b038..adcb036d 100644
--- a/chrome/test/data/webui/extensions/extension_options_dialog_test.js
+++ b/chrome/test/data/webui/extensions/extension_options_dialog_test.js
@@ -41,19 +41,19 @@
       assertFalse(isDialogVisible());
       optionsDialog.show(data);
       const dialogElement = optionsDialog.$.dialog.getNative();
-      return test_util.whenAttributeIs(
-          dialogElement, 'open', '').then(function() {
-        assertTrue(isDialogVisible());
+      return test_util.whenAttributeIs(dialogElement, 'open', '')
+          .then(function() {
+            assertTrue(isDialogVisible());
 
-        const rect = dialogElement.getBoundingClientRect();
-        assertGE(rect.width, extensions.OptionsDialogMinWidth);
-        assertLE(rect.height, extensions.OptionsDialogMaxHeight);
+            const rect = dialogElement.getBoundingClientRect();
+            assertGE(rect.width, extensions.OptionsDialogMinWidth);
+            assertLE(rect.height, extensions.OptionsDialogMaxHeight);
 
-        assertEquals(
-            data.name,
-            assert(optionsDialog.$$('#icon-and-name-wrapper span'))
-                .textContent.trim());
-      });
+            assertEquals(
+                data.name,
+                assert(optionsDialog.$$('#icon-and-name-wrapper span'))
+                    .textContent.trim());
+          });
     });
   });
 
diff --git a/chrome/test/data/webui/extensions/extension_test_util.js b/chrome/test/data/webui/extensions/extension_test_util.js
index 71a1990..8801843 100644
--- a/chrome/test/data/webui/extensions/extension_test_util.js
+++ b/chrome/test/data/webui/extensions/extension_test_util.js
@@ -19,13 +19,12 @@
      *     expected to be called with.
      * @param {*=} opt_returnValue The value to return from the function call.
      */
-    testClickingCalls: function(element, callName, opt_expectedArgs,
-                                opt_returnValue) {
+    testClickingCalls: function(
+        element, callName, opt_expectedArgs, opt_returnValue) {
       var mock = new MockController();
       var mockMethod = mock.createFunctionMock(this, callName);
       mockMethod.returnValue = opt_returnValue;
-      MockMethod.prototype.addExpectation.apply(
-          mockMethod, opt_expectedArgs);
+      MockMethod.prototype.addExpectation.apply(mockMethod, opt_expectedArgs);
       MockInteractions.tap(element);
       mock.verifyMocks();
     },
@@ -69,8 +68,10 @@
      */
     addListener: function(target, eventName, opt_eventArgs) {
       assert(!this.listeners_.hasOwnProperty(eventName));
-      this.listeners_[eventName] =
-          {args: opt_eventArgs || {}, satisfied: false};
+      this.listeners_[eventName] = {
+        args: opt_eventArgs || {},
+        satisfied: false
+      };
       target.addEventListener(eventName, this.onEvent_.bind(this, eventName));
     },
 
@@ -144,7 +145,7 @@
    */
   function isElementVisible(element) {
     var rect = element.getBoundingClientRect();
-    return rect.width * rect.height > 0; // Width and height is never negative.
+    return rect.width * rect.height > 0;  // Width and height is never negative.
   }
 
   /**
@@ -158,8 +159,8 @@
    * @return {boolean}
    */
   function isVisible(parentEl, selector, checkLightDom) {
-    var element = (checkLightDom ? parentEl.querySelector : parentEl.$$).call(
-                      parentEl, selector);
+    var element = (checkLightDom ? parentEl.querySelector : parentEl.$$)
+                      .call(parentEl, selector);
     var rect = element ? element.getBoundingClientRect() : null;
     return !!rect && rect.width * rect.height > 0;
   }
@@ -190,7 +191,8 @@
    */
   function createExtensionInfo(opt_properties) {
     var id = opt_properties && opt_properties.hasOwnProperty('id') ?
-        opt_properties[id] : 'a'.repeat(32);
+        opt_properties[id] :
+        'a'.repeat(32);
     var baseUrl = 'chrome-extension://' + id + '/';
     return Object.assign(
         {
@@ -229,10 +231,11 @@
    */
   function testIcons(e) {
     e.querySelectorAll('* /deep/ iron-icon').forEach(function(icon) {
-      if(isElementVisible(icon)) {
+      if (isElementVisible(icon)) {
         var svg = icon.$$('svg');
-        expectTrue(!!svg && svg.innerHTML != '',
-                   'icon "' + icon.icon + '" is not present');
+        expectTrue(
+            !!svg && svg.innerHTML != '',
+            'icon "' + icon.icon + '" is not present');
       }
     });
 
diff --git a/chrome/test/data/webui/extensions/extension_toolbar_test.js b/chrome/test/data/webui/extensions/extension_toolbar_test.js
index a8e71a4..0aa5638 100644
--- a/chrome/test/data/webui/extensions/extension_toolbar_test.js
+++ b/chrome/test/data/webui/extensions/extension_toolbar_test.js
@@ -21,8 +21,8 @@
     var toolbar;
 
     setup(function() {
-      toolbar = document.querySelector('extensions-manager').$$(
-          'extensions-toolbar');
+      toolbar =
+          document.querySelector('extensions-manager').$$('extensions-toolbar');
       mockDelegate = new extensions.TestService();
       toolbar.set('delegate', mockDelegate);
     });
diff --git a/chrome/test/data/webui/extensions/extension_view_manager_test.js b/chrome/test/data/webui/extensions/extension_view_manager_test.js
index 4a29238..9200833 100644
--- a/chrome/test/data/webui/extensions/extension_view_manager_test.js
+++ b/chrome/test/data/webui/extensions/extension_view_manager_test.js
@@ -63,11 +63,8 @@
 
       var fired = {};
 
-      [
-        'view-enter-start',
-        'view-enter-finish',
-        'view-exit-start',
-        'view-exit-finish',
+      ['view-enter-start', 'view-enter-finish', 'view-exit-start',
+       'view-exit-finish',
       ].forEach(type => {
         viewOne.addEventListener(type, () => {
           fired[type] = true;
diff --git a/chrome/test/data/webui/extensions/toggle_row_test.js b/chrome/test/data/webui/extensions/toggle_row_test.js
index 2672112..1c9eed5d 100644
--- a/chrome/test/data/webui/extensions/toggle_row_test.js
+++ b/chrome/test/data/webui/extensions/toggle_row_test.js
@@ -22,13 +22,15 @@
   test('TestToggleByLabelTap', function() {
     var whenChanged = test_util.eventToPromise('change', row);
     MockInteractions.tap(row.getLabel());
-    return whenChanged.then(function() {
-      assertTrue(row.checked);
-      whenChanged = test_util.eventToPromise('change', row);
-      MockInteractions.tap(row.getLabel());
-      return whenChanged;
-    }).then(function() {
-      assertFalse(row.checked);
-    });
+    return whenChanged
+        .then(function() {
+          assertTrue(row.checked);
+          whenChanged = test_util.eventToPromise('change', row);
+          MockInteractions.tap(row.getLabel());
+          return whenChanged;
+        })
+        .then(function() {
+          assertFalse(row.checked);
+        });
   });
 });
diff --git a/chrome/test/data/webui/inspect_ui_test.js b/chrome/test/data/webui/inspect_ui_test.js
index deaa57a..91f5e83e 100644
--- a/chrome/test/data/webui/inspect_ui_test.js
+++ b/chrome/test/data/webui/inspect_ui_test.js
@@ -33,9 +33,7 @@
 
 function testTargetListed(sectionSelector, populateFunctionName, url) {
   waitForElements(
-      sectionSelector + ' .row',
-      populateFunctionName,
-      function(elements) {
+      sectionSelector + ' .row', populateFunctionName, function(elements) {
         var urlElement = findByContentSubstring(elements, url, '.url');
         expectNotEquals(undefined, urlElement);
         testDone();
@@ -46,37 +44,37 @@
   waitForElements('.device', 'populateRemoteTargets', function(devices) {
     expectEquals(2, devices.length);
 
-    var offlineDevice = findByContentSubstring(
-        devices, 'Offline', '.device-name');
+    var offlineDevice =
+        findByContentSubstring(devices, 'Offline', '.device-name');
     expectNotEquals(undefined, offlineDevice);
 
-    var onlineDevice = findByContentSubstring(
-        devices, 'Nexus 6', '.device-name');
+    var onlineDevice =
+        findByContentSubstring(devices, 'Nexus 6', '.device-name');
     expectNotEquals(undefined, onlineDevice);
 
     var browsers = onlineDevice.querySelectorAll('.browser');
     expectEquals(4, browsers.length);
 
     var chromeBrowser = findByContentSubstring(
-       browsers, 'Chrome (32.0.1679.0)', '.browser-name');
+        browsers, 'Chrome (32.0.1679.0)', '.browser-name');
     expectNotEquals(undefined, chromeBrowser);
 
     var chromePages = chromeBrowser.querySelectorAll('.pages');
-    var chromiumPage = findByContentSubstring(
-       chromePages, 'http://www.chromium.org/', '.url');
+    var chromiumPage =
+        findByContentSubstring(chromePages, 'http://www.chromium.org/', '.url');
     expectNotEquals(undefined, chromiumPage);
 
     var pageById = {};
-    Array.prototype.forEach.call(devices, function (device) {
+    Array.prototype.forEach.call(devices, function(device) {
       var pages = device.querySelectorAll('.row');
-      Array.prototype.forEach.call(pages, function (page) {
+      Array.prototype.forEach.call(pages, function(page) {
         expectEquals(undefined, pageById[page.targetId]);
         pageById[page.targetId] = page;
       });
     });
 
     var webView = findByContentSubstring(
-       browsers, 'WebView in com.sample.feed (4.0)', '.browser-name');
+        browsers, 'WebView in com.sample.feed (4.0)', '.browser-name');
     expectNotEquals(undefined, webView);
 
     testDone();
diff --git a/chrome/test/data/webui/local_discovery_ui_test.js b/chrome/test/data/webui/local_discovery_ui_test.js
index 0cda41f..c1e32af 100644
--- a/chrome/test/data/webui/local_discovery_ui_test.js
+++ b/chrome/test/data/webui/local_discovery_ui_test.js
@@ -58,8 +58,7 @@
   var deviceName = device.querySelector('.device-name').textContent;
   assertEquals('Sample device', deviceName);
 
-  var deviceDescription =
-        device.querySelector('.device-subline').textContent;
+  var deviceDescription = device.querySelector('.device-subline').textContent;
   assertEquals('Sample device description', deviceDescription);
 
   var button = device.querySelector('button');
diff --git a/chrome/test/data/webui/md_bookmarks/list_test.js b/chrome/test/data/webui/md_bookmarks/list_test.js
index f63d938..46693465 100644
--- a/chrome/test/data/webui/md_bookmarks/list_test.js
+++ b/chrome/test/data/webui/md_bookmarks/list_test.js
@@ -23,7 +23,7 @@
     list = document.createElement('bookmarks-list');
     list.style.height = '100%';
     list.style.width = '100%';
-    list.style.position= 'absolute';
+    list.style.position = 'absolute';
 
     replaceBody(list);
     Polymer.dom.flush();
diff --git a/chrome/test/data/webui/md_bookmarks/policy_test.js b/chrome/test/data/webui/md_bookmarks/policy_test.js
index 9498bc88..0896e5f 100644
--- a/chrome/test/data/webui/md_bookmarks/policy_test.js
+++ b/chrome/test/data/webui/md_bookmarks/policy_test.js
@@ -28,32 +28,40 @@
     const commandManager = bookmarks.CommandManager.getInstance();
     // Incognito is disabled during testGenPreamble(). Wait for the front-end to
     // load the config.
-    return store.waitForAction('set-incognito-availability').then(action => {
-      assertEquals(IncognitoAvailability.DISABLED,
-          store.data.prefs.incognitoAvailability);
-      assertFalse(
-          commandManager.canExecute(Command.OPEN_INCOGNITO, new Set(['11'])));
+    return store.waitForAction('set-incognito-availability')
+        .then(action => {
+          assertEquals(
+              IncognitoAvailability.DISABLED,
+              store.data.prefs.incognitoAvailability);
+          assertFalse(commandManager.canExecute(
+              Command.OPEN_INCOGNITO, new Set(['11'])));
 
-      return cr.sendWithPromise(
-          'testSetIncognito', IncognitoAvailability.ENABLED);
-    }).then(() => {
-      assertEquals(IncognitoAvailability.ENABLED,
-          store.data.prefs.incognitoAvailability);
-      assertTrue(
-          commandManager.canExecute(Command.OPEN_INCOGNITO, new Set(['11'])));
-    });
+          return cr.sendWithPromise(
+              'testSetIncognito', IncognitoAvailability.ENABLED);
+        })
+        .then(() => {
+          assertEquals(
+              IncognitoAvailability.ENABLED,
+              store.data.prefs.incognitoAvailability);
+          assertTrue(commandManager.canExecute(
+              Command.OPEN_INCOGNITO, new Set(['11'])));
+        });
   });
 
   test('canEdit updates when changed', function() {
     const commandManager = bookmarks.CommandManager.getInstance();
-    return store.waitForAction('set-can-edit').then(action => {
-      assertFalse(store.data.prefs.canEdit);
-      assertFalse(commandManager.canExecute(Command.DELETE, new Set(['11'])));
+    return store.waitForAction('set-can-edit')
+        .then(action => {
+          assertFalse(store.data.prefs.canEdit);
+          assertFalse(
+              commandManager.canExecute(Command.DELETE, new Set(['11'])));
 
-      return cr.sendWithPromise('testSetCanEdit', true);
-    }).then(() => {
-      assertTrue(store.data.prefs.canEdit);
-      assertTrue(commandManager.canExecute(Command.DELETE, new Set(['11'])));
-    });
+          return cr.sendWithPromise('testSetCanEdit', true);
+        })
+        .then(() => {
+          assertTrue(store.data.prefs.canEdit);
+          assertTrue(
+              commandManager.canExecute(Command.DELETE, new Set(['11'])));
+        });
   });
 });
diff --git a/chrome/test/data/webui/md_bookmarks/reducers_test.js b/chrome/test/data/webui/md_bookmarks/reducers_test.js
index a4d7665..ff8eab1 100644
--- a/chrome/test/data/webui/md_bookmarks/reducers_test.js
+++ b/chrome/test/data/webui/md_bookmarks/reducers_test.js
@@ -127,10 +127,8 @@
   });
 
   test('deselects items when they are moved to a different folder', function() {
-    const nodeMap = testTree(
-        createFolder('1', []),
-        createItem('2'),
-        createItem('3'));
+    const nodeMap =
+        testTree(createFolder('1', []), createItem('2'), createItem('3'));
 
     action = select(['2', '3'], '2', true, false);
     selection = bookmarks.SelectionState.updateSelection(selection, action);
diff --git a/chrome/test/data/webui/md_bookmarks/router_test.js b/chrome/test/data/webui/md_bookmarks/router_test.js
index 7c42f4e..276e080 100644
--- a/chrome/test/data/webui/md_bookmarks/router_test.js
+++ b/chrome/test/data/webui/md_bookmarks/router_test.js
@@ -43,14 +43,16 @@
     store.data.selectedFolder = '2';
     store.notifyObservers();
 
-    return Promise.resolve().then(function() {
-      assertEquals('chrome://bookmarks/?id=2', window.location.href);
-      store.data.selectedFolder = '1';
-      store.notifyObservers();
-    }).then(function() {
-      // Selecting Bookmarks bar clears route.
-      assertEquals('chrome://bookmarks/', window.location.href);
-    });
+    return Promise.resolve()
+        .then(function() {
+          assertEquals('chrome://bookmarks/?id=2', window.location.href);
+          store.data.selectedFolder = '1';
+          store.notifyObservers();
+        })
+        .then(function() {
+          // Selecting Bookmarks bar clears route.
+          assertEquals('chrome://bookmarks/', window.location.href);
+        });
   });
 
   test('route updates from search', function() {
diff --git a/chrome/test/data/webui/md_bookmarks/test_util.js b/chrome/test/data/webui/md_bookmarks/test_util.js
index 92de572..3c24964 100644
--- a/chrome/test/data/webui/md_bookmarks/test_util.js
+++ b/chrome/test/data/webui/md_bookmarks/test_util.js
@@ -151,7 +151,8 @@
     if (node.itemId == id)
       return node;
 
-    node.root.querySelectorAll('bookmarks-folder-node')
-        .forEach((x) => {nodes.unshift(x);});
+    node.root.querySelectorAll('bookmarks-folder-node').forEach((x) => {
+      nodes.unshift(x);
+    });
   }
 }
diff --git a/chrome/test/data/webui/md_downloads/item_tests.js b/chrome/test/data/webui/md_downloads/item_tests.js
index 474b4f6..174dbb64 100644
--- a/chrome/test/data/webui/md_downloads/item_tests.js
+++ b/chrome/test/data/webui/md_downloads/item_tests.js
@@ -11,7 +11,7 @@
     document.body.appendChild(item);
   });
 
-  test("dangerous downloads aren't linkable", function() {
+  test('dangerous downloads aren\'t linkable', function() {
     item.set('data', {
       danger_type: downloads.DangerType.DANGEROUS_FILE,
       file_externally_removed: false,
diff --git a/chrome/test/data/webui/md_downloads/toolbar_tests.js b/chrome/test/data/webui/md_downloads/toolbar_tests.js
index 4335c62..31b10d98 100644
--- a/chrome/test/data/webui/md_downloads/toolbar_tests.js
+++ b/chrome/test/data/webui/md_downloads/toolbar_tests.js
@@ -8,7 +8,8 @@
 
   setup(function() {
     class TestSearchService extends downloads.SearchService {
-      loadMore() { /* Prevent chrome.send(). */ }
+      loadMore() { /* Prevent chrome.send(). */
+      }
     }
 
     toolbar = document.createElement('downloads-toolbar');
diff --git a/chrome/test/data/webui/md_history/history_item_test.js b/chrome/test/data/webui/md_history/history_item_test.js
index 5525d78b..6b5e8ab4 100644
--- a/chrome/test/data/webui/md_history/history_item_test.js
+++ b/chrome/test/data/webui/md_history/history_item_test.js
@@ -12,9 +12,9 @@
 ];
 
 const SEARCH_HISTORY_RESULTS = [
-  createSearchEntry('2016-03-16', "http://www.google.com"),
-  createSearchEntry('2016-03-14 11:00', "http://calendar.google.com"),
-  createSearchEntry('2016-03-14 10:00', "http://mail.google.com")
+  createSearchEntry('2016-03-16', 'http://www.google.com'),
+  createSearchEntry('2016-03-14 11:00', 'http://calendar.google.com'),
+  createSearchEntry('2016-03-14 10:00', 'http://mail.google.com')
 ];
 
 suite('<history-item> unit test', function() {
@@ -122,22 +122,24 @@
 
   test('remove bookmarks', function() {
     element.addNewResults(TEST_HISTORY_RESULTS);
-    return PolymerTest.flushTasks().then(function() {
-      element.set('historyData_.1.starred', true);
-      element.set('historyData_.5.starred', true);
-      return PolymerTest.flushTasks();
-    }).then(function() {
+    return PolymerTest.flushTasks()
+        .then(function() {
+          element.set('historyData_.1.starred', true);
+          element.set('historyData_.5.starred', true);
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
 
-      items = Polymer.dom(element.root).querySelectorAll('history-item');
+          items = Polymer.dom(element.root).querySelectorAll('history-item');
 
-      items[1].$$('#bookmark-star').focus();
-      MockInteractions.tap(items[1].$$('#bookmark-star'));
+          items[1].$$('#bookmark-star').focus();
+          MockInteractions.tap(items[1].$$('#bookmark-star'));
 
-      // Check that focus is shifted to overflow menu icon.
-      assertEquals(items[1].root.activeElement, items[1].$['menu-button']);
-      // Check that all items matching this url are unstarred.
-      assertEquals(element.historyData_[1].starred, false);
-      assertEquals(element.historyData_[5].starred, false);
-    });
+          // Check that focus is shifted to overflow menu icon.
+          assertEquals(items[1].root.activeElement, items[1].$['menu-button']);
+          // Check that all items matching this url are unstarred.
+          assertEquals(element.historyData_[1].starred, false);
+          assertEquals(element.historyData_[5].starred, false);
+        });
   });
 });
diff --git a/chrome/test/data/webui/md_history/history_list_test.js b/chrome/test/data/webui/md_history/history_list_test.js
index 971c719b..5a9d516d 100644
--- a/chrome/test/data/webui/md_history/history_list_test.js
+++ b/chrome/test/data/webui/md_history/history_list_test.js
@@ -35,32 +35,36 @@
 
   test('deleting single item', function(done) {
     const listContainer = app.$.history;
-    app.historyResult(createHistoryInfo(), [
-      createHistoryEntry('2015-01-01', 'http://example.com')
-    ]);
+    app.historyResult(
+        createHistoryInfo(),
+        [createHistoryEntry('2015-01-01', 'http://example.com')]);
 
-    PolymerTest.flushTasks().then(function() {
-      assertEquals(element.historyData_.length, 1);
-      items = polymerSelectAll(element, 'history-item');
-      MockInteractions.tap(items[0].$.checkbox);
-      assertDeepEquals([true], element.historyData_.map(i => i.selected));
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      toolbar.deleteSelectedItems();
-      const dialog = listContainer.$.dialog.get();
-      registerMessageCallback('removeVisits', this, function() {
-        PolymerTest.flushTasks().then(function() {
-          deleteComplete();
-          return PolymerTest.flushTasks();
-        }).then(function() {
+    PolymerTest.flushTasks()
+        .then(function() {
+          assertEquals(element.historyData_.length, 1);
           items = polymerSelectAll(element, 'history-item');
-          assertEquals(element.historyData_.length, 0);
-          done();
+          MockInteractions.tap(items[0].$.checkbox);
+          assertDeepEquals([true], element.historyData_.map(i => i.selected));
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          toolbar.deleteSelectedItems();
+          const dialog = listContainer.$.dialog.get();
+          registerMessageCallback('removeVisits', this, function() {
+            PolymerTest.flushTasks()
+                .then(function() {
+                  deleteComplete();
+                  return PolymerTest.flushTasks();
+                })
+                .then(function() {
+                  items = polymerSelectAll(element, 'history-item');
+                  assertEquals(element.historyData_.length, 0);
+                  done();
+                });
+          });
+          assertTrue(dialog.open);
+          MockInteractions.tap(listContainer.$$('.action-button'));
         });
-      });
-      assertTrue(dialog.open);
-      MockInteractions.tap(listContainer.$$('.action-button'));
-    });
   });
 
   test('cancelling selection of multiple items', function() {
@@ -73,15 +77,17 @@
 
       // Make sure that the array of data that determines whether or not an
       // item is selected is what we expect after selecting the two items.
-      assertDeepEquals([false, false, true, true],
-                       element.historyData_.map(i => i.selected));
+      assertDeepEquals(
+          [false, false, true, true],
+          element.historyData_.map(i => i.selected));
 
       toolbar.clearSelectedItems();
 
       // Make sure that clearing the selection updates both the array and
       // the actual history-items affected.
-      assertDeepEquals([false, false, false, false],
-                       element.historyData_.map(i => i.selected));
+      assertDeepEquals(
+          [false, false, false, false],
+          element.historyData_.map(i => i.selected));
 
       assertFalse(items[2].selected);
       assertFalse(items[3].selected);
@@ -94,44 +100,49 @@
       const items = polymerSelectAll(element, 'history-item');
 
       MockInteractions.tap(items[1].$.checkbox);
-      assertDeepEquals([false, true, false, false],
-                       element.historyData_.map(i => i.selected));
+      assertDeepEquals(
+          [false, true, false, false],
+          element.historyData_.map(i => i.selected));
       assertDeepEquals([1], Array.from(element.selectedItems).sort());
 
       // Shift-select to the last item.
       shiftClick(items[3].$.checkbox);
-      assertDeepEquals([false, true, true, true],
-                       element.historyData_.map(i => i.selected));
+      assertDeepEquals(
+          [false, true, true, true], element.historyData_.map(i => i.selected));
       assertDeepEquals([1, 2, 3], Array.from(element.selectedItems).sort());
 
       // Shift-select back to the first item.
       shiftClick(items[0].$.checkbox);
-      assertDeepEquals([true, true, true, true],
-                       element.historyData_.map(i => i.selected));
+      assertDeepEquals(
+          [true, true, true, true], element.historyData_.map(i => i.selected));
       assertDeepEquals([0, 1, 2, 3], Array.from(element.selectedItems).sort());
 
       // Shift-deselect to the third item.
       shiftClick(items[2].$.checkbox);
-      assertDeepEquals([false, false, false, true],
-                       element.historyData_.map(i => i.selected));
+      assertDeepEquals(
+          [false, false, false, true],
+          element.historyData_.map(i => i.selected));
       assertDeepEquals([3], Array.from(element.selectedItems).sort());
 
       // Select the second item.
       MockInteractions.tap(items[1].$.checkbox);
-      assertDeepEquals([false, true, false, true],
-                       element.historyData_.map(i => i.selected));
+      assertDeepEquals(
+          [false, true, false, true],
+          element.historyData_.map(i => i.selected));
       assertDeepEquals([1, 3], Array.from(element.selectedItems).sort());
 
       // Shift-deselect to the last item.
       shiftClick(items[3].$.checkbox);
-      assertDeepEquals([false, false, false, false],
-                       element.historyData_.map(i => i.selected));
+      assertDeepEquals(
+          [false, false, false, false],
+          element.historyData_.map(i => i.selected));
       assertDeepEquals([], Array.from(element.selectedItems).sort());
 
       // Shift-select back to the third item.
       shiftClick(items[2].$.checkbox);
-      assertDeepEquals([false, false, true, true],
-                       element.historyData_.map(i => i.selected));
+      assertDeepEquals(
+          [false, false, true, true],
+          element.historyData_.map(i => i.selected));
       assertDeepEquals([2, 3], Array.from(element.selectedItems).sort());
 
       // Remove selected items.
@@ -150,18 +161,17 @@
       assertFalse(field.showingSearch);
 
       const modifier = cr.isMac ? 'meta' : 'ctrl';
-      MockInteractions.pressAndReleaseKeyOn(
-          document.body, 65, modifier, 'a');
+      MockInteractions.pressAndReleaseKeyOn(document.body, 65, modifier, 'a');
 
-      assertDeepEquals([true, true, true, true],
-                       element.historyData_.map(i => i.selected));
+      assertDeepEquals(
+          [true, true, true, true], element.historyData_.map(i => i.selected));
 
       // If everything is already selected, the same shortcut will trigger
       // cancelling selection.
-      MockInteractions.pressAndReleaseKeyOn(
-          document.body, 65, modifier, 'a');
-      assertDeepEquals([false, false, false, false],
-                       element.historyData_.map(i => i.selected));
+      MockInteractions.pressAndReleaseKeyOn(document.body, 65, modifier, 'a');
+      assertDeepEquals(
+          [false, false, false, false],
+          element.historyData_.map(i => i.selected));
     });
   });
 
@@ -200,29 +210,32 @@
   test('deleting multiple items from view', function() {
     app.historyResult(createHistoryInfo(), TEST_HISTORY_RESULTS);
     app.historyResult(createHistoryInfo(), ADDITIONAL_RESULTS);
-    return PolymerTest.flushTasks().then(function() {
+    return PolymerTest.flushTasks()
+        .then(function() {
 
-      element.removeItemsByIndex_([2, 5, 7]);
+          element.removeItemsByIndex_([2, 5, 7]);
 
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      items = polymerSelectAll(element, 'history-item');
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          items = polymerSelectAll(element, 'history-item');
 
-      assertEquals(element.historyData_.length, 5);
-      assertEquals(element.historyData_[0].dateRelativeDay, '2016-03-15');
-      assertEquals(element.historyData_[2].dateRelativeDay, '2016-03-13');
-      assertEquals(element.historyData_[4].dateRelativeDay, '2016-03-11');
+          assertEquals(element.historyData_.length, 5);
+          assertEquals(element.historyData_[0].dateRelativeDay, '2016-03-15');
+          assertEquals(element.historyData_[2].dateRelativeDay, '2016-03-13');
+          assertEquals(element.historyData_[4].dateRelativeDay, '2016-03-11');
 
-      // Checks that the first and last items have been reset correctly.
-      assertTrue(items[2].isCardStart);
-      assertTrue(items[3].isCardEnd);
-      assertTrue(items[4].isCardStart);
-      assertTrue(items[4].isCardEnd);
-    });
+          // Checks that the first and last items have been reset correctly.
+          assertTrue(items[2].isCardStart);
+          assertTrue(items[3].isCardEnd);
+          assertTrue(items[4].isCardStart);
+          assertTrue(items[4].isCardEnd);
+        });
   });
 
   test('search results display with correct item title', function() {
-    app.historyResult(createHistoryInfo(),
+    app.historyResult(
+        createHistoryInfo(),
         [createHistoryEntry('2016-03-15', 'https://www.google.com')]);
     element.searchedTerm = 'Google';
 
@@ -244,24 +257,26 @@
   test('correct display message when no history available', function() {
     app.historyResult(createHistoryInfo(), []);
 
-    return PolymerTest.flushTasks().then(function() {
-      assertFalse(element.$['no-results'].hidden);
-      assertNotEquals('', element.$['no-results'].textContent.trim());
-      assertTrue(element.$['infinite-list'].hidden);
+    return PolymerTest.flushTasks()
+        .then(function() {
+          assertFalse(element.$['no-results'].hidden);
+          assertNotEquals('', element.$['no-results'].textContent.trim());
+          assertTrue(element.$['infinite-list'].hidden);
 
-      app.historyResult(createHistoryInfo(), TEST_HISTORY_RESULTS);
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      assertTrue(element.$['no-results'].hidden);
-      assertFalse(element.$['infinite-list'].hidden);
-    });
+          app.historyResult(createHistoryInfo(), TEST_HISTORY_RESULTS);
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          assertTrue(element.$['no-results'].hidden);
+          assertFalse(element.$['infinite-list'].hidden);
+        });
   });
 
   test('more from this site sends and sets correct data', function(done) {
     app.queryState_.queryingDisabled = false;
     app.historyResult(createHistoryInfo(), TEST_HISTORY_RESULTS);
-    PolymerTest.flushTasks().then(function () {
-      registerMessageCallback('queryHistory', this, function (info) {
+    PolymerTest.flushTasks().then(function() {
+      registerMessageCallback('queryHistory', this, function(info) {
         assertEquals('www.google.com', info[0]);
         app.historyResult(
             createHistoryInfo('www.google.com'), TEST_HISTORY_RESULTS);
@@ -292,21 +307,23 @@
 
   // TODO(calamity): Reenable this test after fixing flakiness.
   // See http://crbug.com/640862.
-  test.skip('scrolling history list causes toolbar shadow to appear',
-            () => {
+  test.skip('scrolling history list causes toolbar shadow to appear', () => {
     for (let i = 0; i < 10; i++)
       app.historyResult(createHistoryInfo(), TEST_HISTORY_RESULTS);
-    return PolymerTest.flushTasks().then(function() {
-      assertFalse(app.toolbarShadow_);
-      element.$['infinite-list'].scrollToIndex(20);
-      return waitForEvent(app, 'toolbar-shadow_-changed');
-    }).then(() => {
-      assertTrue(app.toolbarShadow_);
-      element.$['infinite-list'].scrollToIndex(0);
-      return waitForEvent(app, 'toolbar-shadow_-changed');
-    }).then(() => {
-      assertFalse(app.toolbarShadow_);
-    });
+    return PolymerTest.flushTasks()
+        .then(function() {
+          assertFalse(app.toolbarShadow_);
+          element.$['infinite-list'].scrollToIndex(20);
+          return waitForEvent(app, 'toolbar-shadow_-changed');
+        })
+        .then(() => {
+          assertTrue(app.toolbarShadow_);
+          element.$['infinite-list'].scrollToIndex(0);
+          return waitForEvent(app, 'toolbar-shadow_-changed');
+        })
+        .then(() => {
+          assertFalse(app.toolbarShadow_);
+        });
   });
 
   test('changing search deselects items', function() {
@@ -336,49 +353,56 @@
       createHistoryEntry('2015-01-01', 'http://example.com'),
       createHistoryEntry('2015-01-01', 'http://example.com')
     ]);
-    PolymerTest.flushTasks().then(function() {
-      items = polymerSelectAll(element, 'history-item');
-
-      MockInteractions.tap(items[2].$.checkbox);
-      MockInteractions.tap(items[5].$.checkbox);
-      MockInteractions.tap(items[7].$.checkbox);
-      MockInteractions.tap(items[8].$.checkbox);
-      MockInteractions.tap(items[9].$.checkbox);
-      MockInteractions.tap(items[10].$.checkbox);
-
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      toolbar.deleteSelectedItems();
-
-      const dialog = listContainer.$.dialog.get();
-      registerMessageCallback('removeVisits', this, function() {
-        PolymerTest.flushTasks().then(function() {
-          deleteComplete();
-          return PolymerTest.flushTasks();
-        }).then(function() {
-          assertEquals(element.historyData_.length, 5);
-          assertEquals(element.historyData_[0].dateRelativeDay, '2016-03-15');
-          assertEquals(element.historyData_[2].dateRelativeDay, '2016-03-13');
-          assertEquals(element.historyData_[4].dateRelativeDay, '2016-03-11');
-          assertFalse(dialog.open);
-
-          // Ensure the UI is correctly updated.
+    PolymerTest.flushTasks()
+        .then(function() {
           items = polymerSelectAll(element, 'history-item');
-          assertEquals('https://www.google.com', items[0].item.title);
-          assertEquals('https://www.example.com', items[1].item.title);
-          assertEquals('https://en.wikipedia.org', items[2].item.title);
-          assertEquals('https://en.wikipedia.org', items[3].item.title);
-          assertEquals('https://www.google.com', items[4].item.title);
 
-          assertFalse(dialog.open);
-          done();
+          MockInteractions.tap(items[2].$.checkbox);
+          MockInteractions.tap(items[5].$.checkbox);
+          MockInteractions.tap(items[7].$.checkbox);
+          MockInteractions.tap(items[8].$.checkbox);
+          MockInteractions.tap(items[9].$.checkbox);
+          MockInteractions.tap(items[10].$.checkbox);
+
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          toolbar.deleteSelectedItems();
+
+          const dialog = listContainer.$.dialog.get();
+          registerMessageCallback('removeVisits', this, function() {
+            PolymerTest.flushTasks()
+                .then(function() {
+                  deleteComplete();
+                  return PolymerTest.flushTasks();
+                })
+                .then(function() {
+                  assertEquals(element.historyData_.length, 5);
+                  assertEquals(
+                      element.historyData_[0].dateRelativeDay, '2016-03-15');
+                  assertEquals(
+                      element.historyData_[2].dateRelativeDay, '2016-03-13');
+                  assertEquals(
+                      element.historyData_[4].dateRelativeDay, '2016-03-11');
+                  assertFalse(dialog.open);
+
+                  // Ensure the UI is correctly updated.
+                  items = polymerSelectAll(element, 'history-item');
+                  assertEquals('https://www.google.com', items[0].item.title);
+                  assertEquals('https://www.example.com', items[1].item.title);
+                  assertEquals('https://en.wikipedia.org', items[2].item.title);
+                  assertEquals('https://en.wikipedia.org', items[3].item.title);
+                  assertEquals('https://www.google.com', items[4].item.title);
+
+                  assertFalse(dialog.open);
+                  done();
+                });
+          });
+
+          // Confirmation dialog should appear.
+          assertTrue(dialog.open);
+          MockInteractions.tap(listContainer.$$('.action-button'));
         });
-      });
-
-      // Confirmation dialog should appear.
-      assertTrue(dialog.open);
-      MockInteractions.tap(listContainer.$$('.action-button'));
-    });
   });
 
   test('delete via menu button', function(done) {
@@ -388,23 +412,27 @@
     PolymerTest.flushTasks().then(function() {
       items = polymerSelectAll(element, 'history-item');
       registerMessageCallback('removeVisits', this, function() {
-        PolymerTest.flushTasks().then(function() {
-          deleteComplete();
-          return PolymerTest.flushTasks();
-        }).then(function() {
-          assertDeepEquals([
-            'https://www.google.com',
-            'https://www.google.com',
-            'https://en.wikipedia.org',
-          ], element.historyData_.map(item => item.title));
+        PolymerTest.flushTasks()
+            .then(function() {
+              deleteComplete();
+              return PolymerTest.flushTasks();
+            })
+            .then(function() {
+              assertDeepEquals(
+                  [
+                    'https://www.google.com',
+                    'https://www.google.com',
+                    'https://en.wikipedia.org',
+                  ],
+                  element.historyData_.map(item => item.title));
 
-          // Deletion should deselect all.
-          assertDeepEquals(
-              [false, false, false],
-              items.slice(0, 3).map(i => i.selected));
+              // Deletion should deselect all.
+              assertDeepEquals(
+                  [false, false, false],
+                  items.slice(0, 3).map(i => i.selected));
 
-          done();
-        });
+              done();
+            });
       });
 
       MockInteractions.tap(items[1].$.checkbox);
@@ -419,42 +447,49 @@
     const listContainer = app.$.history;
     app.historyResult(createHistoryInfo(), TEST_HISTORY_RESULTS);
     const dialog = listContainer.$.dialog.get();
-    return PolymerTest.flushTasks().then(function() {
-      items = polymerSelectAll(element, 'history-item');
+    return PolymerTest.flushTasks()
+        .then(function() {
+          items = polymerSelectAll(element, 'history-item');
 
-      // Dialog should not appear when there is no item selected.
-      MockInteractions.pressAndReleaseKeyOn(document.body, 46, '', 'Delete');
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      assertFalse(dialog.open);
+          // Dialog should not appear when there is no item selected.
+          MockInteractions.pressAndReleaseKeyOn(
+              document.body, 46, '', 'Delete');
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          assertFalse(dialog.open);
 
-      MockInteractions.tap(items[1].$.checkbox);
-      MockInteractions.tap(items[2].$.checkbox);
+          MockInteractions.tap(items[1].$.checkbox);
+          MockInteractions.tap(items[2].$.checkbox);
 
-      assertEquals(2, toolbar.count);
+          assertEquals(2, toolbar.count);
 
-      MockInteractions.pressAndReleaseKeyOn(document.body, 46, '', 'Delete');
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      assertTrue(dialog.open);
-      MockInteractions.tap(listContainer.$$('.cancel-button'));
-      assertFalse(dialog.open);
+          MockInteractions.pressAndReleaseKeyOn(
+              document.body, 46, '', 'Delete');
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          assertTrue(dialog.open);
+          MockInteractions.tap(listContainer.$$('.cancel-button'));
+          assertFalse(dialog.open);
 
-      MockInteractions.pressAndReleaseKeyOn(document.body, 8, '', 'Backspace');
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      assertTrue(dialog.open);
+          MockInteractions.pressAndReleaseKeyOn(
+              document.body, 8, '', 'Backspace');
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          assertTrue(dialog.open);
 
-      registerMessageCallback('removeVisits', this, function(toRemove) {
-        assertEquals('https://www.example.com', toRemove[0].url);
-        assertEquals('https://www.google.com', toRemove[1].url);
-        assertEquals('2016-03-14 10:00 UTC', toRemove[0].timestamps[0]);
-        assertEquals('2016-03-14 9:00 UTC', toRemove[1].timestamps[0]);
-        done();
-      });
+          registerMessageCallback('removeVisits', this, function(toRemove) {
+            assertEquals('https://www.example.com', toRemove[0].url);
+            assertEquals('https://www.google.com', toRemove[1].url);
+            assertEquals('2016-03-14 10:00 UTC', toRemove[0].timestamps[0]);
+            assertEquals('2016-03-14 9:00 UTC', toRemove[1].timestamps[0]);
+            done();
+          });
 
-      MockInteractions.tap(listContainer.$$('.action-button'));
-    });
+          MockInteractions.tap(listContainer.$$('.action-button'));
+        });
   });
 
   test('delete dialog closed on back navigation', function(done) {
@@ -467,27 +502,30 @@
     app.historyResult(createHistoryInfo(), ADDITIONAL_RESULTS);
 
     const listContainer = app.$.history;
-    PolymerTest.flushTasks().then(function() {
-      items = Polymer.dom(element.root).querySelectorAll('history-item');
+    PolymerTest.flushTasks()
+        .then(function() {
+          items = Polymer.dom(element.root).querySelectorAll('history-item');
 
-      MockInteractions.tap(items[2].$.checkbox);
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      toolbar.deleteSelectedItems();
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      // Confirmation dialog should appear.
-      assertTrue(listContainer.$.dialog.getIfExists().open);
-      // Navigate back to chrome://history.
-      window.history.back();
+          MockInteractions.tap(items[2].$.checkbox);
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          toolbar.deleteSelectedItems();
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          // Confirmation dialog should appear.
+          assertTrue(listContainer.$.dialog.getIfExists().open);
+          // Navigate back to chrome://history.
+          window.history.back();
 
-      listenOnce(window, 'popstate', function() {
-        PolymerTest.flushTasks().then(function() {
-          assertFalse(listContainer.$.dialog.getIfExists().open);
-          done();
+          listenOnce(window, 'popstate', function() {
+            PolymerTest.flushTasks().then(function() {
+              assertFalse(listContainer.$.dialog.getIfExists().open);
+              done();
+            });
+          });
         });
-      });
-    });
   });
 
   test('clicking file:// url sends message to chrome', function(done) {
diff --git a/chrome/test/data/webui/md_history/history_metrics_test.js b/chrome/test/data/webui/md_history/history_metrics_test.js
index ccf783d..039a4cc 100644
--- a/chrome/test/data/webui/md_history/history_metrics_test.js
+++ b/chrome/test/data/webui/md_history/history_metrics_test.js
@@ -84,111 +84,123 @@
         createHistoryEntry('2015-01-01', 'http://www.google.com');
     historyEntry.starred = true;
     app.historyResult(createHistoryInfo(), [
-      createHistoryEntry('2015-01-01', 'http://www.example.com'),
-      historyEntry
+      createHistoryEntry('2015-01-01', 'http://www.example.com'), historyEntry
     ]);
 
-    return PolymerTest.flushTasks().then(() => {
-      const items = polymerSelectAll(app.$.history, 'history-item');
-      MockInteractions.tap(items[1].$$('#bookmark-star'));
-      assertEquals(1, actionMap['BookmarkStarClicked']);
-      MockInteractions.tap(items[1].$.title);
-      assertEquals(1, actionMap['EntryLinkClick']);
-      assertEquals(1, histogramMap['HistoryPage.ClickPosition'][1]);
-      assertEquals(1, histogramMap['HistoryPage.ClickPositionSubset'][1]);
+    return PolymerTest.flushTasks()
+        .then(() => {
+          const items = polymerSelectAll(app.$.history, 'history-item');
+          MockInteractions.tap(items[1].$$('#bookmark-star'));
+          assertEquals(1, actionMap['BookmarkStarClicked']);
+          MockInteractions.tap(items[1].$.title);
+          assertEquals(1, actionMap['EntryLinkClick']);
+          assertEquals(1, histogramMap['HistoryPage.ClickPosition'][1]);
+          assertEquals(1, histogramMap['HistoryPage.ClickPositionSubset'][1]);
 
-      app.fire('change-query', {search: 'goog'});
-      assertEquals(1, actionMap['Search']);
-      app.set('queryState_.incremental', true);
-      app.historyResult(createHistoryInfo('goog'), [
-        createHistoryEntry('2015-01-01', 'http://www.google.com'),
-        createHistoryEntry('2015-01-01', 'http://www.google.com'),
-        createHistoryEntry('2015-01-01', 'http://www.google.com')
-      ]);
-      return PolymerTest.flushTasks();
-    }).then(() => {
-      items = polymerSelectAll(app.$.history, 'history-item');
-      MockInteractions.tap(items[0].$.title);
-      assertEquals(1, actionMap['SearchResultClick']);
-      assertEquals(1, histogramMap['HistoryPage.ClickPosition'][0]);
-      assertEquals(1, histogramMap['HistoryPage.ClickPositionSubset'][0]);
-      MockInteractions.tap(items[0].$.checkbox);
-      MockInteractions.tap(items[4].$.checkbox);
-      return PolymerTest.flushTasks();
-    }).then(() => {
-      app.$.toolbar.deleteSelectedItems();
-      assertEquals(1, actionMap['RemoveSelected']);
-      return PolymerTest.flushTasks();
-    }).then(() => {
-      MockInteractions.tap(app.$.history.$$('.cancel-button'));
-      assertEquals(1, actionMap['CancelRemoveSelected']);
-      app.$.toolbar.deleteSelectedItems();
-      return PolymerTest.flushTasks();
-    }).then(() => {
-      MockInteractions.tap(app.$.history.$$('.action-button'));
-      assertEquals(1, actionMap['ConfirmRemoveSelected']);
-      return PolymerTest.flushTasks();
-    }).then(() => {
-      items = polymerSelectAll(app.$.history, 'history-item');
-      MockInteractions.tap(items[0].$['menu-button']);
-      return PolymerTest.flushTasks();
-    }).then(() => {
-      MockInteractions.tap(app.$.history.$$('#menuRemoveButton'));
-      return PolymerTest.flushTasks();
-    }).then(() => {
-      assertEquals(1, histogramMap['HistoryPage.RemoveEntryPosition'][0]);
-      assertEquals(1, histogramMap['HistoryPage.RemoveEntryPositionSubset'][0]);
-    });
+          app.fire('change-query', {search: 'goog'});
+          assertEquals(1, actionMap['Search']);
+          app.set('queryState_.incremental', true);
+          app.historyResult(createHistoryInfo('goog'), [
+            createHistoryEntry('2015-01-01', 'http://www.google.com'),
+            createHistoryEntry('2015-01-01', 'http://www.google.com'),
+            createHistoryEntry('2015-01-01', 'http://www.google.com')
+          ]);
+          return PolymerTest.flushTasks();
+        })
+        .then(() => {
+          items = polymerSelectAll(app.$.history, 'history-item');
+          MockInteractions.tap(items[0].$.title);
+          assertEquals(1, actionMap['SearchResultClick']);
+          assertEquals(1, histogramMap['HistoryPage.ClickPosition'][0]);
+          assertEquals(1, histogramMap['HistoryPage.ClickPositionSubset'][0]);
+          MockInteractions.tap(items[0].$.checkbox);
+          MockInteractions.tap(items[4].$.checkbox);
+          return PolymerTest.flushTasks();
+        })
+        .then(() => {
+          app.$.toolbar.deleteSelectedItems();
+          assertEquals(1, actionMap['RemoveSelected']);
+          return PolymerTest.flushTasks();
+        })
+        .then(() => {
+          MockInteractions.tap(app.$.history.$$('.cancel-button'));
+          assertEquals(1, actionMap['CancelRemoveSelected']);
+          app.$.toolbar.deleteSelectedItems();
+          return PolymerTest.flushTasks();
+        })
+        .then(() => {
+          MockInteractions.tap(app.$.history.$$('.action-button'));
+          assertEquals(1, actionMap['ConfirmRemoveSelected']);
+          return PolymerTest.flushTasks();
+        })
+        .then(() => {
+          items = polymerSelectAll(app.$.history, 'history-item');
+          MockInteractions.tap(items[0].$['menu-button']);
+          return PolymerTest.flushTasks();
+        })
+        .then(() => {
+          MockInteractions.tap(app.$.history.$$('#menuRemoveButton'));
+          return PolymerTest.flushTasks();
+        })
+        .then(() => {
+          assertEquals(1, histogramMap['HistoryPage.RemoveEntryPosition'][0]);
+          assertEquals(
+              1, histogramMap['HistoryPage.RemoveEntryPositionSubset'][0]);
+        });
   });
 
   test('synced-device-manager', function() {
     app.selectedPage_ = 'syncedTabs';
     let histogram;
     let menuButton;
-    return PolymerTest.flushTasks().then(() => {
-      histogram = histogramMap[SYNCED_TABS_HISTOGRAM_NAME];
-      assertEquals(1, histogram[SyncedTabsHistogram.INITIALIZED]);
+    return PolymerTest.flushTasks()
+        .then(() => {
+          histogram = histogramMap[SYNCED_TABS_HISTOGRAM_NAME];
+          assertEquals(1, histogram[SyncedTabsHistogram.INITIALIZED]);
 
-      const sessionList = [
-        createSession(
-            'Nexus 5',
-            [createWindow(['http://www.google.com', 'http://example.com'])]
-        ),
-        createSession(
-            'Nexus 6',
-            [
-              createWindow(['http://test.com']),
-              createWindow(['http://www.gmail.com', 'http://badssl.com'])
-            ]
-        ),
-      ];
-      setForeignSessions(sessionList);
-      return PolymerTest.flushTasks();
-    }).then(() => {
-      assertEquals(1, histogram[SyncedTabsHistogram.HAS_FOREIGN_DATA]);
-      return PolymerTest.flushTasks();
-    }).then(() => {
-      cards = polymerSelectAll(
-          app.$$('#synced-devices'), 'history-synced-device-card');
-      MockInteractions.tap(cards[0].$['card-heading']);
-      assertEquals(1, histogram[SyncedTabsHistogram.COLLAPSE_SESSION]);
-      MockInteractions.tap(cards[0].$['card-heading']);
-      assertEquals(1, histogram[SyncedTabsHistogram.EXPAND_SESSION]);
-      MockInteractions.tap(polymerSelectAll(cards[0], '.website-title')[0]);
-      assertEquals(1, histogram[SyncedTabsHistogram.LINK_CLICKED]);
+          const sessionList = [
+            createSession('Nexus 5', [createWindow([
+                            'http://www.google.com', 'http://example.com'
+                          ])]),
+            createSession(
+                'Nexus 6',
+                [
+                  createWindow(['http://test.com']),
+                  createWindow(['http://www.gmail.com', 'http://badssl.com'])
+                ]),
+          ];
+          setForeignSessions(sessionList);
+          return PolymerTest.flushTasks();
+        })
+        .then(() => {
+          assertEquals(1, histogram[SyncedTabsHistogram.HAS_FOREIGN_DATA]);
+          return PolymerTest.flushTasks();
+        })
+        .then(() => {
+          cards = polymerSelectAll(
+              app.$$('#synced-devices'), 'history-synced-device-card');
+          MockInteractions.tap(cards[0].$['card-heading']);
+          assertEquals(1, histogram[SyncedTabsHistogram.COLLAPSE_SESSION]);
+          MockInteractions.tap(cards[0].$['card-heading']);
+          assertEquals(1, histogram[SyncedTabsHistogram.EXPAND_SESSION]);
+          MockInteractions.tap(polymerSelectAll(cards[0], '.website-title')[0]);
+          assertEquals(1, histogram[SyncedTabsHistogram.LINK_CLICKED]);
 
-      menuButton = cards[0].$['menu-button'];
-      MockInteractions.tap(menuButton);
-      return PolymerTest.flushTasks();
-    }).then(() => {
-      MockInteractions.tap(app.$$('#synced-devices').$$('#menuOpenButton'));
-      assertEquals(1, histogram[SyncedTabsHistogram.OPEN_ALL]);
+          menuButton = cards[0].$['menu-button'];
+          MockInteractions.tap(menuButton);
+          return PolymerTest.flushTasks();
+        })
+        .then(() => {
+          MockInteractions.tap(app.$$('#synced-devices').$$('#menuOpenButton'));
+          assertEquals(1, histogram[SyncedTabsHistogram.OPEN_ALL]);
 
-      MockInteractions.tap(menuButton);
-      return PolymerTest.flushTasks();
-    }).then(() => {
-      MockInteractions.tap(app.$$('#synced-devices').$$('#menuDeleteButton'));
-      assertEquals(1, histogram[SyncedTabsHistogram.HIDE_FOR_NOW]);
-    });
+          MockInteractions.tap(menuButton);
+          return PolymerTest.flushTasks();
+        })
+        .then(() => {
+          MockInteractions.tap(
+              app.$$('#synced-devices').$$('#menuDeleteButton'));
+          assertEquals(1, histogram[SyncedTabsHistogram.HIDE_FOR_NOW]);
+        });
   });
 });
diff --git a/chrome/test/data/webui/md_history/history_routing_test.js b/chrome/test/data/webui/md_history/history_routing_test.js
index e94d3f0..a2c8edf7 100644
--- a/chrome/test/data/webui/md_history/history_routing_test.js
+++ b/chrome/test/data/webui/md_history/history_routing_test.js
@@ -42,7 +42,7 @@
         assertEquals('syncedTabs', app.selectedPage_);
         assertEquals('chrome://history/syncedTabs', window.location.href);
 
-        MockInteractions.keyDownOn(menu.children[0], 32, '', "Space");
+        MockInteractions.keyDownOn(menu.children[0], 32, '', 'Space');
         assertEquals('history', app.selectedPage_);
         assertEquals('chrome://history/', window.location.href);
       });
@@ -82,9 +82,7 @@
       });
     });
   }
-  return {
-    registerTests: registerTests
-  };
+  return {registerTests: registerTests};
 });
 
 cr.define('md_history.history_routing_test_with_query_param', function() {
@@ -120,7 +118,5 @@
       });
     });
   }
-  return {
-    registerTests: registerTests
-  };
+  return {registerTests: registerTests};
 });
diff --git a/chrome/test/data/webui/md_history/history_supervised_user_test.js b/chrome/test/data/webui/md_history/history_supervised_user_test.js
index f309d3f..d292248 100644
--- a/chrome/test/data/webui/md_history/history_supervised_user_test.js
+++ b/chrome/test/data/webui/md_history/history_supervised_user_test.js
@@ -33,7 +33,7 @@
 
   test('deletion disabled for supervised user', function() {
     // Make sure that removeVisits is not being called.
-    registerMessageCallback('removeVisits', this, function (toBeRemoved) {
+    registerMessageCallback('removeVisits', this, function(toBeRemoved) {
       assertNotReached();
     });
 
diff --git a/chrome/test/data/webui/md_history/history_synced_tabs_test.js b/chrome/test/data/webui/md_history/history_synced_tabs_test.js
index e4153e79..aea906fb 100644
--- a/chrome/test/data/webui/md_history/history_synced_tabs_test.js
+++ b/chrome/test/data/webui/md_history/history_synced_tabs_test.js
@@ -13,9 +13,7 @@
 function assertNoSyncedTabsMessageShown(manager, stringID) {
   assertFalse(manager.$['no-synced-tabs'].hidden);
   const message = loadTimeData.getString(stringID);
-  assertNotEquals(
-      -1,
-      manager.$['no-synced-tabs'].textContent.indexOf(message));
+  assertNotEquals(-1, manager.$['no-synced-tabs'].textContent.indexOf(message));
 }
 
 suite('<history-synced-device-manager>', function() {
@@ -33,12 +31,9 @@
   });
 
   test('single card, single window', function() {
-    const sessionList = [
-      createSession(
-          'Nexus 5',
-          [createWindow(['http://www.google.com', 'http://example.com'])]
-      )
-    ];
+    const sessionList = [createSession(
+        'Nexus 5',
+        [createWindow(['http://www.google.com', 'http://example.com'])])];
     setForeignSessions(sessionList);
 
     return PolymerTest.flushTasks().then(function() {
@@ -46,7 +41,8 @@
       assertEquals(
           'http://www.google.com',
           Polymer.dom(card.root)
-              .querySelectorAll('.website-title')[0].children[0]
+              .querySelectorAll('.website-title')[0]
+              .children[0]
               .textContent.trim());
       assertEquals(2, card.tabs.length);
     });
@@ -56,15 +52,13 @@
     const sessionList = [
       createSession(
           'Nexus 5',
-          [createWindow(['http://www.google.com', 'http://example.com'])]
-      ),
+          [createWindow(['http://www.google.com', 'http://example.com'])]),
       createSession(
           'Nexus 6',
           [
             createWindow(['http://test.com']),
             createWindow(['http://www.gmail.com', 'http://badssl.com'])
-          ]
-      ),
+          ]),
     ];
     setForeignSessions(sessionList);
 
@@ -89,86 +83,91 @@
 
     setForeignSessions([session1, session2]);
 
-    return PolymerTest.flushTasks().then(function() {
-      const session1updated = createSession('Chromebook', [
-        createWindow(['http://www.example.com', 'http://crbug.com/new']),
-        createWindow(['http://web.site'])
-      ]);
-      session1updated.timestamp = 1234;
+    return PolymerTest.flushTasks()
+        .then(function() {
+          const session1updated = createSession('Chromebook', [
+            createWindow(['http://www.example.com', 'http://crbug.com/new']),
+            createWindow(['http://web.site'])
+          ]);
+          session1updated.timestamp = 1234;
 
-      setForeignSessions([session1updated, session2]);
+          setForeignSessions([session1updated, session2]);
 
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      // There should only be two cards.
-      const cards = getCards(element);
-      assertEquals(2, cards.length);
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          // There should only be two cards.
+          const cards = getCards(element);
+          assertEquals(2, cards.length);
 
-      // There are now 2 windows in the first device.
-      assertEquals(1, numWindowSeparators(cards[0]));
+          // There are now 2 windows in the first device.
+          assertEquals(1, numWindowSeparators(cards[0]));
 
-      // Check that the actual link changes.
-      assertEquals(
-          'http://crbug.com/new',
-          Polymer.dom(cards[0].root)
-              .querySelectorAll('.website-title')[1].children[0]
-              .textContent.trim());
-    });
+          // Check that the actual link changes.
+          assertEquals(
+              'http://crbug.com/new',
+              Polymer.dom(cards[0].root)
+                  .querySelectorAll('.website-title')[1]
+                  .children[0]
+                  .textContent.trim());
+        });
   });
 
   test('two cards, multiple windows, search', function() {
     const sessionList = [
       createSession(
           'Nexus 5',
-          [createWindow(['http://www.google.com', 'http://example.com'])]
-      ),
+          [createWindow(['http://www.google.com', 'http://example.com'])]),
       createSession(
           'Nexus 6',
           [
             createWindow(['http://www.gmail.com', 'http://badssl.com']),
             createWindow(['http://test.com']),
             createWindow(['http://www.gmail.com', 'http://bagssl.com'])
-          ]
-      ),
+          ]),
     ];
     setForeignSessions(sessionList);
 
-    return PolymerTest.flushTasks().then(function() {
-      const cards = getCards(element);
-      assertEquals(2, cards.length);
+    return PolymerTest.flushTasks()
+        .then(function() {
+          const cards = getCards(element);
+          assertEquals(2, cards.length);
 
-      // Ensure separators between windows are added appropriately.
-      assertEquals(0, numWindowSeparators(cards[0]));
-      assertEquals(2, numWindowSeparators(cards[1]));
-      element.searchTerm = 'g';
+          // Ensure separators between windows are added appropriately.
+          assertEquals(0, numWindowSeparators(cards[0]));
+          assertEquals(2, numWindowSeparators(cards[1]));
+          element.searchTerm = 'g';
 
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      const cards = getCards(element);
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          const cards = getCards(element);
 
-      assertEquals(0, numWindowSeparators(cards[0]));
-      assertEquals(1, cards[0].tabs.length);
-      assertEquals('http://www.google.com', cards[0].tabs[0].title);
-      assertEquals(1, numWindowSeparators(cards[1]));
-      assertEquals(3, cards[1].tabs.length);
-      assertEquals('http://www.gmail.com', cards[1].tabs[0].title);
-      assertEquals('http://www.gmail.com', cards[1].tabs[1].title);
-      assertEquals('http://bagssl.com', cards[1].tabs[2].title);
+          assertEquals(0, numWindowSeparators(cards[0]));
+          assertEquals(1, cards[0].tabs.length);
+          assertEquals('http://www.google.com', cards[0].tabs[0].title);
+          assertEquals(1, numWindowSeparators(cards[1]));
+          assertEquals(3, cards[1].tabs.length);
+          assertEquals('http://www.gmail.com', cards[1].tabs[0].title);
+          assertEquals('http://www.gmail.com', cards[1].tabs[1].title);
+          assertEquals('http://bagssl.com', cards[1].tabs[2].title);
 
-      // Ensure the title text is rendered during searches.
-      assertEquals(
-          'http://www.google.com',
-          Polymer.dom(cards[0].root)
-              .querySelectorAll('.website-title')[0].children[0]
-              .textContent.trim());
+          // Ensure the title text is rendered during searches.
+          assertEquals(
+              'http://www.google.com',
+              Polymer.dom(cards[0].root)
+                  .querySelectorAll('.website-title')[0]
+                  .children[0]
+                  .textContent.trim());
 
-      element.searchTerm = 'Sans';
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      assertEquals(0, getCards(element).length);
+          element.searchTerm = 'Sans';
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          assertEquals(0, getCards(element).length);
 
-      assertNoSyncedTabsMessageShown(element, 'noSearchResults');
-    });
+          assertNoSyncedTabsMessageShown(element, 'noSearchResults');
+        });
   });
 
   test('delete a session', function(done) {
@@ -179,29 +178,31 @@
 
     setForeignSessions(sessionList);
 
-    return PolymerTest.flushTasks().then(function() {
-      const cards = getCards(element);
-      assertEquals(2, cards.length);
+    return PolymerTest.flushTasks()
+        .then(function() {
+          const cards = getCards(element);
+          assertEquals(2, cards.length);
 
-      MockInteractions.tap(cards[0].$['menu-button']);
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      registerMessageCallback('deleteForeignSession', this, function(args) {
-        assertEquals('Nexus 5', args[0]);
+          MockInteractions.tap(cards[0].$['menu-button']);
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          registerMessageCallback('deleteForeignSession', this, function(args) {
+            assertEquals('Nexus 5', args[0]);
 
-        // Simulate deleting the first device.
-        setForeignSessions([sessionList[1]]);
+            // Simulate deleting the first device.
+            setForeignSessions([sessionList[1]]);
 
-        PolymerTest.flushTasks().then(function() {
-          cards = getCards(element);
-          assertEquals(1, cards.length);
-          assertEquals('http://www.badssl.com', cards[0].tabs[0].title);
-          done();
+            PolymerTest.flushTasks().then(function() {
+              cards = getCards(element);
+              assertEquals(1, cards.length);
+              assertEquals('http://www.badssl.com', cards[0].tabs[0].title);
+              done();
+            });
+          });
+
+          MockInteractions.tap(element.$$('#menuDeleteButton'));
         });
-      });
-
-      MockInteractions.tap(element.$$('#menuDeleteButton'));
-    });
   });
 
   test('delete a collapsed session', function() {
@@ -211,24 +212,25 @@
     ];
 
     setForeignSessions(sessionList);
-    return PolymerTest.flushTasks().then(function() {
-      const cards = getCards(element);
-      MockInteractions.tap(cards[0].$['card-heading']);
-      assertFalse(cards[0].opened);
+    return PolymerTest.flushTasks()
+        .then(function() {
+          const cards = getCards(element);
+          MockInteractions.tap(cards[0].$['card-heading']);
+          assertFalse(cards[0].opened);
 
-      // Simulate deleting the first device.
-      setForeignSessions([sessionList[1]]);
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      const cards = getCards(element);
-      assertTrue(cards[0].opened);
-    });
+          // Simulate deleting the first device.
+          setForeignSessions([sessionList[1]]);
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          const cards = getCards(element);
+          assertTrue(cards[0].opened);
+        });
   });
 
   test('click synced tab', function(done) {
     setForeignSessions(
-        [createSession(
-            'Chromebook', [createWindow(['https://example.com'])])]);
+        [createSession('Chromebook', [createWindow(['https://example.com'])])]);
 
     registerMessageCallback('openForeignSession', this, function(args) {
       assertEquals('Chromebook', args[0], 'sessionTag is correct');
@@ -250,8 +252,7 @@
 
   test('show actions menu', function() {
     setForeignSessions(
-        [createSession(
-            'Chromebook', [createWindow(['https://example.com'])])]);
+        [createSession('Chromebook', [createWindow(['https://example.com'])])]);
 
     return PolymerTest.flushTasks().then(function() {
       const cards = getCards(element);
@@ -262,62 +263,66 @@
 
   test('show sign in promo', function() {
     element.signInState = false;
-    return PolymerTest.flushTasks().then(function() {
-      assertFalse(element.$['sign-in-guide'].hidden);
-      element.signInState = true;
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      assertTrue(element.$['sign-in-guide'].hidden);
-    });
+    return PolymerTest.flushTasks()
+        .then(function() {
+          assertFalse(element.$['sign-in-guide'].hidden);
+          element.signInState = true;
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          assertTrue(element.$['sign-in-guide'].hidden);
+        });
   });
 
   test('no synced tabs message', function() {
     // When user is not logged in, there is no synced tabs.
     element.signInState = false;
     element.syncedDevices_ = [];
-    return PolymerTest.flushTasks().then(function() {
-      assertTrue(element.$['no-synced-tabs'].hidden);
+    return PolymerTest.flushTasks()
+        .then(function() {
+          assertTrue(element.$['no-synced-tabs'].hidden);
 
-      const cards = getCards(element);
-      assertEquals(0, cards.length);
+          const cards = getCards(element);
+          assertEquals(0, cards.length);
 
-      element.signInState = true;
+          element.signInState = true;
 
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      // When user signs in, first show loading message.
-      assertNoSyncedTabsMessageShown(element, 'loading');
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          // When user signs in, first show loading message.
+          assertNoSyncedTabsMessageShown(element, 'loading');
 
-      const sessionList = [];
-      setForeignSessions(sessionList);
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      cards = getCards(element);
-      assertEquals(0, cards.length);
-      // If no synced tabs are fetched, show 'no synced tabs'.
-      assertNoSyncedTabsMessageShown(element, 'noSyncedResults');
+          const sessionList = [];
+          setForeignSessions(sessionList);
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          cards = getCards(element);
+          assertEquals(0, cards.length);
+          // If no synced tabs are fetched, show 'no synced tabs'.
+          assertNoSyncedTabsMessageShown(element, 'noSyncedResults');
 
-      sessionList = [
-        createSession(
-            'Nexus 5',
-            [createWindow(['http://www.google.com', 'http://example.com'])]
-        )
-      ];
-      setForeignSessions(sessionList);
+          sessionList = [createSession(
+              'Nexus 5',
+              [createWindow(['http://www.google.com', 'http://example.com'])])];
+          setForeignSessions(sessionList);
 
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      cards = getCards(element);
-      assertEquals(1, cards.length);
-      // If there are any synced tabs, hide the 'no synced tabs' message.
-      assertTrue(element.$['no-synced-tabs'].hidden);
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          cards = getCards(element);
+          assertEquals(1, cards.length);
+          // If there are any synced tabs, hide the 'no synced tabs' message.
+          assertTrue(element.$['no-synced-tabs'].hidden);
 
-      element.signInState = false;
-      return PolymerTest.flushTasks();
-    }).then(function() {
-      // When user signs out, don't show the message.
-      assertTrue(element.$['no-synced-tabs'].hidden);
-    });
+          element.signInState = false;
+          return PolymerTest.flushTasks();
+        })
+        .then(function() {
+          // When user signs out, don't show the message.
+          assertTrue(element.$['no-synced-tabs'].hidden);
+        });
   });
 
   test('hide sign in promo in guest mode', function() {
diff --git a/chrome/test/data/webui/md_history/history_toolbar_test.js b/chrome/test/data/webui/md_history/history_toolbar_test.js
index 70ca76e..48eb8b0 100644
--- a/chrome/test/data/webui/md_history/history_toolbar_test.js
+++ b/chrome/test/data/webui/md_history/history_toolbar_test.js
@@ -55,7 +55,7 @@
     toolbar.$$('cr-toolbar').fire('search-changed', 'Test');
   });
 
-  test('spinner is active on search' , function(done) {
+  test('spinner is active on search', function(done) {
     app.queryState_.queryingDisabled = false;
     registerMessageCallback('queryHistory', this, function(info) {
       PolymerTest.flushTasks().then(function() {
diff --git a/chrome/test/data/webui/md_history/md_history_browsertest.js b/chrome/test/data/webui/md_history/md_history_browsertest.js
index d05f8fc..9a2857f 100644
--- a/chrome/test/data/webui/md_history/md_history_browsertest.js
+++ b/chrome/test/data/webui/md_history/md_history_browsertest.js
@@ -41,10 +41,14 @@
             // the default, changeed to 2 for performance reasons. TODO(dbeam):
             // maybe trim down the number of items created in the tests? Or
             // don't touch <iron-list>'s physical items as much?
-            Array.from(document.querySelectorAll('* /deep/ iron-list')).forEach(
-                function(ironList) { ironList._maxPages = 3; });
+            Array.from(document.querySelectorAll('* /deep/ iron-list'))
+                .forEach(function(ironList) {
+                  ironList._maxPages = 3;
+                });
           })
-          .then(function() { return md_history.ensureLazyLoaded(); })
+          .then(function() {
+            return md_history.ensureLazyLoaded();
+          })
           .then(function() {
             $('history-app').queryState_.queryingDisabled = true;
           });
@@ -174,7 +178,7 @@
     // since there may be a delay as well, the test might check the global var
     // too early as well. In this case the test will have overtaken the
     // callback.
-    registerMessageCallback('queryHistory', this, function (info) {
+    registerMessageCallback('queryHistory', this, function(info) {
       window.historyQueryInfo = info;
     });
 
@@ -188,8 +192,8 @@
 };
 
 TEST_F('MaterialHistoryRoutingWithQueryParamTest', 'All', function() {
-    md_history.history_routing_test_with_query_param.registerTests();
-    mocha.run();
+  md_history.history_routing_test_with_query_param.registerTests();
+  mocha.run();
 });
 
 function MaterialHistorySyncedTabsTest() {}
diff --git a/chrome/test/data/webui/md_history/md_history_focus_test.js b/chrome/test/data/webui/md_history/md_history_focus_test.js
index f6df17c..e8581bf 100644
--- a/chrome/test/data/webui/md_history/md_history_focus_test.js
+++ b/chrome/test/data/webui/md_history/md_history_focus_test.js
@@ -58,9 +58,7 @@
       return PolymerTest.flushTasks().then(() => {
         // Ensure the search bar is focused on load.
         assertTrue(
-            app.$.toolbar.$['main-toolbar']
-            .getSearchField()
-            .isSearchFocused());
+            app.$.toolbar.$['main-toolbar'].getSearchField().isSearchFocused());
       });
     });
 
@@ -70,11 +68,10 @@
       historyResult(createHistoryInfo(), []);
       return PolymerTest.flushTasks().then(() => {
         // Ensure the search bar is focused on load.
-        assertFalse(
-            $('history-app')
-            .$.toolbar.$['main-toolbar']
-            .getSearchField()
-            .isSearchFocused());
+        assertFalse($('history-app')
+                        .$.toolbar.$['main-toolbar']
+                        .getSearchField()
+                        .isSearchFocused());
       });
     });
 
@@ -83,8 +80,7 @@
       field.blur();
       assertFalse(field.showingSearch);
 
-      MockInteractions.pressAndReleaseKeyOn(
-          document.body, 191, '', '/');
+      MockInteractions.pressAndReleaseKeyOn(document.body, 191, '', '/');
       assertTrue(field.showingSearch);
       assertEquals(field.$.searchInput, field.root.activeElement);
 
@@ -97,8 +93,7 @@
       if (cr.isMac)
         modifier = 'meta';
 
-      MockInteractions.pressAndReleaseKeyOn(
-          document.body, 70, modifier, 'f');
+      MockInteractions.pressAndReleaseKeyOn(document.body, 70, modifier, 'f');
       assertTrue(field.showingSearch);
       assertEquals(field.$.searchInput, field.root.activeElement);
     });
@@ -135,8 +130,7 @@
         // Wait for next render to ensure that focus handlers have been
         // registered (see HistoryItemElement.attached).
         Polymer.RenderStatus.afterNextRender(this, function() {
-          MockInteractions.pressAndReleaseKeyOn(
-              focused, 39, [], 'ArrowRight');
+          MockInteractions.pressAndReleaseKeyOn(focused, 39, [], 'ArrowRight');
           focused = items[2].$.title;
           assertEquals(focused, element.lastFocused_);
           assertTrue(items[2].row_.isActive());
@@ -148,8 +142,7 @@
           assertFalse(items[2].row_.isActive());
           assertTrue(items[3].row_.isActive());
 
-          MockInteractions.pressAndReleaseKeyOn(
-              focused, 39, [], 'ArrowRight');
+          MockInteractions.pressAndReleaseKeyOn(focused, 39, [], 'ArrowRight');
           focused = items[3].$['menu-button'];
           assertEquals(focused, element.lastFocused_);
           assertFalse(items[2].row_.isActive());
@@ -209,72 +202,78 @@
         lastFocused = e.currentTarget;
       };
 
-      return PolymerTest.flushTasks().then(function() {
-        cards = polymerSelectAll(element, 'history-synced-device-card');
+      return PolymerTest.flushTasks()
+          .then(function() {
+            cards = polymerSelectAll(element, 'history-synced-device-card');
 
-        focused = cards[0].$['menu-button'];
-        focused.focus();
+            focused = cards[0].$['menu-button'];
+            focused.focus();
 
-        // Go to the collapse button.
-        MockInteractions.pressAndReleaseKeyOn(focused, 39, [], 'ArrowRight');
-        focused = cards[0].$['collapse-button'];
-        assertEquals(focused, lastFocused);
+            // Go to the collapse button.
+            MockInteractions.pressAndReleaseKeyOn(
+                focused, 39, [], 'ArrowRight');
+            focused = cards[0].$['collapse-button'];
+            assertEquals(focused, lastFocused);
 
-        // Go to the first url.
-        MockInteractions.pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
-        focused = polymerSelectAll(cards[0], '.website-title')[0];
-        assertEquals(focused, lastFocused);
+            // Go to the first url.
+            MockInteractions.pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
+            focused = polymerSelectAll(cards[0], '.website-title')[0];
+            assertEquals(focused, lastFocused);
 
-        // Collapse the first card.
-        MockInteractions.pressAndReleaseKeyOn(focused, 38, [], 'ArrowUp');
-        focused = cards[0].$['collapse-button'];
-        assertEquals(focused, lastFocused);
-        MockInteractions.tap(focused);
-      }).then(function() {
-        // Pressing down goes to the next card.
-        MockInteractions.pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
-        focused = cards[1].$['collapse-button'];
-        assertEquals(focused, lastFocused);
+            // Collapse the first card.
+            MockInteractions.pressAndReleaseKeyOn(focused, 38, [], 'ArrowUp');
+            focused = cards[0].$['collapse-button'];
+            assertEquals(focused, lastFocused);
+            MockInteractions.tap(focused);
+          })
+          .then(function() {
+            // Pressing down goes to the next card.
+            MockInteractions.pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
+            focused = cards[1].$['collapse-button'];
+            assertEquals(focused, lastFocused);
 
-        // Expand the first card.
-        MockInteractions.pressAndReleaseKeyOn(focused, 38, [], 'ArrowUp');
-        focused = cards[0].$['collapse-button'];
-        assertEquals(focused, lastFocused);
-        MockInteractions.tap(focused);
-      }).then(function() {
-        // First card's urls are focusable again.
-        MockInteractions.pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
-        focused = polymerSelectAll(cards[0], '.website-title')[0];
-        assertEquals(focused, lastFocused);
+            // Expand the first card.
+            MockInteractions.pressAndReleaseKeyOn(focused, 38, [], 'ArrowUp');
+            focused = cards[0].$['collapse-button'];
+            assertEquals(focused, lastFocused);
+            MockInteractions.tap(focused);
+          })
+          .then(function() {
+            // First card's urls are focusable again.
+            MockInteractions.pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
+            focused = polymerSelectAll(cards[0], '.website-title')[0];
+            assertEquals(focused, lastFocused);
 
-        // Remove the second URL from the first card.
-        sessionList[0].windows[0].tabs.splice(1, 1);
-        element.sessionList = sessionList.slice();
-        return PolymerTest.flushTasks();
-      }).then(function() {
-        cards = polymerSelectAll(element, 'history-synced-device-card');
+            // Remove the second URL from the first card.
+            sessionList[0].windows[0].tabs.splice(1, 1);
+            element.sessionList = sessionList.slice();
+            return PolymerTest.flushTasks();
+          })
+          .then(function() {
+            cards = polymerSelectAll(element, 'history-synced-device-card');
 
-        // Go to the next card's menu buttons.
-        MockInteractions.pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
-        focused = cards[1].$['collapse-button'];
-        assertEquals(focused, lastFocused);
+            // Go to the next card's menu buttons.
+            MockInteractions.pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
+            focused = cards[1].$['collapse-button'];
+            assertEquals(focused, lastFocused);
 
-        MockInteractions.pressAndReleaseKeyOn(focused, 38, [], 'ArrowUp');
-        focused = polymerSelectAll(cards[0], '.website-title')[0];
-        assertEquals(focused, lastFocused);
+            MockInteractions.pressAndReleaseKeyOn(focused, 38, [], 'ArrowUp');
+            focused = polymerSelectAll(cards[0], '.website-title')[0];
+            assertEquals(focused, lastFocused);
 
-        // Remove the second card.
-        sessionList.splice(1, 1);
-        element.sessionList = sessionList.slice();
-        return PolymerTest.flushTasks();
-      }).then(function() {
-        cards = polymerSelectAll(element, 'history-synced-device-card');
+            // Remove the second card.
+            sessionList.splice(1, 1);
+            element.sessionList = sessionList.slice();
+            return PolymerTest.flushTasks();
+          })
+          .then(function() {
+            cards = polymerSelectAll(element, 'history-synced-device-card');
 
-        // Pressing down goes to the next card.
-        MockInteractions.pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
-        focused = cards[1].$['collapse-button'];
-        assertEquals(focused, lastFocused);
-      });
+            // Pressing down goes to the next card.
+            MockInteractions.pressAndReleaseKeyOn(focused, 40, [], 'ArrowDown');
+            focused = cards[1].$['collapse-button'];
+            assertEquals(focused, lastFocused);
+          });
     });
   });
 
diff --git a/chrome/test/data/webui/md_history/test_util.js b/chrome/test/data/webui/md_history/test_util.js
index 359dedb..2032787a 100644
--- a/chrome/test/data/webui/md_history/test_util.js
+++ b/chrome/test/data/webui/md_history/test_util.js
@@ -87,10 +87,7 @@
  * @return {!HistoryInfo}
  */
 function createHistoryInfo(searchTerm) {
-  return {
-    finished: true,
-    term: searchTerm || ''
-  };
+  return {finished: true, term: searchTerm || ''};
 }
 
 /**
@@ -112,7 +109,9 @@
  */
 function waitForEvent(element, eventName, predicate) {
   if (!predicate)
-    predicate = function() { return true; };
+    predicate = function() {
+      return true;
+    };
 
   return new Promise(function(resolve) {
     const listener = function(e) {
@@ -188,9 +187,5 @@
     return {sessionId: 456, timestamp: 0, title: tabUrl, url: tabUrl};
   });
 
-  return {
-    tabs: tabs,
-    sessionId: '123',
-    userVisibleTimestamp: "A while ago"
-  };
+  return {tabs: tabs, sessionId: '123', userVisibleTimestamp: 'A while ago'};
 }
diff --git a/chrome/test/data/webui/md_user_manager/create_profile_tests.js b/chrome/test/data/webui/md_user_manager/create_profile_tests.js
index 8306df7..b47af5f 100644
--- a/chrome/test/data/webui/md_user_manager/create_profile_tests.js
+++ b/chrome/test/data/webui/md_user_manager/create_profile_tests.js
@@ -24,8 +24,10 @@
         // Replace real proxy with mock proxy.
         signin.ProfileBrowserProxyImpl.instance_ = browserProxy;
         browserProxy.setDefaultProfileInfo({name: 'profile name'});
-        browserProxy.setIcons([{url: 'icon1.png', label: 'icon1'},
-                               {url: 'icon2.png', label: 'icon2'}]);
+        browserProxy.setIcons([
+          {url: 'icon1.png', label: 'icon1'},
+          {url: 'icon2.png', label: 'icon2'}
+        ]);
 
         createProfileElement = createElement();
 
@@ -127,8 +129,8 @@
           // Create is no longer in progress.
           assertFalse(createProfileElement.createInProgress_);
           // Error message is set.
-          assertEquals('Error Message',
-                       createProfileElement.$.message.innerHTML);
+          assertEquals(
+              'Error Message', createProfileElement.$.message.innerHTML);
         });
       });
 
@@ -145,8 +147,8 @@
           // Create is no longer in progress.
           assertFalse(createProfileElement.createInProgress_);
           // Warning message is set.
-          assertEquals('Warning Message',
-                       createProfileElement.$.message.innerHTML);
+          assertEquals(
+              'Warning Message', createProfileElement.$.message.innerHTML);
         });
       });
     });
diff --git a/chrome/test/data/webui/md_user_manager/test_profile_browser_proxy.js b/chrome/test/data/webui/md_user_manager/test_profile_browser_proxy.js
index 1c01a82..e6e140c 100644
--- a/chrome/test/data/webui/md_user_manager/test_profile_browser_proxy.js
+++ b/chrome/test/data/webui/md_user_manager/test_profile_browser_proxy.js
@@ -52,16 +52,17 @@
   getAvailableIcons() {
     this.methodCalled('getAvailableIcons');
     cr.webUIListenerCallback('profile-icons-received', this.icons_);
-    cr.webUIListenerCallback('profile-defaults-received',
-                             this.defaultProfileInfo_);
+    cr.webUIListenerCallback(
+        'profile-defaults-received', this.defaultProfileInfo_);
   }
 
   /** @override */
   createProfile(profileName, profileIconUrl, createShortcut) {
-    this.methodCalled('createProfile',
-                      {profileName: profileName,
-                       profileIconUrl: profileIconUrl,
-                       createShortcut: createShortcut});
+    this.methodCalled('createProfile', {
+      profileName: profileName,
+      profileIconUrl: profileIconUrl,
+      createShortcut: createShortcut
+    });
   }
 
   /** @override */
diff --git a/chrome/test/data/webui/md_user_manager/user_manager_pages_tests.js b/chrome/test/data/webui/md_user_manager/user_manager_pages_tests.js
index b5f63f4e..d22719b8 100644
--- a/chrome/test/data/webui/md_user_manager/user_manager_pages_tests.js
+++ b/chrome/test/data/webui/md_user_manager/user_manager_pages_tests.js
@@ -20,12 +20,10 @@
       });
 
       test('User Pods page is the default visible page', function() {
-        assertTrue(
-          pagesElement.isPresentIn_(pagesElement.selectedPage_,
-                                    'user-pods-page'));
-        assertFalse(
-          pagesElement.isPresentIn_(pagesElement.selectedPage_,
-                                    'create-user-page'));
+        assertTrue(pagesElement.isPresentIn_(
+            pagesElement.selectedPage_, 'user-pods-page'));
+        assertFalse(pagesElement.isPresentIn_(
+            pagesElement.selectedPage_, 'create-user-page'));
       });
 
       test('Change page listener works', function() {
diff --git a/chrome/test/data/webui/media_router/issue_banner_tests.js b/chrome/test/data/webui/media_router/issue_banner_tests.js
index fc19ad3..80fb9cc 100644
--- a/chrome/test/data/webui/media_router/issue_banner_tests.js
+++ b/chrome/test/data/webui/media_router/issue_banner_tests.js
@@ -62,14 +62,16 @@
         if (issue) {
           checkElementText(issue.title, 'title');
 
-          checkElementText(loadTimeData.getString(
-              banner.actionTypeToButtonTextResource_[
-                  issue.defaultActionType]), 'default-button');
+          checkElementText(
+              loadTimeData.getString(banner.actionTypeToButtonTextResource_
+                                         [issue.defaultActionType]),
+              'default-button');
 
           if (issue.secondaryActionType) {
-            checkElementText(loadTimeData.getString(
-                banner.actionTypeToButtonTextResource_[
-                    issue.secondaryActionType]), 'opt-button');
+            checkElementText(
+                loadTimeData.getString(banner.actionTypeToButtonTextResource_
+                                           [issue.secondaryActionType]),
+                'opt-button');
           }
         } else {
           checkElementText('', 'title');
@@ -80,8 +82,9 @@
 
       // Checks whether parts of the UI is visible.
       var checkButtonVisibility = function(optAction) {
-        assertEquals(!optAction, banner.$['buttons']
-            .querySelector('paper-button').hidden);
+        assertEquals(
+            !optAction,
+            banner.$['buttons'].querySelector('paper-button').hidden);
       };
 
       // Import issue_banner.html before running suite.
@@ -99,17 +102,17 @@
 
         // Initialize issues.
         fakeBlockingIssueOne = new media_router.Issue(
-            1, 'Issue Title 1', 'Issue Message 1', 0, 1,
-            'route id 1', true, 1234);
+            1, 'Issue Title 1', 'Issue Message 1', 0, 1, 'route id 1', true,
+            1234);
         fakeBlockingIssueTwo = new media_router.Issue(
-            2, 'Issue Title 2', 'Issue Message 2', 0, undefined,
-            'route id 2', true, 1234);
+            2, 'Issue Title 2', 'Issue Message 2', 0, undefined, 'route id 2',
+            true, 1234);
         fakeNonBlockingIssueOne = new media_router.Issue(
-            3, 'Issue Title 3', 'Issue Message 3', 0, 1,
-            'route id 3', false, 1234);
+            3, 'Issue Title 3', 'Issue Message 3', 0, 1, 'route id 3', false,
+            1234);
         fakeNonBlockingIssueTwo = new media_router.Issue(
-            4, 'Issue Title 4', 'Issue Message 4', 0, undefined,
-            'route id 4', false, 1234);
+            4, 'Issue Title 4', 'Issue Message 4', 0, undefined, 'route id 4',
+            false, 1234);
 
         // Allow for the issue banner to be created and attached.
         setTimeout(done);
@@ -120,8 +123,7 @@
       test('blocking issue default action click', function(done) {
         banner.issue = fakeBlockingIssueOne;
         banner.addEventListener('issue-action-click', function(data) {
-          checkDataFromEventFiring(fakeBlockingIssueOne,
-              data, true);
+          checkDataFromEventFiring(fakeBlockingIssueOne, data, true);
           done();
         });
         MockInteractions.tap(banner.$['default-button']);
@@ -132,8 +134,7 @@
       test('blocking issue optional action click', function(done) {
         banner.issue = fakeBlockingIssueOne;
         banner.addEventListener('issue-action-click', function(data) {
-          checkDataFromEventFiring(fakeBlockingIssueOne,
-              data, false);
+          checkDataFromEventFiring(fakeBlockingIssueOne, data, false);
           done();
         });
         MockInteractions.tap(banner.$['opt-button']);
@@ -144,8 +145,7 @@
       test('non-blocking issue default action click', function(done) {
         banner.issue = fakeNonBlockingIssueOne;
         banner.addEventListener('issue-action-click', function(data) {
-          checkDataFromEventFiring(fakeNonBlockingIssueOne,
-              data, true);
+          checkDataFromEventFiring(fakeNonBlockingIssueOne, data, true);
           done();
         });
         MockInteractions.tap(banner.$['default-button']);
@@ -156,8 +156,7 @@
       test('non-blocking issue optional action click', function(done) {
         banner.issue = fakeNonBlockingIssueOne;
         banner.addEventListener('issue-action-click', function(data) {
-          checkDataFromEventFiring(fakeNonBlockingIssueOne,
-              data, false);
+          checkDataFromEventFiring(fakeNonBlockingIssueOne, data, false);
           done();
         });
         MockInteractions.tap(banner.$['opt-button']);
diff --git a/chrome/test/data/webui/media_router/media_router_container_cast_mode_list_tests.js b/chrome/test/data/webui/media_router/media_router_container_cast_mode_list_tests.js
index dfe283b..8b71536 100644
--- a/chrome/test/data/webui/media_router/media_router_container_cast_mode_list_tests.js
+++ b/chrome/test/data/webui/media_router/media_router_container_cast_mode_list_tests.js
@@ -125,18 +125,18 @@
 
       // Container remains in auto mode even if the cast mode list changed.
       test('cast mode list updated in auto mode', function(done) {
-        assertEquals(media_router.AUTO_CAST_MODE.description,
-            container.headerText);
-        assertEquals(media_router.CastModeType.AUTO,
-            container.shownCastModeValue_);
+        assertEquals(
+            media_router.AUTO_CAST_MODE.description, container.headerText);
+        assertEquals(
+            media_router.CastModeType.AUTO, container.shownCastModeValue_);
         assertFalse(container.userHasSelectedCastMode_);
 
         container.castModeList = fakeCastModeList.slice(1);
         setTimeout(function() {
-          assertEquals(media_router.AUTO_CAST_MODE.description,
-              container.headerText);
-          assertEquals(media_router.CastModeType.AUTO,
-              container.shownCastModeValue_);
+          assertEquals(
+              media_router.AUTO_CAST_MODE.description, container.headerText);
+          assertEquals(
+              media_router.CastModeType.AUTO, container.shownCastModeValue_);
           assertFalse(container.userHasSelectedCastMode_);
           done();
         });
@@ -176,14 +176,15 @@
 
       // Tests the header text. Choosing a cast mode updates the header text.
       test('header text with cast mode selected', function(done) {
-        assertEquals(loadTimeData.getString('selectCastModeHeaderText'),
+        assertEquals(
+            loadTimeData.getString('selectCastModeHeaderText'),
             container.i18n('selectCastModeHeaderText'));
 
         // The container is currently in auto cast mode, since we have not
         // picked a cast mode explicitly, and the sinks is not compatible
         // with exactly one cast mode.
-        assertEquals(media_router.AUTO_CAST_MODE.description,
-            container.headerText);
+        assertEquals(
+            media_router.AUTO_CAST_MODE.description, container.headerText);
         assertFalse(container.userHasSelectedCastMode_);
 
         container.castModeList = fakeCastModeListWithNonPresentationModesOnly;
@@ -194,7 +195,8 @@
         setTimeout(function() {
           var castModeList =
               container.$$('#cast-mode-list').querySelectorAll('paper-item');
-          assertEquals(fakeCastModeListWithNonPresentationModesOnly.length,
+          assertEquals(
+              fakeCastModeListWithNonPresentationModesOnly.length,
               castModeList.length);
           for (var i = 0; i < castModeList.length; i++) {
             MockInteractions.tap(castModeList[i]);
@@ -228,15 +230,15 @@
             MockInteractions.tap(castModeList[i]);
             if (fakeCastModeList[i].type ==
                 media_router.CastModeType.PRESENTATION) {
-              assertEquals(fakeCastModeList[i].description,
-                  container.headerText);
+              assertEquals(
+                  fakeCastModeList[i].description, container.headerText);
 
               checkElementText(fakeCastModeList[i].host, castModeList[i]);
             } else {
-              assertEquals(fakeCastModeList[i].description,
-                  container.headerText);
-              checkElementText(fakeCastModeList[i].description,
-                  castModeList[i]);
+              assertEquals(
+                  fakeCastModeList[i].description, container.headerText);
+              checkElementText(
+                  fakeCastModeList[i].description, castModeList[i]);
             }
           }
 
@@ -247,18 +249,19 @@
       // Tests that pseudo sinks are ignored for the purpose of computing
       // which cast mode to show.
       test('cast modes not affected by pseudo sink', function(done) {
-        assertEquals(media_router.CastModeType.AUTO,
-            container.shownCastModeValue_);
+        assertEquals(
+            media_router.CastModeType.AUTO, container.shownCastModeValue_);
         container.castModeList = fakeCastModeList;
-        var sink = new media_router.Sink('pseudo-sink-id',
-            'Pseudo sink', null, null, media_router.SinkIconType.GENERIC,
-            media_router.SinkStatus.ACTIVE, /* DESKTOP */ 0x4);
+        var sink = new media_router.Sink(
+            'pseudo-sink-id', 'Pseudo sink', null, null,
+            media_router.SinkIconType.GENERIC, media_router.SinkStatus.ACTIVE,
+            /* DESKTOP */ 0x4);
         sink.isPseudoSink = true;
         container.allSinks = [sink];
 
         setTimeout(function() {
-          assertEquals(media_router.CastModeType.AUTO,
-              container.shownCastModeValue_);
+          assertEquals(
+              media_router.CastModeType.AUTO, container.shownCastModeValue_);
           done();
         });
       });
@@ -267,9 +270,8 @@
       test('cast mode list state visibility', function(done) {
         container.showCastModeList_();
         setTimeout(function() {
-          checkElementsVisibleWithId(['cast-mode-list',
-                                      'container-header',
-                                      'device-missing']);
+          checkElementsVisibleWithId(
+              ['cast-mode-list', 'container-header', 'device-missing']);
 
           // Set a non-blocking issue. The issue should be visible.
           container.issue = fakeNonBlockingIssue;
@@ -282,9 +284,8 @@
             // Set a blocking issue. The cast mode list should not be displayed.
             container.issue = fakeBlockingIssue;
             setTimeout(function() {
-              checkElementsVisibleWithId(['container-header',
-                                          'device-missing',
-                                          'issue-banner']);
+              checkElementsVisibleWithId(
+                  ['container-header', 'device-missing', 'issue-banner']);
               done();
             });
           });
@@ -295,32 +296,32 @@
       // no longer exists in the list of cast modes, then switch back to auto
       // mode.
       test('cast mode list updated in selected cast mode', function(done) {
-        assertEquals(media_router.AUTO_CAST_MODE.description,
-            container.headerText);
-        assertEquals(media_router.CastModeType.AUTO,
-            container.shownCastModeValue_);
+        assertEquals(
+            media_router.AUTO_CAST_MODE.description, container.headerText);
+        assertEquals(
+            media_router.CastModeType.AUTO, container.shownCastModeValue_);
         assertFalse(container.userHasSelectedCastMode_);
 
         MockInteractions.tap(
             container.get('container-header').$['arrow-drop-icon']);
         setTimeout(function() {
           var castModeList =
-                container.$$('#cast-mode-list')
-                    .querySelectorAll('paper-item');
+              container.$$('#cast-mode-list').querySelectorAll('paper-item');
           MockInteractions.tap(castModeList[0]);
           setTimeout(function() {
-            assertEquals(fakeCastModeList[0].description,
-                container.headerText);
-            assertEquals(fakeCastModeList[0].type,
-                container.shownCastModeValue_);
+            assertEquals(fakeCastModeList[0].description, container.headerText);
+            assertEquals(
+                fakeCastModeList[0].type, container.shownCastModeValue_);
 
             assertTrue(container.userHasSelectedCastMode_);
 
             container.castModeList = fakeCastModeList.slice(1);
             setTimeout(function() {
-              assertEquals(media_router.AUTO_CAST_MODE.description,
+              assertEquals(
+                  media_router.AUTO_CAST_MODE.description,
                   container.headerText);
-              assertEquals(media_router.CastModeType.AUTO,
+              assertEquals(
+                  media_router.CastModeType.AUTO,
                   container.shownCastModeValue_);
               assertFalse(container.userHasSelectedCastMode_);
               done();
@@ -338,28 +339,23 @@
             container.get('container-header').$['arrow-drop-icon']);
         setTimeout(function() {
           var castModeList =
-                container.$$('#cast-mode-list')
-                    .querySelectorAll('paper-item');
+              container.$$('#cast-mode-list').querySelectorAll('paper-item');
           MockInteractions.tap(castModeList[0]);
-          assertEquals(fakeCastModeList[0].description,
-              container.headerText);
+          assertEquals(fakeCastModeList[0].description, container.headerText);
 
           setTimeout(function() {
-            var sinkList =
-                container.shadowRoot.getElementById('sink-list')
-                    .querySelectorAll('paper-item');
+            var sinkList = container.shadowRoot.getElementById('sink-list')
+                               .querySelectorAll('paper-item');
 
             // The sink list is empty because none of the sinks in
             // fakeSinkList is compatible with cast mode 0.
             assertEquals(0, sinkList.length);
             MockInteractions.tap(castModeList[2]);
-            assertEquals(fakeCastModeList[2].description,
-                container.headerText);
+            assertEquals(fakeCastModeList[2].description, container.headerText);
 
             setTimeout(function() {
-              var sinkList =
-                  container.shadowRoot.getElementById('sink-list')
-                      .querySelectorAll('paper-item');
+              var sinkList = container.shadowRoot.getElementById('sink-list')
+                                 .querySelectorAll('paper-item');
               assertEquals(3, sinkList.length);
               done();
             });
@@ -370,28 +366,28 @@
       // When a forced cast mode it set, it is used.
       test('cast mode list respects forced mode', function(done) {
         container.allSinks = [
-          new media_router.Sink('sink id 1', 'Sink 1', null, null,
-                                media_router.SinkIconType.CAST,
-                                media_router.SinkStatus.ACTIVE, 0x1),
-          new media_router.Sink('sink id 2', 'Sink 2', null, null,
-                                media_router.SinkIconType.CAST,
-                                media_router.SinkStatus.ACTIVE, 0x1 | 0x2),
-          new media_router.Sink('sink id 3', 'Sink 3', null, null,
-                                media_router.SinkIconType.CAST,
-                                media_router.SinkStatus.ACTIVE, 0x2)
+          new media_router.Sink(
+              'sink id 1', 'Sink 1', null, null, media_router.SinkIconType.CAST,
+              media_router.SinkStatus.ACTIVE, 0x1),
+          new media_router.Sink(
+              'sink id 2', 'Sink 2', null, null, media_router.SinkIconType.CAST,
+              media_router.SinkStatus.ACTIVE, 0x1 | 0x2),
+          new media_router.Sink(
+              'sink id 3', 'Sink 3', null, null, media_router.SinkIconType.CAST,
+              media_router.SinkStatus.ACTIVE, 0x2)
         ];
         container.castModeList = fakeCastModeListWithPresentationModeForced;
-        MockInteractions.tap(container.$['container-header'].
-                             $['arrow-drop-icon']);
+        MockInteractions.tap(
+            container.$['container-header'].$['arrow-drop-icon']);
         setTimeout(function() {
-          assertEquals(media_router.CastModeType.PRESENTATION,
-                       container.shownCastModeValue_);
+          assertEquals(
+              media_router.CastModeType.PRESENTATION,
+              container.shownCastModeValue_);
           assertEquals('Cast google.com', container.headerText);
           assertFalse(container.userHasSelectedCastMode_);
 
-          var sinkList =
-              container.shadowRoot.getElementById('sink-list')
-              .querySelectorAll('paper-item');
+          var sinkList = container.shadowRoot.getElementById('sink-list')
+                             .querySelectorAll('paper-item');
 
           // The sink list contains only sinks compatible with PRESENTATION
           // mode.
@@ -407,27 +403,29 @@
       // route.
       test('sink list in user selected cast mode', function(done) {
         var newSinks = [
-          new media_router.Sink('sink id 10', 'Sink 10', null, null,
-              media_router.SinkIconType.CAST,
-              media_router.SinkStatus.ACTIVE, 0x4 | 0x8),
-          new media_router.Sink('sink id 20', 'Sink 20', null, null,
-              media_router.SinkIconType.CAST,
-              media_router.SinkStatus.ACTIVE, 0x2 | 0x4 | 0x8),
-          new media_router.Sink('sink id 30', 'Sink 30', null, null,
-              media_router.SinkIconType.CAST,
-              media_router.SinkStatus.PENDING, 0x4 | 0x8),
+          new media_router.Sink(
+              'sink id 10', 'Sink 10', null, null,
+              media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE,
+              0x4 | 0x8),
+          new media_router.Sink(
+              'sink id 20', 'Sink 20', null, null,
+              media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE,
+              0x2 | 0x4 | 0x8),
+          new media_router.Sink(
+              'sink id 30', 'Sink 30', null, null,
+              media_router.SinkIconType.CAST, media_router.SinkStatus.PENDING,
+              0x4 | 0x8),
         ];
 
         container.allSinks = newSinks;
         container.routeList = [
-          new media_router.Route('id 1', 'sink id 30',
-                                 'Title 1', 1, false, false),
+          new media_router.Route(
+              'id 1', 'sink id 30', 'Title 1', 1, false, false),
         ];
 
         setTimeout(function() {
-          var sinkList =
-              container.shadowRoot.getElementById('sink-list')
-                  .querySelectorAll('paper-item');
+          var sinkList = container.shadowRoot.getElementById('sink-list')
+                             .querySelectorAll('paper-item');
 
           // Since we haven't selected a cast mode, we don't filter sinks.
           assertEquals(3, sinkList.length);
@@ -439,15 +437,13 @@
             var castModeList =
                 container.$$('#cast-mode-list').querySelectorAll('paper-item');
             MockInteractions.tap(castModeList[1]);
-            assertEquals(fakeCastModeList[1].description,
-                container.headerText);
-            assertEquals(fakeCastModeList[1].type,
-                container.shownCastModeValue_);
+            assertEquals(fakeCastModeList[1].description, container.headerText);
+            assertEquals(
+                fakeCastModeList[1].type, container.shownCastModeValue_);
 
             setTimeout(function() {
-              var sinkList =
-                  container.shadowRoot.getElementById('sink-list')
-                      .querySelectorAll('paper-item');
+              var sinkList = container.shadowRoot.getElementById('sink-list')
+                                 .querySelectorAll('paper-item');
 
               // newSinks[0] got filtered out since it is not compatible with
               // cast mode 1.
@@ -467,13 +463,12 @@
               // selected that cast mode.
               container.allSinks = [];
               setTimeout(function() {
-                assertEquals(fakeCastModeList[1].description,
-                    container.headerText);
-                assertEquals(fakeCastModeList[1].type,
-                    container.shownCastModeValue_);
-                var sinkList =
-                    container.shadowRoot.getElementById('sink-list')
-                        .querySelectorAll('paper-item');
+                assertEquals(
+                    fakeCastModeList[1].description, container.headerText);
+                assertEquals(
+                    fakeCastModeList[1].type, container.shownCastModeValue_);
+                var sinkList = container.shadowRoot.getElementById('sink-list')
+                                   .querySelectorAll('paper-item');
                 assertEquals(0, sinkList.length);
                 done();
               });
@@ -507,21 +502,21 @@
       // cast mode.
       test('cast to sink with existing route', function(done) {
         var newSinks = [
-          new media_router.Sink('sink id 10', 'Sink 10', null, null,
-              media_router.SinkIconType.CAST,
-              media_router.SinkStatus.ACTIVE, 0x2 | 0x4 | 0x8),
+          new media_router.Sink(
+              'sink id 10', 'Sink 10', null, null,
+              media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE,
+              0x2 | 0x4 | 0x8),
         ];
 
         container.allSinks = newSinks;
         container.routeList = [
-          new media_router.Route('id 1', 'sink id 10',
-                                 'Title 1', 1, false, false),
+          new media_router.Route(
+              'id 1', 'sink id 10', 'Title 1', 1, false, false),
         ];
 
         setTimeout(function() {
-          var sinkList =
-              container.shadowRoot.getElementById('sink-list')
-                  .querySelectorAll('paper-item');
+          var sinkList = container.shadowRoot.getElementById('sink-list')
+                             .querySelectorAll('paper-item');
 
           MockInteractions.tap(
               container.get('container-header').$['arrow-drop-icon']);
@@ -532,16 +527,15 @@
             MockInteractions.tap(castModeList[1]);
 
             setTimeout(function() {
-              var sinkList =
-                  container.shadowRoot.getElementById('sink-list')
-                      .querySelectorAll('paper-item');
+              var sinkList = container.shadowRoot.getElementById('sink-list')
+                                 .querySelectorAll('paper-item');
 
               MockInteractions.tap(sinkList[0]);
               setTimeout(function() {
                 assertFalse(container.shadowRoot.getElementById('route-details')
-                            .shadowRoot
-                            .getElementById('start-casting-to-route-button')
-                            .hasAttribute('hidden'));
+                                .shadowRoot
+                                .getElementById('start-casting-to-route-button')
+                                .hasAttribute('hidden'));
                 done();
               });
             });
diff --git a/chrome/test/data/webui/media_router/media_router_container_filter_tests.js b/chrome/test/data/webui/media_router/media_router_container_filter_tests.js
index c022dc74..184e8996 100644
--- a/chrome/test/data/webui/media_router/media_router_container_filter_tests.js
+++ b/chrome/test/data/webui/media_router/media_router_container_filter_tests.js
@@ -20,7 +20,9 @@
   var chainOnAnimationPromise = function(f) {
     setTimeout(function() {
       container.animationPromise_.then(f).catch(function(err) {
-        setTimeout(function() { throw err; });
+        setTimeout(function() {
+          throw err;
+        });
       });
     });
   };
@@ -157,8 +159,9 @@
         MockInteractions.tap(container.$$('#sink-search-icon'));
         setTimeout(function() {
           checkCurrentView(media_router.MediaRouterView.FILTER);
-          assertEquals(container.$$('#sink-search-input'),
-                       container.shadowRoot.activeElement);
+          assertEquals(
+              container.$$('#sink-search-input'),
+              container.shadowRoot.activeElement);
           done();
         });
       });
@@ -169,8 +172,9 @@
         MockInteractions.focus(container.$$('#sink-search-input'));
         setTimeout(function() {
           checkCurrentView(media_router.MediaRouterView.FILTER);
-          assertEquals(container.$$('#sink-search-input'),
-                       container.shadowRoot.activeElement);
+          assertEquals(
+              container.$$('#sink-search-input'),
+              container.shadowRoot.activeElement);
           done();
         });
       });
@@ -249,8 +253,7 @@
         MockInteractions.tap(container.$$('#sink-search-icon'));
         setTimeout(function() {
           var item =
-              container.$$('#search-results')
-                  .querySelectorAll('paper-item')[1];
+              container.$$('#search-results').querySelectorAll('paper-item')[1];
           var closeButton = container.$['container-header'].$['close-button'];
           closeButton.focus();
           var focusedSuccess = closeButton.focused;
@@ -268,61 +271,59 @@
 
       // Tests that expected elements are visible when in filter view.
       test('filter view visibility', function(done) {
-        checkElementsVisibleWithId(['container-header',
-                                    'device-missing',
-                                    'sink-search',
-                                    'sink-list-view']);
+        checkElementsVisibleWithId([
+          'container-header', 'device-missing', 'sink-search', 'sink-list-view'
+        ]);
         // Clicking the search icon should transition |container| to FILTER
         // view.
         MockInteractions.tap(container.$$('#sink-search-icon'));
         chainOnAnimationPromise(function() {
-          checkElementsVisibleWithId(['container-header',
-                                      'device-missing',
-                                      'sink-search',
-                                      'sink-list-view']);
+          checkElementsVisibleWithId([
+            'container-header', 'device-missing', 'sink-search',
+            'sink-list-view'
+          ]);
 
           // Adding sinks should populate the search list.
           container.allSinks = fakeSinkList;
           chainOnAnimationPromise(function() {
-            checkElementsVisibleWithId(['container-header',
-                                        'search-results',
-                                        'sink-search',
-                                        'sink-list-view']);
+            checkElementsVisibleWithId([
+              'container-header', 'search-results', 'sink-search',
+              'sink-list-view'
+            ]);
             // Typing text that doesn't match any sinks should display a 'no
             // matches' message.
             container.$$('#sink-search-input').value = searchTextNone;
-            checkElementsVisibleWithId(['container-header',
-                                        'no-search-matches',
-                                        'sink-search',
-                                        'sink-list-view']);
+            checkElementsVisibleWithId([
+              'container-header', 'no-search-matches', 'sink-search',
+              'sink-list-view'
+            ]);
             // Changing that text to something that matches at least one sink
             // should show the matching sinks again.
             container.$$('#sink-search-input').value = searchTextOne;
             // maybe inside setTimeout
-            checkElementsVisibleWithId(['container-header',
-                                        'search-results',
-                                        'sink-search',
-                                        'sink-list-view']);
+            checkElementsVisibleWithId([
+              'container-header', 'search-results', 'sink-search',
+              'sink-list-view'
+            ]);
             // Clicking the back button should leave |searchTextOne| in the
             // input but return to the SINK_LIST view.
             MockInteractions.tap(
                 container.shadowRoot.getElementById('container-header')
                     .shadowRoot.getElementById('back-button'));
             chainOnAnimationPromise(function() {
-              checkElementsVisibleWithId(['container-header',
-                                          'sink-search',
-                                          'sink-list',
-                                          'sink-list-view']);
+              checkElementsVisibleWithId([
+                'container-header', 'sink-search', 'sink-list', 'sink-list-view'
+              ]);
               // When the search button is clicked again, the matching sinks
               // should be shown again. This doesn't prove that the matching
               // worked when returning to the FILTER view though, just that it
               // at least shows some sort of sink list as search results.
               MockInteractions.tap(container.$$('#sink-search-icon'));
               chainOnAnimationPromise(function() {
-                checkElementsVisibleWithId(['container-header',
-                                            'search-results',
-                                            'sink-search',
-                                            'sink-list-view']);
+                checkElementsVisibleWithId([
+                  'container-header', 'search-results', 'sink-search',
+                  'sink-list-view'
+                ]);
 
                 container.$$('#sink-search-input').value = searchTextNone;
                 // Clicking the back button should leave |searchTextNone| in the
@@ -331,27 +332,27 @@
                     container.shadowRoot.getElementById('container-header')
                         .shadowRoot.getElementById('back-button'));
                 chainOnAnimationPromise(function() {
-                  checkElementsVisibleWithId(['container-header',
-                                              'sink-search',
-                                              'sink-list',
-                                              'sink-list-view']);
+                  checkElementsVisibleWithId([
+                    'container-header', 'sink-search', 'sink-list',
+                    'sink-list-view'
+                  ]);
                   // When the search button is clicked again, there should be no
                   // matches because |searchTextNone| should still be used to
                   // filter.
                   MockInteractions.tap(container.$$('#sink-search-icon'));
                   chainOnAnimationPromise(function() {
-                    checkElementsVisibleWithId(['container-header',
-                                                'no-search-matches',
-                                                'sink-search',
-                                                'sink-list-view']);
+                    checkElementsVisibleWithId([
+                      'container-header', 'no-search-matches', 'sink-search',
+                      'sink-list-view'
+                    ]);
                     // Pressing the Escape key in FILTER view should return
                     // |container| to SINK_LIST view and not exit the dialog.
                     pressEscapeOnElement(container);
                     chainOnAnimationPromise(function() {
-                      checkElementsVisibleWithId(['container-header',
-                                                  'sink-search',
-                                                  'sink-list',
-                                                  'sink-list-view']);
+                      checkElementsVisibleWithId([
+                        'container-header', 'sink-search', 'sink-list',
+                        'sink-list-view'
+                      ]);
                       done();
                     });
                   });
@@ -374,11 +375,10 @@
         container.issue = fakeNonBlockingIssue;
         MockInteractions.tap(container.$$('#sink-search-icon'));
         chainOnAnimationPromise(function() {
-          checkElementsVisibleWithId(['container-header',
-                                      'issue-banner',
-                                      'search-results',
-                                      'sink-search',
-                                      'sink-list-view']);
+          checkElementsVisibleWithId([
+            'container-header', 'issue-banner', 'search-results', 'sink-search',
+            'sink-list-view'
+          ]);
           done();
         });
       });
@@ -468,9 +468,8 @@
 
             searchInput.value = searchTextNone;
             setTimeout(function() {
-              var searchResults =
-                  container.$$('#search-results')
-                      .querySelectorAll('paper-item');
+              var searchResults = container.$$('#search-results')
+                                      .querySelectorAll('paper-item');
               assertEquals(0, searchResults.length);
               done();
             });
@@ -538,25 +537,25 @@
         // Sink 3 - no sink description, route -> subtext = route description
         // Sink 4 - sink description, route -> subtext = route description
         container.allSinks = [
-            new media_router.Sink('sink id 1', 'Sink 1', null, null,
-                media_router.SinkIconType.CAST,
-                media_router.SinkStatus.ACTIVE, [1, 2, 3]),
-            new media_router.Sink('sink id 2', 'Sink 2',
-                'Sink 2 description', null,
-                media_router.SinkIconType.CAST,
-                media_router.SinkStatus.ACTIVE, [1, 2, 3]),
-            new media_router.Sink('sink id 3', 'Sink 3', null, null,
-                media_router.SinkIconType.CAST,
-                media_router.SinkStatus.PENDING, [1, 2, 3]),
-            new media_router.Sink('sink id 4', 'Sink 4',
-                'Sink 4 description', null,
-                media_router.SinkIconType.CAST,
-                media_router.SinkStatus.PENDING, [1, 2, 3])
+          new media_router.Sink(
+              'sink id 1', 'Sink 1', null, null, media_router.SinkIconType.CAST,
+              media_router.SinkStatus.ACTIVE, [1, 2, 3]),
+          new media_router.Sink(
+              'sink id 2', 'Sink 2', 'Sink 2 description', null,
+              media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE,
+              [1, 2, 3]),
+          new media_router.Sink(
+              'sink id 3', 'Sink 3', null, null, media_router.SinkIconType.CAST,
+              media_router.SinkStatus.PENDING, [1, 2, 3]),
+          new media_router.Sink(
+              'sink id 4', 'Sink 4', 'Sink 4 description', null,
+              media_router.SinkIconType.CAST, media_router.SinkStatus.PENDING,
+              [1, 2, 3])
         ];
 
         container.routeList = [
-            new media_router.Route('id 3', 'sink id 3', 'Title 3', 0, true),
-            new media_router.Route('id 4', 'sink id 4', 'Title 4', 1, false),
+          new media_router.Route('id 3', 'sink id 3', 'Title 3', 0, true),
+          new media_router.Route('id 4', 'sink id 4', 'Title 4', 1, false),
         ];
 
         MockInteractions.tap(container.$$('#sink-search-icon'));
@@ -568,15 +567,15 @@
           // have any subtext.
           assertEquals(3, sinkSubtextList.length);
 
-          checkElementText(container.allSinks[1].description,
-              sinkSubtextList[0]);
+          checkElementText(
+              container.allSinks[1].description, sinkSubtextList[0]);
 
           // Route description overrides sink description for subtext.
-          checkElementText(container.routeList[0].description,
-              sinkSubtextList[1]);
+          checkElementText(
+              container.routeList[0].description, sinkSubtextList[1]);
 
-          checkElementText(container.routeList[1].description,
-              sinkSubtextList[2]);
+          checkElementText(
+              container.routeList[1].description, sinkSubtextList[2]);
           done();
         });
       });
@@ -695,13 +694,17 @@
         checkEqual(oneMatchSectionSingleChar, oneMatchSectionSingleChar);
         checkLess(oneMatchSectionSingleChar, noMatches);
 
-        var oneMatchSectionBeginningLong = {sinkItem: null,
-                                            substrings: [[0, 2]]};
-        var oneMatchSectionBeginningShort = {sinkItem: null,
-                                             substrings: [[0, 1]]};
+        var oneMatchSectionBeginningLong = {
+          sinkItem: null,
+          substrings: [[0, 2]]
+        };
+        var oneMatchSectionBeginningShort = {
+          sinkItem: null,
+          substrings: [[0, 1]]
+        };
         checkEqual(oneMatchSectionBeginningLong, oneMatchSectionBeginningLong);
-        checkEqual(oneMatchSectionBeginningShort,
-            oneMatchSectionBeginningShort);
+        checkEqual(
+            oneMatchSectionBeginningShort, oneMatchSectionBeginningShort);
 
         checkLess(oneMatchSectionBeginningLong, oneMatchSectionBeginningShort);
 
@@ -739,7 +742,7 @@
 
         var oneMatchBeginningOverlap = {sinkItem: null, substrings: [[0, 2]]};
         var oneMatchMiddleOverlap = {sinkItem: null, substrings: [[1, 3]]};
-        var oneMatchEndOverlap = {sinkItem: null, substrings: [[2, 4]]}
+        var oneMatchEndOverlap = {sinkItem: null, substrings: [[2, 4]]};
 
         checkEqual(oneMatchBeginningOverlap, oneMatchBeginningOverlap);
         checkEqual(oneMatchMiddleOverlap, oneMatchMiddleOverlap);
@@ -831,14 +834,14 @@
           checkEqual(orderedMatches[i], orderedMatches[i]);
         }
         for (var i = 0; i < orderedMatches.length - 1; ++i) {
-          checkLess(orderedMatches[i], orderedMatches[i+1]);
+          checkLess(orderedMatches[i], orderedMatches[i + 1]);
         }
         // Check some transitivity.
         for (var i = 0; i < orderedMatches.length - 2; ++i) {
-          checkLess(orderedMatches[i], orderedMatches[i+2]);
+          checkLess(orderedMatches[i], orderedMatches[i + 2]);
         }
         for (var i = 0; i < orderedMatches.length - 3; ++i) {
-          checkLess(orderedMatches[i], orderedMatches[i+3]);
+          checkLess(orderedMatches[i], orderedMatches[i + 3]);
         }
 
         done();
@@ -890,9 +893,9 @@
       // of match indices.
       test('computeSinkMatchingText_ test', function(done) {
         var sinkName = '012345 789';
-        var sink = new media_router.Sink('id', sinkName, null, null,
-                                         media_router.SinkIconType.CAST,
-                                         media_router.SinkStatus.ACTIVE, 0);
+        var sink = new media_router.Sink(
+            'id', sinkName, null, null, media_router.SinkIconType.CAST,
+            media_router.SinkStatus.ACTIVE, 0);
         var checkMatches = function(matchesAndAnswers) {
           var matches = matchesAndAnswers.matches;
           var plainText = matchesAndAnswers.plainText;
diff --git a/chrome/test/data/webui/media_router/media_router_container_first_run_flow_tests.js b/chrome/test/data/webui/media_router/media_router_container_first_run_flow_tests.js
index de223bc7..1172926 100644
--- a/chrome/test/data/webui/media_router/media_router_container_first_run_flow_tests.js
+++ b/chrome/test/data/webui/media_router/media_router_container_first_run_flow_tests.js
@@ -82,13 +82,13 @@
         container.showFirstRunFlow = true;
 
         setTimeout(function() {
-          container.addEventListener('acknowledge-first-run-flow',
-              function(data) {
-            assertEquals(undefined, data.detail.optedIntoCloudServices);
-            done();
-          });
-          MockInteractions.tap(container.shadowRoot.getElementById(
-              'first-run-button'));
+          container.addEventListener(
+              'acknowledge-first-run-flow', function(data) {
+                assertEquals(undefined, data.detail.optedIntoCloudServices);
+                done();
+              });
+          MockInteractions.tap(
+              container.shadowRoot.getElementById('first-run-button'));
         });
       });
 
@@ -100,34 +100,33 @@
         container.showFirstRunFlowCloudPref = true;
 
         setTimeout(function() {
-          container.addEventListener('acknowledge-first-run-flow',
-              function(data) {
-            assertTrue(data.detail.optedIntoCloudServices);
-            done();
-          });
-          MockInteractions.tap(container.shadowRoot.getElementById(
-              'first-run-button'));
+          container.addEventListener(
+              'acknowledge-first-run-flow', function(data) {
+                assertTrue(data.detail.optedIntoCloudServices);
+                done();
+              });
+          MockInteractions.tap(
+              container.shadowRoot.getElementById('first-run-button'));
         });
       });
 
       // Tests for 'acknowledge-first-run-flow' event firing when the
       // 'first-run-button' button is clicked after the cloud preference
       // checkbox is deselected.
-      test('first run button with cloud pref deselected click',
-          function(done) {
+      test('first run button with cloud pref deselected click', function(done) {
         container.showFirstRunFlow = true;
         container.showFirstRunFlowCloudPref = true;
 
         setTimeout(function() {
-          container.addEventListener('acknowledge-first-run-flow',
-              function(data) {
-            assertFalse(data.detail.optedIntoCloudServices);
-            done();
-          });
-          MockInteractions.tap(container.shadowRoot.getElementById(
-              'first-run-cloud-checkbox'));
-          MockInteractions.tap(container.shadowRoot.getElementById(
-              'first-run-button'));
+          container.addEventListener(
+              'acknowledge-first-run-flow', function(data) {
+                assertFalse(data.detail.optedIntoCloudServices);
+                done();
+              });
+          MockInteractions.tap(
+              container.shadowRoot.getElementById('first-run-cloud-checkbox'));
+          MockInteractions.tap(
+              container.shadowRoot.getElementById('first-run-button'));
         });
       });
 
@@ -138,8 +137,8 @@
 
         setTimeout(function() {
           checkElementVisibleWithId(true, 'first-run-flow');
-          MockInteractions.tap(container.shadowRoot.getElementById(
-              'first-run-button'));
+          MockInteractions.tap(
+              container.shadowRoot.getElementById('first-run-button'));
 
           setTimeout(function() {
             checkElementVisibleWithId(false, 'first-run-flow');
@@ -155,18 +154,16 @@
         container.showFirstRunFlowCloudPref = true;
 
         setTimeout(function() {
-          checkElementsVisibleWithId(['container-header',
-                                      'device-missing',
-                                      'first-run-flow',
-                                      'first-run-flow-cloud-pref',
-                                      'sink-list-view']);
-          MockInteractions.tap(container.shadowRoot.getElementById(
-              'first-run-button'));
+          checkElementsVisibleWithId([
+            'container-header', 'device-missing', 'first-run-flow',
+            'first-run-flow-cloud-pref', 'sink-list-view'
+          ]);
+          MockInteractions.tap(
+              container.shadowRoot.getElementById('first-run-button'));
 
           setTimeout(function() {
-            checkElementsVisibleWithId(['container-header',
-                                        'device-missing',
-                                        'sink-list-view']);
+            checkElementsVisibleWithId(
+                ['container-header', 'device-missing', 'sink-list-view']);
             done();
           });
         });
diff --git a/chrome/test/data/webui/media_router/media_router_container_route_tests.js b/chrome/test/data/webui/media_router/media_router_container_route_tests.js
index 110302c..adf2d3d 100644
--- a/chrome/test/data/webui/media_router/media_router_container_route_tests.js
+++ b/chrome/test/data/webui/media_router/media_router_container_route_tests.js
@@ -120,14 +120,13 @@
         container.allSinks = fakeSinkList;
 
         setTimeout(function() {
-          var sinkList =
-              container.shadowRoot.getElementById('sink-list')
-                  .querySelectorAll('paper-item');
+          var sinkList = container.shadowRoot.getElementById('sink-list')
+                             .querySelectorAll('paper-item');
           container.addEventListener('create-route', function(data) {
             // Container is initially in auto mode since a cast mode has not
             // been selected.
-            assertEquals(media_router.CastModeType.AUTO,
-                container.shownCastModeValue_);
+            assertEquals(
+                media_router.CastModeType.AUTO, container.shownCastModeValue_);
             assertEquals(fakeSinkList[2].id, data.detail.sinkId);
 
             // The preferred compatible cast mode on the sink is used, since
@@ -149,9 +148,8 @@
         container.routeList = fakeRouteList;
 
         setTimeout(function() {
-          var sinkList =
-              container.shadowRoot.getElementById('sink-list')
-                  .querySelectorAll('paper-item');
+          var sinkList = container.shadowRoot.getElementById('sink-list')
+                             .querySelectorAll('paper-item');
 
           // Start from the SINK_LIST view.
           container.showSinkList_();
@@ -169,45 +167,44 @@
         // Sink 3 - no sink description, route -> subtext = route description
         // Sink 4 - sink description, route -> subtext = route description
         container.allSinks = [
-            new media_router.Sink('sink id 1', 'Sink 1', null, null,
-                media_router.SinkIconType.CAST,
-                media_router.SinkStatus.ACTIVE, [1, 2, 3]),
-            new media_router.Sink('sink id 2', 'Sink 2',
-                'Sink 2 description', null,
-                media_router.SinkIconType.CAST,
-                media_router.SinkStatus.ACTIVE, [1, 2, 3]),
-            new media_router.Sink('sink id 3', 'Sink 3', null, null,
-                media_router.SinkIconType.CAST,
-                media_router.SinkStatus.PENDING, [1, 2, 3]),
-            new media_router.Sink('sink id 4', 'Sink 4',
-                'Sink 4 description', null,
-                media_router.SinkIconType.CAST,
-                media_router.SinkStatus.PENDING, [1, 2, 3])
+          new media_router.Sink(
+              'sink id 1', 'Sink 1', null, null, media_router.SinkIconType.CAST,
+              media_router.SinkStatus.ACTIVE, [1, 2, 3]),
+          new media_router.Sink(
+              'sink id 2', 'Sink 2', 'Sink 2 description', null,
+              media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE,
+              [1, 2, 3]),
+          new media_router.Sink(
+              'sink id 3', 'Sink 3', null, null, media_router.SinkIconType.CAST,
+              media_router.SinkStatus.PENDING, [1, 2, 3]),
+          new media_router.Sink(
+              'sink id 4', 'Sink 4', 'Sink 4 description', null,
+              media_router.SinkIconType.CAST, media_router.SinkStatus.PENDING,
+              [1, 2, 3])
         ];
 
         container.routeList = [
-            new media_router.Route('id 3', 'sink id 3', 'Title 3', 0, true),
-            new media_router.Route('id 4', 'sink id 4', 'Title 4', 1, false),
+          new media_router.Route('id 3', 'sink id 3', 'Title 3', 0, true),
+          new media_router.Route('id 4', 'sink id 4', 'Title 4', 1, false),
         ];
 
         setTimeout(function() {
-          var sinkSubtextList =
-              container.shadowRoot.getElementById('sink-list')
-                  .querySelectorAll('.sink-subtext');
+          var sinkSubtextList = container.shadowRoot.getElementById('sink-list')
+                                    .querySelectorAll('.sink-subtext');
 
           // There will only be 3 sink subtext entries, because Sink 1 does not
           // have any subtext.
           assertEquals(3, sinkSubtextList.length);
 
-          checkElementText(container.allSinks[1].description,
-              sinkSubtextList[0]);
+          checkElementText(
+              container.allSinks[1].description, sinkSubtextList[0]);
 
           // Route description overrides sink description for subtext.
-          checkElementText(container.routeList[0].description,
-              sinkSubtextList[1]);
+          checkElementText(
+              container.routeList[0].description, sinkSubtextList[1]);
 
-          checkElementText(container.routeList[1].description,
-              sinkSubtextList[2]);
+          checkElementText(
+              container.routeList[1].description, sinkSubtextList[2]);
           done();
         });
       });
@@ -257,9 +254,8 @@
         container.showRouteDetails_(
             new media_router.Route('id 3', 'sink id 3', 'Title 3', 0, true));
         setTimeout(function() {
-          checkElementsVisibleWithId(['container-header',
-                                      'device-missing',
-                                      'route-details']);
+          checkElementsVisibleWithId(
+              ['container-header', 'device-missing', 'route-details']);
           done();
         });
       });
@@ -301,9 +297,8 @@
         // Set a non-blocking issue. The issue should be shown.
         container.issue = fakeNonBlockingIssue;
         setTimeout(function() {
-          checkElementsVisibleWithId(['container-header',
-                                      'device-missing',
-                                      'route-details']);
+          checkElementsVisibleWithId(
+              ['container-header', 'device-missing', 'route-details']);
           done();
         });
       });
@@ -318,11 +313,10 @@
         // else, hidden.
         container.issue = fakeBlockingIssue;
         setTimeout(function() {
-          checkElementsVisibleWithId(['container-header',
-                                      'device-missing',
-                                      'issue-banner']);
+          checkElementsVisibleWithId(
+              ['container-header', 'device-missing', 'issue-banner']);
           done();
-         });
+        });
       });
 
       test('creating route with selected cast mode', function(done) {
@@ -336,14 +330,13 @@
           MockInteractions.tap(castModeList[1]);
           assertEquals(fakeCastModeList[1].description, container.headerText);
           setTimeout(function() {
-            var sinkList =
-                container.shadowRoot.getElementById('sink-list')
-                    .querySelectorAll('paper-item');
+            var sinkList = container.shadowRoot.getElementById('sink-list')
+                               .querySelectorAll('paper-item');
             container.addEventListener('create-route', function(data) {
               assertEquals(fakeSinkList[2].id, data.detail.sinkId);
               // Cast mode 2 is used, since we selected it explicitly.
-              assertEquals(fakeCastModeList[1].type,
-                           data.detail.selectedCastModeValue);
+              assertEquals(
+                  fakeCastModeList[1].type, data.detail.selectedCastModeValue);
               done();
             });
             // All sinks are compatible with cast mode 2.
@@ -369,17 +362,19 @@
             MockInteractions.tap(sinkList[0]);
             setTimeout(function() {
               checkElementVisible(
-                  false, container.$$('#route-details')
-                             .$$('#start-casting-to-route-button'),
+                  false,
+                  container.$$('#route-details')
+                      .$$('#start-casting-to-route-button'),
                   'start-casting-to-route-button');
               // The other sink stopped launching, due to route failure, so the
               // cast button should now appear.
-              container.onCreateRouteResponseReceived(fakeSinkList[0].id, null,
-                                                      true);
+              container.onCreateRouteResponseReceived(
+                  fakeSinkList[0].id, null, true);
               setTimeout(function() {
                 checkElementVisible(
-                    true, container.$$('#route-details')
-                               .$$('#start-casting-to-route-button'),
+                    true,
+                    container.$$('#route-details')
+                        .$$('#start-casting-to-route-button'),
                     'start-casting-to-route-button');
                 done();
               });
@@ -400,8 +395,9 @@
           setTimeout(function() {
             assertEquals(undefined, container.currentRoute_.currentCastMode);
             checkElementVisible(
-                true, container.$$('#route-details')
-                           .$$('#start-casting-to-route-button'),
+                true,
+                container.$$('#route-details')
+                    .$$('#start-casting-to-route-button'),
                 'start-casting-to-route-button');
             done();
           });
@@ -429,8 +425,9 @@
                 container.$$('#sink-list').querySelectorAll('paper-item')[0]);
             setTimeout(function() {
               checkElementVisible(
-                  true, container.$$('#route-details')
-                             .$$('#start-casting-to-route-button'),
+                  true,
+                  container.$$('#route-details')
+                      .$$('#start-casting-to-route-button'),
                   'start-casting-to-route-button');
               done();
             });
@@ -458,8 +455,9 @@
                 container.$$('#sink-list').querySelectorAll('paper-item')[0]);
             setTimeout(function() {
               checkElementVisible(
-                  false, container.$$('#route-details')
-                             .$$('#start-casting-to-route-button'),
+                  false,
+                  container.$$('#route-details')
+                      .$$('#start-casting-to-route-button'),
                   'start-casting-to-route-button');
               done();
             });
@@ -485,8 +483,9 @@
               container.$$('#sink-list').querySelectorAll('paper-item')[0]);
           setTimeout(function() {
             checkElementVisible(
-                false, container.$$('#route-details')
-                           .$$('#start-casting-to-route-button'),
+                false,
+                container.$$('#route-details')
+                    .$$('#start-casting-to-route-button'),
                 'start-casting-to-route-button');
             done();
           });
@@ -506,8 +505,9 @@
         container.showRouteDetails_(fakeRouteList[0]);
         setTimeout(function() {
           checkElementVisible(
-              false, container.$$('#route-details')
-                         .$$('#start-casting-to-route-button'),
+              false,
+              container.$$('#route-details')
+                  .$$('#start-casting-to-route-button'),
               'start-casting-to-route-button');
           done();
         });
diff --git a/chrome/test/data/webui/media_router/media_router_container_search_tests.js b/chrome/test/data/webui/media_router/media_router_container_search_tests.js
index 4b6497c7..2adc420 100644
--- a/chrome/test/data/webui/media_router/media_router_container_search_tests.js
+++ b/chrome/test/data/webui/media_router/media_router_container_search_tests.js
@@ -20,7 +20,9 @@
   var chainOnAnimationPromise = function(f) {
     setTimeout(function() {
       container.animationPromise_.then(f).catch(function(err) {
-        setTimeout(function() { throw err; });
+        setTimeout(function() {
+          throw err;
+        });
       });
     });
   };
@@ -448,8 +450,8 @@
             searchResults =
                 container.$$('#search-results').querySelectorAll('paper-item');
             assertTrue(container.searchResultsToShow_.some(function(sink) {
-                  return sink.sinkItem.id == pseudoSink.id;
-                }));
+              return sink.sinkItem.id == pseudoSink.id;
+            }));
             done();
           });
         });
diff --git a/chrome/test/data/webui/media_router/media_router_container_sink_list_tests.js b/chrome/test/data/webui/media_router/media_router_container_sink_list_tests.js
index 5a66c5b8..efcb5fe 100644
--- a/chrome/test/data/webui/media_router/media_router_container_sink_list_tests.js
+++ b/chrome/test/data/webui/media_router/media_router_container_sink_list_tests.js
@@ -92,9 +92,8 @@
         container.allSinks = fakeSinkList;
 
         setTimeout(function() {
-          var sinkList =
-              container.shadowRoot.getElementById('sink-list')
-                  .querySelectorAll('paper-item');
+          var sinkList = container.shadowRoot.getElementById('sink-list')
+                             .querySelectorAll('paper-item');
           assertEquals(fakeSinkList.length, sinkList.length);
           for (var i = 0; i < fakeSinkList.length; i++) {
             checkElementText(fakeSinkList[i].name, sinkList[i]);
@@ -105,31 +104,30 @@
 
       // Tests that text shown for each sink matches their names.
       test('updated sink list', function(done) {
-        var sinkOne = new media_router.Sink('sink id 1', 'Sink 1',
-                null, null,
-                media_router.SinkIconType.GENERIC,
-                media_router.SinkStatus.IDLE, [1, 2, 3]);
-        var sinkTwo = new media_router.Sink('sink id 2', 'Sink 2',
-                null, 'example.com',
-                media_router.SinkIconType.GENERIC,
-                media_router.SinkStatus.IDLE, [1, 2, 3]);
-        var sinkThree = new media_router.Sink('sink id 3', 'Sink 3',
-                null, 'example.com',
-                media_router.SinkIconType.GENERIC,
-                media_router.SinkStatus.IDLE, [1, 2, 3]);
-        var sinkFour = new media_router.Sink('sink id 4', 'Sink 4',
-                null, 'example.com',
-                media_router.SinkIconType.GENERIC,
-                media_router.SinkStatus.IDLE, [1, 2, 3]);
+        var sinkOne = new media_router.Sink(
+            'sink id 1', 'Sink 1', null, null,
+            media_router.SinkIconType.GENERIC, media_router.SinkStatus.IDLE,
+            [1, 2, 3]);
+        var sinkTwo = new media_router.Sink(
+            'sink id 2', 'Sink 2', null, 'example.com',
+            media_router.SinkIconType.GENERIC, media_router.SinkStatus.IDLE,
+            [1, 2, 3]);
+        var sinkThree = new media_router.Sink(
+            'sink id 3', 'Sink 3', null, 'example.com',
+            media_router.SinkIconType.GENERIC, media_router.SinkStatus.IDLE,
+            [1, 2, 3]);
+        var sinkFour = new media_router.Sink(
+            'sink id 4', 'Sink 4', null, 'example.com',
+            media_router.SinkIconType.GENERIC, media_router.SinkStatus.IDLE,
+            [1, 2, 3]);
 
         // Set the initial sink list and check that the order corresponds.
         var listOne = [sinkOne, sinkTwo];
         var listOneExpected = [sinkOne, sinkTwo];
         container.allSinks = listOne;
         setTimeout(function() {
-          var sinkList =
-              container.shadowRoot.getElementById('sink-list')
-                  .querySelectorAll('paper-item');
+          var sinkList = container.shadowRoot.getElementById('sink-list')
+                             .querySelectorAll('paper-item');
           assertEquals(listOne.length, sinkList.length);
           for (var i = 0; i < listOneExpected.length; i++) {
             checkElementText(listOneExpected[i].name, sinkList[i]);
@@ -142,9 +140,8 @@
           var listTwoExpected = [sinkOne, sinkTwo, sinkThree];
           container.allSinks = listTwo;
           setTimeout(function() {
-            sinkList =
-                container.shadowRoot.getElementById('sink-list')
-                    .querySelectorAll('paper-item');
+            sinkList = container.shadowRoot.getElementById('sink-list')
+                           .querySelectorAll('paper-item');
             assertEquals(listTwo.length, sinkList.length);
             for (var i = 0; i < listTwoExpected.length; i++) {
               checkElementText(listTwoExpected[i].name, sinkList[i]);
@@ -156,9 +153,8 @@
             var listThreeExpected = [sinkOne, sinkFour];
             container.allSinks = listThree;
             setTimeout(function() {
-              sinkList =
-                  container.shadowRoot.getElementById('sink-list')
-                      .querySelectorAll('paper-item');
+              sinkList = container.shadowRoot.getElementById('sink-list')
+                             .querySelectorAll('paper-item');
               assertEquals(listThree.length, sinkList.length);
               for (var i = 0; i < listThreeExpected.length; i++) {
                 checkElementText(listThreeExpected[i].name, sinkList[i]);
@@ -174,21 +170,21 @@
         // Sink 1 - sink, no domain -> text = name
         // Sink 2 - sink, domain -> text = sink + domain
         container.allSinks = [
-            new media_router.Sink('sink id 1', 'Sink 1', null, null,
-                media_router.SinkIconType.HANGOUT,
-                media_router.SinkStatus.ACTIVE, [1, 2, 3]),
-            new media_router.Sink('sink id 2', 'Sink 2',
-                null, 'example.com',
-                media_router.SinkIconType.HANGOUT,
-                media_router.SinkStatus.ACTIVE, [1, 2, 3]),
+          new media_router.Sink(
+              'sink id 1', 'Sink 1', null, null,
+              media_router.SinkIconType.HANGOUT, media_router.SinkStatus.ACTIVE,
+              [1, 2, 3]),
+          new media_router.Sink(
+              'sink id 2', 'Sink 2', null, 'example.com',
+              media_router.SinkIconType.HANGOUT, media_router.SinkStatus.ACTIVE,
+              [1, 2, 3]),
         ];
 
         container.showDomain = true;
 
         setTimeout(function() {
-          var sinkList =
-              container.shadowRoot.getElementById('sink-list')
-                  .querySelectorAll('paper-item');
+          var sinkList = container.shadowRoot.getElementById('sink-list')
+                             .querySelectorAll('paper-item');
           assertEquals(2, sinkList.length);
 
           // |sinkList[0]| has sink name only.
@@ -196,8 +192,9 @@
           // |sinkList[1]| contains sink name and domain.
           assertTrue(sinkList[1].textContent.trim().startsWith(
               container.allSinks[1].name.trim()));
-          assertTrue(sinkList[1].textContent.trim().indexOf(
-              container.allSinks[1].domain.trim()) != -1);
+          assertTrue(
+              sinkList[1].textContent.trim().indexOf(
+                  container.allSinks[1].domain.trim()) != -1);
           done();
         });
       });
@@ -207,29 +204,30 @@
         // Sink 1 - sink, no domain -> text = name
         // Sink 2 - sink, domain -> text = sink + domain
         container.allSinks = [
-            new media_router.Sink('sink id 1', 'Sink 1', null, null,
-                media_router.SinkIconType.HANGOUT,
-                media_router.SinkStatus.ACTIVE, [1, 2, 3]),
-            new media_router.Sink('sink id 2', 'Sink 2',
-                null, 'example.com',
-                media_router.SinkIconType.HANGOUT,
-                media_router.SinkStatus.ACTIVE, [1, 2, 3]),
+          new media_router.Sink(
+              'sink id 1', 'Sink 1', null, null,
+              media_router.SinkIconType.HANGOUT, media_router.SinkStatus.ACTIVE,
+              [1, 2, 3]),
+          new media_router.Sink(
+              'sink id 2', 'Sink 2', null, 'example.com',
+              media_router.SinkIconType.HANGOUT, media_router.SinkStatus.ACTIVE,
+              [1, 2, 3]),
         ];
 
         container.showDomain = false;
 
         setTimeout(function() {
-          var sinkList =
-              container.shadowRoot.getElementById('sink-list')
-                  .querySelectorAll('paper-item');
+          var sinkList = container.shadowRoot.getElementById('sink-list')
+                             .querySelectorAll('paper-item');
           assertEquals(2, sinkList.length);
 
           // |sinkList[0]| has sink name only.
           checkElementText(container.allSinks[0].name, sinkList[0]);
           // |sinkList[1]| has sink name but domain should be hidden.
           checkElementText(container.allSinks[1].name, sinkList[1]);
-          assertTrue(sinkList[1].textContent.trim().indexOf(
-              container.allSinks[1].domain.trim()) == -1);
+          assertTrue(
+              sinkList[1].textContent.trim().indexOf(
+                  container.allSinks[1].domain.trim()) == -1);
           done();
         });
       });
@@ -237,16 +235,14 @@
       // Tests for expected visible UI when the view is SINK_LIST.
       test('sink list state visibility', function() {
         container.showSinkList_();
-        checkElementsVisibleWithId(['container-header',
-                                    'device-missing',
-                                    'sink-list-view']);
+        checkElementsVisibleWithId(
+            ['container-header', 'device-missing', 'sink-list-view']);
 
         // Set an non-empty sink list.
         container.allSinks = fakeSinkList;
         setTimeout(function() {
-          checkElementsVisibleWithId(['container-header',
-                                      'sink-list',
-                                      'sink-list-view']);
+          checkElementsVisibleWithId(
+              ['container-header', 'sink-list', 'sink-list-view']);
         });
       });
 
@@ -264,17 +260,15 @@
         container.issue = fakeNonBlockingIssue;
         setTimeout(function() {
           checkCurrentView(media_router.MediaRouterView.SINK_LIST);
-          checkElementsVisibleWithId(['container-header',
-                                      'issue-banner',
-                                      'sink-list',
-                                      'sink-list-view']);
+          checkElementsVisibleWithId([
+            'container-header', 'issue-banner', 'sink-list', 'sink-list-view'
+          ]);
           // Replace issue with null.
           container.issue = null;
           setTimeout(function() {
             checkCurrentView(media_router.MediaRouterView.SINK_LIST);
-            checkElementsVisibleWithId(['container-header',
-                                        'sink-list',
-                                        'sink-list-view']);
+            checkElementsVisibleWithId(
+                ['container-header', 'sink-list', 'sink-list-view']);
             done();
           });
         });
@@ -295,16 +289,14 @@
         container.issue = fakeBlockingIssue;
         setTimeout(function() {
           checkCurrentView(media_router.MediaRouterView.ISSUE);
-          checkElementsVisibleWithId(['container-header',
-                                      'issue-banner',
-                                      'sink-list']);
+          checkElementsVisibleWithId(
+              ['container-header', 'issue-banner', 'sink-list']);
           // Replace issue with null.
           container.issue = null;
           setTimeout(function() {
             checkCurrentView(media_router.MediaRouterView.SINK_LIST);
-            checkElementsVisibleWithId(['container-header',
-                                        'sink-list',
-                                        'sink-list-view']);
+            checkElementsVisibleWithId(
+                ['container-header', 'sink-list', 'sink-list-view']);
             done();
           });
         });
@@ -313,35 +305,35 @@
       // Tests for expected visible UI when the view is SINK_LIST, and there is
       // a blocking issue. Also tests for expected visible UI when the issue is
       // cleared.
-      test('sink list visibility non-blocking replaced with blocking issue',
+      test(
+          'sink list visibility non-blocking replaced with blocking issue',
           function(done) {
-        container.showSinkList_();
-        checkCurrentView(media_router.MediaRouterView.SINK_LIST);
+            container.showSinkList_();
+            checkCurrentView(media_router.MediaRouterView.SINK_LIST);
 
-        // Set an non-empty sink list.
-        container.allSinks = fakeSinkList;
+            // Set an non-empty sink list.
+            container.allSinks = fakeSinkList;
 
-        // Set a non-blocking issue. The issue should be shown.
-        container.issue = fakeNonBlockingIssue;
-        setTimeout(function() {
-          checkCurrentView(media_router.MediaRouterView.SINK_LIST);
-          checkElementsVisibleWithId(['container-header',
-                                      'issue-banner',
-                                      'sink-list',
-                                      'sink-list-view']);
+            // Set a non-blocking issue. The issue should be shown.
+            container.issue = fakeNonBlockingIssue;
+            setTimeout(function() {
+              checkCurrentView(media_router.MediaRouterView.SINK_LIST);
+              checkElementsVisibleWithId([
+                'container-header', 'issue-banner', 'sink-list',
+                'sink-list-view'
+              ]);
 
-          // Set a blocking issue. The issue should be shown, and everything
-          // else, hidden.
-          container.issue = fakeBlockingIssue;
-          setTimeout(function() {
-            checkCurrentView(media_router.MediaRouterView.ISSUE);
-            checkElementsVisibleWithId(['container-header',
-                                        'issue-banner',
-                                        'sink-list']);
-            done();
+              // Set a blocking issue. The issue should be shown, and everything
+              // else, hidden.
+              container.issue = fakeBlockingIssue;
+              setTimeout(function() {
+                checkCurrentView(media_router.MediaRouterView.ISSUE);
+                checkElementsVisibleWithId(
+                    ['container-header', 'issue-banner', 'sink-list']);
+                done();
+              });
+            });
           });
-        });
-      });
 
       // Tests all sinks are always shown in auto mode, and that the mode will
       // switch if the sinks support only 1 cast mode.
@@ -350,14 +342,13 @@
         setTimeout(function() {
           // Container is initially in auto mode since a cast mode has not been
           // selected.
-          assertEquals(media_router.AUTO_CAST_MODE.description,
-              container.headerText);
-          assertEquals(media_router.CastModeType.AUTO,
-              container.shownCastModeValue_);
+          assertEquals(
+              media_router.AUTO_CAST_MODE.description, container.headerText);
+          assertEquals(
+              media_router.CastModeType.AUTO, container.shownCastModeValue_);
           assertFalse(container.userHasSelectedCastMode_);
-          var sinkList =
-              container.shadowRoot.getElementById('sink-list')
-                  .querySelectorAll('paper-item');
+          var sinkList = container.shadowRoot.getElementById('sink-list')
+                             .querySelectorAll('paper-item');
 
           // All sinks are shown in auto mode.
           assertEquals(3, sinkList.length);
@@ -365,40 +356,43 @@
           // When sink list changes to only 1 compatible cast mode, the mode is
           // switched, and all sinks are shown.
           container.allSinks = [
-            new media_router.Sink('sink id 10', 'Sink 10', null, null,
-                media_router.SinkIconType.CAST,
-                media_router.SinkStatus.ACTIVE, 0x4),
-            new media_router.Sink('sink id 20', 'Sink 20', null, null,
-                media_router.SinkIconType.CAST,
-                media_router.SinkStatus.ACTIVE, 0x4),
-            new media_router.Sink('sink id 30', 'Sink 30', null, null,
-                media_router.SinkIconType.CAST,
-                media_router.SinkStatus.PENDING, 0x4),
+            new media_router.Sink(
+                'sink id 10', 'Sink 10', null, null,
+                media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE,
+                0x4),
+            new media_router.Sink(
+                'sink id 20', 'Sink 20', null, null,
+                media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE,
+                0x4),
+            new media_router.Sink(
+                'sink id 30', 'Sink 30', null, null,
+                media_router.SinkIconType.CAST, media_router.SinkStatus.PENDING,
+                0x4),
           ];
 
           setTimeout(function() {
             assertEquals(fakeCastModeList[2].description, container.headerText);
-            assertEquals(fakeCastModeList[2].type,
-                container.shownCastModeValue_);
+            assertEquals(
+                fakeCastModeList[2].type, container.shownCastModeValue_);
             assertFalse(container.userHasSelectedCastMode_);
 
-            var sinkList =
-                container.shadowRoot.getElementById('sink-list')
-                    .querySelectorAll('paper-item');
+            var sinkList = container.shadowRoot.getElementById('sink-list')
+                               .querySelectorAll('paper-item');
             assertEquals(3, sinkList.length);
 
             // When compatible cast modes size is no longer exactly 1, switch
             // back to auto mode, and all sinks are shown.
             container.allSinks = fakeSinkList;
             setTimeout(function() {
-              assertEquals(media_router.AUTO_CAST_MODE.description,
+              assertEquals(
+                  media_router.AUTO_CAST_MODE.description,
                   container.headerText);
-              assertEquals(media_router.CastModeType.AUTO,
+              assertEquals(
+                  media_router.CastModeType.AUTO,
                   container.shownCastModeValue_);
               assertFalse(container.userHasSelectedCastMode_);
-              var sinkList =
-                  container.shadowRoot.getElementById('sink-list')
-                      .querySelectorAll('paper-item');
+              var sinkList = container.shadowRoot.getElementById('sink-list')
+                                 .querySelectorAll('paper-item');
 
               // All sinks are shown in auto mode.
               assertEquals(3, sinkList.length);
diff --git a/chrome/test/data/webui/media_router/media_router_container_test_base.js b/chrome/test/data/webui/media_router/media_router_container_test_base.js
index f702ce7e..d9d997d 100644
--- a/chrome/test/data/webui/media_router/media_router_container_test_base.js
+++ b/chrome/test/data/webui/media_router/media_router_container_test_base.js
@@ -44,8 +44,8 @@
      * @param {?string} elementId Optional element id to display.
      */
     var checkElementVisible = function(visible, element, elementId) {
-      var elementVisible = !!element && !element.hidden &&
-          element.style.display != 'none';
+      var elementVisible =
+          !!element && !element.hidden && element.style.display != 'none';
       assertEquals(visible, elementVisible, elementId);
     };
 
@@ -77,8 +77,7 @@
      * @type {!media_router.Issue}
      */
     var fakeBlockingIssue = new media_router.Issue(
-        1, 'Issue Title 1', 'Issue Message 1', 0, 1,
-        'route id 1', true, 1234);
+        1, 'Issue Title 1', 'Issue Message 1', 0, 1, 'route id 1', true, 1234);
 
     /**
      * The list of CastModes to show.
@@ -141,8 +140,7 @@
      * @type {!media_router.Issue}
      */
     var fakeNonBlockingIssue = new media_router.Issue(
-        2, 'Issue Title 2', 'Issue Message 2', 0, 1,
-        'route id 2', false, 1234);
+        2, 'Issue Title 2', 'Issue Message 2', 0, 1, 'route id 2', false, 1234);
 
     /**
      * The list of current routes.
@@ -169,14 +167,14 @@
      * @type {!Array<!media_router.Sink>}
      */
     var fakeSinkList = [
-      new media_router.Sink('sink id 1', 'Sink 1', null, null,
-          media_router.SinkIconType.CAST,
+      new media_router.Sink(
+          'sink id 1', 'Sink 1', null, null, media_router.SinkIconType.CAST,
           media_router.SinkStatus.ACTIVE, castModeBitset),
-      new media_router.Sink('sink id 2', 'Sink 2', null, null,
-          media_router.SinkIconType.CAST,
+      new media_router.Sink(
+          'sink id 2', 'Sink 2', null, null, media_router.SinkIconType.CAST,
           media_router.SinkStatus.ACTIVE, castModeBitset),
-      new media_router.Sink('sink id 3', 'Sink 3', null, null,
-          media_router.SinkIconType.CAST,
+      new media_router.Sink(
+          'sink id 3', 'Sink 3', null, null, media_router.SinkIconType.CAST,
           media_router.SinkStatus.PENDING, castModeBitset),
     ];
 
diff --git a/chrome/test/data/webui/media_router/media_router_elements_browsertest.js b/chrome/test/data/webui/media_router/media_router_elements_browsertest.js
index 0dbc252fd..7450f38 100644
--- a/chrome/test/data/webui/media_router/media_router_elements_browsertest.js
+++ b/chrome/test/data/webui/media_router/media_router_elements_browsertest.js
@@ -124,7 +124,7 @@
     // deleted. The user will be unable to tab to it. Remove when there is a
     // long term fix.
     this.accessibilityAuditConfig.ignoreSelectors(
-       'focusableElementNotVisibleAndNotAriaHidden', '#focus-placeholder');
+        'focusableElementNotVisibleAndNotAriaHidden', '#focus-placeholder');
   },
 };
 
@@ -135,47 +135,46 @@
 
 // The media-router-container tests are being split into multiple parts due to
 // timeout issues on bots.
-TEST_F('MediaRouterElementsBrowserTest',
-    'MediaRouterContainerCastModeList',
+TEST_F(
+    'MediaRouterElementsBrowserTest', 'MediaRouterContainerCastModeList',
     function() {
-  media_router_container_cast_mode_list.registerTests();
-  mocha.run();
-});
+      media_router_container_cast_mode_list.registerTests();
+      mocha.run();
+    });
 
-TEST_F('MediaRouterElementsBrowserTest',
-    'MediaRouterContainerFirstRunFlow',
+TEST_F(
+    'MediaRouterElementsBrowserTest', 'MediaRouterContainerFirstRunFlow',
     function() {
-  media_router_container_first_run_flow.registerTests();
-  mocha.run();
-});
+      media_router_container_first_run_flow.registerTests();
+      mocha.run();
+    });
 
-TEST_F('MediaRouterElementsBrowserTest',
-    'MediaRouterContainerRoute',
-    function() {
-  media_router_container_route.registerTests();
-  mocha.run();
-});
+TEST_F(
+    'MediaRouterElementsBrowserTest', 'MediaRouterContainerRoute', function() {
+      media_router_container_route.registerTests();
+      mocha.run();
+    });
 
-TEST_F('MediaRouterElementsBrowserTest',
-    'MediaRouterContainerSearchPart1',
+TEST_F(
+    'MediaRouterElementsBrowserTest', 'MediaRouterContainerSearchPart1',
     function() {
-  media_router_container_search.registerTestsPart1();
-  mocha.run();
-});
+      media_router_container_search.registerTestsPart1();
+      mocha.run();
+    });
 
-TEST_F('MediaRouterElementsBrowserTest',
-    'MediaRouterContainerSearchPart2',
+TEST_F(
+    'MediaRouterElementsBrowserTest', 'MediaRouterContainerSearchPart2',
     function() {
-  media_router_container_search.registerTestsPart2();
-  mocha.run();
-});
+      media_router_container_search.registerTestsPart2();
+      mocha.run();
+    });
 
-TEST_F('MediaRouterElementsBrowserTest',
-    'MediaRouterContainerSinkList',
+TEST_F(
+    'MediaRouterElementsBrowserTest', 'MediaRouterContainerSinkList',
     function() {
-  media_router_container_sink_list.registerTests();
-  mocha.run();
-});
+      media_router_container_sink_list.registerTests();
+      mocha.run();
+    });
 
 // Disabling on Windows Debug due to flaky timeout on Win7 Tests (dbg)(1).
 // https://crbug.com/832947
@@ -187,31 +186,31 @@
 GEN('    MediaRouterContainerFilterPart1');
 GEN('#endif');
 
-TEST_F('MediaRouterElementsBrowserTest',
-    'MAYBE_MediaRouterContainerFilterPart1',
+TEST_F(
+    'MediaRouterElementsBrowserTest', 'MAYBE_MediaRouterContainerFilterPart1',
     function() {
-  media_router_container_filter.registerTestsPart1();
-  mocha.run();
-});
+      media_router_container_filter.registerTestsPart1();
+      mocha.run();
+    });
 
-TEST_F('MediaRouterElementsBrowserTest',
-    'MediaRouterContainerFilterPart2',
+TEST_F(
+    'MediaRouterElementsBrowserTest', 'MediaRouterContainerFilterPart2',
     function() {
-  media_router_container_filter.registerTestsPart2();
-  mocha.run();
-});
+      media_router_container_filter.registerTestsPart2();
+      mocha.run();
+    });
 
 TEST_F('MediaRouterElementsBrowserTest', 'MediaRouterHeader', function() {
   media_router_header.registerTests();
   mocha.run();
 });
 
-TEST_F('MediaRouterElementsBrowserTest',
-    'MediaRouterSearchHighlighter',
+TEST_F(
+    'MediaRouterElementsBrowserTest', 'MediaRouterSearchHighlighter',
     function() {
-  media_router_search_highlighter.registerTests();
-  mocha.run();
-});
+      media_router_search_highlighter.registerTests();
+      mocha.run();
+    });
 
 TEST_F(
     'MediaRouterElementsBrowserTest', 'MediaRouterRouteControls', function() {
diff --git a/chrome/test/data/webui/media_router/media_router_header_tests.js b/chrome/test/data/webui/media_router/media_router_header_tests.js
index 841fe45..6c70eb97 100644
--- a/chrome/test/data/webui/media_router/media_router_header_tests.js
+++ b/chrome/test/data/webui/media_router/media_router_header_tests.js
@@ -32,7 +32,8 @@
 
       // Checks whether the current icon matches the icon used for the view.
       var checkArrowDropIcon = function(view) {
-        assertEquals(header.computeArrowDropIcon_(view),
+        assertEquals(
+            header.computeArrowDropIcon_(view),
             header.$['arrow-drop-icon'].icon);
       };
 
@@ -40,11 +41,13 @@
       // An element is considered hidden if it does not exist (e.g. unstamped)
       // or its |hidden| property is |false|.
       var checkElementHidden = function(hidden, elementId) {
-        var element = header.$[elementId] ||
-            header.shadowRoot.getElementById(elementId);
-        assertEquals(hidden, !element || element.hidden ||
-            window.getComputedStyle(element, null)
-                .getPropertyValue('display') == 'none');
+        var element =
+            header.$[elementId] || header.shadowRoot.getElementById(elementId);
+        assertEquals(
+            hidden,
+            !element || element.hidden ||
+                window.getComputedStyle(element, null)
+                        .getPropertyValue('display') == 'none');
       };
 
       // Checks whether the elements specified in |elementIdList| are visible.
@@ -101,8 +104,7 @@
           header.addEventListener('back-click', function() {
             done();
           });
-          MockInteractions.tap(
-              header.shadowRoot.getElementById('back-button'));
+          MockInteractions.tap(header.shadowRoot.getElementById('back-button'));
         });
       });
 
@@ -189,51 +191,49 @@
 
       // Tests the |computeArrowDropIcon_| function.
       test('compute arrow drop icon', function() {
-        assertEquals('media-router:arrow-drop-up',
+        assertEquals(
+            'media-router:arrow-drop-up',
             header.computeArrowDropIcon_(
                 media_router.MediaRouterView.CAST_MODE_LIST));
-        assertEquals('media-router:arrow-drop-down',
-            header.computeArrowDropIcon_(
-                media_router.MediaRouterView.FILTER));
-        assertEquals('media-router:arrow-drop-down',
-            header.computeArrowDropIcon_(
-                media_router.MediaRouterView.ISSUE));
-        assertEquals('media-router:arrow-drop-down',
+        assertEquals(
+            'media-router:arrow-drop-down',
+            header.computeArrowDropIcon_(media_router.MediaRouterView.FILTER));
+        assertEquals(
+            'media-router:arrow-drop-down',
+            header.computeArrowDropIcon_(media_router.MediaRouterView.ISSUE));
+        assertEquals(
+            'media-router:arrow-drop-down',
             header.computeArrowDropIcon_(
                 media_router.MediaRouterView.ROUTE_DETAILS));
-        assertEquals('media-router:arrow-drop-down',
+        assertEquals(
+            'media-router:arrow-drop-down',
             header.computeArrowDropIcon_(
                 media_router.MediaRouterView.SINK_LIST));
       });
 
       test('visibility of UI depending on view', function(done) {
         header.view = media_router.MediaRouterView.CAST_MODE_LIST;
-        checkElementsVisibleWithId(['arrow-drop-icon',
-                                    'close-button',
-                                    'header-text']);
+        checkElementsVisibleWithId(
+            ['arrow-drop-icon', 'close-button', 'header-text']);
 
         header.view = media_router.MediaRouterView.FILTER;
         setTimeout(function() {
-          checkElementsVisibleWithId(['back-button-container',
-                                      'close-button',
-                                      'header-text']);
+          checkElementsVisibleWithId(
+              ['back-button-container', 'close-button', 'header-text']);
 
           header.view = media_router.MediaRouterView.ISSUE;
           setTimeout(function() {
-            checkElementsVisibleWithId(['close-button',
-                                        'header-text']);
+            checkElementsVisibleWithId(['close-button', 'header-text']);
 
             header.view = media_router.MediaRouterView.ROUTE_DETAILS;
             setTimeout(function() {
-              checkElementsVisibleWithId(['back-button-container',
-                                          'close-button',
-                                          'header-text']);
+              checkElementsVisibleWithId(
+                  ['back-button-container', 'close-button', 'header-text']);
 
               header.view = media_router.MediaRouterView.SINK_LIST;
               setTimeout(function() {
-                checkElementsVisibleWithId(['arrow-drop-icon',
-                                            'close-button',
-                                            'header-text']);
+                checkElementsVisibleWithId(
+                    ['arrow-drop-icon', 'close-button', 'header-text']);
                 done();
               });
             });
@@ -246,12 +246,11 @@
         header.userEmail = 'user@example.com';
         header.showEmail = true;
         setTimeout(function() {
-          assertEquals(header.headerWithEmailHeight_, header.offsetHeight)
+          assertEquals(header.headerWithEmailHeight_, header.offsetHeight);
 
           assertFalse(header.$$('#user-email-container').hidden);
           checkElementText(
-              header.userEmail,
-              header.$$('#user-email-container'));
+              header.userEmail, header.$$('#user-email-container'));
           done();
         });
       });
@@ -261,10 +260,8 @@
         header.userEmail = undefined;
         header.showEmail = true;
         setTimeout(function() {
-          assertNotEquals(header.headerWithEmailHeight_, header.offsetHeight)
-          checkElementText(
-              '',
-              header.$$('#user-email-container'));
+          assertNotEquals(header.headerWithEmailHeight_, header.offsetHeight);
+          checkElementText('', header.$$('#user-email-container'));
           done();
         });
       });
diff --git a/chrome/test/data/webui/media_router/media_router_search_highlighter_tests.js b/chrome/test/data/webui/media_router/media_router_search_highlighter_tests.js
index f7fcc76..8c7196e 100644
--- a/chrome/test/data/webui/media_router/media_router_search_highlighter_tests.js
+++ b/chrome/test/data/webui/media_router/media_router_search_highlighter_tests.js
@@ -17,7 +17,7 @@
       var checkTextContent = function(expected) {
         assertEquals(expected, searchHighlighter.$['text'].textContent);
         assertEquals(expected, searchHighlighter.text);
-      }
+      };
 
       // Computes the flat text string that should be displayed when the search
       // highlighter is given |data|.
@@ -32,7 +32,7 @@
           }
         }
         return answer;
-      }
+      };
 
       // Import media_router_search_highlighter.html before running suite.
       suiteSetup(function() {
diff --git a/chrome/test/data/webui/media_router/route_controls_tests.js b/chrome/test/data/webui/media_router/route_controls_tests.js
index 2d833d1..efc7727 100644
--- a/chrome/test/data/webui/media_router/route_controls_tests.js
+++ b/chrome/test/data/webui/media_router/route_controls_tests.js
@@ -44,8 +44,7 @@
       // parameter is not set, it defaults to an empty string, zero, or false.
       var createRouteStatus = function(params = {}) {
         return new media_router.RouteStatus(
-            params.title ? params.title : '',
-            !!params.canPlayPause,
+            params.title ? params.title : '', !!params.canPlayPause,
             !!params.canMute, !!params.canSetVolume, !!params.canSeek,
             params.playState ? params.playState :
                                media_router.PlayState.PLAYING,
@@ -98,8 +97,7 @@
 
         // Set the route status title.
         var title = 'test title';
-        controls.routeStatus =
-            createRouteStatus({title: title});
+        controls.routeStatus = createRouteStatus({title: title});
 
         assertElementText(fakeRouteOne.description, 'route-description');
         assertElementText(title, 'route-title');
@@ -286,11 +284,12 @@
         routeStatus.mirroringExtraData = {mediaRemotingEnabled: true};
         controls.routeStatus = routeStatus;
         assertElementShown('mirroring-fullscreen-video-controls');
-        assertEquals(controls.FullscreenVideoOption_.REMOTE_SCREEN,
+        assertEquals(
+            controls.FullscreenVideoOption_.REMOTE_SCREEN,
             controls.$$('#mirroring-fullscreen-video-dropdown').value);
 
-        document.addEventListener('mock-set-media-remoting-enabled',
-            function(e) {
+        document.addEventListener(
+            'mock-set-media-remoting-enabled', function(e) {
               assertFalse(e.detail.enabled);
               done();
             });
@@ -298,8 +297,8 @@
         // Simulate changing the dropdown menu value.
         controls.$$('#mirroring-fullscreen-video-dropdown').value =
             controls.FullscreenVideoOption_.BOTH_SCREENS;
-        controls.$$('#mirroring-fullscreen-video-dropdown').dispatchEvent(
-            new Event('change'));
+        controls.$$('#mirroring-fullscreen-video-dropdown')
+            .dispatchEvent(new Event('change'));
       });
 
       test('hangouts local present mode', function(done) {
@@ -319,15 +318,15 @@
         assertElementShown('hangouts-local-present-controls');
         assertTrue(controls.$$('#hangouts-local-present-checkbox').checked);
 
-        document.addEventListener('mock-set-hangouts-local-present',
-            function(e) {
+        document.addEventListener(
+            'mock-set-hangouts-local-present', function(e) {
               done();
             });
         MockInteractions.tap(controls.$$('#hangouts-local-present-checkbox'));
         assertFalse(controls.$$('#hangouts-local-present-checkbox').checked);
-    });
+      });
 
-    test('ignore external updates right after using sliders', function(done) {
+      test('ignore external updates right after using sliders', function(done) {
         var currentTime = 500;
         var externalCurrentTime = 800;
         var volume = 0.45;
diff --git a/chrome/test/data/webui/media_router/route_details_tests.js b/chrome/test/data/webui/media_router/route_details_tests.js
index e376721..4652bb2 100644
--- a/chrome/test/data/webui/media_router/route_details_tests.js
+++ b/chrome/test/data/webui/media_router/route_details_tests.js
@@ -48,9 +48,7 @@
       // Checks whether |expected| and the text in the element in the
       // |elementId| element are equal.
       var checkElementText = function(expected, elementId) {
-        assertEquals(
-            expected,
-            details.$$('#' + elementId).innerText);
+        assertEquals(expected, details.$$('#' + elementId).innerText);
       };
 
       // Checks the default route view is shown.
@@ -90,8 +88,8 @@
         fakeRouteOne = new media_router.Route(
             'route id 1', 'sink id 1', 'Video 1', 1, true, false,
             fakeRouteOneControllerPath);
-        fakeRouteTwo = new media_router.Route('route id 2', 'sink id 2',
-            'Video 2', 2, false, true);
+        fakeRouteTwo = new media_router.Route(
+            'route id 2', 'sink id 2', 'Video 2', 2, false, true);
         fakeSinkOne = new media_router.Sink(
             'sink id 1', 'sink 1', 'description', null,
             media_router.SinkIconType.CAST, media_router.SinkStatus.ACTIVE,
@@ -153,7 +151,9 @@
       // 'start-casting-to-route-button' button is clicked when the current
       // route is joinable.
       test('start casting to route button click', function(done) {
-        details.addEventListener('join-route-click', function() { done(); });
+        details.addEventListener('join-route-click', function() {
+          done();
+        });
         details.route = fakeRouteTwo;
         MockInteractions.tap(details.$$('#start-casting-to-route-button'));
       });
@@ -162,8 +162,9 @@
       // 'start-casting-to-route-button' button is clicked when the current
       // route is not joinable.
       test('start casting button click replaces route', function(done) {
-        details.addEventListener(
-            'change-route-source-click', function() { done(); });
+        details.addEventListener('change-route-source-click', function() {
+          done();
+        });
         details.route = fakeRouteOne;
         details.availableCastModes = 1;
         MockInteractions.tap(details.$$('#start-casting-to-route-button'));
@@ -172,8 +173,9 @@
       // Tests the initial expected text.
       test('initial text setting', function() {
         // <paper-button> text is styled as upper case.
-        checkSpanText(loadTimeData.getString('stopCastingButtonText')
-            .toUpperCase(), 'close-route-button');
+        checkSpanText(
+            loadTimeData.getString('stopCastingButtonText').toUpperCase(),
+            'close-route-button');
         checkSpanText(
             loadTimeData.getString('startCastingButtonText').toUpperCase(),
             'start-casting-to-route-button');
diff --git a/chrome/test/data/webui/mocha_adapter.js b/chrome/test/data/webui/mocha_adapter.js
index a99483df..2f0632e 100644
--- a/chrome/test/data/webui/mocha_adapter.js
+++ b/chrome/test/data/webui/mocha_adapter.js
@@ -60,7 +60,7 @@
     testDone([
       false,
       'Test Errors: ' + failures + '/' + (passes + failures) +
-      ' tests had failed assertions.'
+          ' tests had failed assertions.'
     ]);
   });
 }
diff --git a/chrome/test/data/webui/mock_controller.js b/chrome/test/data/webui/mock_controller.js
index 66b0011a..d51bf19 100644
--- a/chrome/test/data/webui/mock_controller.js
+++ b/chrome/test/data/webui/mock_controller.js
@@ -10,8 +10,9 @@
 function MockMethod() {
   var fn = function() {
     var args = Array.prototype.slice.call(arguments);
-    var callbacks =
-        args.filter(function(arg) { return (typeof arg == 'function'); });
+    var callbacks = args.filter(function(arg) {
+      return (typeof arg == 'function');
+    });
 
     if (callbacks.length > 1) {
       console.error('Only support mocking function with at most one callback.');
@@ -79,12 +80,10 @@
    * the correct signature for each call.
    */
   verifyMock: function() {
-    var errorMessage =  'Number of method calls did not match expectation.';
+    var errorMessage = 'Number of method calls did not match expectation.';
     if (this.functionName)
       errorMessage = 'Error in ' + this.functionName + ':\n' + errorMessage;
-    assertEquals(this.expectations_.length,
-                 this.calls_.length,
-                 errorMessage);
+    assertEquals(this.expectations_.length, this.calls_.length, errorMessage);
     for (var i = 0; i < this.expectations_.length; i++) {
       this.validateCall(i, this.expectations_[i], this.calls_[i]);
     }
diff --git a/chrome/test/data/webui/mock_timer.js b/chrome/test/data/webui/mock_timer.js
index 37f5f6c..96a61fd 100644
--- a/chrome/test/data/webui/mock_timer.js
+++ b/chrome/test/data/webui/mock_timer.js
@@ -31,7 +31,7 @@
    *                repeats: boolean}>}
    * @private
    */
-  this.timers_ =  [];
+  this.timers_ = [];
 
   /**
    * List of scheduled tasks.
@@ -99,12 +99,8 @@
    */
   createTimer_: function(callback, delayInMs, repeats) {
     var key = this.nextTimerKey_++;
-    var task = {
-      callback: callback,
-      delay: delayInMs,
-      key: key,
-      repeats: repeats
-    };
+    var task =
+        {callback: callback, delay: delayInMs, key: key, repeats: repeats};
     this.timers_[key] = task;
     this.scheduleTask_(task);
     return key;
diff --git a/chrome/test/data/webui/net_internals/bandwidth_view.js b/chrome/test/data/webui/net_internals/bandwidth_view.js
index c02e913..381f3794 100644
--- a/chrome/test/data/webui/net_internals/bandwidth_view.js
+++ b/chrome/test/data/webui/net_internals/bandwidth_view.js
@@ -68,8 +68,8 @@
    * Returns the float value the specified cell of the bandwidth table.
    */
   getBandwidthTableCell_: function(row, col) {
-    return parseFloat(NetInternalsTest.getTbodyText(
-        BandwidthView.STATS_BOX_ID, row, col));
+    return parseFloat(
+        NetInternalsTest.getTbodyText(BandwidthView.STATS_BOX_ID, row, col));
   },
 
   /**
@@ -210,8 +210,7 @@
    * @param {object} info State of the data reduction proxy.
    */
   onDataReductionProxyInfoChanged: function(info) {
-    if (this.isDone() ||
-        this.dataReductionProxyInfoVerified_ ||
+    if (this.isDone() || this.dataReductionProxyInfoVerified_ ||
         !this.proxySettingsReceived_) {
       return;
     }
@@ -219,11 +218,11 @@
     if (info) {
       expectEquals(this.enabled_, info.enabled);
       if (this.enabled_) {
-        expectEquals("Enabled", $(BandwidthView.ENABLED_ID).innerText);
+        expectEquals('Enabled', $(BandwidthView.ENABLED_ID).innerText);
         expectNotEquals('', $(BandwidthView.PRIMARY_PROXY_ID).innerText);
         expectNotEquals('', $(BandwidthView.SECONDARY_PROXY_ID).innerText);
       } else {
-        expectEquals("Disabled", $(BandwidthView.ENABLED_ID).innerText);
+        expectEquals('Disabled', $(BandwidthView.ENABLED_ID).innerText);
         expectEquals('', $(BandwidthView.PRIMARY_PROXY_ID).innerText);
         expectEquals('', $(BandwidthView.SECONDARY_PROXY_ID).innerText);
         // Each event results in 2 rows, and we get 2 events since the startup
@@ -244,8 +243,7 @@
  */
 TEST_F('NetInternalsTest', 'netInternalsSessionBandwidthSucceed', function() {
   var taskQueue = new NetInternalsTest.TaskQueue(true);
-  taskQueue.addTask(
-      new NetInternalsTest.GetTestServerURLTask('/title1.html'));
+  taskQueue.addTask(new NetInternalsTest.GetTestServerURLTask('/title1.html'));
   // Load a page with a content length of 66 bytes and a 45-byte favicon.
   taskQueue.addTask(new BandwidthTask(66, 45));
   taskQueue.run();
@@ -254,23 +252,23 @@
 /**
  * Checks data reduction proxy info when it is enabled.
  */
-TEST_F('NetInternalsTest',
-       'DISABLED_netInternalsDataReductionProxyEnabled',
-       function() {
-  var taskQueue = new NetInternalsTest.TaskQueue(true);
-  taskQueue.addTask(new DataReductionProxyTask(true));
-  taskQueue.run();
-});
+TEST_F(
+    'NetInternalsTest', 'DISABLED_netInternalsDataReductionProxyEnabled',
+    function() {
+      var taskQueue = new NetInternalsTest.TaskQueue(true);
+      taskQueue.addTask(new DataReductionProxyTask(true));
+      taskQueue.run();
+    });
 
 /**
  * Checks data reduction proxy info when it is disabled.
  */
-TEST_F('NetInternalsTest',
-       'DISABLED_netInternalsDataReductionProxyDisabled',
-       function() {
-  var taskQueue = new NetInternalsTest.TaskQueue(true);
-  taskQueue.addTask(new DataReductionProxyTask(false));
-  taskQueue.run();
-});
+TEST_F(
+    'NetInternalsTest', 'DISABLED_netInternalsDataReductionProxyDisabled',
+    function() {
+      var taskQueue = new NetInternalsTest.TaskQueue(true);
+      taskQueue.addTask(new DataReductionProxyTask(false));
+      taskQueue.run();
+    });
 
 })();  // Anonymous namespace
diff --git a/chrome/test/data/webui/net_internals/chromeos_view.js b/chrome/test/data/webui/net_internals/chromeos_view.js
index 35454b1..736dad9 100644
--- a/chrome/test/data/webui/net_internals/chromeos_view.js
+++ b/chrome/test/data/webui/net_internals/chromeos_view.js
@@ -46,22 +46,21 @@
   }
 };
 
-TEST_F('NetInternalsTest',
-       'netInternalsChromeOSViewStoreDebugLogs',
-       function() {
-  if (!cr.isChromeOS) {
-    testDone();
-    return;
-  }
+TEST_F(
+    'NetInternalsTest', 'netInternalsChromeOSViewStoreDebugLogs', function() {
+      if (!cr.isChromeOS) {
+        testDone();
+        return;
+      }
 
-  // #chromeos-view-import-onc fails accessibility check.
-  this.runAccessibilityChecks = false;
-  NetInternalsTest.switchToView('chromeos');
+      // #chromeos-view-import-onc fails accessibility check.
+      this.runAccessibilityChecks = false;
+      NetInternalsTest.switchToView('chromeos');
 
-  var taskQueue = new NetInternalsTest.TaskQueue(true);
-  taskQueue.addTask(new DebugLogsStatusWatcher());
-  taskQueue.addTask(new ResultChecker());
-  taskQueue.run();
-});
+      var taskQueue = new NetInternalsTest.TaskQueue(true);
+      taskQueue.addTask(new DebugLogsStatusWatcher());
+      taskQueue.addTask(new ResultChecker());
+      taskQueue.run();
+    });
 
 })();  // Anonymous namespace
diff --git a/chrome/test/data/webui/net_internals/dns_view.js b/chrome/test/data/webui/net_internals/dns_view.js
index 8f77dde..8b23505 100644
--- a/chrome/test/data/webui/net_internals/dns_view.js
+++ b/chrome/test/data/webui/net_internals/dns_view.js
@@ -14,8 +14,9 @@
  * @param {object} hostResolverInfo Results from a host resolver info query.
  */
 function checkDisplay(hostResolverInfo) {
-  expectEquals(hostResolverInfo.cache.capacity,
-               parseInt($(DnsView.CAPACITY_SPAN_ID).innerText));
+  expectEquals(
+      hostResolverInfo.cache.capacity,
+      parseInt($(DnsView.CAPACITY_SPAN_ID).innerText));
 
   var entries = hostResolverInfo.cache.entries;
 
@@ -88,10 +89,7 @@
    */
   start: function() {
     var addCacheEntryParams = [
-      this.hostname_,
-      this.ipAddress_,
-      this.netError_,
-      this.expired_ ? -2 : 2
+      this.hostname_, this.ipAddress_, this.netError_, this.expired_ ? -2 : 2
     ];
     chrome.send('addCacheEntry', addCacheEntryParams);
     g_browser.addHostResolverInfoObserver(this, false);
@@ -180,10 +178,10 @@
 
       // Look for an entry that's expired due to a network change.
       for (var row = 0; row < entries.length; ++row) {
-          var text = NetInternalsTest.getTbodyText(tableId, row, 5);
+        var text = NetInternalsTest.getTbodyText(tableId, row, 5);
         if (/expired/i.test(text)) {
-            foundExpired = true;
-        };
+          foundExpired = true;
+        }
       }
 
       if (foundExpired) {
@@ -258,8 +256,8 @@
 TEST_F('NetInternalsTest', 'netInternalsDnsViewSuccess', function() {
   NetInternalsTest.switchToView('dns');
   var taskQueue = new NetInternalsTest.TaskQueue(true);
-  taskQueue.addTask(new AddCacheEntryTask(
-      'somewhere.com', '1.2.3.4', 0, false));
+  taskQueue.addTask(
+      new AddCacheEntryTask('somewhere.com', '1.2.3.4', 0, false));
   taskQueue.addTask(new ClearCacheTask());
   taskQueue.addTask(new WaitForEntryDestructionTask('somewhere.com'));
   taskQueue.run(true);
@@ -284,8 +282,7 @@
 TEST_F('NetInternalsTest', 'netInternalsDnsViewExpired', function() {
   NetInternalsTest.switchToView('dns');
   var taskQueue = new NetInternalsTest.TaskQueue(true);
-  taskQueue.addTask(new AddCacheEntryTask(
-      'somewhere.com', '1.2.3.4', 0, true));
+  taskQueue.addTask(new AddCacheEntryTask('somewhere.com', '1.2.3.4', 0, true));
   taskQueue.addTask(new ClearCacheTask());
   taskQueue.addTask(new WaitForEntryDestructionTask('somewhere.com'));
   taskQueue.run(true);
@@ -298,8 +295,8 @@
   NetInternalsTest.switchToView('dns');
   var taskQueue = new NetInternalsTest.TaskQueue(true);
   for (var i = 0; i < 2; ++i) {
-    taskQueue.addTask(new AddCacheEntryTask(
-        'somewhere.com', '1.2.3.4', 0, false));
+    taskQueue.addTask(
+        new AddCacheEntryTask('somewhere.com', '1.2.3.4', 0, false));
     taskQueue.addTask(new AddCacheEntryTask(
         'nowhere.com', '', NetError.ERR_NAME_NOT_RESOLVED, true));
     taskQueue.addTask(new ClearCacheTask());
@@ -318,8 +315,7 @@
   NetInternalsTest.switchToView('dns');
   var taskQueue = new NetInternalsTest.TaskQueue(true);
   taskQueue.addTask(new NetInternalsTest.CreateIncognitoBrowserTask());
-  taskQueue.addTask(new AddCacheEntryTask(
-      'somewhere.com', '1.2.3.4', 0, true));
+  taskQueue.addTask(new AddCacheEntryTask('somewhere.com', '1.2.3.4', 0, true));
   taskQueue.addTask(NetInternalsTest.getCloseIncognitoBrowserTask());
   taskQueue.addTask(new WaitForEntryDestructionTask('somewhere.com'));
   taskQueue.run(true);
@@ -332,8 +328,8 @@
 TEST_F('NetInternalsTest', 'netInternalsDnsViewNetworkChanged', function() {
   NetInternalsTest.switchToView('dns');
   var taskQueue = new NetInternalsTest.TaskQueue(true);
-  taskQueue.addTask(new AddCacheEntryTask(
-      'somewhere.com', '1.2.3.4', 0, false));
+  taskQueue.addTask(
+      new AddCacheEntryTask('somewhere.com', '1.2.3.4', 0, false));
   taskQueue.addTask(new NetworkChangeTask());
   taskQueue.addTask(new ClearCacheTask());
   taskQueue.addTask(new WaitForEntryDestructionTask('somewhere.com'));
diff --git a/chrome/test/data/webui/net_internals/domain_security_policy_view.js b/chrome/test/data/webui/net_internals/domain_security_policy_view.js
index ad96d67..cdcfbe08 100644
--- a/chrome/test/data/webui/net_internals/domain_security_policy_view.js
+++ b/chrome/test/data/webui/net_internals/domain_security_policy_view.js
@@ -24,11 +24,7 @@
  * Possible results of an HSTS query.
  * @enum {number}
  */
-var QueryResultType = {
-  SUCCESS: 0,
-  NOT_FOUND: 1,
-  ERROR: 2
-};
+var QueryResultType = {SUCCESS: 0, NOT_FOUND: 1, ERROR: 2};
 
 /**
  * A Task that waits for the results of a lookup query. Once the results are
@@ -245,8 +241,10 @@
   start: function() {
     $(DomainSecurityPolicyView.ADD_HSTS_PKP_INPUT_ID).value = this.domain_;
     $(DomainSecurityPolicyView.ADD_STS_CHECK_ID).checked = this.stsSubdomains_;
-    $(DomainSecurityPolicyView.ADD_PKP_CHECK_ID).checked = this.requestedPkpSubdomains_;
-    $(DomainSecurityPolicyView.ADD_PINS_ID).value = this.requestedPublicKeyHashes_;
+    $(DomainSecurityPolicyView.ADD_PKP_CHECK_ID).checked =
+        this.requestedPkpSubdomains_;
+    $(DomainSecurityPolicyView.ADD_PINS_ID).value =
+        this.requestedPublicKeyHashes_;
     $(DomainSecurityPolicyView.ADD_HSTS_PKP_SUBMIT_ID).click();
     CheckHSTSPKPQueryResultTask.prototype.start.call(this);
   }
@@ -444,7 +442,7 @@
    * Saves the received report-uri and completes the task.
    * @param {string} reportURI Report URI received from the browser process.
    */
-  onReportURIReceived_: function (reportURI) {
+  onReportURIReceived_: function(reportURI) {
     this.reportURI_ = reportURI;
     this.onTaskDone();
   },
@@ -452,7 +450,7 @@
   /**
    * Returns the saved report-uri received from the browser process.
    */
-  reportURI: function () {
+  reportURI: function() {
     return this.reportURI_;
   }
 };
@@ -497,117 +495,141 @@
 /**
  * Checks that querying a domain that was never added fails.
  */
-TEST_F('NetInternalsTest', 'netInternalsDomainSecurityPolicyViewQueryNotFound', function() {
-  NetInternalsTest.switchToView('hsts');
-  taskQueue = new NetInternalsTest.TaskQueue(true);
-  var now = new Date().getTime() / 1000.0;
-  taskQueue.addTask(new QueryHSTSPKPTask(
-      'somewhere.com', false, false, now, now, '', QueryResultType.NOT_FOUND));
-  taskQueue.run();
-});
+TEST_F(
+    'NetInternalsTest', 'netInternalsDomainSecurityPolicyViewQueryNotFound',
+    function() {
+      NetInternalsTest.switchToView('hsts');
+      taskQueue = new NetInternalsTest.TaskQueue(true);
+      var now = new Date().getTime() / 1000.0;
+      taskQueue.addTask(new QueryHSTSPKPTask(
+          'somewhere.com', false, false, now, now, '',
+          QueryResultType.NOT_FOUND));
+      taskQueue.run();
+    });
 
 /**
  * Checks that querying a domain with an invalid name returns an error.
  */
-TEST_F('NetInternalsTest', 'netInternalsDomainSecurityPolicyViewQueryError', function() {
-  NetInternalsTest.switchToView('hsts');
-  taskQueue = new NetInternalsTest.TaskQueue(true);
-  var now = new Date().getTime() / 1000.0;
-  taskQueue.addTask(new QueryHSTSPKPTask(
-      '\u3024', false, false, now, now, '', QueryResultType.ERROR));
-  taskQueue.run();
-});
+TEST_F(
+    'NetInternalsTest', 'netInternalsDomainSecurityPolicyViewQueryError',
+    function() {
+      NetInternalsTest.switchToView('hsts');
+      taskQueue = new NetInternalsTest.TaskQueue(true);
+      var now = new Date().getTime() / 1000.0;
+      taskQueue.addTask(new QueryHSTSPKPTask(
+          '\u3024', false, false, now, now, '', QueryResultType.ERROR));
+      taskQueue.run();
+    });
 
 /**
  * Deletes a domain that was never added.
  */
-TEST_F('NetInternalsTest', 'netInternalsDomainSecurityPolicyViewDeleteNotFound', function() {
-  NetInternalsTest.switchToView('hsts');
-  taskQueue = new NetInternalsTest.TaskQueue(true);
-  taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
-  taskQueue.run();
-});
+TEST_F(
+    'NetInternalsTest', 'netInternalsDomainSecurityPolicyViewDeleteNotFound',
+    function() {
+      NetInternalsTest.switchToView('hsts');
+      taskQueue = new NetInternalsTest.TaskQueue(true);
+      taskQueue.addTask(
+          new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
+      taskQueue.run();
+    });
 
 /**
  * Deletes a domain that returns an error on lookup.
  */
-TEST_F('NetInternalsTest', 'netInternalsDomainSecurityPolicyViewDeleteError', function() {
-  NetInternalsTest.switchToView('hsts');
-  taskQueue = new NetInternalsTest.TaskQueue(true);
-  taskQueue.addTask(new DeleteTask('\u3024', QueryResultType.ERROR));
-  taskQueue.run();
-});
+TEST_F(
+    'NetInternalsTest', 'netInternalsDomainSecurityPolicyViewDeleteError',
+    function() {
+      NetInternalsTest.switchToView('hsts');
+      taskQueue = new NetInternalsTest.TaskQueue(true);
+      taskQueue.addTask(new DeleteTask('\u3024', QueryResultType.ERROR));
+      taskQueue.run();
+    });
 
 /**
  * Adds a domain and then deletes it.
  */
-TEST_F('NetInternalsTest', 'netInternalsDomainSecurityPolicyViewAddDelete', function() {
-  NetInternalsTest.switchToView('hsts');
-  taskQueue = new NetInternalsTest.TaskQueue(true);
-  var now = new Date().getTime() / 1000.0;
-  taskQueue.addTask(new AddHSTSPKPTask(
-      'somewhere.com', false, false, VALID_HASH, now, now,
-      QueryResultType.SUCCESS));
-  taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
-  taskQueue.run();
-});
+TEST_F(
+    'NetInternalsTest', 'netInternalsDomainSecurityPolicyViewAddDelete',
+    function() {
+      NetInternalsTest.switchToView('hsts');
+      taskQueue = new NetInternalsTest.TaskQueue(true);
+      var now = new Date().getTime() / 1000.0;
+      taskQueue.addTask(new AddHSTSPKPTask(
+          'somewhere.com', false, false, VALID_HASH, now, now,
+          QueryResultType.SUCCESS));
+      taskQueue.addTask(
+          new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
+      taskQueue.run();
+    });
 
 /**
  * Tries to add a domain with an invalid name.
  */
-TEST_F('NetInternalsTest', 'netInternalsDomainSecurityPolicyViewAddFail', function() {
-  NetInternalsTest.switchToView('hsts');
-  taskQueue = new NetInternalsTest.TaskQueue(true);
-  var now = new Date().getTime() / 1000.0;
-  taskQueue.addTask(new AddHSTSPKPTask(
-      '0123456789012345678901234567890' +
-          '012345678901234567890123456789012345',
-      false, false, '', now, now, QueryResultType.NOT_FOUND));
-  taskQueue.run();
-});
+TEST_F(
+    'NetInternalsTest', 'netInternalsDomainSecurityPolicyViewAddFail',
+    function() {
+      NetInternalsTest.switchToView('hsts');
+      taskQueue = new NetInternalsTest.TaskQueue(true);
+      var now = new Date().getTime() / 1000.0;
+      taskQueue.addTask(new AddHSTSPKPTask(
+          '0123456789012345678901234567890' +
+              '012345678901234567890123456789012345',
+          false, false, '', now, now, QueryResultType.NOT_FOUND));
+      taskQueue.run();
+    });
 
 /**
  * Tries to add a domain with a name that errors out on lookup due to having
  * non-ASCII characters in it.
  */
-TEST_F('NetInternalsTest', 'netInternalsDomainSecurityPolicyViewAddError', function() {
-  NetInternalsTest.switchToView('hsts');
-  taskQueue = new NetInternalsTest.TaskQueue(true);
-  var now = new Date().getTime() / 1000.0;
-  taskQueue.addTask(new AddHSTSPKPTask(
-      '\u3024', false, false, '', now, now, QueryResultType.ERROR));
-  taskQueue.run();
-});
+TEST_F(
+    'NetInternalsTest', 'netInternalsDomainSecurityPolicyViewAddError',
+    function() {
+      NetInternalsTest.switchToView('hsts');
+      taskQueue = new NetInternalsTest.TaskQueue(true);
+      var now = new Date().getTime() / 1000.0;
+      taskQueue.addTask(new AddHSTSPKPTask(
+          '\u3024', false, false, '', now, now, QueryResultType.ERROR));
+      taskQueue.run();
+    });
 
 /**
  * Adds a domain with an invalid hash.
  */
-TEST_F('NetInternalsTest', 'netInternalsDomainSecurityPolicyViewAddInvalidHash', function() {
-  NetInternalsTest.switchToView('hsts');
-  taskQueue = new NetInternalsTest.TaskQueue(true);
-  var now = new Date().getTime() / 1000.0;
-  taskQueue.addTask(new AddHSTSPKPTask(
-      'somewhere.com', true, true, INVALID_HASH, now, now,
-      QueryResultType.SUCCESS));
-  taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
-  taskQueue.run();
-});
+TEST_F(
+    'NetInternalsTest', 'netInternalsDomainSecurityPolicyViewAddInvalidHash',
+    function() {
+      NetInternalsTest.switchToView('hsts');
+      taskQueue = new NetInternalsTest.TaskQueue(true);
+      var now = new Date().getTime() / 1000.0;
+      taskQueue.addTask(new AddHSTSPKPTask(
+          'somewhere.com', true, true, INVALID_HASH, now, now,
+          QueryResultType.SUCCESS));
+      taskQueue.addTask(
+          new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
+      taskQueue.run();
+    });
 
 /**
  * Adds the same domain twice in a row, modifying some values the second time.
  */
-TEST_F('NetInternalsTest', 'netInternalsDomainSecurityPolicyViewAddOverwrite', function() {
-  NetInternalsTest.switchToView('hsts');
-  taskQueue = new NetInternalsTest.TaskQueue(true);
-  var now = new Date().getTime() / 1000.0;
-  taskQueue.addTask(new AddHSTSPKPTask(
-      'somewhere.com', true, true, VALID_HASH, now, now,
-      QueryResultType.SUCCESS));
-  taskQueue.addTask(new AddHSTSPKPTask(
-      'somewhere.com', false, false, '', now, now, QueryResultType.SUCCESS));
-  taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
-  taskQueue.run();
-});
+TEST_F(
+    'NetInternalsTest', 'netInternalsDomainSecurityPolicyViewAddOverwrite',
+    function() {
+      NetInternalsTest.switchToView('hsts');
+      taskQueue = new NetInternalsTest.TaskQueue(true);
+      var now = new Date().getTime() / 1000.0;
+      taskQueue.addTask(new AddHSTSPKPTask(
+          'somewhere.com', true, true, VALID_HASH, now, now,
+          QueryResultType.SUCCESS));
+      taskQueue.addTask(new AddHSTSPKPTask(
+          'somewhere.com', false, false, '', now, now,
+          QueryResultType.SUCCESS));
+      taskQueue.addTask(
+          new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
+      taskQueue.run();
+    });
 
 /**
  * Adds two different domains and then deletes them.
diff --git a/chrome/test/data/webui/net_internals/events_view.js b/chrome/test/data/webui/net_internals/events_view.js
index d62d9e3..9d02ae5 100644
--- a/chrome/test/data/webui/net_internals/events_view.js
+++ b/chrome/test/data/webui/net_internals/events_view.js
@@ -13,10 +13,7 @@
   return [
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': id,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': id, 'type': EventSourceType.URL_REQUEST},
       'time': '953534778',
       'type': EventType.REQUEST_ALIVE
     },
@@ -28,28 +25,19 @@
         'url': 'http://www.google.com/'
       },
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': id,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': id, 'type': EventSourceType.URL_REQUEST},
       'time': '953534792',
       'type': EventType.URL_REQUEST_START_JOB
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': id,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': id, 'type': EventSourceType.URL_REQUEST},
       'time': '953534800',
       'type': EventType.URL_REQUEST_START_JOB
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': id,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': id, 'type': EventSourceType.URL_REQUEST},
       'time': '953534906',
       'type': EventType.HTTP_TRANSACTION_SEND_REQUEST
     },
@@ -68,28 +56,19 @@
         'line': 'GET / HTTP/1.1\r\n'
       },
       'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': id,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': id, 'type': EventSourceType.URL_REQUEST},
       'time': '953534910',
       'type': EventType.HTTP_TRANSACTION_SEND_REQUEST_HEADERS
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': id,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': id, 'type': EventSourceType.URL_REQUEST},
       'time': '953534915',
       'type': EventType.HTTP_TRANSACTION_SEND_REQUEST
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': id,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': id, 'type': EventSourceType.URL_REQUEST},
       'time': '953535567',
       'type': EventType.REQUEST_ALIVE
     }
@@ -127,18 +106,18 @@
     // call update function to check displayed event count.
     EventsView.getInstance().repaintFilterCounter_();
 
-    expectEquals(postFilter + ' of ' + matches.length,
-                 $(EventsView.FILTER_COUNT_ID).innerText,
-                 filter);
+    expectEquals(
+        postFilter + ' of ' + matches.length,
+        $(EventsView.FILTER_COUNT_ID).innerText, filter);
 
     var tbody = $(EventsView.TBODY_ID);
     assertEquals(matches.length, tbody.childElementCount, filter);
 
     var visibleCount = 0;
     for (var i = 0; i < tbody.childElementCount; ++i) {
-      expectEquals(matches[i],
-                   NetInternalsTest.nodeIsVisible(tbody.children[i]),
-                   filter);
+      expectEquals(
+          matches[i], NetInternalsTest.nodeIsVisible(tbody.children[i]),
+          filter);
     }
   }
 
@@ -158,43 +137,52 @@
   // |matches| is a 2-element array of booleans indicating which of the two
   //      requests passes the filter.
   var testFilters = [
-    {text: 'http://www.google.com', matches: [true, true] },
-    {text: 'MyMagicPony', matches: [false, false] },
-    {text: 'type:URL_REQUEST', matches: [true, true] },
-    {text: 'type:SOCKET,URL_REQUEST', matches: [true, true] },
-    {text: 'type:SOCKET', matches: [false, false] },
-    {text: '-type:PONY', matches: [true, true] },
-    {text: '-type:URL_REQUEST', matches: [false, false] },
-    {text: 'id:31,32', matches: [true, false] },
-    {text: '-id:31,32', matches: [false, true] },
-    {text: 'id:32,56,', matches: [false, true] },
-    {text: '-is:active', matches: [true, false] },
-    {text: 'is:active', matches: [false, true] },
-    {text: '-is:error', matches: [true, true] },
-    {text: 'is:error', matches: [false, false] },
+    {text: 'http://www.google.com', matches: [true, true]},
+    {text: 'MyMagicPony', matches: [false, false]},
+    {text: 'type:URL_REQUEST', matches: [true, true]},
+    {text: 'type:SOCKET,URL_REQUEST', matches: [true, true]},
+    {text: 'type:SOCKET', matches: [false, false]},
+    {text: '-type:PONY', matches: [true, true]},
+    {text: '-type:URL_REQUEST', matches: [false, false]},
+    {text: 'id:31,32', matches: [true, false]},
+    {text: '-id:31,32', matches: [false, true]},
+    {text: 'id:32,56,', matches: [false, true]},
+    {text: '-is:active', matches: [true, false]},
+    {text: 'is:active', matches: [false, true]},
+    {text: '-is:error', matches: [true, true]},
+    {text: 'is:error', matches: [false, false]},
     // Partial match of source type.
-    {text: 'URL_REQ', matches: [true, true] },
+    {text: 'URL_REQ', matches: [true, true]},
     // Partial match of event type type.
-    {text: 'SEND_REQUEST', matches: [true, false] },
+    {text: 'SEND_REQUEST', matches: [true, false]},
     // Check that ":" works in strings.
-    { text: 'Host:', matches: [true, false] },
-    { text: '::', matches: [false, false] },
+    {text: 'Host:', matches: [true, false]},
+    {text: '::', matches: [false, false]},
     // Test quotes.
-    { text: '"Quoted String"', matches: [true, false] },
-    { text: '"Quoted source"', matches: [false, false] },
-    { text: '"\\"Quoted String\\""', matches: [true, false] },
-    { text: '"\\"\\"Quoted String\\""', matches: [false, false] },
-    { text: '\\"\\"\\"', matches: [true, false] },
-    { text: '\\"\\"\\"\\"', matches: [false, false] },
-    { text: '"Host: www.google.com"', matches: [true, false], },
-    { text: 'Connection:" keep-alive"', matches: [true, false], },
-    { text: '-Connection:" keep-alive"', matches: [false, true], },
-    { text: '"Host: GET"', matches: [false, false] },
+    {text: '"Quoted String"', matches: [true, false]},
+    {text: '"Quoted source"', matches: [false, false]},
+    {text: '"\\"Quoted String\\""', matches: [true, false]},
+    {text: '"\\"\\"Quoted String\\""', matches: [false, false]},
+    {text: '\\"\\"\\"', matches: [true, false]},
+    {text: '\\"\\"\\"\\"', matches: [false, false]},
+    {
+      text: '"Host: www.google.com"',
+      matches: [true, false],
+    },
+    {
+      text: 'Connection:" keep-alive"',
+      matches: [true, false],
+    },
+    {
+      text: '-Connection:" keep-alive"',
+      matches: [false, true],
+    },
+    {text: '"Host: GET"', matches: [false, false]},
     // Make sure sorting has no effect on filters.  Sort by ID so order is
     // preserved.
-    { text: 'sort:"id"', matches: [true, true] },
-    { text: '-sort:"shoe size"', matches: [true, true] },
-    { text: '"-sort:shoe size"', matches: [false, false] },
+    {text: 'sort:"id"', matches: [true, true]},
+    {text: '-sort:"shoe size"', matches: [true, true]},
+    {text: '"-sort:shoe size"', matches: [false, false]},
   ];
 
   for (var filter1 = 0; filter1 < testFilters.length; ++filter1) {
@@ -204,13 +192,13 @@
       var matches = [];
       for (var i = 0; i < testFilters[filter1].matches.length; ++i) {
         // The merged filter matches an entry if both individual filters do.
-        matches[i] = testFilters[filter1].matches[i] &&
-                     testFilters[filter2].matches[i];
+        matches[i] =
+            testFilters[filter1].matches[i] && testFilters[filter2].matches[i];
       }
 
-      checkFilter(testFilters[filter1].text + ' ' + testFilters[filter2].text,
-                  matches,
-                  1);
+      checkFilter(
+          testFilters[filter1].text + ' ' + testFilters[filter2].text, matches,
+          1);
     }
   }
 
diff --git a/chrome/test/data/webui/net_internals/log_util.js b/chrome/test/data/webui/net_internals/log_util.js
index 30dc58d..1fa616c 100644
--- a/chrome/test/data/webui/net_internals/log_util.js
+++ b/chrome/test/data/webui/net_internals/log_util.js
@@ -34,8 +34,8 @@
    * Starts creating the log dump.
    */
   start: function() {
-    log_util.createLogDumpAsync(this.userComments_,
-                                this.onLogDumpCreated.bind(this), true);
+    log_util.createLogDumpAsync(
+        this.userComments_, this.onLogDumpCreated.bind(this), true);
   },
 
   /**
@@ -51,8 +51,9 @@
     // Make sure the DIV on the import tab containing the comments is visible
     // before checking the displayed text.
     expectTrue(NetInternalsTest.nodeIsVisible($(ImportView.LOADED_DIV_ID)));
-    expectEquals(this.userComments_,
-                 $(ImportView.LOADED_INFO_USER_COMMENTS_ID).innerText);
+    expectEquals(
+        this.userComments_,
+        $(ImportView.LOADED_INFO_USER_COMMENTS_ID).innerText);
 
     this.onTaskDone();
   }
@@ -88,13 +89,13 @@
 };
 
 /**
-  * A Task that creates a log dump in the browser process, waits to receive it
-  * via IPC, and and then loads it as a string.
-  * @param {integer} truncate The number of bytes to truncate from the end of
-  *     the string, if any, to simulate a truncated log due to crash, or
-  *     quitting without properly shutting down the log writer.
-  * @extends {NetInternalsTest.Task}
-  */
+ * A Task that creates a log dump in the browser process, waits to receive it
+ * via IPC, and and then loads it as a string.
+ * @param {integer} truncate The number of bytes to truncate from the end of
+ *     the string, if any, to simulate a truncated log due to crash, or
+ *     quitting without properly shutting down the log writer.
+ * @extends {NetInternalsTest.Task}
+ */
 function GetNetLogFileContentsAndLoadLogTask(truncate) {
   NetInternalsTest.Task.call(this);
   this.setCompleteAsync(true);
@@ -224,9 +225,7 @@
  * Attempts to load a NetLog created by the browser. The log contents are
  * passed to Javascript via an IPC rather than drag and drop.
  */
-TEST_F('NetInternalsTest',
-    'netInternalsLogUtilImportNetLogFile',
-    function() {
+TEST_F('NetInternalsTest', 'netInternalsLogUtilImportNetLogFile', function() {
   var taskQueue = new NetInternalsTest.TaskQueue(true);
   taskQueue.addTask(new GetNetLogFileContentsAndLoadLogTask(0));
   taskQueue.addFunctionTask(checkViewsAfterNetLogFileLoaded);
@@ -237,13 +236,14 @@
  * Same as above, but it truncates the log to simulate the case of a crash when
  * creating a log.
  */
-TEST_F('NetInternalsTest', 'netInternalsLogUtilImportNetLogFileTruncated',
+TEST_F(
+    'NetInternalsTest', 'netInternalsLogUtilImportNetLogFileTruncated',
     function() {
-  var taskQueue = new NetInternalsTest.TaskQueue(true);
-  taskQueue.addTask(new GetNetLogFileContentsAndLoadLogTask(20));
-  taskQueue.addFunctionTask(checkViewsAfterNetLogFileLoaded);
-  taskQueue.run(true);
-});
+      var taskQueue = new NetInternalsTest.TaskQueue(true);
+      taskQueue.addTask(new GetNetLogFileContentsAndLoadLogTask(20));
+      taskQueue.addFunctionTask(checkViewsAfterNetLogFileLoaded);
+      taskQueue.run(true);
+    });
 
 /**
  * Checks pressing the stop capturing button.
@@ -254,9 +254,8 @@
   // the constants.
   taskQueue.addTask(new WaitForConstantsTask());
 
-  taskQueue.addFunctionTask(
-      NetInternalsTest.expectStatusViewNodeVisible.bind(
-          null, HaltedStatusView.MAIN_BOX_ID));
+  taskQueue.addFunctionTask(NetInternalsTest.expectStatusViewNodeVisible.bind(
+      null, HaltedStatusView.MAIN_BOX_ID));
   taskQueue.addFunctionTask(checkViewsAfterLogLoaded);
   taskQueue.addFunctionTask(checkActiveView.bind(null, EventsView.TAB_ID));
   taskQueue.run();
diff --git a/chrome/test/data/webui/net_internals/log_view_painter.js b/chrome/test/data/webui/net_internals/log_view_painter.js
index 72d0e9e..735befb9 100644
--- a/chrome/test/data/webui/net_internals/log_view_painter.js
+++ b/chrome/test/data/webui/net_internals/log_view_painter.js
@@ -24,9 +24,8 @@
     if (typeof testCase.baseTimeTicks != 'undefined')
       baseTime = timeutil.convertTimeTicksToTime(testCase.baseTimeTicks);
 
-    var tablePrinter =
-        createLogEntryTablePrinter(testCase.logEntries,
-                                   baseTime, testCase.logCreationTime);
+    var tablePrinter = createLogEntryTablePrinter(
+        testCase.logEntries, baseTime, testCase.logCreationTime);
     tablePrinter.toText(0, div);
 
     // Strip any trailing newlines, since the whitespace when using innerText
@@ -68,16 +67,13 @@
   var testCase = {};
   testCase.tickOffset = '1337911098446';
   testCase.logCreationTime = 1338864634013;
-  testCase.loadFlags = LoadFlag.MAIN_FRAME_DEPRECATED |
-                       LoadFlag.MAYBE_USER_GESTURE;
+  testCase.loadFlags =
+      LoadFlag.MAIN_FRAME_DEPRECATED | LoadFlag.MAYBE_USER_GESTURE;
 
   testCase.logEntries = [
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534778',
       'type': EventType.REQUEST_ALIVE
     },
@@ -89,19 +85,13 @@
         'url': 'http://www.google.com/'
       },
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534792',
       'type': EventType.URL_REQUEST_START_JOB
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534800',
       'type': EventType.URL_REQUEST_START_JOB
     },
@@ -113,181 +103,122 @@
         'url': 'http://www.google.com/'
       },
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534802',
       'type': EventType.URL_REQUEST_START_JOB
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534809',
       'type': EventType.HTTP_CACHE_GET_BACKEND
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534810',
       'type': EventType.HTTP_CACHE_GET_BACKEND
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534811',
       'type': EventType.HTTP_CACHE_OPEN_ENTRY
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534816',
       'type': EventType.HTTP_CACHE_OPEN_ENTRY
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534817',
       'type': EventType.HTTP_CACHE_ADD_TO_ENTRY
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534818',
       'type': EventType.HTTP_CACHE_ADD_TO_ENTRY
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534823',
       'type': EventType.HTTP_CACHE_READ_INFO
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534827',
       'type': EventType.HTTP_CACHE_READ_INFO
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534830',
       'type': EventType.HTTP_STREAM_REQUEST
     },
     {
       'params': {
-        'source_dependency': {
-          'id': 149,
-          'type': EventSourceType.HTTP_STREAM_JOB
-        }
+        'source_dependency':
+            {'id': 149, 'type': EventSourceType.HTTP_STREAM_JOB}
       },
       'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534898',
       'type': EventType.HTTP_STREAM_REQUEST_BOUND_TO_JOB
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534902',
       'type': EventType.HTTP_STREAM_REQUEST
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534906',
       'type': EventType.HTTP_TRANSACTION_SEND_REQUEST
     },
     {
       'params': {
         'headers': [
-          'Host: www.google.com',
-          'Connection: keep-alive',
-          'User-Agent: Mozilla/5.0',
-          'Accept: text/html',
-          'Accept-Encoding: gzip,deflate',
-          'Accept-Language: en-US,en;q=0.8',
+          'Host: www.google.com', 'Connection: keep-alive',
+          'User-Agent: Mozilla/5.0', 'Accept: text/html',
+          'Accept-Encoding: gzip,deflate', 'Accept-Language: en-US,en;q=0.8',
           'Accept-Charset: ISO-8859-1'
         ],
         'line': 'GET / HTTP/1.1\r\n'
       },
       'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534910',
       'type': EventType.HTTP_TRANSACTION_SEND_REQUEST_HEADERS
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534915',
       'type': EventType.HTTP_TRANSACTION_SEND_REQUEST
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534916',
       'type': EventType.HTTP_TRANSACTION_READ_HEADERS
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534917',
       'type': EventType.HTTP_STREAM_PARSER_READ_HEADERS
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534987',
       'type': EventType.HTTP_STREAM_PARSER_READ_HEADERS
     },
@@ -305,377 +236,275 @@
         ]
       },
       'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534989',
       'type': EventType.HTTP_TRANSACTION_READ_RESPONSE_HEADERS
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534992',
       'type': EventType.HTTP_TRANSACTION_READ_HEADERS
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534993',
       'type': EventType.HTTP_CACHE_WRITE_INFO
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535023',
       'type': EventType.HTTP_CACHE_WRITE_INFO
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535024',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535062',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535062',
       'type': EventType.HTTP_CACHE_WRITE_INFO
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535075',
       'type': EventType.HTTP_CACHE_WRITE_INFO
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535081',
       'type': EventType.URL_REQUEST_START_JOB
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535537',
       'type': EventType.HTTP_TRANSACTION_READ_BODY
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535538',
       'type': EventType.HTTP_TRANSACTION_READ_BODY
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535538',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535541',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535542',
       'type': EventType.HTTP_TRANSACTION_READ_BODY
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535545',
       'type': EventType.HTTP_TRANSACTION_READ_BODY
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535546',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535548',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535548',
       'type': EventType.HTTP_TRANSACTION_READ_BODY
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535548',
       'type': EventType.HTTP_TRANSACTION_READ_BODY
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535549',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535549',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535550',
       'type': EventType.HTTP_TRANSACTION_READ_BODY
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535550',
       'type': EventType.HTTP_TRANSACTION_READ_BODY
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535550',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535551',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535552',
       'type': EventType.HTTP_TRANSACTION_READ_BODY
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535553',
       'type': EventType.HTTP_TRANSACTION_READ_BODY
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535553',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535556',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535556',
       'type': EventType.HTTP_TRANSACTION_READ_BODY
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535559',
       'type': EventType.HTTP_TRANSACTION_READ_BODY
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535559',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535559',
       'type': EventType.HTTP_CACHE_WRITE_DATA
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953535567',
       'type': EventType.REQUEST_ALIVE
     }
   ];
 
   testCase.expectedText =
-'t=1338864633224 [st=  0] +REQUEST_ALIVE  [dt=789]\n' +
-'t=1338864633238 [st= 14]    URL_REQUEST_START_JOB  [dt=8]\n' +
-'                            --> load_flags = ' +
-    testCase.loadFlags.toString() +
-    ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' +
-'                            --> method = "GET"\n' +
-'                            --> priority = 4\n' +
-'                            --> url = "http://www.google.com/"\n' +
-'t=1338864633248 [st= 24]   +URL_REQUEST_START_JOB  [dt=279]\n' +
-'                            --> load_flags = ' +
-    testCase.loadFlags.toString() +
-    ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' +
-'                            --> method = "GET"\n' +
-'                            --> priority = 4\n' +
-'                            --> url = "http://www.google.com/"\n' +
-'t=1338864633255 [st= 31]      HTTP_CACHE_GET_BACKEND  [dt=1]\n' +
-'t=1338864633257 [st= 33]      HTTP_CACHE_OPEN_ENTRY  [dt=5]\n' +
-'t=1338864633263 [st= 39]      HTTP_CACHE_ADD_TO_ENTRY  [dt=1]\n' +
-'t=1338864633269 [st= 45]      HTTP_CACHE_READ_INFO  [dt=4]\n' +
-'t=1338864633276 [st= 52]     +HTTP_STREAM_REQUEST  [dt=72]\n' +
-'t=1338864633344 [st=120]        HTTP_STREAM_REQUEST_BOUND_TO_JOB\n' +
-'                                --> source_dependency = 149 ' +
-    '(HTTP_STREAM_JOB)\n' +
-'t=1338864633348 [st=124]     -HTTP_STREAM_REQUEST\n' +
-'t=1338864633352 [st=128]     +HTTP_TRANSACTION_SEND_REQUEST  [dt=9]\n' +
-'t=1338864633356 [st=132]        HTTP_TRANSACTION_SEND_REQUEST_HEADERS\n' +
-'                                --> GET / HTTP/1.1\n' +
-'                                    Host: www.google.com\n' +
-'                                    Connection: keep-alive\n' +
-'                                    User-Agent: Mozilla/5.0\n' +
-'                                    Accept: text/html\n' +
-'                                    Accept-Encoding: gzip,deflate\n' +
-'                                    Accept-Language: en-US,en;q=0.8\n' +
-'                                    Accept-Charset: ISO-8859-1\n' +
-'t=1338864633361 [st=137]     -HTTP_TRANSACTION_SEND_REQUEST\n' +
-'t=1338864633362 [st=138]     +HTTP_TRANSACTION_READ_HEADERS  [dt=76]\n' +
-'t=1338864633363 [st=139]        HTTP_STREAM_PARSER_READ_HEADERS  [dt=70]\n' +
-'t=1338864633435 [st=211]        HTTP_TRANSACTION_READ_RESPONSE_HEADERS\n' +
-'                                --> HTTP/1.1 200 OK\n' +
-'                                    Date: Tue, 05 Jun 2012 02:50:33 GMT\n' +
-'                                    Expires: -1\n' +
-'                                    Cache-Control: private, max-age=0\n' +
-'                                    Content-Type: text/html; charset=UTF-8\n' +
-'                                    Content-Encoding: gzip\n' +
-'                                    Server: gws\n' +
-'                                    Content-Length: 23798\n' +
-'t=1338864633438 [st=214]     -HTTP_TRANSACTION_READ_HEADERS\n' +
-'t=1338864633439 [st=215]      HTTP_CACHE_WRITE_INFO  [dt=30]\n' +
-'t=1338864633470 [st=246]      HTTP_CACHE_WRITE_DATA  [dt=38]\n' +
-'t=1338864633508 [st=284]      HTTP_CACHE_WRITE_INFO  [dt=13]\n' +
-'t=1338864633527 [st=303]   -URL_REQUEST_START_JOB\n' +
-'t=1338864633983 [st=759]    HTTP_TRANSACTION_READ_BODY  [dt=1]\n' +
-'t=1338864633984 [st=760]    HTTP_CACHE_WRITE_DATA  [dt=3]\n' +
-'t=1338864633988 [st=764]    HTTP_TRANSACTION_READ_BODY  [dt=3]\n' +
-'t=1338864633992 [st=768]    HTTP_CACHE_WRITE_DATA  [dt=2]\n' +
-'t=1338864633994 [st=770]    HTTP_TRANSACTION_READ_BODY  [dt=0]\n' +
-'t=1338864633995 [st=771]    HTTP_CACHE_WRITE_DATA  [dt=0]\n' +
-'t=1338864633996 [st=772]    HTTP_TRANSACTION_READ_BODY  [dt=0]\n' +
-'t=1338864633996 [st=772]    HTTP_CACHE_WRITE_DATA  [dt=1]\n' +
-'t=1338864633998 [st=774]    HTTP_TRANSACTION_READ_BODY  [dt=1]\n' +
-'t=1338864633999 [st=775]    HTTP_CACHE_WRITE_DATA  [dt=3]\n' +
-'t=1338864634002 [st=778]    HTTP_TRANSACTION_READ_BODY  [dt=3]\n' +
-'t=1338864634005 [st=781]    HTTP_CACHE_WRITE_DATA  [dt=0]\n' +
-'t=1338864634013 [st=789] -REQUEST_ALIVE';
+      't=1338864633224 [st=  0] +REQUEST_ALIVE  [dt=789]\n' +
+      't=1338864633238 [st= 14]    URL_REQUEST_START_JOB  [dt=8]\n' +
+      '                            --> load_flags = ' +
+      testCase.loadFlags.toString() +
+      ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' +
+      '                            --> method = "GET"\n' +
+      '                            --> priority = 4\n' +
+      '                            --> url = "http://www.google.com/"\n' +
+      't=1338864633248 [st= 24]   +URL_REQUEST_START_JOB  [dt=279]\n' +
+      '                            --> load_flags = ' +
+      testCase.loadFlags.toString() +
+      ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' +
+      '                            --> method = "GET"\n' +
+      '                            --> priority = 4\n' +
+      '                            --> url = "http://www.google.com/"\n' +
+      't=1338864633255 [st= 31]      HTTP_CACHE_GET_BACKEND  [dt=1]\n' +
+      't=1338864633257 [st= 33]      HTTP_CACHE_OPEN_ENTRY  [dt=5]\n' +
+      't=1338864633263 [st= 39]      HTTP_CACHE_ADD_TO_ENTRY  [dt=1]\n' +
+      't=1338864633269 [st= 45]      HTTP_CACHE_READ_INFO  [dt=4]\n' +
+      't=1338864633276 [st= 52]     +HTTP_STREAM_REQUEST  [dt=72]\n' +
+      't=1338864633344 [st=120]        HTTP_STREAM_REQUEST_BOUND_TO_JOB\n' +
+      '                                --> source_dependency = 149 ' +
+      '(HTTP_STREAM_JOB)\n' +
+      't=1338864633348 [st=124]     -HTTP_STREAM_REQUEST\n' +
+      't=1338864633352 [st=128]     +HTTP_TRANSACTION_SEND_REQUEST  [dt=9]\n' +
+      't=1338864633356 [st=132]        HTTP_TRANSACTION_SEND_REQUEST_HEADERS\n' +
+      '                                --> GET / HTTP/1.1\n' +
+      '                                    Host: www.google.com\n' +
+      '                                    Connection: keep-alive\n' +
+      '                                    User-Agent: Mozilla/5.0\n' +
+      '                                    Accept: text/html\n' +
+      '                                    Accept-Encoding: gzip,deflate\n' +
+      '                                    Accept-Language: en-US,en;q=0.8\n' +
+      '                                    Accept-Charset: ISO-8859-1\n' +
+      't=1338864633361 [st=137]     -HTTP_TRANSACTION_SEND_REQUEST\n' +
+      't=1338864633362 [st=138]     +HTTP_TRANSACTION_READ_HEADERS  [dt=76]\n' +
+      't=1338864633363 [st=139]        HTTP_STREAM_PARSER_READ_HEADERS  [dt=70]\n' +
+      't=1338864633435 [st=211]        HTTP_TRANSACTION_READ_RESPONSE_HEADERS\n' +
+      '                                --> HTTP/1.1 200 OK\n' +
+      '                                    Date: Tue, 05 Jun 2012 02:50:33 GMT\n' +
+      '                                    Expires: -1\n' +
+      '                                    Cache-Control: private, max-age=0\n' +
+      '                                    Content-Type: text/html; charset=UTF-8\n' +
+      '                                    Content-Encoding: gzip\n' +
+      '                                    Server: gws\n' +
+      '                                    Content-Length: 23798\n' +
+      't=1338864633438 [st=214]     -HTTP_TRANSACTION_READ_HEADERS\n' +
+      't=1338864633439 [st=215]      HTTP_CACHE_WRITE_INFO  [dt=30]\n' +
+      't=1338864633470 [st=246]      HTTP_CACHE_WRITE_DATA  [dt=38]\n' +
+      't=1338864633508 [st=284]      HTTP_CACHE_WRITE_INFO  [dt=13]\n' +
+      't=1338864633527 [st=303]   -URL_REQUEST_START_JOB\n' +
+      't=1338864633983 [st=759]    HTTP_TRANSACTION_READ_BODY  [dt=1]\n' +
+      't=1338864633984 [st=760]    HTTP_CACHE_WRITE_DATA  [dt=3]\n' +
+      't=1338864633988 [st=764]    HTTP_TRANSACTION_READ_BODY  [dt=3]\n' +
+      't=1338864633992 [st=768]    HTTP_CACHE_WRITE_DATA  [dt=2]\n' +
+      't=1338864633994 [st=770]    HTTP_TRANSACTION_READ_BODY  [dt=0]\n' +
+      't=1338864633995 [st=771]    HTTP_CACHE_WRITE_DATA  [dt=0]\n' +
+      't=1338864633996 [st=772]    HTTP_TRANSACTION_READ_BODY  [dt=0]\n' +
+      't=1338864633996 [st=772]    HTTP_CACHE_WRITE_DATA  [dt=1]\n' +
+      't=1338864633998 [st=774]    HTTP_TRANSACTION_READ_BODY  [dt=1]\n' +
+      't=1338864633999 [st=775]    HTTP_CACHE_WRITE_DATA  [dt=3]\n' +
+      't=1338864634002 [st=778]    HTTP_TRANSACTION_READ_BODY  [dt=3]\n' +
+      't=1338864634005 [st=781]    HTTP_CACHE_WRITE_DATA  [dt=0]\n' +
+      't=1338864634013 [st=789] -REQUEST_ALIVE';
 
   return testCase;
 }
@@ -691,10 +520,7 @@
   testCase.logEntries = [
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534778',
       'type': EventType.REQUEST_ALIVE
     },
@@ -706,31 +532,24 @@
         'url': 'http://www.google.com/'
       },
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534910',
       'type': EventType.URL_REQUEST_START_JOB
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534970',
       'type': EventType.URL_REQUEST_START_JOB
     },
   ];
 
-  testCase.expectedText =
-'t=1338864633224 [st=  0] +REQUEST_ALIVE  [dt=?]\n' +
-'t=1338864633356 [st=132]    URL_REQUEST_START_JOB  [dt=60]\n' +
-'                            --> load_flags = 0 (NORMAL)\n' +
-'                            --> method = "GET"\n' +
-'                            --> priority = 4\n' +
-'                            --> url = "http://www.google.com/"';
+  testCase.expectedText = 't=1338864633224 [st=  0] +REQUEST_ALIVE  [dt=?]\n' +
+      't=1338864633356 [st=132]    URL_REQUEST_START_JOB  [dt=60]\n' +
+      '                            --> load_flags = 0 (NORMAL)\n' +
+      '                            --> method = "GET"\n' +
+      '                            --> priority = 4\n' +
+      '                            --> url = "http://www.google.com/"';
 
   return testCase;
 }
@@ -743,13 +562,13 @@
   var testCase = painterTestURLRequestIncomplete();
   testCase.logCreationTime = 1338864634013;
   testCase.expectedText =
-'t=1338864633224 [st=  0] +REQUEST_ALIVE  [dt=789+]\n' +
-'t=1338864633356 [st=132]    URL_REQUEST_START_JOB  [dt=60]\n' +
-'                            --> load_flags = 0 (NORMAL)\n' +
-'                            --> method = "GET"\n' +
-'                            --> priority = 4\n' +
-'                            --> url = "http://www.google.com/"\n' +
-'t=1338864634013 [st=789]';
+      't=1338864633224 [st=  0] +REQUEST_ALIVE  [dt=789+]\n' +
+      't=1338864633356 [st=132]    URL_REQUEST_START_JOB  [dt=60]\n' +
+      '                            --> load_flags = 0 (NORMAL)\n' +
+      '                            --> method = "GET"\n' +
+      '                            --> priority = 4\n' +
+      '                            --> url = "http://www.google.com/"\n' +
+      't=1338864634013 [st=789]';
   return testCase;
 }
 
@@ -762,8 +581,8 @@
   testCase.logEntries = [testCase.logEntries[0]];
   testCase.logCreationTime = 1338864634013;
   testCase.expectedText =
-'t=1338864633224 [st=  0] +REQUEST_ALIVE  [dt=789+]\n' +
-'t=1338864634013 [st=789]';
+      't=1338864633224 [st=  0] +REQUEST_ALIVE  [dt=789+]\n' +
+      't=1338864634013 [st=789]';
   return testCase;
 }
 
@@ -774,16 +593,13 @@
 function painterTestNetError() {
   var testCase = {};
   testCase.tickOffset = '1337911098446';
-  testCase.loadFlags = LoadFlag.MAIN_FRAME_DEPRECATED |
-                       LoadFlag.MAYBE_USER_GESTURE;
+  testCase.loadFlags =
+      LoadFlag.MAIN_FRAME_DEPRECATED | LoadFlag.MAYBE_USER_GESTURE;
 
   testCase.logEntries = [
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675448',
       'type': EventType.REQUEST_ALIVE
     },
@@ -795,19 +611,13 @@
         'url': 'http://www.doesnotexistdomain.com/'
       },
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675455',
       'type': EventType.URL_REQUEST_START_JOB
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675460',
       'type': EventType.URL_REQUEST_START_JOB
     },
@@ -819,158 +629,113 @@
         'url': 'http://www.doesnotexistdomain.com/'
       },
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675460',
       'type': EventType.URL_REQUEST_START_JOB
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675469',
       'type': EventType.HTTP_CACHE_GET_BACKEND
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675469',
       'type': EventType.HTTP_CACHE_GET_BACKEND
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675469',
       'type': EventType.HTTP_CACHE_OPEN_ENTRY
     },
     {
-      'params': {
-        'net_error': -2
-      },
+      'params': {'net_error': -2},
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675470',
       'type': EventType.HTTP_CACHE_OPEN_ENTRY
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675471',
       'type': EventType.HTTP_CACHE_CREATE_ENTRY
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675473',
       'type': EventType.HTTP_CACHE_CREATE_ENTRY
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675473',
       'type': EventType.HTTP_CACHE_ADD_TO_ENTRY
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675474',
       'type': EventType.HTTP_CACHE_ADD_TO_ENTRY
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675474',
       'type': EventType.HTTP_STREAM_REQUEST
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675699',
       'type': EventType.HTTP_STREAM_REQUEST
     },
     {
-      'params': {
-        'net_error': -105
-      },
+      'params': {'net_error': -105},
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675705',
       'type': EventType.URL_REQUEST_START_JOB
     },
     {
-      'params': {
-        'net_error': -105
-      },
+      'params': {'net_error': -105},
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675923',
       'type': EventType.REQUEST_ALIVE
     }
   ];
 
   testCase.expectedText =
-'t=1338864773894 [st=  0] +REQUEST_ALIVE  [dt=475]\n' +
-'t=1338864773901 [st=  7]    URL_REQUEST_START_JOB  [dt=5]\n' +
-'                            --> load_flags = ' +
-        testCase.loadFlags.toString() +
-        ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' +
-'                            --> method = "GET"\n' +
-'                            --> priority = 4\n' +
-'                            --> url = "http://www.doesnotexistdomain.com/"\n' +
-'t=1338864773906 [st= 12]   +URL_REQUEST_START_JOB  [dt=245]\n' +
-'                            --> load_flags = ' +
-        testCase.loadFlags.toString() +
-        ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' +
-'                            --> method = "GET"\n' +
-'                            --> priority = 4\n' +
-'                            --> url = "http://www.doesnotexistdomain.com/"\n' +
-'t=1338864773915 [st= 21]      HTTP_CACHE_GET_BACKEND  [dt=0]\n' +
-'t=1338864773915 [st= 21]      HTTP_CACHE_OPEN_ENTRY  [dt=1]\n' +
-'                              --> net_error = -2 (ERR_FAILED)\n' +
-'t=1338864773917 [st= 23]      HTTP_CACHE_CREATE_ENTRY  [dt=2]\n' +
-'t=1338864773919 [st= 25]      HTTP_CACHE_ADD_TO_ENTRY  [dt=1]\n' +
-'t=1338864773920 [st= 26]      HTTP_STREAM_REQUEST  [dt=225]\n' +
-'t=1338864774151 [st=257]   -URL_REQUEST_START_JOB\n' +
-'                            --> net_error = -105 (ERR_NAME_NOT_RESOLVED)\n' +
-'t=1338864774369 [st=475] -REQUEST_ALIVE\n' +
-'                          --> net_error = -105 (ERR_NAME_NOT_RESOLVED)';
+      't=1338864773894 [st=  0] +REQUEST_ALIVE  [dt=475]\n' +
+      't=1338864773901 [st=  7]    URL_REQUEST_START_JOB  [dt=5]\n' +
+      '                            --> load_flags = ' +
+      testCase.loadFlags.toString() +
+      ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' +
+      '                            --> method = "GET"\n' +
+      '                            --> priority = 4\n' +
+      '                            --> url = "http://www.doesnotexistdomain.com/"\n' +
+      't=1338864773906 [st= 12]   +URL_REQUEST_START_JOB  [dt=245]\n' +
+      '                            --> load_flags = ' +
+      testCase.loadFlags.toString() +
+      ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' +
+      '                            --> method = "GET"\n' +
+      '                            --> priority = 4\n' +
+      '                            --> url = "http://www.doesnotexistdomain.com/"\n' +
+      't=1338864773915 [st= 21]      HTTP_CACHE_GET_BACKEND  [dt=0]\n' +
+      't=1338864773915 [st= 21]      HTTP_CACHE_OPEN_ENTRY  [dt=1]\n' +
+      '                              --> net_error = -2 (ERR_FAILED)\n' +
+      't=1338864773917 [st= 23]      HTTP_CACHE_CREATE_ENTRY  [dt=2]\n' +
+      't=1338864773919 [st= 25]      HTTP_CACHE_ADD_TO_ENTRY  [dt=1]\n' +
+      't=1338864773920 [st= 26]      HTTP_STREAM_REQUEST  [dt=225]\n' +
+      't=1338864774151 [st=257]   -URL_REQUEST_START_JOB\n' +
+      '                            --> net_error = -105 (ERR_NAME_NOT_RESOLVED)\n' +
+      't=1338864774369 [st=475] -REQUEST_ALIVE\n' +
+      '                          --> net_error = -105 (ERR_NAME_NOT_RESOLVED)';
 
   return testCase;
 }
@@ -985,29 +750,21 @@
 
   testCase.logEntries = [
     {
-      'params': {
-        "host": "www.example.com"
-      },
+      'params': {'host': 'www.example.com'},
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675448',
       'type': EventType.QUIC_SESSION
     },
     {
       'params': {
-        'details': "invalid headers",
+        'details': 'invalid headers',
         'quic_rst_stream_error':
             QuicRstStreamError.QUIC_BAD_APPLICATION_PAYLOAD,
         'stream_id': 1
       },
       'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675460',
       'type': EventType.QUIC_SESSION_RST_STREAM_FRAME_RECEIVED
     },
@@ -1016,42 +773,33 @@
         'quic_error': QuicError.QUIC_NETWORK_IDLE_TIMEOUT,
       },
       'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675705',
       'type': EventType.QUIC_SESSION_CONNECTION_CLOSE_FRAME_RECEIVED
     },
     {
-      'params': {
-        'quic_error': QuicError.QUIC_NETWORK_IDLE_TIMEOUT
-      },
+      'params': {'quic_error': QuicError.QUIC_NETWORK_IDLE_TIMEOUT},
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675923',
       'type': EventType.QUIC_SESSION
     }
   ];
 
-  testCase.expectedText =
-'t=1338864773894 [st=  0] +QUIC_SESSION  [dt=475]\n' +
-'                          --> host = "www.example.com"\n' +
-'t=1338864773906 [st= 12]    QUIC_SESSION_RST_STREAM_FRAME_RECEIVED\n' +
-'                            --> details = "invalid headers"\n' +
-'                            --> quic_rst_stream_error = ' +
-        QuicRstStreamError.QUIC_BAD_APPLICATION_PAYLOAD + ' (' +
-        'QUIC_BAD_APPLICATION_PAYLOAD)\n' +
-'                            --> stream_id = 1\n' +
-'t=1338864774151 [st=257]    QUIC_SESSION_CONNECTION_CLOSE_FRAME_RECEIVED\n' +
-'                            --> quic_error = ' +
-        QuicError.QUIC_NETWORK_IDLE_TIMEOUT + ' (QUIC_NETWORK_IDLE_TIMEOUT)\n' +
-'t=1338864774369 [st=475] -QUIC_SESSION\n' +
-'                          --> quic_error = ' +
-        QuicError.QUIC_NETWORK_IDLE_TIMEOUT + ' (QUIC_NETWORK_IDLE_TIMEOUT)';
+  testCase.expectedText = 't=1338864773894 [st=  0] +QUIC_SESSION  [dt=475]\n' +
+      '                          --> host = "www.example.com"\n' +
+      't=1338864773906 [st= 12]    QUIC_SESSION_RST_STREAM_FRAME_RECEIVED\n' +
+      '                            --> details = "invalid headers"\n' +
+      '                            --> quic_rst_stream_error = ' +
+      QuicRstStreamError.QUIC_BAD_APPLICATION_PAYLOAD + ' (' +
+      'QUIC_BAD_APPLICATION_PAYLOAD)\n' +
+      '                            --> stream_id = 1\n' +
+      't=1338864774151 [st=257]    QUIC_SESSION_CONNECTION_CLOSE_FRAME_RECEIVED\n' +
+      '                            --> quic_error = ' +
+      QuicError.QUIC_NETWORK_IDLE_TIMEOUT + ' (QUIC_NETWORK_IDLE_TIMEOUT)\n' +
+      't=1338864774369 [st=475] -QUIC_SESSION\n' +
+      '                          --> quic_error = ' +
+      QuicError.QUIC_NETWORK_IDLE_TIMEOUT + ' (QUIC_NETWORK_IDLE_TIMEOUT)';
 
   return testCase;
 }
@@ -1065,77 +813,64 @@
 
   testCase.logEntries = [
     {
-      'params': {
-        "host": "www.example.com"
-      },
+      'params': {'host': 'www.example.com'},
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675448',
       'type': EventType.QUIC_SESSION
     },
     {
       'params': {
-        'quic_crypto_handshake_message':
-            "REJ <\n" +
-            "  STK : 4FDE\n" +
-            "  SNO : A228\n" +
-            "  PROF: 3045\n" +
-            "  SCFG:\n" +
-            "    SCFG<\n" +
-            "      AEAD: AESG\n" +
-            "      SCID: FED7\n" +
-            "      PDMD: CHID\n" +
-            "      PUBS: 2000\n" +
-            "      VERS: 0000\n" +
-            "      KEXS: C255,P256\n" +
-            "      OBIT: 7883764781F2DFD0\n" +
-            "      EXPY: FFEE725200000000\n" +
-            "    >\n" +
-            "  >"
+        'quic_crypto_handshake_message': 'REJ <\n' +
+            '  STK : 4FDE\n' +
+            '  SNO : A228\n' +
+            '  PROF: 3045\n' +
+            '  SCFG:\n' +
+            '    SCFG<\n' +
+            '      AEAD: AESG\n' +
+            '      SCID: FED7\n' +
+            '      PDMD: CHID\n' +
+            '      PUBS: 2000\n' +
+            '      VERS: 0000\n' +
+            '      KEXS: C255,P256\n' +
+            '      OBIT: 7883764781F2DFD0\n' +
+            '      EXPY: FFEE725200000000\n' +
+            '    >\n' +
+            '  >'
       },
       'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675460',
       'type': EventType.QUIC_SESSION_CRYPTO_HANDSHAKE_MESSAGE_SENT
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675923',
       'type': EventType.QUIC_SESSION
     }
   ];
 
-  testCase.expectedText =
-'t=1338864773894 [st=  0] +QUIC_SESSION  [dt=475]\n' +
-'                          --> host = "www.example.com"\n' +
-'t=1338864773906 [st= 12]    QUIC_SESSION_CRYPTO_HANDSHAKE_MESSAGE_SENT\n' +
-'                            --> REJ <\n' +
-'                                  STK : 4FDE\n' +
-'                                  SNO : A228\n' +
-'                                  PROF: 3045\n' +
-'                                  SCFG:\n' +
-'                                    SCFG<\n' +
-'                                      AEAD: AESG\n' +
-'                                      SCID: FED7\n' +
-'                                      PDMD: CHID\n' +
-'                                      PUBS: 2000\n' +
-'                                      VERS: 0000\n' +
-'                                      KEXS: C255,P256\n' +
-'                                      OBIT: 7883764781F2DFD0\n' +
-'                                      EXPY: FFEE725200000000\n' +
-'                                    >\n' +
-'                                  >\n' +
-'t=1338864774369 [st=475] -QUIC_SESSION';
+  testCase.expectedText = 't=1338864773894 [st=  0] +QUIC_SESSION  [dt=475]\n' +
+      '                          --> host = "www.example.com"\n' +
+      't=1338864773906 [st= 12]    QUIC_SESSION_CRYPTO_HANDSHAKE_MESSAGE_SENT\n' +
+      '                            --> REJ <\n' +
+      '                                  STK : 4FDE\n' +
+      '                                  SNO : A228\n' +
+      '                                  PROF: 3045\n' +
+      '                                  SCFG:\n' +
+      '                                    SCFG<\n' +
+      '                                      AEAD: AESG\n' +
+      '                                      SCID: FED7\n' +
+      '                                      PDMD: CHID\n' +
+      '                                      PUBS: 2000\n' +
+      '                                      VERS: 0000\n' +
+      '                                      KEXS: C255,P256\n' +
+      '                                      OBIT: 7883764781F2DFD0\n' +
+      '                                      EXPY: FFEE725200000000\n' +
+      '                                    >\n' +
+      '                                  >\n' +
+      't=1338864774369 [st=475] -QUIC_SESSION';
 
   return testCase;
 }
@@ -1152,78 +887,48 @@
   testCase.logEntries = [
     {
       'params': {
-        'source_dependency': {
-          'id': 634,
-          'type': EventSourceType.TRANSPORT_CONNECT_JOB
-        }
+        'source_dependency':
+            {'id': 634, 'type': EventSourceType.TRANSPORT_CONNECT_JOB}
       },
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 637,
-        'type': EventSourceType.SOCKET
-      },
+      'source': {'id': 637, 'type': EventSourceType.SOCKET},
       'time': '953918459',
       'type': EventType.SOCKET_ALIVE
     },
     {
-      'params': {
-        'address_list': [
-          '184.30.253.15:80'
-        ]
-      },
+      'params': {'address_list': ['184.30.253.15:80']},
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 637,
-        'type': EventSourceType.SOCKET
-      },
+      'source': {'id': 637, 'type': EventSourceType.SOCKET},
       'time': '953918460',
       'type': EventType.TCP_CONNECT
     },
     {
-      'params': {
-        'address': '184.30.253.15:80'
-      },
+      'params': {'address': '184.30.253.15:80'},
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 637,
-        'type': EventSourceType.SOCKET
-      },
+      'source': {'id': 637, 'type': EventSourceType.SOCKET},
       'time': '953918461',
       'type': EventType.TCP_CONNECT_ATTEMPT
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 637,
-        'type': EventSourceType.SOCKET
-      },
+      'source': {'id': 637, 'type': EventSourceType.SOCKET},
       'time': '953918464',
       'type': EventType.TCP_CONNECT_ATTEMPT
     },
     {
-      'params': {
-        'source_address': '127.0.0.1:54041'
-      },
+      'params': {'source_address': '127.0.0.1:54041'},
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 637,
-        'type': EventSourceType.SOCKET
-      },
+      'source': {'id': 637, 'type': EventSourceType.SOCKET},
       'time': '953918465',
       'type': EventType.TCP_CONNECT
     },
     {
       'params': {
-        'source_dependency': {
-          'id': 628,
-          'type': EventSourceType.HTTP_STREAM_JOB
-        }
+        'source_dependency':
+            {'id': 628, 'type': EventSourceType.HTTP_STREAM_JOB}
       },
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 637,
-        'type': EventSourceType.SOCKET
-      },
+      'source': {'id': 637, 'type': EventSourceType.SOCKET},
       'time': '953918472',
       'type': EventType.SOCKET_IN_USE
     },
@@ -1231,14 +936,11 @@
       'params': {
         'byte_count': 780,
         'hex_encoded_bytes': '474554202F66617669636F6E2E69636F20485454502' +
-                             'F312E310D0A486F73743A207777772E6170706C652E' +
-                             '636F6D0D0A436F6E6E656374696F6E3A20'
+            'F312E310D0A486F73743A207777772E6170706C652E' +
+            '636F6D0D0A436F6E6E656374696F6E3A20'
       },
       'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 637,
-        'type': EventSourceType.SOCKET
-      },
+      'source': {'id': 637, 'type': EventSourceType.SOCKET},
       'time': '953918484',
       'type': EventType.SOCKET_BYTES_SENT
     },
@@ -1246,53 +948,49 @@
       'params': {
         'byte_count': 1024,
         'hex_encoded_bytes': '485454502F312E3120323030204F4B0D0A4C6173742' +
-                             'D4D6F6469666965643A204D6F6E2C20313920446563' +
-                             '20323031312032323A34363A353920474D'
+            'D4D6F6469666965643A204D6F6E2C20313920446563' +
+            '20323031312032323A34363A353920474D'
       },
       'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 637,
-        'type': EventSourceType.SOCKET
-      },
+      'source': {'id': 637, 'type': EventSourceType.SOCKET},
       'time': '953918596',
       'type': EventType.SOCKET_BYTES_RECEIVED
     }
   ];
 
-  testCase.expectedText =
-'t=1338865016932 [st=  0] +SOCKET_ALIVE  [dt=?]\n' +
-'                          --> source_dependency = 634 (TRANSPORT_CONNECT_JOB' +
-    ')\n' +
-'t=1338865016933 [st=  1]   +TCP_CONNECT  [dt=5]\n' +
-'                            --> address_list = ["184.30.253.15:80"]\n' +
-'t=1338865016934 [st=  2]      TCP_CONNECT_ATTEMPT  [dt=3]\n' +
-'                              --> address = "184.30.253.15:80"\n' +
-'t=1338865016938 [st=  6]   -TCP_CONNECT\n' +
-'                            --> source_address = "127.0.0.1:54041"\n' +
-'t=1338865016945 [st= 13]   +SOCKET_IN_USE  [dt=?]\n' +
-'                            --> source_dependency = 628 (HTTP_STREAM_JOB)\n' +
-'t=1338865016957 [st= 25]      SOCKET_BYTES_SENT\n' +
-'                              --> byte_count = 780\n' +
-'                              --> hex_encoded_bytes =\n' +
-'                                47 45 54 20 2F 66 61 76  69 63 6F 6E 2E 69 ' +
-    '63 6F   GET /favicon.ico\n' +
-'                                20 48 54 54 50 2F 31 2E  31 0D 0A 48 6F 73 ' +
-    '74 3A    HTTP/1.1..Host:\n' +
-'                                20 77 77 77 2E 61 70 70  6C 65 2E 63 6F 6D ' +
-    '0D 0A    www.apple.com..\n' +
-'                                43 6F 6E 6E 65 63 74 69  6F 6E 3A 20       ' +
-    '        Connection: \n' +
-'t=1338865017069 [st=137]      SOCKET_BYTES_RECEIVED\n' +
-'                              --> byte_count = 1024\n' +
-'                              --> hex_encoded_bytes =\n' +
-'                                48 54 54 50 2F 31 2E 31  20 32 30 30 20 4F ' +
-    '4B 0D   HTTP/1.1 200 OK.\n' +
-'                                0A 4C 61 73 74 2D 4D 6F  64 69 66 69 65 64 ' +
-    '3A 20   .Last-Modified: \n' +
-'                                4D 6F 6E 2C 20 31 39 20  44 65 63 20 32 30 ' +
-    '31 31   Mon, 19 Dec 2011\n' +
-'                                20 32 32 3A 34 36 3A 35  39 20 47 4D       ' +
-    '         22:46:59 GM';
+  testCase.expectedText = 't=1338865016932 [st=  0] +SOCKET_ALIVE  [dt=?]\n' +
+      '                          --> source_dependency = 634 (TRANSPORT_CONNECT_JOB' +
+      ')\n' +
+      't=1338865016933 [st=  1]   +TCP_CONNECT  [dt=5]\n' +
+      '                            --> address_list = ["184.30.253.15:80"]\n' +
+      't=1338865016934 [st=  2]      TCP_CONNECT_ATTEMPT  [dt=3]\n' +
+      '                              --> address = "184.30.253.15:80"\n' +
+      't=1338865016938 [st=  6]   -TCP_CONNECT\n' +
+      '                            --> source_address = "127.0.0.1:54041"\n' +
+      't=1338865016945 [st= 13]   +SOCKET_IN_USE  [dt=?]\n' +
+      '                            --> source_dependency = 628 (HTTP_STREAM_JOB)\n' +
+      't=1338865016957 [st= 25]      SOCKET_BYTES_SENT\n' +
+      '                              --> byte_count = 780\n' +
+      '                              --> hex_encoded_bytes =\n' +
+      '                                47 45 54 20 2F 66 61 76  69 63 6F 6E 2E 69 ' +
+      '63 6F   GET /favicon.ico\n' +
+      '                                20 48 54 54 50 2F 31 2E  31 0D 0A 48 6F 73 ' +
+      '74 3A    HTTP/1.1..Host:\n' +
+      '                                20 77 77 77 2E 61 70 70  6C 65 2E 63 6F 6D ' +
+      '0D 0A    www.apple.com..\n' +
+      '                                43 6F 6E 6E 65 63 74 69  6F 6E 3A 20       ' +
+      '        Connection: \n' +
+      't=1338865017069 [st=137]      SOCKET_BYTES_RECEIVED\n' +
+      '                              --> byte_count = 1024\n' +
+      '                              --> hex_encoded_bytes =\n' +
+      '                                48 54 54 50 2F 31 2E 31  20 32 30 30 20 4F ' +
+      '4B 0D   HTTP/1.1 200 OK.\n' +
+      '                                0A 4C 61 73 74 2D 4D 6F  64 69 66 69 65 64 ' +
+      '3A 20   .Last-Modified: \n' +
+      '                                4D 6F 6E 2C 20 31 39 20  44 65 63 20 32 30 ' +
+      '31 31   Mon, 19 Dec 2011\n' +
+      '                                20 32 32 3A 34 36 3A 35  39 20 47 4D       ' +
+      '         22:46:59 GM';
 
   return testCase;
 }
@@ -1313,36 +1011,29 @@
         ]
       },
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 752,
-        'type': EventSourceType.CERT_VERIFIER_JOB
-      },
+      'source': {'id': 752, 'type': EventSourceType.CERT_VERIFIER_JOB},
       'time': '954124663',
       'type': EventType.CERT_VERIFIER_JOB
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 752,
-        'type': EventSourceType.CERT_VERIFIER_JOB
-      },
+      'source': {'id': 752, 'type': EventSourceType.CERT_VERIFIER_JOB},
       'time': '954124697',
       'type': EventType.CERT_VERIFIER_JOB
     }
   ];
 
   testCase.expectedText =
-    't=1338865223144 [st=0]  CERT_VERIFIER_JOB  [dt=34]\n' +
-    '                        --> certificates =\n' +
-    '                               -----BEGIN CERTIFICATE-----\n' +
-    '                               1\n' +
-    '                               -----END CERTIFICATE-----\n' +
-    '                               \n' +
-    '                               -----BEGIN CERTIFICATE-----\n' +
-    '                               2\n' +
-    '                               -----END CERTIFICATE-----';
+      't=1338865223144 [st=0]  CERT_VERIFIER_JOB  [dt=34]\n' +
+      '                        --> certificates =\n' +
+      '                               -----BEGIN CERTIFICATE-----\n' +
+      '                               1\n' +
+      '                               -----END CERTIFICATE-----\n' +
+      '                               \n' +
+      '                               -----BEGIN CERTIFICATE-----\n' +
+      '                               2\n' +
+      '                               -----END CERTIFICATE-----';
   return testCase;
-
 }
 
 /**
@@ -1361,10 +1052,7 @@
         ]
       },
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 752,
-        'type': EventSourceType.CERT_VERIFIER_JOB
-      },
+      'source': {'id': 752, 'type': EventSourceType.CERT_VERIFIER_JOB},
       'time': '954124663',
       'type': EventType.CERT_VERIFIER_JOB
     },
@@ -1378,8 +1066,8 @@
         'cert_status': 5,
         'verified_cert': {
           'certificates': [
-          '-----BEGIN CERTIFICATE-----\n1\n-----END CERTIFICATE-----\n',
-          '-----BEGIN CERTIFICATE-----\n2\n-----END CERTIFICATE-----\n',
+            '-----BEGIN CERTIFICATE-----\n1\n-----END CERTIFICATE-----\n',
+            '-----BEGIN CERTIFICATE-----\n2\n-----END CERTIFICATE-----\n',
           ]
         },
         'public_key_hashes': [
@@ -1388,45 +1076,42 @@
         ]
       },
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 752,
-        'type': EventSourceType.CERT_VERIFIER_JOB
-      },
+      'source': {'id': 752, 'type': EventSourceType.CERT_VERIFIER_JOB},
       'time': '954124697',
       'type': EventType.CERT_VERIFIER_JOB
     }
   ];
 
   testCase.expectedText =
-    't=1338865223144 [st= 0] +CERT_VERIFIER_JOB  [dt=34]\n' +
-    '                         --> certificates =\n' +
-    '                                -----BEGIN CERTIFICATE-----\n' +
-    '                                1\n' +
-    '                                -----END CERTIFICATE-----\n' +
-    '                                \n' +
-    '                                -----BEGIN CERTIFICATE-----\n' +
-    '                                2\n' +
-    '                                -----END CERTIFICATE-----\n' +
-    '                                \n' +
-    't=1338865223178 [st=34] -CERT_VERIFIER_JOB\n' +
-    '                         --> verified_cert =\n' +
-    '                                -----BEGIN CERTIFICATE-----\n' +
-    '                                1\n' +
-    '                                -----END CERTIFICATE-----\n' +
-    '                                \n' +
-    '                                -----BEGIN CERTIFICATE-----\n' +
-    '                                2\n' +
-    '                                -----END CERTIFICATE-----\n' +
-    '                                \n' +
-    '                         --> cert_status = 5 (AUTHORITY_INVALID |' +
-    ' COMMON_NAME_INVALID)\n' +
-    '                         --> has_md5 = true\n' +
-    '                         --> has_md2 = false\n' +
-    '                         --> has_md4 = true\n' +
-    '                         --> is_issued_by_known_root = true\n' +
-    '                         --> is_issued_by_additional_trust_anchor =' +
-    ' false\n' +
-    '                         --> public_key_hashes = ["hash1","hash2"]';
+      't=1338865223144 [st= 0] +CERT_VERIFIER_JOB  [dt=34]\n' +
+      '                         --> certificates =\n' +
+      '                                -----BEGIN CERTIFICATE-----\n' +
+      '                                1\n' +
+      '                                -----END CERTIFICATE-----\n' +
+      '                                \n' +
+      '                                -----BEGIN CERTIFICATE-----\n' +
+      '                                2\n' +
+      '                                -----END CERTIFICATE-----\n' +
+      '                                \n' +
+      't=1338865223178 [st=34] -CERT_VERIFIER_JOB\n' +
+      '                         --> verified_cert =\n' +
+      '                                -----BEGIN CERTIFICATE-----\n' +
+      '                                1\n' +
+      '                                -----END CERTIFICATE-----\n' +
+      '                                \n' +
+      '                                -----BEGIN CERTIFICATE-----\n' +
+      '                                2\n' +
+      '                                -----END CERTIFICATE-----\n' +
+      '                                \n' +
+      '                         --> cert_status = 5 (AUTHORITY_INVALID |' +
+      ' COMMON_NAME_INVALID)\n' +
+      '                         --> has_md5 = true\n' +
+      '                         --> has_md2 = false\n' +
+      '                         --> has_md4 = true\n' +
+      '                         --> is_issued_by_known_root = true\n' +
+      '                         --> is_issued_by_additional_trust_anchor =' +
+      ' false\n' +
+      '                         --> public_key_hashes = ["hash1","hash2"]';
 
   return testCase;
 }
@@ -1438,36 +1123,31 @@
   var testCase = {};
   testCase.tickOffset = '1337911098481';
 
-  testCase.logEntries = [
-    {
-      'params': {
-        'certificate': {
-          'certificates': [
-            '-----BEGIN CERTIFICATE-----\n1\n-----END CERTIFICATE-----\n',
-            '-----BEGIN CERTIFICATE-----\n2\n-----END CERTIFICATE-----\n'
-          ]
-        }
-      },
-      'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 752,
-        'type': EventSourceType.SOCKET
-      },
-      'time': '954124697',
-      'type': EventType.CERT_CT_COMPLIANCE_CHECKED
-    }
-  ];
+  testCase.logEntries = [{
+    'params': {
+      'certificate': {
+        'certificates': [
+          '-----BEGIN CERTIFICATE-----\n1\n-----END CERTIFICATE-----\n',
+          '-----BEGIN CERTIFICATE-----\n2\n-----END CERTIFICATE-----\n'
+        ]
+      }
+    },
+    'phase': EventPhase.PHASE_NONE,
+    'source': {'id': 752, 'type': EventSourceType.SOCKET},
+    'time': '954124697',
+    'type': EventType.CERT_CT_COMPLIANCE_CHECKED
+  }];
 
   testCase.expectedText =
-  't=1338865223178 [st=0]  CERT_CT_COMPLIANCE_CHECKED\n' +
-  '                        --> certificate =\n' +
-  '                               -----BEGIN CERTIFICATE-----\n' +
-  '                               1\n' +
-  '                               -----END CERTIFICATE-----\n' +
-  '                               \n' +
-  '                               -----BEGIN CERTIFICATE-----\n' +
-  '                               2\n' +
-  '                               -----END CERTIFICATE-----';
+      't=1338865223178 [st=0]  CERT_CT_COMPLIANCE_CHECKED\n' +
+      '                        --> certificate =\n' +
+      '                               -----BEGIN CERTIFICATE-----\n' +
+      '                               1\n' +
+      '                               -----END CERTIFICATE-----\n' +
+      '                               \n' +
+      '                               -----BEGIN CERTIFICATE-----\n' +
+      '                               2\n' +
+      '                               -----END CERTIFICATE-----';
 
   return testCase;
 }
@@ -1480,47 +1160,35 @@
   var testCase = {};
   testCase.tickOffset = '1337911098481';
 
-  testCase.logEntries = [
-    {
-      'params': {
-        'new_config': {
-          'auto_detect': true,
-          'bypass_list': [
-            '*.local',
-            'foo',
-            '<local>'
-          ],
-          'pac_url': 'https://config/wpad.dat',
-          'single_proxy': 'cache-proxy:3128',
-          'source': 'SYSTEM'
-        },
-        'old_config': {
-          'auto_detect': true
-        }
+  testCase.logEntries = [{
+    'params': {
+      'new_config': {
+        'auto_detect': true,
+        'bypass_list': ['*.local', 'foo', '<local>'],
+        'pac_url': 'https://config/wpad.dat',
+        'single_proxy': 'cache-proxy:3128',
+        'source': 'SYSTEM'
       },
-      'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 814,
-        'type': EventSourceType.NONE
-      },
-      'time': '954443578',
-      'type': EventType.PROXY_CONFIG_CHANGED
-    }
-  ];
+      'old_config': {'auto_detect': true}
+    },
+    'phase': EventPhase.PHASE_NONE,
+    'source': {'id': 814, 'type': EventSourceType.NONE},
+    'time': '954443578',
+    'type': EventType.PROXY_CONFIG_CHANGED
+  }];
 
-  testCase.expectedText =
-    't=1338865542059 [st=0]  PROXY_CONFIG_CHANGED\n' +
-    '                        --> old_config =\n' +
-    '                               Auto-detect\n' +
-    '                        --> new_config =\n' +
-    '                               (1) Auto-detect\n' +
-    '                               (2) PAC script: https://config/wpad.dat\n' +
-    '                               (3) Proxy server: cache-proxy:3128\n' +
-    '                                   Bypass list: \n' +
-    '                                     *.local\n' +
-    '                                     foo\n' +
-    '                                     <local>\n' +
-    '                               Source: SYSTEM';
+  testCase.expectedText = 't=1338865542059 [st=0]  PROXY_CONFIG_CHANGED\n' +
+      '                        --> old_config =\n' +
+      '                               Auto-detect\n' +
+      '                        --> new_config =\n' +
+      '                               (1) Auto-detect\n' +
+      '                               (2) PAC script: https://config/wpad.dat\n' +
+      '                               (3) Proxy server: cache-proxy:3128\n' +
+      '                                   Bypass list: \n' +
+      '                                     *.local\n' +
+      '                                     foo\n' +
+      '                                     <local>\n' +
+      '                               Source: SYSTEM';
 
   return testCase;
 }
@@ -1533,48 +1201,36 @@
   var testCase = {};
   testCase.tickOffset = '1337911098481';
 
-  testCase.logEntries = [
-    {
-      'params': {
-        'new_config': {
-          'auto_detect': true,
-          'bypass_list': [
-            '*.local',
-            'foo',
-            '<local>'
-          ],
-          'pac_url': 'https://config/wpad.dat',
-          'single_proxy': ['cache-proxy:3128', 'socks4://other:999'],
-          'source': 'SYSTEM'
-        },
-        'old_config': {
-          'auto_detect': true
-        }
+  testCase.logEntries = [{
+    'params': {
+      'new_config': {
+        'auto_detect': true,
+        'bypass_list': ['*.local', 'foo', '<local>'],
+        'pac_url': 'https://config/wpad.dat',
+        'single_proxy': ['cache-proxy:3128', 'socks4://other:999'],
+        'source': 'SYSTEM'
       },
-      'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 814,
-        'type': EventSourceType.NONE
-      },
-      'time': '954443578',
-      'type': EventType.PROXY_CONFIG_CHANGED
-    }
-  ];
+      'old_config': {'auto_detect': true}
+    },
+    'phase': EventPhase.PHASE_NONE,
+    'source': {'id': 814, 'type': EventSourceType.NONE},
+    'time': '954443578',
+    'type': EventType.PROXY_CONFIG_CHANGED
+  }];
 
-  testCase.expectedText =
-    't=1338865542059 [st=0]  PROXY_CONFIG_CHANGED\n' +
-    '                        --> old_config =\n' +
-    '                               Auto-detect\n' +
-    '                        --> new_config =\n' +
-    '                               (1) Auto-detect\n' +
-    '                               (2) PAC script: https://config/wpad.dat\n' +
-    '                               (3) Proxy server: [cache-proxy:3128, ' +
-        'socks4://other:999]\n' +
-    '                                   Bypass list: \n' +
-    '                                     *.local\n' +
-    '                                     foo\n' +
-    '                                     <local>\n' +
-    '                               Source: SYSTEM';
+  testCase.expectedText = 't=1338865542059 [st=0]  PROXY_CONFIG_CHANGED\n' +
+      '                        --> old_config =\n' +
+      '                               Auto-detect\n' +
+      '                        --> new_config =\n' +
+      '                               (1) Auto-detect\n' +
+      '                               (2) PAC script: https://config/wpad.dat\n' +
+      '                               (3) Proxy server: [cache-proxy:3128, ' +
+      'socks4://other:999]\n' +
+      '                                   Bypass list: \n' +
+      '                                     *.local\n' +
+      '                                     foo\n' +
+      '                                     <local>\n' +
+      '                               Source: SYSTEM';
 
   return testCase;
 }
@@ -1590,30 +1246,24 @@
   testCase.logEntries = [
     {
       'params': {
-        'headers': [
-          'Host: www.google.com',
-          'Connection: keep-alive'
-        ],
+        'headers': ['Host: www.google.com', 'Connection: keep-alive'],
         'line': 'GET / HTTP/1.1\r\n',
         // This is unexpected!
         'hello': 'yo dawg, i heard you like strings'
       },
       'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534910',
       'type': EventType.HTTP_TRANSACTION_SEND_REQUEST_HEADERS
     },
   ];
 
   testCase.expectedText =
-    't=1338864633356 [st=0]  HTTP_TRANSACTION_SEND_REQUEST_HEADERS\n' +
-    '                        --> GET / HTTP/1.1\n' +
-    '                            Host: www.google.com\n' +
-    '                            Connection: keep-alive\n' +
-    '                        --> hello = "yo dawg, i heard you like strings"';
+      't=1338864633356 [st=0]  HTTP_TRANSACTION_SEND_REQUEST_HEADERS\n' +
+      '                        --> GET / HTTP/1.1\n' +
+      '                            Host: www.google.com\n' +
+      '                            Connection: keep-alive\n' +
+      '                        --> hello = "yo dawg, i heard you like strings"';
 
   return testCase;
 }
@@ -1630,27 +1280,21 @@
     {
       'params': {
         // The expectation is for this to be called "headers".
-        'headersWRONG': [
-          'Host: www.google.com',
-          'Connection: keep-alive'
-        ],
+        'headersWRONG': ['Host: www.google.com', 'Connection: keep-alive'],
         'line': 'GET / HTTP/1.1\r\n'
       },
       'phase': EventPhase.PHASE_NONE,
-      'source': {
-        'id': 146,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 146, 'type': EventSourceType.URL_REQUEST},
       'time': '953534910',
       'type': EventType.HTTP_TRANSACTION_SEND_REQUEST_HEADERS
     },
   ];
 
   testCase.expectedText =
-'t=1338864633356 [st=0]  HTTP_TRANSACTION_SEND_REQUEST_HEADERS\n' +
-'                        --> headersWRONG = ["Host: www.google.com",' +
-    '"Connection: keep-alive"]\n' +
-'                        --> line = "GET / HTTP/1.1\\r\\n"';
+      't=1338864633356 [st=0]  HTTP_TRANSACTION_SEND_REQUEST_HEADERS\n' +
+      '                        --> headersWRONG = ["Host: www.google.com",' +
+      '"Connection: keep-alive"]\n' +
+      '                        --> line = "GET / HTTP/1.1\\r\\n"';
 
   return testCase;
 }
@@ -1662,8 +1306,8 @@
 function painterTestInProgressURLRequest() {
   var testCase = {};
   testCase.tickOffset = '1337911098446';
-  testCase.loadFlags = LoadFlag.MAIN_FRAME_DEPRECATED |
-                       LoadFlag.MAYBE_USER_GESTURE;
+  testCase.loadFlags =
+      LoadFlag.MAIN_FRAME_DEPRECATED | LoadFlag.MAYBE_USER_GESTURE;
 
   testCase.logEntries = [
     {
@@ -1674,62 +1318,50 @@
         'url': 'http://www.MagicPonyShopper.com'
       },
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675548',
       'type': EventType.REQUEST_ALIVE
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675699',
       'type': EventType.HTTP_STREAM_REQUEST
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675705',
       'type': EventType.URL_REQUEST_START_JOB
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675923',
       'type': EventType.REQUEST_ALIVE
     }
   ];
 
   testCase.expectedText =
-'t=1338864773994 [st=  0] +REQUEST_ALIVE  [dt=375]\n' +
-'                          --> load_flags = ' +
-    testCase.loadFlags.toString() +
-    ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' +
-'                          --> load_state = ' + LoadState.READING_RESPONSE +
-    ' (READING_RESPONSE)\n' +
-'                          --> method = "GET"\n' +
-'                          --> url = "http://www.MagicPonyShopper.com"\n' +
-'t=1338864774145 [st=151]   -HTTP_STREAM_REQUEST\n' +
-'t=1338864774151 [st=157]   -URL_REQUEST_START_JOB\n' +
-'t=1338864774369 [st=375] -REQUEST_ALIVE';
+      't=1338864773994 [st=  0] +REQUEST_ALIVE  [dt=375]\n' +
+      '                          --> load_flags = ' +
+      testCase.loadFlags.toString() +
+      ' (MAIN_FRAME_DEPRECATED | MAYBE_USER_GESTURE)\n' +
+      '                          --> load_state = ' +
+      LoadState.READING_RESPONSE + ' (READING_RESPONSE)\n' +
+      '                          --> method = "GET"\n' +
+      '                          --> url = "http://www.MagicPonyShopper.com"\n' +
+      't=1338864774145 [st=151]   -HTTP_STREAM_REQUEST\n' +
+      't=1338864774151 [st=157]   -URL_REQUEST_START_JOB\n' +
+      't=1338864774369 [st=375] -REQUEST_ALIVE';
 
   return testCase;
 }
 
 /**
-  * Tests the formatting using a non-zero base time.  Also has no final event,
-  * to make sure logCreationTime is handled correctly.
-  */
+ * Tests the formatting using a non-zero base time.  Also has no final event,
+ * to make sure logCreationTime is handled correctly.
+ */
 function painterTestBaseTime() {
   var testCase = {};
   testCase.tickOffset = '1337911098446';
@@ -1739,37 +1371,27 @@
   testCase.logEntries = [
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675548',
       'type': EventType.REQUEST_ALIVE
     },
     {
       'phase': EventPhase.PHASE_BEGIN,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675698',
       'type': EventType.HTTP_STREAM_REQUEST
     },
     {
       'phase': EventPhase.PHASE_END,
-      'source': {
-        'id': 318,
-        'type': EventSourceType.URL_REQUEST
-      },
+      'source': {'id': 318, 'type': EventSourceType.URL_REQUEST},
       'time': '953675699',
       'type': EventType.HTTP_STREAM_REQUEST
     },
   ];
 
-  testCase.expectedText =
-'t=  2 [st=  0] +REQUEST_ALIVE  [dt=789+]\n' +
-'t=152 [st=150]    HTTP_STREAM_REQUEST  [dt=1]\n' +
-'t=791 [st=789]';
+  testCase.expectedText = 't=  2 [st=  0] +REQUEST_ALIVE  [dt=789+]\n' +
+      't=152 [st=150]    HTTP_STREAM_REQUEST  [dt=1]\n' +
+      't=791 [st=789]';
 
   return testCase;
 }
diff --git a/chrome/test/data/webui/net_internals/net_internals_test.js b/chrome/test/data/webui/net_internals/net_internals_test.js
index 72eb860..e2d8e13d 100644
--- a/chrome/test/data/webui/net_internals/net_internals_test.js
+++ b/chrome/test/data/webui/net_internals/net_internals_test.js
@@ -87,20 +87,16 @@
       // Enable when failure is resolved.
       // AX_TEXT_01: http://crbug.com/559203
       this.accessibilityAuditConfig.ignoreSelectors(
-          'controlsWithoutLabel',
-          controlsWithoutLabelSelectors);
+          'controlsWithoutLabel', controlsWithoutLabelSelectors);
 
       // Enable when warning is resolved.
       // AX_HTML_01: http://crbug.com/559204
-      this.accessibilityAuditConfig.ignoreSelectors(
-          'humanLangMissing',
-          'html');
+      this.accessibilityAuditConfig.ignoreSelectors('humanLangMissing', 'html');
 
       // Wrap g_browser.receive around a test function so that assert and expect
       // functions can be called from observers.
-      g_browser.receive =
-          this.continueTest(WhenTestDone.EXPECT,
-                            BrowserBridge.prototype.receive.bind(g_browser));
+      g_browser.receive = this.continueTest(
+          WhenTestDone.EXPECT, BrowserBridge.prototype.receive.bind(g_browser));
 
       g_browser.setPollInterval(TESTING_POLL_INTERVAL_MS);
 
@@ -210,9 +206,9 @@
    * @param {number} expectedRows Expected number of rows in the table.
    */
   NetInternalsTest.checkTbodyRows = function(ancestorId, expectedRows) {
-    expectEquals(expectedRows,
-                 NetInternalsTest.getTbodyNumRows(ancestorId),
-                 'Incorrect number of rows in ' + ancestorId);
+    expectEquals(
+        expectedRows, NetInternalsTest.getTbodyNumRows(ancestorId),
+        'Incorrect number of rows in ' + ancestorId);
   };
 
   /**
@@ -318,11 +314,12 @@
       chromeos: CrosView.TAB_ID
     };
 
-    assertEquals(typeof hashToTabIdMap[hash], 'string',
-                 'Invalid tab anchor: ' + hash);
+    assertEquals(
+        typeof hashToTabIdMap[hash], 'string', 'Invalid tab anchor: ' + hash);
     var tabId = hashToTabIdMap[hash];
-    assertEquals('object', typeof NetInternalsTest.getTab(tabId),
-                 'Invalid tab: ' + tabId);
+    assertEquals(
+        'object', typeof NetInternalsTest.getTab(tabId),
+        'Invalid tab: ' + tabId);
     return tabId;
   };
 
@@ -334,14 +331,16 @@
     var tabId = NetInternalsTest.getTabId(hash);
 
     // Make sure the tab link is visible, as we only simulate normal usage.
-    expectTrue(NetInternalsTest.tabLinkIsVisible(tabId),
-               tabId + ' does not have a visible tab link.');
+    expectTrue(
+        NetInternalsTest.tabLinkIsVisible(tabId),
+        tabId + ' does not have a visible tab link.');
     var tabLinkNode = NetInternalsTest.getTab(tabId).tabLink;
 
     // Simulate a left click on the link.
     var mouseEvent = document.createEvent('MouseEvents');
-    mouseEvent.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false,
-                              false, false, false, 0, null);
+    mouseEvent.initMouseEvent(
+        'click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false,
+        0, null);
     tabLinkNode.dispatchEvent(mouseEvent);
 
     // Make sure the hash changed.
@@ -355,9 +354,9 @@
     var tabSwitcher = MainView.getInstance().tabSwitcher();
     var tabIdToView = tabSwitcher.getAllTabViews();
     for (var curTabId in tabIdToView) {
-      expectEquals(curTabId == tabId,
-                   tabSwitcher.getTabView(curTabId).isVisible(),
-                   curTabId + ': Unexpected visibility state.');
+      expectEquals(
+          curTabId == tabId, tabSwitcher.getTabView(curTabId).isVisible(),
+          curTabId + ': Unexpected visibility state.');
     }
   };
 
@@ -369,21 +368,22 @@
    * @param {bool+}: tourTabs True if tabs expected to be visible should should
    *     each be navigated to as well.
    */
-  NetInternalsTest.checkTabLinkVisibility = function(tabVisibilityState,
-                                                     tourTabs) {
+  NetInternalsTest.checkTabLinkVisibility = function(
+      tabVisibilityState, tourTabs) {
     // The currently active tab should have a link that is visible.
-    expectTrue(NetInternalsTest.tabLinkIsVisible(
-                   NetInternalsTest.getActiveTabId()));
+    expectTrue(
+        NetInternalsTest.tabLinkIsVisible(NetInternalsTest.getActiveTabId()));
 
     // Check visibility state of all tabs.
     var tabCount = 0;
     for (var hash in tabVisibilityState) {
       var tabId = NetInternalsTest.getTabId(hash);
-      assertEquals('object', typeof NetInternalsTest.getTab(tabId),
-                   'Invalid tab: ' + tabId);
-      expectEquals(tabVisibilityState[hash],
-                   NetInternalsTest.tabLinkIsVisible(tabId),
-                   tabId + ' visibility state is unexpected.');
+      assertEquals(
+          'object', typeof NetInternalsTest.getTab(tabId),
+          'Invalid tab: ' + tabId);
+      expectEquals(
+          tabVisibilityState[hash], NetInternalsTest.tabLinkIsVisible(tabId),
+          tabId + ' visibility state is unexpected.');
       if (tourTabs && tabVisibilityState[hash])
         NetInternalsTest.switchToView(hash);
       tabCount++;
@@ -525,15 +525,13 @@
 
       // Function to run the next task in the queue.
       var runNextTask = this.taskQueue_.runNextTask_.bind(
-                            this.taskQueue_,
-                            Array.prototype.slice.call(arguments));
+          this.taskQueue_, Array.prototype.slice.call(arguments));
 
       // If we need to start the next task asynchronously, we need to wrap
       // it with the test framework code.
       if (this.completeAsync_) {
-        window.setTimeout(activeTest_.continueTest(WhenTestDone.EXPECT,
-                                                   runNextTask),
-                          0);
+        window.setTimeout(
+            activeTest_.continueTest(WhenTestDone.EXPECT, runNextTask), 0);
         return;
       }
 
@@ -625,8 +623,8 @@
     start: function() {
       // Reuse the BrowserBridge's callback mechanism, since it's already
       // wrapped in our test harness.
-      assertEquals('undefined',
-                   typeof g_browser.onIncognitoBrowserCreatedForTest);
+      assertEquals(
+          'undefined', typeof g_browser.onIncognitoBrowserCreatedForTest);
       g_browser.onIncognitoBrowserCreatedForTest =
           this.onIncognitoBrowserCreatedForTest.bind(this);
 
@@ -649,10 +647,9 @@
    * @return {Task} Task that closes incognito browser window.
    */
   NetInternalsTest.getCloseIncognitoBrowserTask = function() {
-    return new NetInternalsTest.CallFunctionTask(
-        function() {
-          chrome.send('closeIncognitoBrowser');
-        });
+    return new NetInternalsTest.CallFunctionTask(function() {
+      chrome.send('closeIncognitoBrowser');
+    });
   };
 
   /**
@@ -706,8 +703,8 @@
    * @see Event
    */
   NetInternalsTest.createBeginEvent = function(source, type, time, params) {
-    return new NetInternalsTest.Event(source, type, time,
-                                      EventPhase.PHASE_BEGIN, params);
+    return new NetInternalsTest.Event(
+        source, type, time, EventPhase.PHASE_BEGIN, params);
   };
 
   /**
@@ -716,8 +713,8 @@
    * @see Event
    */
   NetInternalsTest.createEndEvent = function(source, type, time, params) {
-    return new NetInternalsTest.Event(source, type, time,
-                                      EventPhase.PHASE_END, params);
+    return new NetInternalsTest.Event(
+        source, type, time, EventPhase.PHASE_END, params);
   };
 
   /**
@@ -730,7 +727,7 @@
    */
   NetInternalsTest.createMatchingEndEvent = function(beginEvent, time, params) {
     return NetInternalsTest.createEndEvent(
-               beginEvent.source, beginEvent.type, time, params);
+        beginEvent.source, beginEvent.type, time, params);
   };
 
   /**
@@ -739,8 +736,7 @@
    */
   NetInternalsTest.expectStatusViewNodeVisible = function(nodeId) {
     var allIds = [
-      CaptureStatusView.MAIN_BOX_ID,
-      LoadedStatusView.MAIN_BOX_ID,
+      CaptureStatusView.MAIN_BOX_ID, LoadedStatusView.MAIN_BOX_ID,
       HaltedStatusView.MAIN_BOX_ID
     ];
 
diff --git a/chrome/test/data/webui/net_internals/prerender_view.js b/chrome/test/data/webui/net_internals/prerender_view.js
index b4a0d2c0..803c292b 100644
--- a/chrome/test/data/webui/net_internals/prerender_view.js
+++ b/chrome/test/data/webui/net_internals/prerender_view.js
@@ -90,10 +90,10 @@
     assertTrue(prerenderInfo.enabled, 'Prerendering not enabled.');
 
     // Check number of rows in both tables.
-    NetInternalsTest.checkTbodyRows(PrerenderView.HISTORY_TABLE_ID,
-                                    prerenderInfo.history.length);
-    NetInternalsTest.checkTbodyRows(PrerenderView.ACTIVE_TABLE_ID,
-                                    prerenderInfo.active.length);
+    NetInternalsTest.checkTbodyRows(
+        PrerenderView.HISTORY_TABLE_ID, prerenderInfo.history.length);
+    NetInternalsTest.checkTbodyRows(
+        PrerenderView.ACTIVE_TABLE_ID, prerenderInfo.active.length);
 
     if (this.state_ == STATE.START_PRERENDERING) {
       this.startPrerendering_(prerenderInfo);
@@ -186,8 +186,7 @@
  */
 TEST_F('NetInternalsTest', 'netInternalsPrerenderViewSucceed', function() {
   var taskQueue = new NetInternalsTest.TaskQueue(true);
-  taskQueue.addTask(
-      new NetInternalsTest.GetTestServerURLTask('/title1.html'));
+  taskQueue.addTask(new NetInternalsTest.GetTestServerURLTask('/title1.html'));
   taskQueue.addTask(new PrerenderTask(true, 'Used'));
   taskQueue.run();
 });
diff --git a/chrome/test/data/webui/net_internals/timeline_view.js b/chrome/test/data/webui/net_internals/timeline_view.js
index f98d9fa..2721ee3 100644
--- a/chrome/test/data/webui/net_internals/timeline_view.js
+++ b/chrome/test/data/webui/net_internals/timeline_view.js
@@ -67,12 +67,10 @@
     logDump.events = [];
 
     var source = new NetInternalsTest.Source(1, EventSourceType.SOCKET);
-    logDump.events.push(
-        NetInternalsTest.createBeginEvent(source, EventType.SOCKET_ALIVE,
-                                          this.startTime_, null));
-    logDump.events.push(
-        NetInternalsTest.createMatchingEndEvent(logDump.events[0],
-                                                this.endTime_, null));
+    logDump.events.push(NetInternalsTest.createBeginEvent(
+        source, EventType.SOCKET_ALIVE, this.startTime_, null));
+    logDump.events.push(NetInternalsTest.createMatchingEndEvent(
+        logDump.events[0], this.endTime_, null));
     logDumpText = JSON.stringify(logDump);
 
     assertEquals('Log loaded.', log_util.loadLogFile(logDumpText));
@@ -300,10 +298,8 @@
   var taskQueue = new NetInternalsTest.TaskQueue(true);
   // Load a log and then switch to the timeline view.  The end time is
   // calculated so that the range is exactly |expectedGraphRange|.
-  taskQueue.addTask(
-      new LoadLogWithNewEventsTask(
-          55,
-          55 + graphView().scale_ * (canvas().width + expectedGraphRange)));
+  taskQueue.addTask(new LoadLogWithNewEventsTask(
+      55, 55 + graphView().scale_ * (canvas().width + expectedGraphRange)));
   taskQueue.addFunctionTask(
       NetInternalsTest.switchToView.bind(null, 'timeline'));
   taskQueue.addFunctionTask(checkGraphRange);
diff --git a/chrome/test/data/webui/ntp4.js b/chrome/test/data/webui/ntp4.js
index 1dc5e01..50c1322 100644
--- a/chrome/test/data/webui/ntp4.js
+++ b/chrome/test/data/webui/ntp4.js
@@ -54,12 +54,13 @@
 // http://crbug.com/118514
 TEST_F('NTP4WebUITest', 'DISABLED_NTPHasSelectedPageAndDot', function() {
   var selectedDot = document.querySelectorAll('.dot.selected');
-  assertEquals(1, selectedDot.length,
-               'There should be exactly one selected dot.');
+  assertEquals(
+      1, selectedDot.length, 'There should be exactly one selected dot.');
 
   var selectedTilePage = document.querySelectorAll('.tile-page.selected-card');
-  assertEquals(1, selectedTilePage.length,
-               'There should be exactly one selected tile page.');
+  assertEquals(
+      1, selectedTilePage.length,
+      'There should be exactly one selected tile page.');
 });
 
 TEST_F('NTP4WebUITest', 'DISABLED_NTPHasNoLoginNameWhenSignedOut', function() {
@@ -89,12 +90,16 @@
 // The following test is irrelevant to Chrome on Chrome OS.
 GEN('#if !defined(OS_CHROMEOS)');
 
-TEST_F('NTP4LoggedInWebUITest', 'DISABLED_NTPHasLoginNameWhenSignedIn',
+TEST_F(
+    'NTP4LoggedInWebUITest', 'DISABLED_NTPHasLoginNameWhenSignedIn',
     function() {
-  var userName = document.querySelector('#login-status-header .profile-name');
-  assertNotEquals(userName, null, 'The logged-in user name can\'t be found.');
-  assertEquals('user@gmail.com', userName.textContent,
-               'The user name should be present on the new tab.');
-});
+      var userName =
+          document.querySelector('#login-status-header .profile-name');
+      assertNotEquals(
+          userName, null, 'The logged-in user name can\'t be found.');
+      assertEquals(
+          'user@gmail.com', userName.textContent,
+          'The user name should be present on the new tab.');
+    });
 
 GEN('#endif');
diff --git a/chrome/test/data/webui/password_manager_internals_browsertest.js b/chrome/test/data/webui/password_manager_internals_browsertest.js
index 3e114bb..d379b10 100644
--- a/chrome/test/data/webui/password_manager_internals_browsertest.js
+++ b/chrome/test/data/webui/password_manager_internals_browsertest.js
@@ -4,29 +4,28 @@
 
 function testLogText() {
   var divLogs = document.getElementById('log-entries');
-  assertNotEquals(null, divLogs, "The <div> with logs not found.");
-  assertNotEquals(null,
-                  divLogs.innerHTML.match(/text for testing/),
-                  "The logged text not found.");
-  assertEquals(null,
-               divLogs.innerHTML.match(/<script>/),
-               "The logged text was not escaped.");
+  assertNotEquals(null, divLogs, 'The <div> with logs not found.');
+  assertNotEquals(
+      null, divLogs.innerHTML.match(/text for testing/),
+      'The logged text not found.');
+  assertEquals(
+      null, divLogs.innerHTML.match(/<script>/),
+      'The logged text was not escaped.');
 }
 
 function testLogEmpty() {
   var divLogs = document.getElementById('log-entries');
-  assertNotEquals(null, divLogs, "The <div> with logs not found.");
-  assertEquals(null,
-               divLogs.innerHTML.match(/[^\s]/),
-               "There were some logs:" + divLogs.innerHTML);
+  assertNotEquals(null, divLogs, 'The <div> with logs not found.');
+  assertEquals(
+      null, divLogs.innerHTML.match(/[^\s]/),
+      'There were some logs:' + divLogs.innerHTML);
 }
 
 function testNonIncognitoDescription() {
   var body = document.getElementsByTagName('body')[0];
   var bodyText = body.innerText;
   var match = bodyText.match(/logs are listed below/);
-  assertEquals(1, match.length,
-               "Where are the logs in: " + bodyText);
+  assertEquals(1, match.length, 'Where are the logs in: ' + bodyText);
   match = bodyText.match(/in Incognito/);
   assertEquals(null, match);
 }
@@ -35,8 +34,7 @@
   var body = document.getElementsByTagName('body')[0];
   var bodyText = body.innerText;
   var match = bodyText.match(/in Incognito/);
-  assertEquals(1, match.length,
-               "Where is Incognito in: " + bodyText);
+  assertEquals(1, match.length, 'Where is Incognito in: ' + bodyText);
   match = bodyText.match(/logs are listed below/);
   assertEquals(null, match);
 }
diff --git a/chrome/test/data/webui/polymer_browser_test_base.js b/chrome/test/data/webui/polymer_browser_test_base.js
index 1ededb8..131e3aa 100644
--- a/chrome/test/data/webui/polymer_browser_test_base.js
+++ b/chrome/test/data/webui/polymer_browser_test_base.js
@@ -114,13 +114,15 @@
     // set icon is valid for cases when we don't want to display anything.
     if (!icon.icon) {
       var rect = icon.getBoundingClientRect();
-      expectFalse(rect.width * rect.height > 0,
-                  'iron-icon with undefined "icon" is visible in the DOM.');
+      expectFalse(
+          rect.width * rect.height > 0,
+          'iron-icon with undefined "icon" is visible in the DOM.');
       return;
     }
     var svg = icon.$$('svg');
-    expectTrue(!!svg && svg.innerHTML != '',
-               'icon "' + icon.icon + '" is not present');
+    expectTrue(
+        !!svg && svg.innerHTML != '',
+        'icon "' + icon.icon + '" is not present');
   });
 };
 
@@ -165,8 +167,8 @@
  */
 PolymerTest.clearBody = function() {
   // Save the div where vulcanize inlines content before clearing the page.
-  var vulcanizeDiv = document.querySelector(
-      'body > div[hidden][by-polymer-bundler]');
+  var vulcanizeDiv =
+      document.querySelector('body > div[hidden][by-polymer-bundler]');
   document.body.innerHTML = '';
   if (vulcanizeDiv)
     document.body.appendChild(vulcanizeDiv);
diff --git a/chrome/test/data/webui/print_preview/cloud_print_interface_stub.js b/chrome/test/data/webui/print_preview/cloud_print_interface_stub.js
index 1e8e0ec..e2116d1 100644
--- a/chrome/test/data/webui/print_preview/cloud_print_interface_stub.js
+++ b/chrome/test/data/webui/print_preview/cloud_print_interface_stub.js
@@ -4,8 +4,8 @@
 
 cr.define('print_preview', function() {
   /**
-  * Test version of the cloud print interface.
-  */
+   * Test version of the cloud print interface.
+   */
   class CloudPrintInterfaceStub extends cr.EventTarget {
     constructor() {
       super();
@@ -28,12 +28,12 @@
      * printers that have been set so far using setPrinter().
      */
     search() {
-      const searchDoneEvent = new Event(
-          cloudprint.CloudPrintInterfaceEventType.SEARCH_DONE);
+      const searchDoneEvent =
+          new Event(cloudprint.CloudPrintInterfaceEventType.SEARCH_DONE);
       searchDoneEvent.origin = print_preview.DestinationOrigin.COOKIES;
       searchDoneEvent.printers = [];
       this.cloudPrintersMap_.forEach((value) => {
-          searchDoneEvent.printers.push(value);
+        searchDoneEvent.printers.push(value);
       });
       searchDoneEvent.isRecent = true;
       searchDoneEvent.user = 'foo@chromium.org';
diff --git a/chrome/test/data/webui/print_preview/custom_margins_test.js b/chrome/test/data/webui/print_preview/custom_margins_test.js
index 0baf91e..13e85522 100644
--- a/chrome/test/data/webui/print_preview/custom_margins_test.js
+++ b/chrome/test/data/webui/print_preview/custom_margins_test.js
@@ -43,9 +43,8 @@
       // Other inputs needed by margin control container.
       const pageSize = new print_preview.Size(5100, 6600);
       const documentMargins = new print_preview.Margins(300, 300, 300, 300);
-      const measurementSystem =
-          new print_preview.MeasurementSystem(
-              ',', '.', print_preview.MeasurementSystemUnitType.IMPERIAL);
+      const measurementSystem = new print_preview.MeasurementSystem(
+          ',', '.', print_preview.MeasurementSystemUnitType.IMPERIAL);
 
       // Set up container
       container =
@@ -79,9 +78,8 @@
        *     for all of the controls.
        */
       const getAllTransitions = function(controls) {
-        return Promise.all(
-            Array.from(controls).map(
-                control => test_util.eventToPromise('transitionend', control)));
+        return Promise.all(Array.from(controls).map(
+            control => test_util.eventToPromise('transitionend', control)));
       };
 
       let onTransitionEnd = getAllTransitions(controls);
@@ -91,41 +89,46 @@
           print_preview.ticket_items.MarginsTypeValue.CUSTOM);
 
       // Wait for the opacity transitions to finish.
-      return onTransitionEnd.then(function() {
-        // Verify margins are correctly set based on previous value.
-        assertEquals(300, container.settings.customMargins.value.marginTop);
-        assertEquals(300, container.settings.customMargins.value.marginLeft);
-        assertEquals(300, container.settings.customMargins.value.marginRight);
-        assertEquals(300, container.settings.customMargins.value.marginBottom);
+      return onTransitionEnd
+          .then(function() {
+            // Verify margins are correctly set based on previous value.
+            assertEquals(300, container.settings.customMargins.value.marginTop);
+            assertEquals(
+                300, container.settings.customMargins.value.marginLeft);
+            assertEquals(
+                300, container.settings.customMargins.value.marginRight);
+            assertEquals(
+                300, container.settings.customMargins.value.marginBottom);
 
-        // Verify there is one control for each side and that controls are
-        // visible and positioned correctly.
-        const sides = [
-          print_preview.ticket_items.CustomMarginsOrientation.TOP,
-          print_preview.ticket_items.CustomMarginsOrientation.RIGHT,
-          print_preview.ticket_items.CustomMarginsOrientation.BOTTOM,
-          print_preview.ticket_items.CustomMarginsOrientation.LEFT
-        ];
-        controls.forEach((control, index) => {
-          assertFalse(control.invisible);
-          assertEquals('1', window.getComputedStyle(control).opacity);
-          assertEquals(sides[index], control.side);
-          assertEquals(300, control.getPositionInPts());
-        });
+            // Verify there is one control for each side and that controls are
+            // visible and positioned correctly.
+            const sides = [
+              print_preview.ticket_items.CustomMarginsOrientation.TOP,
+              print_preview.ticket_items.CustomMarginsOrientation.RIGHT,
+              print_preview.ticket_items.CustomMarginsOrientation.BOTTOM,
+              print_preview.ticket_items.CustomMarginsOrientation.LEFT
+            ];
+            controls.forEach((control, index) => {
+              assertFalse(control.invisible);
+              assertEquals('1', window.getComputedStyle(control).opacity);
+              assertEquals(sides[index], control.side);
+              assertEquals(300, control.getPositionInPts());
+            });
 
-        let onTransitionEnd = getAllTransitions(controls);
+            let onTransitionEnd = getAllTransitions(controls);
 
-        // Disappears when preview is loading or an error message is shown.
-        // Check that all the controls also disappear.
-        container.previewLoaded = false;
-        // Wait for the opacity transitions to finish.
-        return onTransitionEnd;
-      }).then(function() {
-        controls.forEach((control, index) => {
-          assertEquals('0', window.getComputedStyle(control).opacity);
-          assertTrue(control.invisible);
-        });
-      });
+            // Disappears when preview is loading or an error message is shown.
+            // Check that all the controls also disappear.
+            container.previewLoaded = false;
+            // Wait for the opacity transitions to finish.
+            return onTransitionEnd;
+          })
+          .then(function() {
+            controls.forEach((control, index) => {
+              assertEquals('0', window.getComputedStyle(control).opacity);
+              assertTrue(control.invisible);
+            });
+          });
     });
   });
 
diff --git a/chrome/test/data/webui/print_preview/destination_dialog_test.js b/chrome/test/data/webui/print_preview/destination_dialog_test.js
index 06283ae..3f1dec51 100644
--- a/chrome/test/data/webui/print_preview/destination_dialog_test.js
+++ b/chrome/test/data/webui/print_preview/destination_dialog_test.js
@@ -44,8 +44,7 @@
       recentDestinations =
           [print_preview.makeRecentDestination(destinations[4])];
       destinationStore.init(
-          false /* isInAppKioskMode */,
-          'FooDevice' /* printerName */,
+          false /* isInAppKioskMode */, 'FooDevice' /* printerName */,
           '' /* serializedDefaultDestinationSelectionRulesStr */,
           recentDestinations /* recentDestinations */);
       nativeLayer.setLocalDestinations(localDestinations);
@@ -57,19 +56,21 @@
       dialog.invitationStore = new print_preview.InvitationStore(userInfo);
       dialog.recentDestinations = recentDestinations;
       document.body.appendChild(dialog);
-      return nativeLayer.whenCalled('getPrinterCapabilities').then(function() {
-        destinationStore.startLoadAllDestinations();
-        dialog.show();
-        return nativeLayer.whenCalled('getPrinters');
-      }).then(function() {
-        Polymer.dom.flush();
-      });
+      return nativeLayer.whenCalled('getPrinterCapabilities')
+          .then(function() {
+            destinationStore.startLoadAllDestinations();
+            dialog.show();
+            return nativeLayer.whenCalled('getPrinters');
+          })
+          .then(function() {
+            Polymer.dom.flush();
+          });
     });
 
     // Test that destinations are correctly displayed in the lists.
     test(assert(TestNames.PrinterList), function() {
-      const lists = dialog.shadowRoot.querySelectorAll(
-          'print-preview-destination-list');
+      const lists =
+          dialog.shadowRoot.querySelectorAll('print-preview-destination-list');
       assertEquals(2, lists.length);
 
       const recentItems = lists[0].shadowRoot.querySelectorAll(
@@ -85,13 +86,13 @@
       // 5 printers + Save as PDF
       assertEquals(6, printerItems.length);
       // Save as PDF shows up first.
-      assertEquals(print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,
-                   getDisplayedName(printerItems[0]));
+      assertEquals(
+          print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,
+          getDisplayedName(printerItems[0]));
       // FooName will be second since it was updated by the capabilities fetch.
       assertEquals('FooName', getDisplayedName(printerItems[1]));
       Array.from(printerItems).slice(2).forEach((item, index) => {
-        assertEquals(destinations[index].displayName,
-                     getDisplayedName(item));
+        assertEquals(destinations[index].displayName, getDisplayedName(item));
       });
 
     });
diff --git a/chrome/test/data/webui/print_preview/destination_search_test.js b/chrome/test/data/webui/print_preview/destination_search_test.js
index 16404ea..c94c837e 100644
--- a/chrome/test/data/webui/print_preview/destination_search_test.js
+++ b/chrome/test/data/webui/print_preview/destination_search_test.js
@@ -37,8 +37,7 @@
       nativeLayer.setLocalDestinationCapabilities(
           print_preview_test_utils.getCddTemplate('FooDevice', 'FooName'));
       destinationStore.init(
-          false /* isInAppKioskMode */,
-          'FooDevice' /* printerName */,
+          false /* isInAppKioskMode */, 'FooDevice' /* printerName */,
           '' /* serializedDefaultDestinationSelectionRulesStr */,
           [] /* recentDestinations */);
 
@@ -80,12 +79,10 @@
      */
     function requestSetup(destId) {
       const origin = cr.isChromeOS ? print_preview.DestinationOrigin.CROS :
-                                   print_preview.DestinationOrigin.LOCAL;
+                                     print_preview.DestinationOrigin.LOCAL;
 
-      const dest = new print_preview.Destination(destId,
-          print_preview.DestinationType.LOCAL,
-          origin,
-          'displayName',
+      const dest = new print_preview.Destination(
+          destId, print_preview.DestinationType.LOCAL, origin, 'displayName',
           print_preview.DestinationConnectionStatus.ONLINE);
 
       // Add the destination to the list.
@@ -116,8 +113,8 @@
       requestSetup(destId);
       const callback =
           cr.isChromeOS ? 'setupPrinter' : 'getPrinterCapabilities';
-      return Promise.all([nativeLayer.whenCalled(callback), waiter]).then(
-          function(results) {
+      return Promise.all([nativeLayer.whenCalled(callback), waiter])
+          .then(function(results) {
             const actualId =
                 cr.isChromeOS ? results[0] : results[0].destinationId;
             assertEquals(destId, actualId);
@@ -133,17 +130,15 @@
     test(assert(TestNames.ResolutionFails), function() {
       const destId = '001122DEADBEEF';
       const originalDestination = destinationStore.selectedDestination;
-      nativeLayer.setSetupPrinterResponse(true, {printerId: destId,
-                                                 success: false});
+      nativeLayer.setSetupPrinterResponse(
+          true, {printerId: destId, success: false});
       requestSetup(destId);
-      return nativeLayer.whenCalled('setupPrinter').then(
-          function(actualId) {
-            assertEquals(destId, actualId);
-            // The selected printer should not have changed, since a printer
-            // cannot be selected until setup succeeds.
-            assertEquals(originalDestination,
-                         destinationStore.selectedDestination);
-          });
+      return nativeLayer.whenCalled('setupPrinter').then(function(actualId) {
+        assertEquals(destId, actualId);
+        // The selected printer should not have changed, since a printer
+        // cannot be selected until setup succeeds.
+        assertEquals(originalDestination, destinationStore.selectedDestination);
+      });
     });
 
     // Test what happens when the setupPrinter request is resolved with a
@@ -159,13 +154,13 @@
       };
       nativeLayer.setSetupPrinterResponse(false, response);
       requestSetup(destId);
-      return nativeLayer.whenCalled('setupPrinter').then(
-          function (actualDestId) {
+      return nativeLayer.whenCalled('setupPrinter')
+          .then(function(actualDestId) {
             assertEquals(destId, actualDestId);
             // The selected printer should not have changed, since a printer
             // cannot be selected until setup succeeds.
-            assertEquals(originalDestination,
-                         destinationStore.selectedDestination);
+            assertEquals(
+                originalDestination, destinationStore.selectedDestination);
           });
     });
 
@@ -177,8 +172,8 @@
       nativeLayer.setLocalDestinationCapabilities(
           print_preview_test_utils.getCddTemplate(destId), true);
       requestSetup(destId);
-      return nativeLayer.whenCalled('getPrinterCapabilities').then(
-          function(args) {
+      return nativeLayer.whenCalled('getPrinterCapabilities')
+          .then(function(args) {
             assertEquals(destId, args.destinationId);
             // The destination is selected even though capabilities cannot be
             // retrieved.
@@ -191,10 +186,9 @@
       const printerId = 'cloud-printer-id';
 
       // Create cloud destination.
-      const cloudDest = new print_preview.Destination(printerId,
-          print_preview.DestinationType.GOOGLE,
-          print_preview.DestinationOrigin.DEVICE,
-          'displayName',
+      const cloudDest = new print_preview.Destination(
+          printerId, print_preview.DestinationType.GOOGLE,
+          print_preview.DestinationOrigin.DEVICE, 'displayName',
           print_preview.DestinationConnectionStatus.ONLINE);
       cloudDest.capabilities =
           print_preview_test_utils.getCddTemplate(printerId, 'displayName')
diff --git a/chrome/test/data/webui/print_preview/destination_select_test.js b/chrome/test/data/webui/print_preview/destination_select_test.js
index 30986a6d..a1a6a3f6 100644
--- a/chrome/test/data/webui/print_preview/destination_select_test.js
+++ b/chrome/test/data/webui/print_preview/destination_select_test.js
@@ -67,7 +67,7 @@
           print_preview.makeRecentDestination(destinations[0]);
       initialSettings.serializedAppStateStr = JSON.stringify({
         version: 2,
-        recentDestinations: [ recentDestination ],
+        recentDestinations: [recentDestination],
       });
 
       return setInitialSettings().then(function(argsArray) {
@@ -91,27 +91,30 @@
         recentDestinations: recentDestinations,
       });
 
-      return setInitialSettings().then(function(argsArray) {
-        // Should have loaded ID1 as the selected printer, since it was most
-        // recent.
-        assertEquals('ID1', argsArray[1].destinationId);
-        assertEquals(print_preview.PrinterType.LOCAL, argsArray[1].type);
-        assertEquals('ID1', page.destination_.id);
+      return setInitialSettings()
+          .then(function(argsArray) {
+            // Should have loaded ID1 as the selected printer, since it was most
+            // recent.
+            assertEquals('ID1', argsArray[1].destinationId);
+            assertEquals(print_preview.PrinterType.LOCAL, argsArray[1].type);
+            assertEquals('ID1', page.destination_.id);
 
-        // Load all local destinations.
-        page.destinationStore_.startLoadDestinations(
-            print_preview.PrinterType.LOCAL_PRINTER);
-        return nativeLayer.whenCalled('getPrinters');
-      }).then(function() {
-        // Verify the correct printers are marked as recent in the store.
-        const reportedPrinters = page.destinationStore_.destinations();
-        destinations.forEach((destination, index) => {
-          const match = reportedPrinters.find((reportedPrinter) => {
-              return reportedPrinter.id == destination.id;});
-          assertFalse(typeof match === "undefined");
-          assertEquals(index < 3, match.isRecent);
-        });
-      });
+            // Load all local destinations.
+            page.destinationStore_.startLoadDestinations(
+                print_preview.PrinterType.LOCAL_PRINTER);
+            return nativeLayer.whenCalled('getPrinters');
+          })
+          .then(function() {
+            // Verify the correct printers are marked as recent in the store.
+            const reportedPrinters = page.destinationStore_.destinations();
+            destinations.forEach((destination, index) => {
+              const match = reportedPrinters.find((reportedPrinter) => {
+                return reportedPrinter.id == destination.id;
+              });
+              assertFalse(typeof match === 'undefined');
+              assertEquals(index < 3, match.isRecent);
+            });
+          });
     });
 
     /**
@@ -129,31 +132,33 @@
         recentDestinations: recentDestinations,
       });
 
-      return setInitialSettings().then(function(argsArray) {
-        // Should have loaded ID1 as the selected printer, since it was most
-        // recent.
-        assertEquals('ID1', argsArray[1].destinationId);
-        assertEquals(print_preview.PrinterType.LOCAL, argsArray[1].type);
-        assertEquals('ID1', page.destination_.id);
+      return setInitialSettings()
+          .then(function(argsArray) {
+            // Should have loaded ID1 as the selected printer, since it was most
+            // recent.
+            assertEquals('ID1', argsArray[1].destinationId);
+            assertEquals(print_preview.PrinterType.LOCAL, argsArray[1].type);
+            assertEquals('ID1', page.destination_.id);
 
-        return nativeLayer.whenCalled('getPreview');
-      }).then(function(previewArgs) {
-        const ticket = JSON.parse(previewArgs.printTicket);
-        assertEquals(0, ticket.requestID);
-        assertEquals('ID1', ticket.deviceName);
+            return nativeLayer.whenCalled('getPreview');
+          })
+          .then(function(previewArgs) {
+            const ticket = JSON.parse(previewArgs.printTicket);
+            assertEquals(0, ticket.requestID);
+            assertEquals('ID1', ticket.deviceName);
 
-        // None of the other printers should have been loaded. Should only have
-        // ID1 and Save as PDF. They will be loaded when the dialog is opened
-        // and startLoadDestinations() is called.
-        const reportedPrinters = page.destinationStore_.destinations();
-        assertEquals(2, reportedPrinters.length);
-        destinations.forEach((destination, index) => {
-          if (destination.id == 'ID1')
-            return;
+            // None of the other printers should have been loaded. Should only
+            // have ID1 and Save as PDF. They will be loaded when the dialog is
+            // opened and startLoadDestinations() is called.
+            const reportedPrinters = page.destinationStore_.destinations();
+            assertEquals(2, reportedPrinters.length);
+            destinations.forEach((destination, index) => {
+              if (destination.id == 'ID1')
+                return;
 
-          assertFalse(reportedPrinters.some(p => p.id == destination.id));
-        });
-      });
+              assertFalse(reportedPrinters.some(p => p.id == destination.id));
+            });
+          });
     });
 
     /**
diff --git a/chrome/test/data/webui/print_preview/invalid_settings_browsertest.js b/chrome/test/data/webui/print_preview/invalid_settings_browsertest.js
index 663a2ac..bb09183 100644
--- a/chrome/test/data/webui/print_preview/invalid_settings_browsertest.js
+++ b/chrome/test/data/webui/print_preview/invalid_settings_browsertest.js
@@ -37,8 +37,8 @@
 
     /** @type {!Array<!print_preview.LocalDestinationInfo>} */
     let localDestinationInfos = [
-      { printerName: 'FooName', deviceName: 'FooDevice' },
-      { printerName: 'BarName', deviceName: 'BarDevice' },
+      {printerName: 'FooName', deviceName: 'FooDevice'},
+      {printerName: 'BarName', deviceName: 'BarDevice'},
     ];
 
     /** @override */
@@ -82,8 +82,8 @@
       initialSettings.serializedAppStateStr = JSON.stringify({
         version: 2,
         recentDestinations: [
-            print_preview.makeRecentDestination(printers[0]),
-            print_preview.makeRecentDestination(printers[1]),
+          print_preview.makeRecentDestination(printers[0]),
+          print_preview.makeRecentDestination(printers[1]),
         ],
       });
       localDestinationInfos = [];
@@ -119,8 +119,9 @@
             'viewer which is required for Print Preview to function.';
         const expectedMessageChrome = 'Google Chrome cannot show the print ' +
             'preview when the built-in PDF viewer is missing.';
-        assertTrue(messageEl.textContent.includes(expectedMessageChromium) ||
-                   messageEl.textContent.includes(expectedMessageChrome));
+        assertTrue(
+            messageEl.textContent.includes(expectedMessageChromium) ||
+            messageEl.textContent.includes(expectedMessageChrome));
       });
     });
 
@@ -138,9 +139,9 @@
       nativeLayer.setInvalidPrinterId('FooDevice');
 
       // Expected message
-      const expectedMessage = 'The selected printer is not available or not '
-          + 'installed correctly.  Check your printer or try selecting another '
-          + 'printer.';
+      const expectedMessage = 'The selected printer is not available or not ' +
+          'installed correctly.  Check your printer or try selecting another ' +
+          'printer.';
 
       // Get references to relevant elements.
       const previewAreaEl = page.$.previewArea;
@@ -150,69 +151,73 @@
       const printButton = header.$$('.print');
 
       document.body.appendChild(page);
-      return nativeLayer.whenCalled('getInitialSettings').then(function() {
-        page.destinationStore_.startLoadDestinations(
-            print_preview.PrinterType.LOCAL_PRINTER);
-        // Wait for the preview request.
-        return Promise.all([
-          nativeLayer.whenCalled('getPrinterCapabilities'),
-          nativeLayer.whenCalled('getPreview')
-        ]);
-      }).then(function() {
-        // Print preview should have failed with invalid settings, since
-        // FooDevice was set as an invalid printer.
-        assertFalse(overlay.classList.contains('invisible'));
-        assertTrue(messageEl.textContent.includes(expectedMessage));
+      return nativeLayer.whenCalled('getInitialSettings')
+          .then(function() {
+            page.destinationStore_.startLoadDestinations(
+                print_preview.PrinterType.LOCAL_PRINTER);
+            // Wait for the preview request.
+            return Promise.all([
+              nativeLayer.whenCalled('getPrinterCapabilities'),
+              nativeLayer.whenCalled('getPreview')
+            ]);
+          })
+          .then(function() {
+            // Print preview should have failed with invalid settings, since
+            // FooDevice was set as an invalid printer.
+            assertFalse(overlay.classList.contains('invisible'));
+            assertTrue(messageEl.textContent.includes(expectedMessage));
 
-        // Verify that the print button is disabled
-        assertTrue(printButton.disabled);
+            // Verify that the print button is disabled
+            assertTrue(printButton.disabled);
 
-        // Reset
-        nativeLayer.reset();
+            // Reset
+            nativeLayer.reset();
 
-        // Select a new destination
-        const barDestination =
-            page.destinationStore_.destinations().find(
+            // Select a new destination
+            const barDestination = page.destinationStore_.destinations().find(
                 d => d.id == 'BarDevice');
-        page.destinationStore_.selectDestination(barDestination);
+            page.destinationStore_.selectDestination(barDestination);
 
-        // Wait for the preview to be updated.
-        return Promise.all([
-          nativeLayer.whenCalled('getPrinterCapabilities'),
-          nativeLayer.whenCalled('getPreview')
-        ]);
-      }).then(function() {
-        // Message should be gone.
-        assertTrue(overlay.classList.contains('invisible'));
-        assertFalse(messageEl.textContent.includes(expectedMessage));
+            // Wait for the preview to be updated.
+            return Promise.all([
+              nativeLayer.whenCalled('getPrinterCapabilities'),
+              nativeLayer.whenCalled('getPreview')
+            ]);
+          })
+          .then(function() {
+            // Message should be gone.
+            assertTrue(overlay.classList.contains('invisible'));
+            assertFalse(messageEl.textContent.includes(expectedMessage));
 
-        // Has active print button and successfully 'prints', indicating
-        assertFalse(printButton.disabled);
-        printButton.click();
-        // This should result in a call to print.
-        return nativeLayer.whenCalled('print');
-      }).then(
-          /**
-           * @param {string} printTicket The print ticket print() was called
-           *     for.
-           */
-          function(printTicket) {
-            // Sanity check some printing argument values.
-            const ticket = JSON.parse(printTicket);
-            assertEquals(barDevice.printer.deviceName, ticket.deviceName);
-            assertEquals(
-                print_preview_test_utils.getDefaultOrientation(barDevice) ==
-                    'LANDSCAPE',
-                ticket.landscape);
-            assertEquals(1, ticket.copies);
-            const mediaDefault =
-                print_preview_test_utils.getDefaultMediaSize(barDevice);
-            assertEquals(
-                mediaDefault.width_microns, ticket.mediaSize.width_microns);
-            assertEquals(
-                mediaDefault.height_microns, ticket.mediaSize.height_microns);
-            return nativeLayer.whenCalled('dialogClose');
-          });
+            // Has active print button and successfully 'prints', indicating
+            assertFalse(printButton.disabled);
+            printButton.click();
+            // This should result in a call to print.
+            return nativeLayer.whenCalled('print');
+          })
+          .then(
+              /**
+               * @param {string} printTicket The print ticket print() was called
+               *     for.
+               */
+              function(printTicket) {
+                // Sanity check some printing argument values.
+                const ticket = JSON.parse(printTicket);
+                assertEquals(barDevice.printer.deviceName, ticket.deviceName);
+                assertEquals(
+                    print_preview_test_utils.getDefaultOrientation(barDevice) ==
+                        'LANDSCAPE',
+                    ticket.landscape);
+                assertEquals(1, ticket.copies);
+                const mediaDefault =
+                    print_preview_test_utils.getDefaultMediaSize(barDevice);
+                assertEquals(
+                    mediaDefault.width_microns, ticket.mediaSize.width_microns);
+                assertEquals(
+                    mediaDefault.height_microns,
+                    ticket.mediaSize.height_microns);
+                return nativeLayer.whenCalled('dialogClose');
+              });
     });
 
     // Test that GCP invalid certificate printers disable the print preview when
@@ -230,9 +235,9 @@
       setupInvalidCertificateTest([invalidPrinter, validPrinter]);
 
       // Expected message
-      const expectedMessage = 'The selected Google Cloud Print device is no '
-          + 'longer supported. Try setting up the printer in your computer\'s '
-          + 'system settings.';
+      const expectedMessage = 'The selected Google Cloud Print device is no ' +
+          'longer supported. Try setting up the printer in your computer\'s ' +
+          'system settings.';
 
       // Get references to relevant elements.
       const previewAreaEl = page.$.previewArea;
@@ -244,111 +249,118 @@
       const scalingSettings = page.$$('print-preview-scaling-settings');
       const layoutSettings = page.$$('print-preview-layout-settings');
 
-      return nativeLayer.whenCalled('getInitialSettings').then(function() {
-        page.destinationStore_.startLoadCloudDestinations();
+      return nativeLayer.whenCalled('getInitialSettings')
+          .then(function() {
+            page.destinationStore_.startLoadCloudDestinations();
 
-        // FooDevice will be selected since it is the most recently used
-        // printer, so the invalid certificate error should be shown.
-        // The overlay must be visible for the message to be seen.
-        assertFalse(overlayEl.classList.contains('invisible'));
+            // FooDevice will be selected since it is the most recently used
+            // printer, so the invalid certificate error should be shown.
+            // The overlay must be visible for the message to be seen.
+            assertFalse(overlayEl.classList.contains('invisible'));
 
-        // Verify that the correct message is shown.
-        assertTrue(messageEl.textContent.includes(expectedMessage));
+            // Verify that the correct message is shown.
+            assertTrue(messageEl.textContent.includes(expectedMessage));
 
-        // Verify that the print button is disabled
-        assertTrue(printButton.disabled);
+            // Verify that the print button is disabled
+            assertTrue(printButton.disabled);
 
-        // Verify the state is invalid and that some settings sections are also
-        // disabled, so there is no way to regenerate the preview.
-        assertEquals(print_preview_new.State.INVALID_PRINTER, page.state);
-        assertTrue(layoutSettings.$$('select').disabled);
-        assertTrue(scalingSettings.$$('input').disabled);
+            // Verify the state is invalid and that some settings sections are
+            // also disabled, so there is no way to regenerate the preview.
+            assertEquals(print_preview_new.State.INVALID_PRINTER, page.state);
+            assertTrue(layoutSettings.$$('select').disabled);
+            assertTrue(scalingSettings.$$('input').disabled);
 
-        // The destination settings button should be enabled, so that the user
-        // can select a new printer.
-        assertFalse(destinationSettings.$$('button').disabled);
+            // The destination settings button should be enabled, so that the
+            // user can select a new printer.
+            assertFalse(destinationSettings.$$('button').disabled);
 
-        // Reset
-        nativeLayer.reset();
+            // Reset
+            nativeLayer.reset();
 
-        // Select a new, valid cloud destination.
-        page.destinationStore_.selectDestination(validPrinter);
-        return nativeLayer.whenCalled('getPreview');
-      }).then(function() {
-        // Has active print button, indicating recovery from error state.
-        assertFalse(printButton.disabled);
+            // Select a new, valid cloud destination.
+            page.destinationStore_.selectDestination(validPrinter);
+            return nativeLayer.whenCalled('getPreview');
+          })
+          .then(function() {
+            // Has active print button, indicating recovery from error state.
+            assertFalse(printButton.disabled);
 
-        // Settings sections are now active.
-        assertFalse(layoutSettings.$$('select').disabled);
-        assertFalse(scalingSettings.$$('input').disabled);
+            // Settings sections are now active.
+            assertFalse(layoutSettings.$$('select').disabled);
+            assertFalse(scalingSettings.$$('input').disabled);
 
-        // The destination settings button should still be enabled.
-        assertFalse(destinationSettings.$$('button').disabled);
+            // The destination settings button should still be enabled.
+            assertFalse(destinationSettings.$$('button').disabled);
 
-        // Message text should have changed and overlay should be invisible.
-        assertFalse(messageEl.textContent.includes(expectedMessage));
-        assertTrue(overlayEl.classList.contains('invisible'));
-      });
+            // Message text should have changed and overlay should be invisible.
+            assertFalse(messageEl.textContent.includes(expectedMessage));
+            assertTrue(overlayEl.classList.contains('invisible'));
+          });
     });
 
     // Test that GCP invalid certificate printers disable the print preview when
     // selected and display an error and that the preview dialog can be
     // recovered by selecting a new destination. Tests that even if destination
     // was previously selected, the error is cleared.
-    test(assert(TestNames.InvalidCertificateErrorReselectDestination),
+    test(
+        assert(TestNames.InvalidCertificateErrorReselectDestination),
         function() {
-      const invalidPrinter =
-          print_preview_test_utils.createDestinationWithCertificateStatus(
-              'FooDevice', 'FooName', true);
-      const validPrinter =
-          print_preview_test_utils.createDestinationWithCertificateStatus(
-              'BarDevice', 'BarName', false);
-      setupInvalidCertificateTest([validPrinter, invalidPrinter]);
+          const invalidPrinter =
+              print_preview_test_utils.createDestinationWithCertificateStatus(
+                  'FooDevice', 'FooName', true);
+          const validPrinter =
+              print_preview_test_utils.createDestinationWithCertificateStatus(
+                  'BarDevice', 'BarName', false);
+          setupInvalidCertificateTest([validPrinter, invalidPrinter]);
 
-      // Get references to relevant elements.
-      const previewAreaEl = page.$.previewArea;
-      const overlayEl = previewAreaEl.$$('.preview-area-overlay-layer');
-      const messageEl = previewAreaEl.$$('.preview-area-message');
-      const header = page.$$('print-preview-header');
-      const printButton = header.$$('.print');
+          // Get references to relevant elements.
+          const previewAreaEl = page.$.previewArea;
+          const overlayEl = previewAreaEl.$$('.preview-area-overlay-layer');
+          const messageEl = previewAreaEl.$$('.preview-area-message');
+          const header = page.$$('print-preview-header');
+          const printButton = header.$$('.print');
 
-      return nativeLayer.whenCalled('getInitialSettings').then(function() {
-        // Start loading cloud destinations so that the printer capabilities
-        // arrive.
-        page.destinationStore_.startLoadCloudDestinations();
-        return nativeLayer.whenCalled('getPreview');
-      }).then(function() {
-        // Has active print button.
-        assertFalse(printButton.disabled);
-        // No error message.
-        assertTrue(overlayEl.classList.contains('invisible'));
+          return nativeLayer.whenCalled('getInitialSettings')
+              .then(function() {
+                // Start loading cloud destinations so that the printer
+                // capabilities arrive.
+                page.destinationStore_.startLoadCloudDestinations();
+                return nativeLayer.whenCalled('getPreview');
+              })
+              .then(function() {
+                // Has active print button.
+                assertFalse(printButton.disabled);
+                // No error message.
+                assertTrue(overlayEl.classList.contains('invisible'));
 
-        // Select the invalid destination and wait for the event.
-        const whenInvalid = test_util.eventToPromise(
-            print_preview.DestinationStore.EventType
-                .SELECTED_DESTINATION_UNSUPPORTED,
-            page.destinationStore_);
-        page.destinationStore_.selectDestination(invalidPrinter);
-        return whenInvalid;
-      }).then(function() {
-        // Should have error message.
-        assertFalse(overlayEl.classList.contains('invisible'));
+                // Select the invalid destination and wait for the event.
+                const whenInvalid = test_util.eventToPromise(
+                    print_preview.DestinationStore.EventType
+                        .SELECTED_DESTINATION_UNSUPPORTED,
+                    page.destinationStore_);
+                page.destinationStore_.selectDestination(invalidPrinter);
+                return whenInvalid;
+              })
+              .then(function() {
+                // Should have error message.
+                assertFalse(overlayEl.classList.contains('invisible'));
 
-        // Reset
-        nativeLayer.reset();
+                // Reset
+                nativeLayer.reset();
 
-        // Reselect the valid cloud destination.
-        const whenSelected = test_util.eventToPromise(
-            print_preview.DestinationStore.EventType.DESTINATION_SELECT,
-            page.destinationStore_);
-        page.destinationStore_.selectDestination(validPrinter);
-        return whenSelected;
-      }).then(function() {
-        // Has active print button and no error message.
-        assertFalse(printButton.disabled);
-        assertTrue(overlayEl.classList.contains('invisible'));
-      });
-    });
+                // Reselect the valid cloud destination.
+                const whenSelected = test_util.eventToPromise(
+                    print_preview.DestinationStore.EventType.DESTINATION_SELECT,
+                    page.destinationStore_);
+                page.destinationStore_.selectDestination(validPrinter);
+                return whenSelected;
+              })
+              .then(function() {
+                // Has active print button and no error message.
+                assertFalse(printButton.disabled);
+                assertTrue(overlayEl.classList.contains('invisible'));
+              });
+        });
   });
 
   return {
diff --git a/chrome/test/data/webui/print_preview/model_test.js b/chrome/test/data/webui/print_preview/model_test.js
index cb5b25c7..052a6130 100644
--- a/chrome/test/data/webui/print_preview/model_test.js
+++ b/chrome/test/data/webui/print_preview/model_test.js
@@ -29,9 +29,8 @@
         version: 2,
         recentDestinations: [],
         dpi: {},
-        mediaSize: {width_microns: 215900,
-                    height_microns: 279400},
-        marginsType: 0,  /* default */
+        mediaSize: {width_microns: 215900, height_microns: 279400},
+        marginsType: 0, /* default */
         scaling: '100',
         isHeaderFooterEnabled: true,
         isCssBackgroundEnabled: false,
@@ -47,9 +46,8 @@
         version: 2,
         recentDestinations: [],
         dpi: {horizontal_dpi: 1000, vertical_dpi: 500},
-        mediaSize: {width_microns: 43180,
-                    height_microns: 21590},
-        marginsType: 2,  /* none */
+        mediaSize: {width_microns: 43180, height_microns: 21590},
+        marginsType: 2, /* none */
         scaling: '85',
         isHeaderFooterEnabled: false,
         isCssBackgroundEnabled: true,
@@ -80,8 +78,8 @@
               let settings = JSON.parse(e.detail);
               for (let settingName in stickySettingsDefault) {
                 if (stickySettingsDefault.hasOwnProperty(settingName)) {
-                  let toCompare = settingName == field ?
-                      stickySettingsChange : stickySettingsDefault;
+                  let toCompare = settingName == field ? stickySettingsChange :
+                                                         stickySettingsDefault;
                   assertDeepEquals(
                       toCompare[settingName], settings[settingName]);
                 }
@@ -95,29 +93,40 @@
       };
 
       model.initialized_ = true;
-      return testStickySetting('collate', 'isCollateEnabled').then(function() {
-        return testStickySetting('color', 'isColorEnabled');
-      }).then(function() {
-        return testStickySetting('cssBackground', 'isCssBackgroundEnabled');
-      }).then(function() {
-        return testStickySetting('dpi', 'dpi');
-      }).then(function() {
-        return testStickySetting('duplex', 'isDuplexEnabled');
-      }).then(function() {
-        return testStickySetting('fitToPage', 'isFitToPageEnabled');
-      }).then(function() {
-        return testStickySetting('headerFooter', 'isHeaderFooterEnabled');
-      }).then(function() {
-        return testStickySetting('layout', 'isLandscapeEnabled');
-      }).then(function() {
-        return testStickySetting('margins', 'marginsType');
-      }).then(function() {
-        return testStickySetting('mediaSize', 'mediaSize');
-      }).then(function() {
-        return testStickySetting('scaling', 'scaling');
-      }).then(function() {
-        return testStickySetting('fitToPage', 'isFitToPageEnabled');
-      });
+      return testStickySetting('collate', 'isCollateEnabled')
+          .then(function() {
+            return testStickySetting('color', 'isColorEnabled');
+          })
+          .then(function() {
+            return testStickySetting('cssBackground', 'isCssBackgroundEnabled');
+          })
+          .then(function() {
+            return testStickySetting('dpi', 'dpi');
+          })
+          .then(function() {
+            return testStickySetting('duplex', 'isDuplexEnabled');
+          })
+          .then(function() {
+            return testStickySetting('fitToPage', 'isFitToPageEnabled');
+          })
+          .then(function() {
+            return testStickySetting('headerFooter', 'isHeaderFooterEnabled');
+          })
+          .then(function() {
+            return testStickySetting('layout', 'isLandscapeEnabled');
+          })
+          .then(function() {
+            return testStickySetting('margins', 'marginsType');
+          })
+          .then(function() {
+            return testStickySetting('mediaSize', 'mediaSize');
+          })
+          .then(function() {
+            return testStickySetting('scaling', 'scaling');
+          })
+          .then(function() {
+            return testStickySetting('fitToPage', 'isFitToPageEnabled');
+          });
     });
   });
 
diff --git a/chrome/test/data/webui/print_preview/native_layer_stub.js b/chrome/test/data/webui/print_preview/native_layer_stub.js
index 77bd163..90caa2a9 100644
--- a/chrome/test/data/webui/print_preview/native_layer_stub.js
+++ b/chrome/test/data/webui/print_preview/native_layer_stub.js
@@ -4,8 +4,8 @@
 
 cr.define('print_preview', function() {
   /**
-  * Test version of the native layer.
-  */
+   * Test version of the native layer.
+   */
   class NativeLayerStub extends TestBrowserProxy {
     constructor() {
       super([
@@ -90,10 +90,8 @@
 
     /** @override */
     getPreview(printTicket, pageCount) {
-      this.methodCalled('getPreview', {
-        printTicket: printTicket,
-        pageCount: pageCount
-      });
+      this.methodCalled(
+          'getPreview', {printTicket: printTicket, pageCount: pageCount});
       const printTicketParsed = JSON.parse(printTicket);
       if (printTicketParsed.deviceName == this.badPrinterId_)
         return Promise.reject('SETTINGS_INVALID');
@@ -129,9 +127,9 @@
 
     /** @override */
     getPrinterCapabilities(printerId, type) {
-      this.methodCalled('getPrinterCapabilities', {
-        destinationId: printerId, printerType: type
-      });
+      this.methodCalled(
+          'getPrinterCapabilities',
+          {destinationId: printerId, printerType: type});
       if (type != print_preview.PrinterType.LOCAL_PRINTER)
         return Promise.reject();
       return this.localDestinationCapabilities_.get(printerId);
@@ -191,7 +189,8 @@
      *     provided.
      */
     setLocalDestinationCapabilities(response, opt_reject) {
-      this.localDestinationCapabilities_.set(response.printer.deviceName,
+      this.localDestinationCapabilities_.set(
+          response.printer.deviceName,
           opt_reject ? Promise.reject() : Promise.resolve(response));
     }
 
diff --git a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js
index 8ad4b12f..31d267c 100644
--- a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js
+++ b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js
@@ -169,8 +169,7 @@
   }
 };
 
-TEST_F('PrintPreviewSettingsSelectTest', 'CustomMediaNames',
-       function() {
+TEST_F('PrintPreviewSettingsSelectTest', 'CustomMediaNames', function() {
   this.runMochaTest(settings_select_test.TestNames.CustomMediaNames);
 });
 
@@ -195,13 +194,11 @@
   }
 };
 
-TEST_F('PrintPreviewPagesSettingsTest', 'ValidPageRanges',
-       function() {
+TEST_F('PrintPreviewPagesSettingsTest', 'ValidPageRanges', function() {
   this.runMochaTest(pages_settings_test.TestNames.ValidPageRanges);
 });
 
-TEST_F('PrintPreviewPagesSettingsTest', 'InvalidPageRanges',
-       function() {
+TEST_F('PrintPreviewPagesSettingsTest', 'InvalidPageRanges', function() {
   this.runMochaTest(pages_settings_test.TestNames.InvalidPageRanges);
 });
 
@@ -399,16 +396,19 @@
   }
 };
 
-TEST_F('PrintPreviewSystemDialogBrowserTest', 'LinkTriggersLocalPrint',
-       function() {
-  this.runMochaTest(system_dialog_browsertest.TestNames.LinkTriggersLocalPrint);
-});
+TEST_F(
+    'PrintPreviewSystemDialogBrowserTest', 'LinkTriggersLocalPrint',
+    function() {
+      this.runMochaTest(
+          system_dialog_browsertest.TestNames.LinkTriggersLocalPrint);
+    });
 
-TEST_F('PrintPreviewSystemDialogBrowserTest', 'InvalidSettingsDisableLink',
-       function() {
-  this.runMochaTest(
-      system_dialog_browsertest.TestNames.InvalidSettingsDisableLink);
-});
+TEST_F(
+    'PrintPreviewSystemDialogBrowserTest', 'InvalidSettingsDisableLink',
+    function() {
+      this.runMochaTest(
+          system_dialog_browsertest.TestNames.InvalidSettingsDisableLink);
+    });
 GEN('#endif');  // defined(OS_WIN) || defined(OS_MACOSX)
 
 PrintPreviewInvalidSettingsBrowserTest = class extends NewPrintPreviewTest {
@@ -437,33 +437,34 @@
   }
 };
 
-TEST_F('PrintPreviewInvalidSettingsBrowserTest', 'NoPDFPluginError',
-       function() {
-  this.runMochaTest(
-      invalid_settings_browsertest.TestNames.NoPDFPluginError);
-});
+TEST_F(
+    'PrintPreviewInvalidSettingsBrowserTest', 'NoPDFPluginError', function() {
+      this.runMochaTest(
+          invalid_settings_browsertest.TestNames.NoPDFPluginError);
+    });
 
-TEST_F('PrintPreviewInvalidSettingsBrowserTest', 'InvalidSettingsError',
-       function() {
-  this.runMochaTest(
-      invalid_settings_browsertest.TestNames.InvalidSettingsError);
-});
+TEST_F(
+    'PrintPreviewInvalidSettingsBrowserTest', 'InvalidSettingsError',
+    function() {
+      this.runMochaTest(
+          invalid_settings_browsertest.TestNames.InvalidSettingsError);
+    });
 
-TEST_F('PrintPreviewInvalidSettingsBrowserTest', 'InvalidCertificateError',
-       function() {
-  loadTimeData.overrideValues({isEnterpriseManaged: false});
-  this.runMochaTest(
-      invalid_settings_browsertest.TestNames.InvalidCertificateError);
-});
+TEST_F(
+    'PrintPreviewInvalidSettingsBrowserTest', 'InvalidCertificateError',
+    function() {
+      loadTimeData.overrideValues({isEnterpriseManaged: false});
+      this.runMochaTest(
+          invalid_settings_browsertest.TestNames.InvalidCertificateError);
+    });
 
-TEST_F('PrintPreviewInvalidSettingsBrowserTest',
-       'InvalidCertificateErrorReselectDestination',
-       function() {
-  loadTimeData.overrideValues({isEnterpriseManaged: false});
-  this.runMochaTest(
-      invalid_settings_browsertest.TestNames
-          .InvalidCertificateErrorReselectDestination);
-});
+TEST_F(
+    'PrintPreviewInvalidSettingsBrowserTest',
+    'InvalidCertificateErrorReselectDestination', function() {
+      loadTimeData.overrideValues({isEnterpriseManaged: false});
+      this.runMochaTest(invalid_settings_browsertest.TestNames
+                            .InvalidCertificateErrorReselectDestination);
+    });
 
 PrintPreviewDestinationSelectTest = class extends NewPrintPreviewTest {
   /** @override */
@@ -487,37 +488,41 @@
   }
 };
 
-TEST_F('PrintPreviewDestinationSelectTest', 'SingleRecentDestination',
-    function() {
-  this.runMochaTest(destination_select_test.TestNames.SingleRecentDestination);
-});
+TEST_F(
+    'PrintPreviewDestinationSelectTest', 'SingleRecentDestination', function() {
+      this.runMochaTest(
+          destination_select_test.TestNames.SingleRecentDestination);
+    });
 
-TEST_F('PrintPreviewDestinationSelectTest', 'MultipleRecentDestinations',
+TEST_F(
+    'PrintPreviewDestinationSelectTest', 'MultipleRecentDestinations',
     function() {
-  this.runMochaTest(
-      destination_select_test.TestNames.MultipleRecentDestinations);
-});
+      this.runMochaTest(
+          destination_select_test.TestNames.MultipleRecentDestinations);
+    });
 
-TEST_F('PrintPreviewDestinationSelectTest',
-    'MultipleRecentDestinationsOneRequest',
+TEST_F(
+    'PrintPreviewDestinationSelectTest', 'MultipleRecentDestinationsOneRequest',
     function() {
-  this.runMochaTest(
-      destination_select_test.TestNames.MultipleRecentDestinationsOneRequest);
-});
+      this.runMochaTest(destination_select_test.TestNames
+                            .MultipleRecentDestinationsOneRequest);
+    });
 
-TEST_F('PrintPreviewDestinationSelectTest', 'DefaultDestinationSelectionRules',
+TEST_F(
+    'PrintPreviewDestinationSelectTest', 'DefaultDestinationSelectionRules',
     function() {
-  this.runMochaTest(
-      destination_select_test.TestNames.DefaultDestinationSelectionRules);
-});
+      this.runMochaTest(
+          destination_select_test.TestNames.DefaultDestinationSelectionRules);
+    });
 
 GEN('#if !defined(OS_CHROMEOS)');
-TEST_F('PrintPreviewDestinationSelectTest', 'SystemDefaultPrinterPolicy',
+TEST_F(
+    'PrintPreviewDestinationSelectTest', 'SystemDefaultPrinterPolicy',
     function() {
-  loadTimeData.overrideValues({useSystemDefaultPrinter: true});
-  this.runMochaTest(
-      destination_select_test.TestNames.SystemDefaultPrinterPolicy);
-});
+      loadTimeData.overrideValues({useSystemDefaultPrinter: true});
+      this.runMochaTest(
+          destination_select_test.TestNames.SystemDefaultPrinterPolicy);
+    });
 GEN('#endif');
 
 PrintPreviewDestinationDialogTest = class extends NewPrintPreviewTest {
@@ -546,8 +551,7 @@
   }
 };
 
-TEST_F('PrintPreviewDestinationDialogTest', 'PrinterList',
-       function() {
+TEST_F('PrintPreviewDestinationDialogTest', 'PrinterList', function() {
   this.runMochaTest(destination_dialog_test.TestNames.PrinterList);
 });
 
@@ -571,15 +575,15 @@
   }
 };
 
-TEST_F('PrintPreviewAdvancedDialogTest', 'AdvancedSettings1Option',
-       function() {
+TEST_F('PrintPreviewAdvancedDialogTest', 'AdvancedSettings1Option', function() {
   this.runMochaTest(advanced_dialog_test.TestNames.AdvancedSettings1Option);
 });
 
-TEST_F('PrintPreviewAdvancedDialogTest', 'AdvancedSettings2Options',
-       function() {
-  this.runMochaTest(advanced_dialog_test.TestNames.AdvancedSettings2Options);
-});
+TEST_F(
+    'PrintPreviewAdvancedDialogTest', 'AdvancedSettings2Options', function() {
+      this.runMochaTest(
+          advanced_dialog_test.TestNames.AdvancedSettings2Options);
+    });
 
 PrintPreviewCustomMarginsTest = class extends NewPrintPreviewTest {
   /** @override */
@@ -602,8 +606,7 @@
   }
 };
 
-TEST_F('PrintPreviewCustomMarginsTest', 'ControlsCheck',
-       function() {
+TEST_F('PrintPreviewCustomMarginsTest', 'ControlsCheck', function() {
   this.runMochaTest(custom_margins_test.TestNames.ControlsCheck);
 });
 
@@ -631,30 +634,30 @@
   }
 };
 
-TEST_F('PrintPreviewNewDestinationSearchTest', 'ReceiveSuccessfulSetup',
-       function() {
-  this.runMochaTest(destination_search_test.TestNames.ReceiveSuccessfulSetup);
-});
+TEST_F(
+    'PrintPreviewNewDestinationSearchTest', 'ReceiveSuccessfulSetup',
+    function() {
+      this.runMochaTest(
+          destination_search_test.TestNames.ReceiveSuccessfulSetup);
+    });
 
 GEN('#if defined(OS_CHROMEOS)');
-TEST_F('PrintPreviewNewDestinationSearchTest', 'ResolutionFails',
-       function() {
+TEST_F('PrintPreviewNewDestinationSearchTest', 'ResolutionFails', function() {
   this.runMochaTest(destination_search_test.TestNames.ResolutionFails);
 });
 
-TEST_F('PrintPreviewNewDestinationSearchTest', 'ReceiveFailedSetup',
-       function() {
-  this.runMochaTest(destination_search_test.TestNames.ReceiveFailedSetup);
-});
+TEST_F(
+    'PrintPreviewNewDestinationSearchTest', 'ReceiveFailedSetup', function() {
+      this.runMochaTest(destination_search_test.TestNames.ReceiveFailedSetup);
+    });
 
 GEN('#else');  // !defined(OS_CHROMEOS)
-TEST_F('PrintPreviewNewDestinationSearchTest', 'GetCapabilitiesFails',
-       function() {
-  this.runMochaTest(destination_search_test.TestNames.GetCapabilitiesFails);
-});
+TEST_F(
+    'PrintPreviewNewDestinationSearchTest', 'GetCapabilitiesFails', function() {
+      this.runMochaTest(destination_search_test.TestNames.GetCapabilitiesFails);
+    });
 GEN('#endif');  // defined(OS_CHROMEOS)
 
-TEST_F('PrintPreviewNewDestinationSearchTest', 'CloudKioskPrinter',
-       function() {
+TEST_F('PrintPreviewNewDestinationSearchTest', 'CloudKioskPrinter', function() {
   this.runMochaTest(destination_search_test.TestNames.CloudKioskPrinter);
 });
diff --git a/chrome/test/data/webui/print_preview/pages_settings_test.js b/chrome/test/data/webui/print_preview/pages_settings_test.js
index 7bfefd0..e127dc88 100644
--- a/chrome/test/data/webui/print_preview/pages_settings_test.js
+++ b/chrome/test/data/webui/print_preview/pages_settings_test.js
@@ -61,8 +61,8 @@
 
       // Select custom
       pagesSection.$$('#custom-radio-button').checked = true;
-      pagesSection.$$('#all-radio-button').dispatchEvent(
-          new CustomEvent('change'));
+      pagesSection.$$('#all-radio-button')
+          .dispatchEvent(new CustomEvent('change'));
 
       // Set input string
       const input = pagesSection.$.pageSettingsCustomInput;
@@ -88,28 +88,35 @@
       const oneToHundred = Array.from({length: 100}, (x, i) => i + 1);
       const tenToHundred = Array.from({length: 91}, (x, i) => i + 10);
 
-      return setupInput('1, 2, 3, 1, 56', 100).then(function() {
-        validateState([1, 2, 3, 56]);
-        return setupInput('1-3, 6-9, 6-10', 100);
-      }).then(function() {
-        validateState([1, 2, 3, 6, 7, 8, 9, 10]);
-        return setupInput('10-', 100);
-      }).then(function() {
-        validateState(tenToHundred);
-        return setupInput('10-100', 100);
-      }).then(function() {
-        validateState(tenToHundred);
-        return setupInput('-', 100);
-      }).then(function() {
-        validateState(oneToHundred);
-        // https://crbug.com/806165
-        return setupInput('1\u30012\u30013\u30011\u300156', 100);
-      }).then(function() {
-        validateState([1, 2, 3, 56]);
-        return setupInput('1,2,3\u30011\u300156', 100);
-      }).then(function() {
-        validateState([1, 2, 3, 56]);
-      });
+      return setupInput('1, 2, 3, 1, 56', 100)
+          .then(function() {
+            validateState([1, 2, 3, 56]);
+            return setupInput('1-3, 6-9, 6-10', 100);
+          })
+          .then(function() {
+            validateState([1, 2, 3, 6, 7, 8, 9, 10]);
+            return setupInput('10-', 100);
+          })
+          .then(function() {
+            validateState(tenToHundred);
+            return setupInput('10-100', 100);
+          })
+          .then(function() {
+            validateState(tenToHundred);
+            return setupInput('-', 100);
+          })
+          .then(function() {
+            validateState(oneToHundred);
+            // https://crbug.com/806165
+            return setupInput('1\u30012\u30013\u30011\u300156', 100);
+          })
+          .then(function() {
+            validateState([1, 2, 3, 56]);
+            return setupInput('1,2,3\u30011\u300156', 100);
+          })
+          .then(function() {
+            validateState([1, 2, 3, 56]);
+          });
     });
 
     // Tests that the correct error messages are shown for different user
@@ -121,34 +128,42 @@
       /** @param {string} expectedMessage The expected error message. */
       const validateState = function(expectedMessage) {
         assertFalse(pagesSection.$$('.hint').hidden);
-        assertEquals(expectedMessage,
-                     pagesSection.$$('.hint').textContent.trim());
+        assertEquals(
+            expectedMessage, pagesSection.$$('.hint').textContent.trim());
       };
 
-      return setupInput('10-100000', 100).then(function() {
-        validateState(limitError + '100');
-        return setupInput('1, 100000', 100);
-      }).then(function() {
-        validateState(limitError + '100');
-        return setupInput('1, 2, 0, 56', 100);
-      }).then(function() {
-        validateState(syntaxError);
-        return setupInput('-1, 1, 2,, 56', 100);
-      }).then(function() {
-        validateState(syntaxError);
-        return setupInput('1,2,56-40', 100);
-      }).then(function() {
-        validateState(syntaxError);
-        return setupInput('101-110', 100);
-      }).then(function() {
-        validateState(limitError + '100');
-        return setupInput('1\u30012\u30010\u300156', 100);
-      }).then(function() {
-        validateState(syntaxError);
-        return setupInput('-1,1,2\u3001\u300156', 100);
-      }).then(function() {
-        validateState(syntaxError);
-      });
+      return setupInput('10-100000', 100)
+          .then(function() {
+            validateState(limitError + '100');
+            return setupInput('1, 100000', 100);
+          })
+          .then(function() {
+            validateState(limitError + '100');
+            return setupInput('1, 2, 0, 56', 100);
+          })
+          .then(function() {
+            validateState(syntaxError);
+            return setupInput('-1, 1, 2,, 56', 100);
+          })
+          .then(function() {
+            validateState(syntaxError);
+            return setupInput('1,2,56-40', 100);
+          })
+          .then(function() {
+            validateState(syntaxError);
+            return setupInput('101-110', 100);
+          })
+          .then(function() {
+            validateState(limitError + '100');
+            return setupInput('1\u30012\u30010\u300156', 100);
+          })
+          .then(function() {
+            validateState(syntaxError);
+            return setupInput('-1,1,2\u3001\u300156', 100);
+          })
+          .then(function() {
+            validateState(syntaxError);
+          });
     });
   });
 
diff --git a/chrome/test/data/webui/print_preview/preview_generation_test.js b/chrome/test/data/webui/print_preview/preview_generation_test.js
index 4402100..5278bb9 100644
--- a/chrome/test/data/webui/print_preview/preview_generation_test.js
+++ b/chrome/test/data/webui/print_preview/preview_generation_test.js
@@ -59,16 +59,18 @@
       previewArea.plugin_ = new print_preview.PDFPluginStub(
           previewArea.onPluginLoad_.bind(previewArea));
       document.body.appendChild(page);
-      return Promise.all([
-        nativeLayer.whenCalled('getInitialSettings'),
-        nativeLayer.whenCalled('getPrinterCapabilities'),
-      ]).then(function() {
-        if (!documentInfo)
-          initDocumentInfo(false, false);
-        page.set('documentInfo_', documentInfo);
-        page.notifyPath('documentInfo_.isModifiable');
-        return nativeLayer.whenCalled('getPreview');
-      });
+      return Promise
+          .all([
+            nativeLayer.whenCalled('getInitialSettings'),
+            nativeLayer.whenCalled('getPrinterCapabilities'),
+          ])
+          .then(function() {
+            if (!documentInfo)
+              initDocumentInfo(false, false);
+            page.set('documentInfo_', documentInfo);
+            page.notifyPath('documentInfo_.isModifiable');
+            return nativeLayer.whenCalled('getPreview');
+          });
     }
 
     /**
@@ -100,21 +102,25 @@
      *     UI state have been verified.
      */
     function testSimpleSetting(
-        settingName, initialSettingValue, updatedSettingValue,
-        ticketKey, initialTicketValue, updatedTicketValue) {
-      return initialize().then(function(args) {
-        const originalTicket = JSON.parse(args.printTicket);
-        assertEquals(initialTicketValue, originalTicket[ticketKey]);
-        nativeLayer.resetResolver('getPreview');
-        assertEquals(initialSettingValue, page.getSettingValue(settingName));
-        page.setSetting(settingName, updatedSettingValue);
-        return nativeLayer.whenCalled('getPreview');
-      }).then(function(args) {
-        assertEquals(updatedSettingValue, page.getSettingValue(settingName));
-        const ticket = JSON.parse(args.printTicket);
-        assertEquals(updatedTicketValue, ticket[ticketKey]);
-        assertEquals(2, ticket.requestID);
-      });
+        settingName, initialSettingValue, updatedSettingValue, ticketKey,
+        initialTicketValue, updatedTicketValue) {
+      return initialize()
+          .then(function(args) {
+            const originalTicket = JSON.parse(args.printTicket);
+            assertEquals(initialTicketValue, originalTicket[ticketKey]);
+            nativeLayer.resetResolver('getPreview');
+            assertEquals(
+                initialSettingValue, page.getSettingValue(settingName));
+            page.setSetting(settingName, updatedSettingValue);
+            return nativeLayer.whenCalled('getPreview');
+          })
+          .then(function(args) {
+            assertEquals(
+                updatedSettingValue, page.getSettingValue(settingName));
+            const ticket = JSON.parse(args.printTicket);
+            assertEquals(updatedTicketValue, ticket[ticketKey]);
+            assertEquals(2, ticket.requestID);
+          });
     }
 
     /** Validate changing the color updates the preview. */
@@ -161,60 +167,68 @@
     /** Validate changing the paper size updates the preview. */
     test(assert(TestNames.MediaSize), function() {
       const mediaSizeCapability =
-          print_preview_test_utils.getCddTemplate('FooDevice').capabilities
-              .printer.media_size;
+          print_preview_test_utils.getCddTemplate('FooDevice')
+              .capabilities.printer.media_size;
       const letterOption = mediaSizeCapability.option[0];
       const squareOption = mediaSizeCapability.option[1];
-      return initialize().then(function(args) {
-        const originalTicket = JSON.parse(args.printTicket);
-        assertEquals(letterOption.width_microns,
-                     originalTicket.mediaSize.width_microns);
-        assertEquals(letterOption.height_microns,
-                     originalTicket.mediaSize.height_microns);
-        nativeLayer.resetResolver('getPreview');
-        const mediaSizeSetting = page.getSettingValue('mediaSize');
-        assertEquals(letterOption.width_microns,
-                     mediaSizeSetting.width_microns);
-        assertEquals(letterOption.height_microns,
-                     mediaSizeSetting.height_microns);
-        page.setSetting('mediaSize', squareOption);
-        return nativeLayer.whenCalled('getPreview');
-      }).then(function(args) {
-        const mediaSizeSettingUpdated = page.getSettingValue('mediaSize');
-        assertEquals(squareOption.width_microns,
-                     mediaSizeSettingUpdated.width_microns);
-        assertEquals(squareOption.height_microns,
-                     mediaSizeSettingUpdated.height_microns);
-        const ticket = JSON.parse(args.printTicket);
-        assertEquals(squareOption.width_microns,
-                     ticket.mediaSize.width_microns);
-        assertEquals(squareOption.height_microns,
-                     ticket.mediaSize.height_microns);
-        nativeLayer.resetResolver('getPreview');
-        assertEquals(2, ticket.requestID);
-      });
+      return initialize()
+          .then(function(args) {
+            const originalTicket = JSON.parse(args.printTicket);
+            assertEquals(
+                letterOption.width_microns,
+                originalTicket.mediaSize.width_microns);
+            assertEquals(
+                letterOption.height_microns,
+                originalTicket.mediaSize.height_microns);
+            nativeLayer.resetResolver('getPreview');
+            const mediaSizeSetting = page.getSettingValue('mediaSize');
+            assertEquals(
+                letterOption.width_microns, mediaSizeSetting.width_microns);
+            assertEquals(
+                letterOption.height_microns, mediaSizeSetting.height_microns);
+            page.setSetting('mediaSize', squareOption);
+            return nativeLayer.whenCalled('getPreview');
+          })
+          .then(function(args) {
+            const mediaSizeSettingUpdated = page.getSettingValue('mediaSize');
+            assertEquals(
+                squareOption.width_microns,
+                mediaSizeSettingUpdated.width_microns);
+            assertEquals(
+                squareOption.height_microns,
+                mediaSizeSettingUpdated.height_microns);
+            const ticket = JSON.parse(args.printTicket);
+            assertEquals(
+                squareOption.width_microns, ticket.mediaSize.width_microns);
+            assertEquals(
+                squareOption.height_microns, ticket.mediaSize.height_microns);
+            nativeLayer.resetResolver('getPreview');
+            assertEquals(2, ticket.requestID);
+          });
     });
 
     /** Validate changing the page range updates the preview. */
     test(assert(TestNames.PageRange), function() {
-      return initialize().then(function(args) {
-        const originalTicket = JSON.parse(args.printTicket);
-        // Ranges is empty for full document.
-        assertEquals(0, page.getSettingValue('ranges').length);
-        assertEquals(0, originalTicket.pageRange.length);
-        nativeLayer.resetResolver('getPreview');
-        page.setSetting('ranges', [{from: 1, to: 2}]);
-        return nativeLayer.whenCalled('getPreview');
-      }).then(function(args) {
-        const setting = page.getSettingValue('ranges');
-        assertEquals(1, setting.length);
-        assertEquals(1, setting[0].from);
-        assertEquals(2, setting[0].to);
-        const ticket = JSON.parse(args.printTicket);
-        assertEquals(1, ticket.pageRange.length);
-        assertEquals(1, ticket.pageRange[0].from);
-        assertEquals(2, ticket.pageRange[0].to);
-      });
+      return initialize()
+          .then(function(args) {
+            const originalTicket = JSON.parse(args.printTicket);
+            // Ranges is empty for full document.
+            assertEquals(0, page.getSettingValue('ranges').length);
+            assertEquals(0, originalTicket.pageRange.length);
+            nativeLayer.resetResolver('getPreview');
+            page.setSetting('ranges', [{from: 1, to: 2}]);
+            return nativeLayer.whenCalled('getPreview');
+          })
+          .then(function(args) {
+            const setting = page.getSettingValue('ranges');
+            assertEquals(1, setting.length);
+            assertEquals(1, setting[0].from);
+            assertEquals(2, setting[0].to);
+            const ticket = JSON.parse(args.printTicket);
+            assertEquals(1, ticket.pageRange.length);
+            assertEquals(1, ticket.pageRange[0].from);
+            assertEquals(2, ticket.pageRange[0].to);
+          });
     });
 
     /** Validate changing the selection only setting updates the preview. */
@@ -228,8 +242,7 @@
 
     /** Validate changing the scaling updates the preview. */
     test(assert(TestNames.Scaling), function() {
-      return testSimpleSetting(
-          'scaling', '100', '90', 'scaleFactor', 100, 90);
+      return testSimpleSetting('scaling', '100', '90', 'scaleFactor', 100, 90);
     });
 
     /**
@@ -245,26 +258,28 @@
 
     /** Validate changing the destination updates the preview. */
     test(assert(TestNames.Destination), function() {
-      return initialize().then(function(args) {
-        const originalTicket = JSON.parse(args.printTicket);
-        assertEquals('FooDevice', page.destination_.id);
-        assertEquals('FooDevice', originalTicket.deviceName);
-        const barDestination = new print_preview.Destination(
-            'BarDevice', print_preview.DestinationType.LOCAL,
-            print_preview.DestinationOrigin.LOCAL, 'BarName',
-            false /*isRecent*/,
-            print_preview.DestinationConnectionStatus.ONLINE);
-        barDestination.capabilities =
-            print_preview_test_utils.getCddTemplate(barDestination.id)
-                .capabilities;
-        nativeLayer.resetResolver('getPreview');
-        page.set('destination_', barDestination);
-        return nativeLayer.whenCalled('getPreview');
-      }).then(function(args) {
-        assertEquals('BarDevice', page.destination_.id);
-        const ticket = JSON.parse(args.printTicket);
-        assertEquals('BarDevice', ticket.deviceName);
-      });
+      return initialize()
+          .then(function(args) {
+            const originalTicket = JSON.parse(args.printTicket);
+            assertEquals('FooDevice', page.destination_.id);
+            assertEquals('FooDevice', originalTicket.deviceName);
+            const barDestination = new print_preview.Destination(
+                'BarDevice', print_preview.DestinationType.LOCAL,
+                print_preview.DestinationOrigin.LOCAL, 'BarName',
+                false /*isRecent*/,
+                print_preview.DestinationConnectionStatus.ONLINE);
+            barDestination.capabilities =
+                print_preview_test_utils.getCddTemplate(barDestination.id)
+                    .capabilities;
+            nativeLayer.resetResolver('getPreview');
+            page.set('destination_', barDestination);
+            return nativeLayer.whenCalled('getPreview');
+          })
+          .then(function(args) {
+            assertEquals('BarDevice', page.destination_.id);
+            const ticket = JSON.parse(args.printTicket);
+            assertEquals('BarDevice', ticket.deviceName);
+          });
     });
   });
 
diff --git a/chrome/test/data/webui/print_preview/print_preview_destination_search_test.js b/chrome/test/data/webui/print_preview/print_preview_destination_search_test.js
index 1701380..28827db9 100644
--- a/chrome/test/data/webui/print_preview/print_preview_destination_search_test.js
+++ b/chrome/test/data/webui/print_preview/print_preview_destination_search_test.js
@@ -5,7 +5,7 @@
 const ROOT_PATH = '../../../../../';
 
 GEN_INCLUDE(
-        [ROOT_PATH + 'chrome/test/data/webui/polymer_browser_test_base.js']);
+    [ROOT_PATH + 'chrome/test/data/webui/polymer_browser_test_base.js']);
 
 /**
  * Test fixture for DestinationSearch of Print Preview.
@@ -25,14 +25,14 @@
 
   /** @override */
   extraLibraries: PolymerTest.getLibraries(ROOT_PATH).concat([
-      ROOT_PATH + 'chrome/test/data/webui/test_browser_proxy.js',
-      'native_layer_stub.js',
-      ROOT_PATH + 'chrome/test/data/webui/settings/test_util.js',
-    ]),
+    ROOT_PATH + 'chrome/test/data/webui/test_browser_proxy.js',
+    'native_layer_stub.js',
+    ROOT_PATH + 'chrome/test/data/webui/settings/test_util.js',
+  ]),
 
 };
 
-TEST_F('PrintPreviewDestinationSearchTest', 'Select', function(){
+TEST_F('PrintPreviewDestinationSearchTest', 'Select', function() {
   suite('DestinationSearchTest', function() {
     let root_;
 
@@ -92,12 +92,10 @@
 
     function requestSetup(destId, destinationSearch) {
       const origin = cr.isChromeOS ? print_preview.DestinationOrigin.CROS :
-                                   print_preview.DestinationOrigin.LOCAL;
+                                     print_preview.DestinationOrigin.LOCAL;
 
-      const dest = new print_preview.Destination(destId,
-          print_preview.DestinationType.LOCAL,
-          origin,
-          "displayName",
+      const dest = new print_preview.Destination(
+          destId, print_preview.DestinationType.LOCAL, origin, 'displayName',
           print_preview.DestinationConnectionStatus.ONLINE);
 
       // Add the destination to the list.
@@ -126,28 +124,32 @@
     });
 
     test('ResolutionFails', function() {
-      const destId = "001122DEADBEEF";
+      const destId = '001122DEADBEEF';
       if (cr.isChromeOS) {
-        nativeLayer_.setSetupPrinterResponse(true, {printerId: destId,
-                                                    success: false,});
+        nativeLayer_.setSetupPrinterResponse(true, {
+          printerId: destId,
+          success: false,
+        });
       } else {
-        nativeLayer_.setLocalDestinationCapabilities({printer: {
-                                                          deviceName: destId,
-                                                      },
-                                                      capabilities: getCaps()},
-                                                     true);
+        nativeLayer_.setLocalDestinationCapabilities(
+            {
+              printer: {
+                deviceName: destId,
+              },
+              capabilities: getCaps()
+            },
+            true);
       }
       requestSetup(destId, destinationSearch_);
       const callback =
           cr.isChromeOS ? 'setupPrinter' : 'getPrinterCapabilities';
-      return nativeLayer_.whenCalled(callback).then(
-          function(args) {
-            assertEquals(destId, cr.isChromeOS ? args : args.destinationId);
-          });
+      return nativeLayer_.whenCalled(callback).then(function(args) {
+        assertEquals(destId, cr.isChromeOS ? args : args.destinationId);
+      });
     });
 
     test('ReceiveSuccessfulSetup', function() {
-      const destId = "00112233DEADBEEF";
+      const destId = '00112233DEADBEEF';
       const response = {
         printerId: destId,
         capabilities: getCaps(),
@@ -156,10 +158,12 @@
       if (cr.isChromeOS)
         nativeLayer_.setSetupPrinterResponse(false, response);
       else
-        nativeLayer_.setLocalDestinationCapabilities({printer: {
-                                                          deviceName: destId,
-                                                      },
-                                                      capabilities: getCaps()});
+        nativeLayer_.setLocalDestinationCapabilities({
+          printer: {
+            deviceName: destId,
+          },
+          capabilities: getCaps()
+        });
 
       const waiter = test_util.eventToPromise(
           print_preview.DestinationStore.EventType.DESTINATION_SELECT,
@@ -167,8 +171,8 @@
       requestSetup(destId, destinationSearch_);
       const callback =
           cr.isChromeOS ? 'setupPrinter' : 'getPrinterCapabilities';
-      return Promise.all([nativeLayer_.whenCalled(callback), waiter]).then(
-          function(results) {
+      return Promise.all([nativeLayer_.whenCalled(callback), waiter])
+          .then(function(results) {
             const actualId =
                 cr.isChromeOS ? results[0] : results[0].destinationId;
             assertEquals(destId, actualId);
@@ -189,8 +193,8 @@
         };
         nativeLayer_.setSetupPrinterResponse(false, response);
         requestSetup(destId, destinationSearch_);
-        return nativeLayer_.whenCalled('setupPrinter').then(
-            function (actualDestId) {
+        return nativeLayer_.whenCalled('setupPrinter')
+            .then(function(actualDestId) {
               // Selection should not change on ChromeOS.
               assertEquals(destId, actualDestId);
               assertEquals(null, destinationStore_.selectedDestination);
@@ -202,10 +206,9 @@
       const printerId = 'cloud-printer-id';
 
       // Create cloud destination.
-      const cloudDest = new print_preview.Destination(printerId,
-          print_preview.DestinationType.GOOGLE,
-          print_preview.DestinationOrigin.DEVICE,
-          "displayName",
+      const cloudDest = new print_preview.Destination(
+          printerId, print_preview.DestinationType.GOOGLE,
+          print_preview.DestinationOrigin.DEVICE, 'displayName',
           print_preview.DestinationConnectionStatus.ONLINE);
       cloudDest.capabilities = getCaps();
 
diff --git a/chrome/test/data/webui/print_preview/print_preview_test_utils.js b/chrome/test/data/webui/print_preview/print_preview_test_utils.js
index fe08bba..018b429 100644
--- a/chrome/test/data/webui/print_preview/print_preview_test_utils.js
+++ b/chrome/test/data/webui/print_preview/print_preview_test_utils.js
@@ -52,31 +52,30 @@
           },
           duplex: {
             option: [
-              {type: 'NO_DUPLEX', is_default: true},
-              {type: 'LONG_EDGE'},
+              {type: 'NO_DUPLEX', is_default: true}, {type: 'LONG_EDGE'},
               {type: 'SHORT_EDGE'}
             ]
           },
           page_orientation: {
             option: [
-              {type: 'PORTRAIT', is_default: true},
-              {type: 'LANDSCAPE'},
+              {type: 'PORTRAIT', is_default: true}, {type: 'LANDSCAPE'},
               {type: 'AUTO'}
             ]
           },
           media_size: {
             option: [
-              { name: 'NA_LETTER',
+              {
+                name: 'NA_LETTER',
                 width_microns: 215900,
                 height_microns: 279400,
                 is_default: true,
-                custom_display_name: "Letter",
+                custom_display_name: 'Letter',
               },
               {
                 name: 'CUSTOM_SQUARE',
                 width_microns: 215900,
                 height_microns: 215900,
-                custom_display_name: "CUSTOM_SQUARE",
+                custom_display_name: 'CUSTOM_SQUARE',
               }
             ]
           }
@@ -116,16 +115,16 @@
 
     // Add new capability.
     template.capabilities.printer.vendor_capability.push({
-        display_name: 'Paper Type',
-        id: 'Paper Type',
-        type: 'SELECT',
-        select_cap: {
-            option: [
-                {display_name: 'Standard', value: 0, is_default: true},
-                {display_name: 'Recycled', value: 1},
-                {display_name: 'Special', value: 2}
-            ]
-        }
+      display_name: 'Paper Type',
+      id: 'Paper Type',
+      type: 'SELECT',
+      select_cap: {
+        option: [
+          {display_name: 'Standard', value: 0, is_default: true},
+          {display_name: 'Recycled', value: 1},
+          {display_name: 'Special', value: 2}
+        ]
+      }
     });
     return template;
   }
@@ -160,8 +159,10 @@
   function getDefaultMediaSize(device) {
     const size = device.capabilities.printer.media_size.option.find(
         opt => opt.is_default);
-    return { width_microns: size.width_microns,
-             height_microns: size.height_microns };
+    return {
+      width_microns: size.width_microns,
+      height_microns: size.height_microns
+    };
   }
 
   /**
@@ -170,8 +171,9 @@
    * @return {string} The default orientation.
    */
   function getDefaultOrientation(device) {
-    return device.capabilities.printer.page_orientation.option.find(
-        opt => opt.is_default).type;
+    return device.capabilities.printer.page_orientation.option
+        .find(opt => opt.is_default)
+        .type;
   }
 
   /**
@@ -186,19 +188,18 @@
     const origin = cr.isChromeOS ? print_preview.DestinationOrigin.CROS :
                                    print_preview.DestinationOrigin.LOCAL;
     // Five destinations. FooDevice is the system default.
-    [ { id: 'ID1', name: 'One' },
-      { id: 'ID2', name: 'Two' },
-      { id: 'ID3', name: 'Three'},
-      { id: 'ID4', name: 'Four'},
-      { id: 'FooDevice', name: 'FooName' }].forEach((info, index) => {
-      const destination = new print_preview.Destination(
-        info.id, print_preview.DestinationType.LOCAL, origin, info.name,
-        false, print_preview.DestinationConnectionStatus.ONLINE);
-      nativeLayer.setLocalDestinationCapabilities(
-          print_preview_test_utils.getCddTemplate(info.id, info.name));
-      localDestinations.push({ printerName: info.name, deviceName: info.id });
-      destinations.push(destination);
-    });
+    [{id: 'ID1', name: 'One'}, {id: 'ID2', name: 'Two'},
+     {id: 'ID3', name: 'Three'}, {id: 'ID4', name: 'Four'},
+     {id: 'FooDevice', name: 'FooName'}]
+        .forEach((info, index) => {
+          const destination = new print_preview.Destination(
+              info.id, print_preview.DestinationType.LOCAL, origin, info.name,
+              false, print_preview.DestinationConnectionStatus.ONLINE);
+          nativeLayer.setLocalDestinationCapabilities(
+              print_preview_test_utils.getCddTemplate(info.id, info.name));
+          localDestinations.push({printerName: info.name, deviceName: info.id});
+          destinations.push(destination);
+        });
     return destinations;
   }
 
@@ -212,17 +213,16 @@
 
     return {
       option: [
-        { name: 'CUSTOM',
+        {
+          name: 'CUSTOM',
           width_microns: 15900,
           height_microns: 79400,
           is_default: true,
-          custom_display_name_localized: [
-            { locale: navigator.language,
-              value: customLocalizedMediaName
-            }
-          ]
+          custom_display_name_localized:
+              [{locale: navigator.language, value: customLocalizedMediaName}]
         },
-        { name: 'CUSTOM',
+        {
+          name: 'CUSTOM',
           width_microns: 15900,
           height_microns: 79400,
           custom_display_name: customMediaName
diff --git a/chrome/test/data/webui/print_preview/print_preview_tests.js b/chrome/test/data/webui/print_preview/print_preview_tests.js
index 32e3b37..6525792 100644
--- a/chrome/test/data/webui/print_preview/print_preview_tests.js
+++ b/chrome/test/data/webui/print_preview/print_preview_tests.js
@@ -79,8 +79,8 @@
    */
   function waitForPrinterToUpdatePreview() {
     return Promise.all([
-        nativeLayer.whenCalled('getPrinterCapabilities'),
-        nativeLayer.whenCalled('getPreview'),
+      nativeLayer.whenCalled('getPrinterCapabilities'),
+      nativeLayer.whenCalled('getPreview'),
     ]);
   }
 
@@ -92,8 +92,8 @@
   function checkSectionVisible(section, visible) {
     assertNotEquals(null, section);
     expectEquals(
-        visible,
-        section.classList.contains('visible'), 'section=' + section.id);
+        visible, section.classList.contains('visible'),
+        'section=' + section.id);
   }
 
   /**
@@ -102,9 +102,9 @@
    */
   function checkElementDisplayed(el, isDisplayed) {
     assertNotEquals(null, el);
-    expectEquals(isDisplayed,
-                 !el.hidden,
-                 'element="' + el.id + '" of class "' + el.classList + '"');
+    expectEquals(
+        isDisplayed, !el.hidden,
+        'element="' + el.id + '" of class "' + el.classList + '"');
   }
 
   /**
@@ -121,24 +121,18 @@
         printer: {
           page_orientation: {
             option: [
-              {type: 'AUTO', is_default: true},
-              {type: 'PORTRAIT'},
+              {type: 'AUTO', is_default: true}, {type: 'PORTRAIT'},
               {type: 'LANDSCAPE'}
             ]
           },
-          color: {
-            option: [
-              {type: 'STANDARD_COLOR', is_default: true}
-            ]
-          },
+          color: {option: [{type: 'STANDARD_COLOR', is_default: true}]},
           media_size: {
-            option: [
-              { name: 'NA_LETTER',
-                width_microns: 0,
-                height_microns: 0,
-                is_default: true
-              }
-            ]
+            option: [{
+              name: 'NA_LETTER',
+              width_microns: 0,
+              height_microns: 0,
+              is_default: true
+            }]
           }
         }
       }
@@ -154,50 +148,54 @@
     const cdd =
         print_preview_test_utils.getCddTemplate('ID1', 'One').capabilities;
     return JSON.stringify({
-        version: 2,
-        recentDestinations: [
-          {
-            id: 'ID1',
-            origin: origin,
-            account: '',
-            capabilities: cdd,
-            displayName: 'One',
-            extensionId: '',
-            extensionName: '',
-          }, {
-            id: 'ID2',
-            origin: origin,
-            account: '',
-            capabilities: cdd,
-            displayName: 'Two',
-            extensionId: '',
-            extensionName: '',
-          }, {
-            id: 'ID3',
-            origin: origin,
-            account: '',
-            capabilities: cdd,
-            displayName: 'Three',
-            extensionId: '',
-            extensionName: '',
-          },
-        ],
-        dpi: {horizontal_dpi: 100, vertical_dpi: 100},
-        mediaSize: {name: 'CUSTOM_SQUARE',
-                    width_microns: 215900,
-                    height_microns: 215900,
-                    custom_display_name: 'CUSTOM_SQUARE'},
-        customMargins: {top: 74, right: 74, bottom: 74, left: 74},
-        vendorOptions: {},
-        marginsType: print_preview.ticket_items.MarginsTypeValue.CUSTOM,
-        scaling: '90',
-        isHeaderFooterEnabled: true,
-        isCssBackgroundEnabled: true,
-        isFitToPageEnabled: true,
-        isCollateEnabled: true,
-        isDuplexEnabled: true,
-        isLandscapeEnabled: true,
-        isColorEnabled: true,
+      version: 2,
+      recentDestinations: [
+        {
+          id: 'ID1',
+          origin: origin,
+          account: '',
+          capabilities: cdd,
+          displayName: 'One',
+          extensionId: '',
+          extensionName: '',
+        },
+        {
+          id: 'ID2',
+          origin: origin,
+          account: '',
+          capabilities: cdd,
+          displayName: 'Two',
+          extensionId: '',
+          extensionName: '',
+        },
+        {
+          id: 'ID3',
+          origin: origin,
+          account: '',
+          capabilities: cdd,
+          displayName: 'Three',
+          extensionId: '',
+          extensionName: '',
+        },
+      ],
+      dpi: {horizontal_dpi: 100, vertical_dpi: 100},
+      mediaSize: {
+        name: 'CUSTOM_SQUARE',
+        width_microns: 215900,
+        height_microns: 215900,
+        custom_display_name: 'CUSTOM_SQUARE'
+      },
+      customMargins: {top: 74, right: 74, bottom: 74, left: 74},
+      vendorOptions: {},
+      marginsType: print_preview.ticket_items.MarginsTypeValue.CUSTOM,
+      scaling: '90',
+      isHeaderFooterEnabled: true,
+      isCssBackgroundEnabled: true,
+      isFitToPageEnabled: true,
+      isCollateEnabled: true,
+      isDuplexEnabled: true,
+      isLandscapeEnabled: true,
+      isColorEnabled: true,
     });
   }
 
@@ -243,8 +241,8 @@
   function openAdvancedSettings() {
     // Check for button and click to view advanced settings section.
     const advancedOptionsSettingsButton =
-        $('advanced-options-settings').
-        querySelector('.advanced-options-settings-button');
+        $('advanced-options-settings')
+            .querySelector('.advanced-options-settings-button');
     checkElementDisplayed(advancedOptionsSettingsButton, true);
     // Button is disabled during testing due to test version of
     // testPluginCompatibility() being set to always return false. Enable button
@@ -270,8 +268,8 @@
 
     // Check advanced settings overlay is visible by checking that the close
     // button is displayed.
-    const advancedSettingsCloseButton = $('advanced-settings').
-        querySelector('.close-button');
+    const advancedSettingsCloseButton =
+        $('advanced-settings').querySelector('.close-button');
     checkElementDisplayed(advancedSettingsCloseButton, true);
   }
 
@@ -287,16 +285,15 @@
     initialSettings.serializedAppStateStr = JSON.stringify({
       version: 2,
       recentDestinations: [
-          print_preview.makeRecentDestination(printers[0]),
-          print_preview.makeRecentDestination(printers[1]),
+        print_preview.makeRecentDestination(printers[0]),
+        print_preview.makeRecentDestination(printers[1]),
       ],
     });
 
     nativeLayer.setInitialSettings(initialSettings);
     localDestinationInfos = [];
     nativeLayer.setLocalDestinations(localDestinationInfos);
-    printPreview.userInfo_.setUsers(
-        'foo@chromium.org', ['foo@chromium.org']);
+    printPreview.userInfo_.setUsers('foo@chromium.org', ['foo@chromium.org']);
     printPreview.initialize();
     cr.webUIListenerCallback('use-cloud-print', 'cloudprint url', false);
     printers.forEach(printer => {
@@ -307,8 +304,9 @@
   /** @return {boolean} */
   function isPrintAsImageEnabled() {
     // Should be enabled by default on non Windows/Mac.
-    return (!cr.isWindows && !cr.isMac &&
-            loadTimeData.getBoolean('printPdfAsImageEnabled'));
+    return (
+        !cr.isWindows && !cr.isMac &&
+        loadTimeData.getBoolean('printPdfAsImageEnabled'));
   }
 
   const suiteName = 'PrintPreview';
@@ -323,11 +321,10 @@
     });
 
     setup(function() {
-      initialSettings =
-          print_preview_test_utils.getDefaultInitialSettings();
+      initialSettings = print_preview_test_utils.getDefaultInitialSettings();
       localDestinationInfos = [
-        { printerName: 'FooName', deviceName: 'FooDevice' },
-        { printerName: 'BarName', deviceName: 'BarDevice' },
+        {printerName: 'FooName', deviceName: 'FooDevice'},
+        {printerName: 'BarName', deviceName: 'BarDevice'},
       ];
 
       nativeLayer = new print_preview.NativeLayerStub();
@@ -347,23 +344,28 @@
             $('destination-search').querySelector('.print-list ul');
         assertNotEquals(null, recentList);
         assertEquals(1, recentList.childNodes.length);
-        assertEquals('FooName',
-                     recentList.childNodes.item(0).querySelector(
-                         '.destination-list-item-name').textContent);
+        assertEquals(
+            'FooName',
+            recentList.childNodes.item(0)
+                .querySelector('.destination-list-item-name')
+                .textContent);
         assertNotEquals(null, printList);
         assertEquals(3, printList.childNodes.length);
         assertEquals(
             'Save as PDF',
-            printList.childNodes.item(PDF_INDEX).
-            querySelector('.destination-list-item-name').textContent);
+            printList.childNodes.item(PDF_INDEX)
+                .querySelector('.destination-list-item-name')
+                .textContent);
         assertEquals(
             'FooName',
-            printList.childNodes.item(FOO_INDEX).
-            querySelector('.destination-list-item-name').textContent);
+            printList.childNodes.item(FOO_INDEX)
+                .querySelector('.destination-list-item-name')
+                .textContent);
         assertEquals(
             'BarName',
-            printList.childNodes.item(BAR_INDEX).
-            querySelector('.destination-list-item-name').textContent);
+            printList.childNodes.item(BAR_INDEX)
+                .querySelector('.destination-list-item-name')
+                .textContent);
       });
     });
 
@@ -394,10 +396,10 @@
       // Set all three of these destinations in the local destination infos
       // (represents currently available printers), plus an extra destination.
       localDestinationInfos = [
-        { printerName: 'One', deviceName: 'ID1' },
-        { printerName: 'Two', deviceName: 'ID2' },
-        { printerName: 'Three', deviceName: 'ID3' },
-        { printerName: 'Four', deviceName: 'ID4' }
+        {printerName: 'One', deviceName: 'ID1'},
+        {printerName: 'Two', deviceName: 'ID2'},
+        {printerName: 'Three', deviceName: 'ID3'},
+        {printerName: 'Four', deviceName: 'ID4'}
       ];
 
       // Set up capabilities for ID1. This should be the device that should hav
@@ -438,10 +440,10 @@
       // Set all three of these destinations in the local destination infos
       // (represents currently available printers), plus an extra destination.
       localDestinationInfos = [
-        { printerName: 'One', deviceName: 'ID1' },
-        { printerName: 'Two', deviceName: 'ID2' },
-        { printerName: 'Three', deviceName: 'ID3' },
-        { printerName: 'Four', deviceName: 'ID4' }
+        {printerName: 'One', deviceName: 'ID1'},
+        {printerName: 'Two', deviceName: 'ID2'},
+        {printerName: 'Three', deviceName: 'ID3'},
+        {printerName: 'Four', deviceName: 'ID4'}
       ];
 
       initialSettings.printerName = 'ID3';
@@ -451,63 +453,70 @@
           print_preview_test_utils.getCddTemplate('ID1', 'One'));
       nativeLayer.setLocalDestinationCapabilities(
           print_preview_test_utils.getCddTemplate('ID2', 'Two'));
-      return setupSettingsAndDestinationsWithCapabilities(device).then(
-          function() {
-        nativeLayer.reset();
-        // Select ID2 then ID1 so that recent destinations will be 1, 2, 3
-        const destination2 =
-            printPreview.destinationStore_.destinations().find(
-                d => d.id == 'ID2');
-        printPreview.destinationStore_.selectDestination(destination2);
-        return waitForPrinterToUpdatePreview();
-      }).then(function() {
-        nativeLayer.reset();
-        const destination1 =
-            printPreview.destinationStore_.destinations().find(
-                d => d.id == 'ID1');
-        printPreview.destinationStore_.selectDestination(destination1);
-        return waitForPrinterToUpdatePreview();
-      }).then(function() {
-        // Update the persisted ticket items.
-        printPreview.printTicketStore_.mediaSize.updateValue(
-            {name: 'CUSTOM_SQUARE',
-             width_microns: 215900,
-             height_microns: 215900,
-             custom_display_name: 'CUSTOM_SQUARE'});
-        printPreview.printTicketStore_.scaling.updateValue('90');
-        printPreview.printTicketStore_.dpi.updateValue(
-            {horizontal_dpi: 100, vertical_dpi: 100});
-        printPreview.printTicketStore_.headerFooter.updateValue(true);
-        printPreview.printTicketStore_.cssBackground.updateValue(true);
-        printPreview.printTicketStore_.fitToPage.updateValue(true);
-        printPreview.printTicketStore_.collate.updateValue(true);
-        printPreview.printTicketStore_.duplex.updateValue(true);
-        printPreview.printTicketStore_.landscape.updateValue(true);
-        printPreview.printTicketStore_.color.updateValue(true);
-        printPreview.printTicketStore_.marginsType.updateValue(
-        print_preview.ticket_items.MarginsTypeValue.CUSTOM);
-        nativeLayer.resetResolver('saveAppState');
-        printPreview.printTicketStore_.customMargins.updateValue(
-            new print_preview.Margins(74, 74, 74, 74));
-        return nativeLayer.whenCalled('saveAppState');
-      }).then(function(state) {  // validate state serialized correctly.
-        expectEquals(getAppStateString(), state);
-      });
+      return setupSettingsAndDestinationsWithCapabilities(device)
+          .then(function() {
+            nativeLayer.reset();
+            // Select ID2 then ID1 so that recent destinations will be 1, 2, 3
+            const destination2 =
+                printPreview.destinationStore_.destinations().find(
+                    d => d.id == 'ID2');
+            printPreview.destinationStore_.selectDestination(destination2);
+            return waitForPrinterToUpdatePreview();
+          })
+          .then(function() {
+            nativeLayer.reset();
+            const destination1 =
+                printPreview.destinationStore_.destinations().find(
+                    d => d.id == 'ID1');
+            printPreview.destinationStore_.selectDestination(destination1);
+            return waitForPrinterToUpdatePreview();
+          })
+          .then(function() {
+            // Update the persisted ticket items.
+            printPreview.printTicketStore_.mediaSize.updateValue({
+              name: 'CUSTOM_SQUARE',
+              width_microns: 215900,
+              height_microns: 215900,
+              custom_display_name: 'CUSTOM_SQUARE'
+            });
+            printPreview.printTicketStore_.scaling.updateValue('90');
+            printPreview.printTicketStore_.dpi.updateValue(
+                {horizontal_dpi: 100, vertical_dpi: 100});
+            printPreview.printTicketStore_.headerFooter.updateValue(true);
+            printPreview.printTicketStore_.cssBackground.updateValue(true);
+            printPreview.printTicketStore_.fitToPage.updateValue(true);
+            printPreview.printTicketStore_.collate.updateValue(true);
+            printPreview.printTicketStore_.duplex.updateValue(true);
+            printPreview.printTicketStore_.landscape.updateValue(true);
+            printPreview.printTicketStore_.color.updateValue(true);
+            printPreview.printTicketStore_.marginsType.updateValue(
+                print_preview.ticket_items.MarginsTypeValue.CUSTOM);
+            nativeLayer.resetResolver('saveAppState');
+            printPreview.printTicketStore_.customMargins.updateValue(
+                new print_preview.Margins(74, 74, 74, 74));
+            return nativeLayer.whenCalled('saveAppState');
+          })
+          .then(function(state) {  // validate state serialized correctly.
+            expectEquals(getAppStateString(), state);
+          });
     });
 
     test('RestoreAppState', function() {
       initialSettings.serializedAppStateStr = getAppStateString();
       // Set up destinations from app state.
       localDestinationInfos = [
-        { printerName: 'One', deviceName: 'ID1' },
-        { printerName: 'Two', deviceName: 'ID2' },
-        { printerName: 'Three', deviceName: 'ID3' },
+        {printerName: 'One', deviceName: 'ID1'},
+        {printerName: 'Two', deviceName: 'ID2'},
+        {printerName: 'Three', deviceName: 'ID3'},
       ];
       const device = print_preview_test_utils.getCddTemplate('ID1', 'One');
 
-      return Promise.all([
-          setupSettingsAndDestinationsWithCapabilities(device),
-          nativeLayer.whenCalled('getPreview')]).then(function(args) {
+      return Promise
+          .all([
+            setupSettingsAndDestinationsWithCapabilities(device),
+            nativeLayer.whenCalled('getPreview')
+          ])
+          .then(function(args) {
             // Check printer 1 was selected.
             assertEquals(
                 'ID1', printPreview.destinationStore_.selectedDestination.id);
@@ -521,12 +530,14 @@
             expectTrue(ticket.shouldPrintBackgrounds);
             expectTrue(ticket.fitToPageEnabled);
             expectTrue(ticket.collate);
-            expectEquals(ticket.duplex,
-                         print_preview.PreviewGenerator.DuplexMode.LONG_EDGE);
+            expectEquals(
+                ticket.duplex,
+                print_preview.PreviewGenerator.DuplexMode.LONG_EDGE);
             expectTrue(ticket.landscape);
             expectEquals(ticket.color, print_preview.ColorMode.COLOR);
-            expectEquals(print_preview.ticket_items.MarginsTypeValue.CUSTOM,
-                         ticket.marginsType);
+            expectEquals(
+                print_preview.ticket_items.MarginsTypeValue.CUSTOM,
+                ticket.marginsType);
             expectEquals(74, ticket.marginsCustom.marginTop);
 
             // Change scaling (a persisted ticket item value)
@@ -549,7 +560,7 @@
               // Validate that the re-serialized app state string matches.
               expectEquals(getAppStateString(), state);
             });
-        });
+          });
     });
 
     test('DefaultDestinationSelectionRules', function() {
@@ -560,8 +571,9 @@
                  print_preview_test_utils.getCddTemplate(
                      'BarDevice', 'BarName'))
           .then(function() {
-            assertEquals('BarDevice',
-                         printPreview.destinationStore_.selectedDestination.id);
+            assertEquals(
+                'BarDevice',
+                printPreview.destinationStore_.selectedDestination.id);
           });
     });
 
@@ -571,13 +583,12 @@
       nativeLayer.setLocalDestinationCapabilities(
           print_preview_test_utils.getCddTemplate('FooDevice'));
       setInitialSettings();
-      return nativeLayer.whenCalled('getInitialSettings').then(
-          function() {
-            if (cr.isChromeOS)
-              assertEquals(null, $('system-dialog-link'));
-            else
-              checkElementDisplayed($('system-dialog-link'), false);
-          });
+      return nativeLayer.whenCalled('getInitialSettings').then(function() {
+        if (cr.isChromeOS)
+          assertEquals(null, $('system-dialog-link'));
+        else
+          checkElementDisplayed($('system-dialog-link'), false);
+      });
     });
 
     test('SectionsDisabled', function() {
@@ -590,14 +601,14 @@
       };
       delete device.capabilities.printer.copies;
 
-      return setupSettingsAndDestinationsWithCapabilities(device)
-        .then(function() {
-          checkSectionVisible($('layout-settings'), true);
-          checkSectionVisible($('color-settings'), false);
-          checkSectionVisible($('copies-settings'), false);
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            checkSectionVisible($('layout-settings'), true);
+            checkSectionVisible($('color-settings'), false);
+            checkSectionVisible($('copies-settings'), false);
 
-          return whenAnimationDone('other-options-collapsible');
-        });
+            return whenAnimationDone('other-options-collapsible');
+          });
     });
 
     // When the source is 'PDF' and 'Save as PDF' option is selected, we hide
@@ -611,23 +622,25 @@
       nativeLayer.setLocalDestinationCapabilities(getPdfPrinter());
 
       setInitialSettings();
-      return nativeLayer.whenCalled('getInitialSettings').then(function() {
-        return nativeLayer.whenCalled('getPrinterCapabilities');
-      }).then(function() {
-        const otherOptions = $('other-options-settings');
-        const scalingSettings = $('scaling-settings');
-        // If rasterization is an option, other options should be visible.
-        // If not, there should be no available other options.
-        checkSectionVisible(otherOptions, isPrintAsImageEnabled());
-        if (isPrintAsImageEnabled()) {
-          checkElementDisplayed(
-              otherOptions.querySelector('#rasterize-container'), true);
-        }
-        checkSectionVisible($('media-size-settings'), false);
-        checkSectionVisible(scalingSettings, false);
-        checkElementDisplayed(
-            scalingSettings.querySelector('#fit-to-page-container'), false);
-      });
+      return nativeLayer.whenCalled('getInitialSettings')
+          .then(function() {
+            return nativeLayer.whenCalled('getPrinterCapabilities');
+          })
+          .then(function() {
+            const otherOptions = $('other-options-settings');
+            const scalingSettings = $('scaling-settings');
+            // If rasterization is an option, other options should be visible.
+            // If not, there should be no available other options.
+            checkSectionVisible(otherOptions, isPrintAsImageEnabled());
+            if (isPrintAsImageEnabled()) {
+              checkElementDisplayed(
+                  otherOptions.querySelector('#rasterize-container'), true);
+            }
+            checkSectionVisible($('media-size-settings'), false);
+            checkSectionVisible(scalingSettings, false);
+            checkElementDisplayed(
+                scalingSettings.querySelector('#fit-to-page-container'), false);
+          });
     });
 
     // When the source is 'HTML', we always hide the fit to page option and show
@@ -676,20 +689,18 @@
         let rasterizeContainer;
         if (isPrintAsImageEnabled()) {
           rasterizeContainer =
-            otherOptions.querySelector('#rasterize-container');
+              otherOptions.querySelector('#rasterize-container');
         }
 
         checkSectionVisible(otherOptions, true);
         checkElementDisplayed(fitToPageContainer, true);
         if (isPrintAsImageEnabled())
           checkElementDisplayed(rasterizeContainer, false);
-        expectTrue(
-            fitToPageContainer.querySelector('.checkbox').checked);
+        expectTrue(fitToPageContainer.querySelector('.checkbox').checked);
         expandMoreSettings();
         if (isPrintAsImageEnabled()) {
           checkElementDisplayed(rasterizeContainer, true);
-          expectFalse(
-              rasterizeContainer.querySelector('.checkbox').checked);
+          expectFalse(rasterizeContainer.querySelector('.checkbox').checked);
         }
         checkSectionVisible($('media-size-settings'), true);
         checkSectionVisible(scalingSettings, true);
@@ -703,45 +714,49 @@
     test('ScalingUnchecksFitToPage', function() {
       initialSettings.previewModifiable = false;
       // Wait for preview to load.
-      return Promise.all([setupSettingsAndDestinationsWithCapabilities(),
-                          nativeLayer.whenCalled('getPreview')]).then(
-        function(args) {
-          const scalingSettings = $('scaling-settings');
-          checkSectionVisible(scalingSettings, true);
-          const fitToPageContainer =
-              scalingSettings.querySelector('#fit-to-page-container');
-          checkElementDisplayed(fitToPageContainer, true);
-          const ticket = JSON.parse(args[1].printTicket);
-          expectTrue(ticket.fitToPageEnabled);
-          expectEquals(100, ticket.scaleFactor);
-          expectTrue(fitToPageContainer.querySelector('.checkbox').checked);
-          expandMoreSettings();
-          checkSectionVisible($('media-size-settings'), true);
-          checkSectionVisible(scalingSettings, true);
-          nativeLayer.resetResolver('getPreview');
+      return Promise
+          .all([
+            setupSettingsAndDestinationsWithCapabilities(),
+            nativeLayer.whenCalled('getPreview')
+          ])
+          .then(function(args) {
+            const scalingSettings = $('scaling-settings');
+            checkSectionVisible(scalingSettings, true);
+            const fitToPageContainer =
+                scalingSettings.querySelector('#fit-to-page-container');
+            checkElementDisplayed(fitToPageContainer, true);
+            const ticket = JSON.parse(args[1].printTicket);
+            expectTrue(ticket.fitToPageEnabled);
+            expectEquals(100, ticket.scaleFactor);
+            expectTrue(fitToPageContainer.querySelector('.checkbox').checked);
+            expandMoreSettings();
+            checkSectionVisible($('media-size-settings'), true);
+            checkSectionVisible(scalingSettings, true);
+            nativeLayer.resetResolver('getPreview');
 
-          // Change scaling input
-          const scalingInput = scalingSettings.querySelector('.user-value');
-          expectEquals('100', scalingInput.value);
-          scalingInput.stepUp(5);
-          expectEquals('105', scalingInput.value);
+            // Change scaling input
+            const scalingInput = scalingSettings.querySelector('.user-value');
+            expectEquals('100', scalingInput.value);
+            scalingInput.stepUp(5);
+            expectEquals('105', scalingInput.value);
 
-          // Trigger the event
-          const enterEvent = document.createEvent('Event');
-          enterEvent.initEvent('keydown');
-          enterEvent.keyCode = 'Enter';
-          scalingInput.dispatchEvent(enterEvent);
+            // Trigger the event
+            const enterEvent = document.createEvent('Event');
+            enterEvent.initEvent('keydown');
+            enterEvent.keyCode = 'Enter';
+            scalingInput.dispatchEvent(enterEvent);
 
-          // Wait for the preview to refresh and verify print ticket and
-          // display. There will be 2 preview requests. Since we only catch
-          // the first one, only verify fit to page in print ticket.
-          return nativeLayer.whenCalled('getPreview').then(function(args) {
-            const updatedTicket = JSON.parse(args.printTicket);
-            expectFalse(updatedTicket.fitToPageEnabled);
-            expectFalse(fitToPageContainer.querySelector('.checkbox').checked);
-            return whenAnimationDone('more-settings');
+            // Wait for the preview to refresh and verify print ticket and
+            // display. There will be 2 preview requests. Since we only catch
+            // the first one, only verify fit to page in print ticket.
+            return nativeLayer.whenCalled('getPreview').then(function(args) {
+              const updatedTicket = JSON.parse(args.printTicket);
+              expectFalse(updatedTicket.fitToPageEnabled);
+              expectFalse(
+                  fitToPageContainer.querySelector('.checkbox').checked);
+              return whenAnimationDone('more-settings');
+            });
           });
-        });
     });
 
     // When the number of copies print preset is set for source 'PDF', we update
@@ -772,8 +787,7 @@
         cr.webUIListenerCallback('print-preset-options', false, 1, 1);
         const otherOptions = $('other-options-settings');
         checkSectionVisible(otherOptions, true);
-        const duplexContainer =
-            otherOptions.querySelector('#duplex-container');
+        const duplexContainer = otherOptions.querySelector('#duplex-container');
         checkElementDisplayed(duplexContainer, true);
         expectTrue(duplexContainer.querySelector('.checkbox').checked);
 
@@ -910,42 +924,50 @@
       const device = print_preview_test_utils.getCddTemplate('FooDevice');
       device.capabilities.printer.media_size = {
         'option': [
-          {'name': 'SmallLabel', 'width_microns': 38100,
-            'height_microns': 12700, 'is_default': false},
-          {'name': 'BigLabel', 'width_microns': 50800,
-            'height_microns': 76200, 'is_default': true}
+          {
+            'name': 'SmallLabel',
+            'width_microns': 38100,
+            'height_microns': 12700,
+            'is_default': false
+          },
+          {
+            'name': 'BigLabel',
+            'width_microns': 50800,
+            'height_microns': 76200,
+            'is_default': true
+          }
         ]
       };
-      return setupSettingsAndDestinationsWithCapabilities(device)
-          .then(function() {
-        const otherOptions = $('other-options-settings');
-        const headerFooter =
-            otherOptions.querySelector('#header-footer-container');
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            const otherOptions = $('other-options-settings');
+            const headerFooter =
+                otherOptions.querySelector('#header-footer-container');
 
-        // Check that options are collapsed (section is visible, because
-        // duplex is available).
-        checkSectionVisible(otherOptions, true);
-        checkElementDisplayed(headerFooter, false);
+            // Check that options are collapsed (section is visible, because
+            // duplex is available).
+            checkSectionVisible(otherOptions, true);
+            checkElementDisplayed(headerFooter, false);
 
-        expandMoreSettings();
+            expandMoreSettings();
 
-        // Big label should have header/footer
-        checkElementDisplayed(headerFooter, true);
+            // Big label should have header/footer
+            checkElementDisplayed(headerFooter, true);
 
-        // Small label should not
-        nativeLayer.resetResolver('getPreview');
-        printPreview.printTicketStore_.mediaSize.updateValue(
-            device.capabilities.printer.media_size.option[0]);
-        return nativeLayer.whenCalled('getPreview').then(function() {
-          checkElementDisplayed(headerFooter, false);
+            // Small label should not
+            nativeLayer.resetResolver('getPreview');
+            printPreview.printTicketStore_.mediaSize.updateValue(
+                device.capabilities.printer.media_size.option[0]);
+            return nativeLayer.whenCalled('getPreview').then(function() {
+              checkElementDisplayed(headerFooter, false);
 
-          // Oriented in landscape, there should be enough space for
-          // header/footer.
-          nativeLayer.resetResolver('getPreview');
-          printPreview.printTicketStore_.landscape.updateValue(true);
-          return checkHeaderFooterOnLoad(headerFooter, true);
-        });
-      });
+              // Oriented in landscape, there should be enough space for
+              // header/footer.
+              nativeLayer.resetResolver('getPreview');
+              printPreview.printTicketStore_.landscape.updateValue(true);
+              return checkHeaderFooterOnLoad(headerFooter, true);
+            });
+          });
     });
 
     // Test that the color settings, one option, standard monochrome.
@@ -953,17 +975,15 @@
       // Only one option, standard monochrome.
       const device = print_preview_test_utils.getCddTemplate('FooDevice');
       device.capabilities.printer.color = {
-        'option': [
-          {'is_default': true, 'type': 'STANDARD_MONOCHROME'}
-        ]
+        'option': [{'is_default': true, 'type': 'STANDARD_MONOCHROME'}]
       };
 
-      return setupSettingsAndDestinationsWithCapabilities(device)
-          .then(function() {
-        checkSectionVisible($('color-settings'), false);
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            checkSectionVisible($('color-settings'), false);
 
-        return whenAnimationDone('more-settings');
-      });
+            return whenAnimationDone('more-settings');
+          });
     });
 
     // Test that the color settings, one option, custom monochrome.
@@ -971,51 +991,49 @@
       // Only one option, standard monochrome.
       const device = print_preview_test_utils.getCddTemplate('FooDevice');
       device.capabilities.printer.color = {
-        'option': [
-          {'is_default': true, 'type': 'CUSTOM_MONOCHROME',
-           'vendor_id': '42'}
-        ]
+        'option': [{
+          'is_default': true,
+          'type': 'CUSTOM_MONOCHROME',
+          'vendor_id': '42'
+        }]
       };
 
-      return setupSettingsAndDestinationsWithCapabilities(device)
-          .then(function() {
-        checkSectionVisible($('color-settings'), false);
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            checkSectionVisible($('color-settings'), false);
 
-        return whenAnimationDone('more-settings');
-      });
+            return whenAnimationDone('more-settings');
+          });
     });
 
     // Test that the color settings, one option, standard color.
     test('ColorSettingsColor', function() {
       const device = print_preview_test_utils.getCddTemplate('FooDevice');
       device.capabilities.printer.color = {
-        'option': [
-          {'is_default': true, 'type': 'STANDARD_COLOR'}
-        ]
+        'option': [{'is_default': true, 'type': 'STANDARD_COLOR'}]
       };
 
-      return setupSettingsAndDestinationsWithCapabilities(device)
-          .then(function() {
-        checkSectionVisible($('color-settings'), false);
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            checkSectionVisible($('color-settings'), false);
 
-        return whenAnimationDone('more-settings');
-      });
+            return whenAnimationDone('more-settings');
+          });
     });
 
     // Test that the color settings, one option, custom color.
     test('ColorSettingsCustomColor', function() {
       const device = print_preview_test_utils.getCddTemplate('FooDevice');
       device.capabilities.printer.color = {
-        'option': [
-          {'is_default': true, 'type': 'CUSTOM_COLOR', 'vendor_id': '42'}
-        ]
+        'option':
+            [{'is_default': true, 'type': 'CUSTOM_COLOR', 'vendor_id': '42'}]
       };
-      return setupSettingsAndDestinationsWithCapabilities(device)
-          .then(function() {
-        checkSectionVisible($('color-settings'), false);
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            checkSectionVisible($('color-settings'), false);
 
-        return whenAnimationDone('more-settings');
-      });
+            return whenAnimationDone('more-settings');
+          });
     });
 
     // Test that the color settings, two options, both standard, defaults to
@@ -1028,16 +1046,17 @@
           {'is_default': true, 'type': 'STANDARD_COLOR'}
         ]
       };
-      return setupSettingsAndDestinationsWithCapabilities(device)
-          .then(function() {
-        checkSectionVisible($('color-settings'), true);
-        expectEquals(
-            'color',
-            $('color-settings').querySelector(
-                '.color-settings-select').value);
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            checkSectionVisible($('color-settings'), true);
+            expectEquals(
+                'color',
+                $('color-settings')
+                    .querySelector('.color-settings-select')
+                    .value);
 
-        return whenAnimationDone('more-settings');
-      });
+            return whenAnimationDone('more-settings');
+          });
     });
 
     // Test that the color settings, two options, both standard, defaults to
@@ -1050,16 +1069,17 @@
           {'type': 'STANDARD_COLOR'}
         ]
       };
-      return setupSettingsAndDestinationsWithCapabilities(device)
-          .then(function() {
-        checkSectionVisible($('color-settings'), true);
-        expectEquals(
-            'bw',
-            $('color-settings').querySelector(
-                '.color-settings-select').value);
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            checkSectionVisible($('color-settings'), true);
+            expectEquals(
+                'bw',
+                $('color-settings')
+                    .querySelector('.color-settings-select')
+                    .value);
 
-        return whenAnimationDone('more-settings');
-      });
+            return whenAnimationDone('more-settings');
+          });
     });
 
     // Test that the color settings, two options, both custom, defaults to
@@ -1072,16 +1092,17 @@
           {'is_default': true, 'type': 'CUSTOM_COLOR', 'vendor_id': '43'}
         ]
       };
-      return setupSettingsAndDestinationsWithCapabilities(device)
-          .then(function() {
-        checkSectionVisible($('color-settings'), true);
-        expectEquals(
-            'color',
-            $('color-settings').querySelector(
-                '.color-settings-select').value);
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            checkSectionVisible($('color-settings'), true);
+            expectEquals(
+                'color',
+                $('color-settings')
+                    .querySelector('.color-settings-select')
+                    .value);
 
-        return whenAnimationDone('more-settings');
-      });
+            return whenAnimationDone('more-settings');
+          });
     });
 
     // Test to verify that duplex settings are set according to the printer
@@ -1103,52 +1124,53 @@
     test('DuplexSettingsFalse', function() {
       const device = print_preview_test_utils.getCddTemplate('FooDevice');
       delete device.capabilities.printer.duplex;
-      return setupSettingsAndDestinationsWithCapabilities(device)
-          .then(function() {
-        // Check that it is collapsed.
-        const otherOptions = $('other-options-settings');
-        checkSectionVisible(otherOptions, false);
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            // Check that it is collapsed.
+            const otherOptions = $('other-options-settings');
+            checkSectionVisible(otherOptions, false);
 
-        expandMoreSettings();
+            expandMoreSettings();
 
-        // Now it should be visible.
-        checkSectionVisible(otherOptions, true);
-        expectTrue(otherOptions.querySelector('#duplex-container').hidden);
+            // Now it should be visible.
+            checkSectionVisible(otherOptions, true);
+            expectTrue(otherOptions.querySelector('#duplex-container').hidden);
 
-        return whenAnimationDone('more-settings');
-      });
+            return whenAnimationDone('more-settings');
+          });
     });
 
     // Test that changing the selected printer updates the preview.
     test('PrinterChangeUpdatesPreview', function() {
-      return Promise.all([
-          setupSettingsAndDestinationsWithCapabilities(),
-          nativeLayer.whenCalled('getPreview'),
-      ]).then(function(args) {
-        const ticket = JSON.parse(args[1].printTicket);
-        expectEquals(0, ticket.requestID);
-        expectEquals('FooDevice', ticket.deviceName);
-        nativeLayer.reset();
+      return Promise
+          .all([
+            setupSettingsAndDestinationsWithCapabilities(),
+            nativeLayer.whenCalled('getPreview'),
+          ])
+          .then(function(args) {
+            const ticket = JSON.parse(args[1].printTicket);
+            expectEquals(0, ticket.requestID);
+            expectEquals('FooDevice', ticket.deviceName);
+            nativeLayer.reset();
 
-        // Setup capabilities for BarDevice.
-        const device = print_preview_test_utils.getCddTemplate('BarDevice');
-        device.capabilities.printer.color = {
-          'option': [
-            {'is_default': true, 'type': 'STANDARD_MONOCHROME'}
-          ]
-        };
-        nativeLayer.setLocalDestinationCapabilities(device);
-        // Select BarDevice
-        const barDestination =
-            printPreview.destinationStore_.destinations().find(
-                d => d.id == 'BarDevice');
-        printPreview.destinationStore_.selectDestination(barDestination);
-        return waitForPrinterToUpdatePreview();
-      }).then(function(args) {
-        const ticket = JSON.parse(args[1].printTicket);
-        expectEquals(1, ticket.requestID);
-        expectEquals('BarDevice', ticket.deviceName);
-      });
+            // Setup capabilities for BarDevice.
+            const device = print_preview_test_utils.getCddTemplate('BarDevice');
+            device.capabilities.printer.color = {
+              'option': [{'is_default': true, 'type': 'STANDARD_MONOCHROME'}]
+            };
+            nativeLayer.setLocalDestinationCapabilities(device);
+            // Select BarDevice
+            const barDestination =
+                printPreview.destinationStore_.destinations().find(
+                    d => d.id == 'BarDevice');
+            printPreview.destinationStore_.selectDestination(barDestination);
+            return waitForPrinterToUpdatePreview();
+          })
+          .then(function(args) {
+            const ticket = JSON.parse(args[1].printTicket);
+            expectEquals(1, ticket.requestID);
+            expectEquals('BarDevice', ticket.deviceName);
+          });
     });
 
     // Test that error message is displayed when plugin doesn't exist.
@@ -1162,23 +1184,20 @@
       return nativeLayer.whenCalled('getInitialSettings').then(function() {
         const previewAreaEl = $('preview-area');
 
-        const loadingMessageEl =
-            previewAreaEl.
-            getElementsByClassName('preview-area-loading-message')[0];
+        const loadingMessageEl = previewAreaEl.getElementsByClassName(
+            'preview-area-loading-message')[0];
         expectTrue(loadingMessageEl.hidden);
 
         const previewFailedMessageEl = previewAreaEl.getElementsByClassName(
             'preview-area-preview-failed-message')[0];
         expectTrue(previewFailedMessageEl.hidden);
 
-        const printFailedMessageEl =
-            previewAreaEl.
-            getElementsByClassName('preview-area-print-failed')[0];
+        const printFailedMessageEl = previewAreaEl.getElementsByClassName(
+            'preview-area-print-failed')[0];
         expectTrue(printFailedMessageEl.hidden);
 
-        const customMessageEl =
-            previewAreaEl.
-            getElementsByClassName('preview-area-custom-message')[0];
+        const customMessageEl = previewAreaEl.getElementsByClassName(
+            'preview-area-custom-message')[0];
         expectFalse(customMessageEl.hidden);
       });
     });
@@ -1191,17 +1210,17 @@
       const device = print_preview_test_utils.getCddTemplate('FooDevice');
       device.capabilities.printer.media_size = {
         option: [
-          { name: 'CUSTOM',
+          {
+            name: 'CUSTOM',
             width_microns: 15900,
             height_microns: 79400,
             is_default: true,
             custom_display_name_localized: [
-              { locale: navigator.language,
-                value: customLocalizedMediaName
-              }
+              {locale: navigator.language, value: customLocalizedMediaName}
             ]
           },
-          { name: 'CUSTOM',
+          {
+            name: 'CUSTOM',
             width_microns: 15900,
             height_microns: 79400,
             custom_display_name: customMediaName
@@ -1209,24 +1228,25 @@
         ]
       };
 
-      return setupSettingsAndDestinationsWithCapabilities(device)
-          .then(function() {
-        expandMoreSettings();
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            expandMoreSettings();
 
-        checkSectionVisible($('media-size-settings'), true);
-        const mediaSelect =
-            $('media-size-settings').querySelector('.settings-select');
-        // Check the default media item.
-        expectEquals(
-            customLocalizedMediaName,
-            mediaSelect.options[mediaSelect.selectedIndex].text);
-        // Check the other media item.
-        expectEquals(
-            customMediaName,
-            mediaSelect.options[mediaSelect.selectedIndex == 0 ? 1 : 0].text);
+            checkSectionVisible($('media-size-settings'), true);
+            const mediaSelect =
+                $('media-size-settings').querySelector('.settings-select');
+            // Check the default media item.
+            expectEquals(
+                customLocalizedMediaName,
+                mediaSelect.options[mediaSelect.selectedIndex].text);
+            // Check the other media item.
+            expectEquals(
+                customMediaName,
+                mediaSelect.options[mediaSelect.selectedIndex == 0 ? 1 : 0]
+                    .text);
 
-        return whenAnimationDone('more-settings');
-      });
+            return whenAnimationDone('more-settings');
+          });
     });
 
     // Test advanced settings with 1 capability (should not display settings
@@ -1235,14 +1255,15 @@
       const device =
           print_preview_test_utils.getCddTemplateWithAdvancedSettings(
               1, 'FooDevice');
-      return setupSettingsAndDestinationsWithCapabilities(device)
-          .then(function() {
-        startAdvancedSettingsTest(device);
-        checkElementDisplayed($('advanced-settings').
-            querySelector('.search-box-area'), false);
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            startAdvancedSettingsTest(device);
+            checkElementDisplayed(
+                $('advanced-settings').querySelector('.search-box-area'),
+                false);
 
-        return whenAnimationDone('more-settings');
-      });
+            return whenAnimationDone('more-settings');
+          });
     });
 
     // Test advanced settings with 2 capabilities (should have settings search
@@ -1251,15 +1272,15 @@
       const device =
           print_preview_test_utils.getCddTemplateWithAdvancedSettings(
               2, 'FooDevice');
-      return setupSettingsAndDestinationsWithCapabilities(device)
-          .then(function() {
-        startAdvancedSettingsTest(device);
+      return setupSettingsAndDestinationsWithCapabilities(device).then(
+          function() {
+            startAdvancedSettingsTest(device);
 
-        checkElementDisplayed($('advanced-settings').
-          querySelector('.search-box-area'), true);
+            checkElementDisplayed(
+                $('advanced-settings').querySelector('.search-box-area'), true);
 
-        return whenAnimationDone('more-settings');
-      });
+            return whenAnimationDone('more-settings');
+          });
     });
 
     // Test that initialization with saved destination only issues one call
@@ -1297,17 +1318,20 @@
       // request. Ensure this is also ID1.
       setInitialSettings();
       const initialSettingsSet = nativeLayer.whenCalled('getInitialSettings');
-      return initialSettingsSet.then(function() {
-        return nativeLayer.whenCalled('getPrinterCapabilities');
-      }).then(function(args) {
-        expectEquals('ID1', args.destinationId);
-        expectEquals(print_preview.PrinterType.LOCAL, args.type);
-        return nativeLayer.whenCalled('getPreview');
-      }).then(function(previewArgs) {
-        const ticket = JSON.parse(previewArgs.printTicket);
-        expectEquals(0, ticket.requestID);
-        expectEquals('ID1', ticket.deviceName);
-      });
+      return initialSettingsSet
+          .then(function() {
+            return nativeLayer.whenCalled('getPrinterCapabilities');
+          })
+          .then(function(args) {
+            expectEquals('ID1', args.destinationId);
+            expectEquals(print_preview.PrinterType.LOCAL, args.type);
+            return nativeLayer.whenCalled('getPreview');
+          })
+          .then(function(previewArgs) {
+            const ticket = JSON.parse(previewArgs.printTicket);
+            expectEquals(0, ticket.requestID);
+            expectEquals('ID1', ticket.deviceName);
+          });
     });
 
     // Test that invalid settings errors disable the print preview and display
@@ -1320,66 +1344,71 @@
       // FooDevice is the default printer, so will be selected for the initial
       // preview request.
       nativeLayer.setInvalidPrinterId('FooDevice');
-      return Promise.all([
-          setupSettingsAndDestinationsWithCapabilities(),
-          nativeLayer.whenCalled('getPreview'),
-      ]).then(function() {
-        // Print preview should have failed with invalid settings, since
-        // FooDevice was set as an invalid printer.
-        const previewAreaEl = $('preview-area');
-        const customMessageEl =
-            previewAreaEl.
-            getElementsByClassName('preview-area-custom-message')[0];
-        expectFalse(customMessageEl.hidden);
-        const expectedMessageStart = 'The selected printer is not available or '
-            + 'not installed correctly.';
-        expectTrue(customMessageEl.textContent.includes(
-            expectedMessageStart));
+      return Promise
+          .all([
+            setupSettingsAndDestinationsWithCapabilities(),
+            nativeLayer.whenCalled('getPreview'),
+          ])
+          .then(function() {
+            // Print preview should have failed with invalid settings, since
+            // FooDevice was set as an invalid printer.
+            const previewAreaEl = $('preview-area');
+            const customMessageEl = previewAreaEl.getElementsByClassName(
+                'preview-area-custom-message')[0];
+            expectFalse(customMessageEl.hidden);
+            const expectedMessageStart =
+                'The selected printer is not available or ' +
+                'not installed correctly.';
+            expectTrue(
+                customMessageEl.textContent.includes(expectedMessageStart));
 
-        // Verify that the print button is disabled
-        const printButton = $('print-header').querySelector('button.print');
-        checkElementDisplayed(printButton, true);
-        expectTrue(printButton.disabled);
+            // Verify that the print button is disabled
+            const printButton = $('print-header').querySelector('button.print');
+            checkElementDisplayed(printButton, true);
+            expectTrue(printButton.disabled);
 
-        // Reset
-        nativeLayer.reset();
+            // Reset
+            nativeLayer.reset();
 
-        // Select a new destination
-        const barDestination =
-            printPreview.destinationStore_.destinations().find(
-                d => d.id == 'BarDevice');
-        printPreview.destinationStore_.selectDestination(barDestination);
-        return waitForPrinterToUpdatePreview();
-      }).then(function() {
-        // Has active print button and successfully 'prints', indicating
-        // recovery from error state.
-        const printButton = $('print-header').querySelector('button.print');
-        expectFalse(printButton.disabled);
-        printButton.click();
-        // This should result in a call to print.
-        return nativeLayer.whenCalled('print');
-      }).then(
-          /**
-           * @param {string} printTicket The print ticket print() was called
-           *     for.
-           */
-          function(printTicket) {
-            // Sanity check some printing argument values.
-            const ticket = JSON.parse(printTicket);
-            expectEquals(barDevice.printer.deviceName, ticket.deviceName);
-            expectEquals(
-                print_preview_test_utils.getDefaultOrientation(barDevice) ==
-                    'LANDSCAPE',
-                ticket.landscape);
-            expectEquals(1, ticket.copies);
-            const mediaDefault =
-                print_preview_test_utils.getDefaultMediaSize(barDevice);
-            expectEquals(
-                mediaDefault.width_microns, ticket.mediaSize.width_microns);
-            expectEquals(
-                mediaDefault.height_microns, ticket.mediaSize.height_microns);
-            return nativeLayer.whenCalled('dialogClose');
-          });
+            // Select a new destination
+            const barDestination =
+                printPreview.destinationStore_.destinations().find(
+                    d => d.id == 'BarDevice');
+            printPreview.destinationStore_.selectDestination(barDestination);
+            return waitForPrinterToUpdatePreview();
+          })
+          .then(function() {
+            // Has active print button and successfully 'prints', indicating
+            // recovery from error state.
+            const printButton = $('print-header').querySelector('button.print');
+            expectFalse(printButton.disabled);
+            printButton.click();
+            // This should result in a call to print.
+            return nativeLayer.whenCalled('print');
+          })
+          .then(
+              /**
+               * @param {string} printTicket The print ticket print() was called
+               *     for.
+               */
+              function(printTicket) {
+                // Sanity check some printing argument values.
+                const ticket = JSON.parse(printTicket);
+                expectEquals(barDevice.printer.deviceName, ticket.deviceName);
+                expectEquals(
+                    print_preview_test_utils.getDefaultOrientation(barDevice) ==
+                        'LANDSCAPE',
+                    ticket.landscape);
+                expectEquals(1, ticket.copies);
+                const mediaDefault =
+                    print_preview_test_utils.getDefaultMediaSize(barDevice);
+                expectEquals(
+                    mediaDefault.width_microns, ticket.mediaSize.width_microns);
+                expectEquals(
+                    mediaDefault.height_microns,
+                    ticket.mediaSize.height_microns);
+                return nativeLayer.whenCalled('dialogClose');
+              });
     });
 
     // Test that GCP invalid certificate printers disable the print preview when
@@ -1399,51 +1428,55 @@
       // Get references to a few elements for testing.
       const printButton = $('print-header').querySelector('button.print');
       const previewAreaEl = $('preview-area');
-      const overlayEl = previewAreaEl.getElementsByClassName(
-          'preview-area-overlay-layer')[0];
-      const cloudPrintMessageEl =
-          previewAreaEl.
-          getElementsByClassName('preview-area-unsupported-cloud-printer')[0];
+      const overlayEl =
+          previewAreaEl.getElementsByClassName('preview-area-overlay-layer')[0];
+      const cloudPrintMessageEl = previewAreaEl.getElementsByClassName(
+          'preview-area-unsupported-cloud-printer')[0];
 
-      return nativeLayer.whenCalled('getInitialSettings').then(function() {
-        printPreview.destinationStore_.startLoadCloudDestinations();
+      return nativeLayer.whenCalled('getInitialSettings')
+          .then(function() {
+            printPreview.destinationStore_.startLoadCloudDestinations();
 
-        // FooDevice will be selected since it is the most recently used
-        // printer, so the invalid certificate error should be shown.
-        // The overlay must be visible for the message to be seen.
-        expectFalse(overlayEl.classList.contains('invisible'));
+            // FooDevice will be selected since it is the most recently used
+            // printer, so the invalid certificate error should be shown.
+            // The overlay must be visible for the message to be seen.
+            expectFalse(overlayEl.classList.contains('invisible'));
 
-        // Verify that the correct message is shown.
-        expectFalse(cloudPrintMessageEl.hidden);
-        const expectedMessageStart = 'The selected Google Cloud Print device '
-            + 'is no longer supported. Try setting up the printer in your '
-            + 'computer\'s system settings.';
-        expectTrue(cloudPrintMessageEl.textContent.includes(
-            expectedMessageStart));
+            // Verify that the correct message is shown.
+            expectFalse(cloudPrintMessageEl.hidden);
+            const expectedMessageStart =
+                'The selected Google Cloud Print device ' +
+                'is no longer supported. Try setting up the printer in your ' +
+                'computer\'s system settings.';
+            expectTrue(
+                cloudPrintMessageEl.textContent.includes(expectedMessageStart));
 
-        // Verify that the print button is disabled
-        checkElementDisplayed(printButton, true);
-        expectTrue(printButton.disabled);
+            // Verify that the print button is disabled
+            checkElementDisplayed(printButton, true);
+            expectTrue(printButton.disabled);
 
-        // Reset
-        nativeLayer.reset();
+            // Reset
+            nativeLayer.reset();
 
-        // Select a new, valid cloud destination.
-        printPreview.destinationStore_.selectDestination(validPrinter);
-        return nativeLayer.whenCalled('getPreview');
-      }).then(function() {
-        // Has active print button, indicating recovery from error state.
-        expectFalse(printButton.disabled);
+            // Select a new, valid cloud destination.
+            printPreview.destinationStore_.selectDestination(validPrinter);
+            return nativeLayer.whenCalled('getPreview');
+          })
+          .then(function() {
+            // Has active print button, indicating recovery from error state.
+            expectFalse(printButton.disabled);
 
-        // Note: because in the test it is generally true that the preview
-        // request is resolved before the 200ms timeout to show the loading
-        // message expires, the message element may not be hidden. It will be
-        // hidden the next time a different message, e.g. 'Loading...', is shown
-        // in the overlay. However, if this is the case, the overlay should not
-        // be visible, so that the message is no longer visible to the user.
-        expectTrue(cloudPrintMessageEl.hidden ||
-                   overlayEl.classList.contains('invisible'));
-      });
+            // Note: because in the test it is generally true that the preview
+            // request is resolved before the 200ms timeout to show the loading
+            // message expires, the message element may not be hidden. It will
+            // be hidden the next time a different message, e.g. 'Loading...',
+            // is shown in the overlay. However, if this is the case, the
+            // overlay should not be visible, so that the message is no longer
+            // visible to the user.
+            expectTrue(
+                cloudPrintMessageEl.hidden ||
+                overlayEl.classList.contains('invisible'));
+          });
     });
 
     // Test that GCP invalid certificate printers disable the print preview when
@@ -1462,52 +1495,57 @@
       // Get references to a few elements for testing.
       const printButton = $('print-header').querySelector('button.print');
       const previewAreaEl = $('preview-area');
-      const overlayEl = previewAreaEl.getElementsByClassName(
-          'preview-area-overlay-layer')[0];
-      const cloudPrintMessageEl =
-          previewAreaEl.
-          getElementsByClassName('preview-area-unsupported-cloud-printer')[0];
+      const overlayEl =
+          previewAreaEl.getElementsByClassName('preview-area-overlay-layer')[0];
+      const cloudPrintMessageEl = previewAreaEl.getElementsByClassName(
+          'preview-area-unsupported-cloud-printer')[0];
 
-      return nativeLayer.whenCalled('getInitialSettings').then(function() {
-        // Start loading cloud destinations so that the printer capabilities
-        // arrive.
-        printPreview.destinationStore_.startLoadCloudDestinations();
-        return nativeLayer.whenCalled('getPreview');
-      }).then(function() {
-        // Has active print button.
-        expectFalse(printButton.disabled);
-        // No error message.
-        expectTrue(cloudPrintMessageEl.hidden ||
-                   overlayEl.classList.contains('invisible'));
+      return nativeLayer.whenCalled('getInitialSettings')
+          .then(function() {
+            // Start loading cloud destinations so that the printer capabilities
+            // arrive.
+            printPreview.destinationStore_.startLoadCloudDestinations();
+            return nativeLayer.whenCalled('getPreview');
+          })
+          .then(function() {
+            // Has active print button.
+            expectFalse(printButton.disabled);
+            // No error message.
+            expectTrue(
+                cloudPrintMessageEl.hidden ||
+                overlayEl.classList.contains('invisible'));
 
-        // Select the invalid destination and wait for the event.
-        const whenInvalid = test_util.eventToPromise(
-            print_preview.DestinationStore.EventType
-                .SELECTED_DESTINATION_UNSUPPORTED,
-            printPreview.destinationStore_);
-        printPreview.destinationStore_.selectDestination(invalidPrinter);
-        return whenInvalid;
-      }).then(function() {
-        // Should have error message.
-        expectFalse(overlayEl.classList.contains('invisible'));
-        expectFalse(cloudPrintMessageEl.hidden);
+            // Select the invalid destination and wait for the event.
+            const whenInvalid = test_util.eventToPromise(
+                print_preview.DestinationStore.EventType
+                    .SELECTED_DESTINATION_UNSUPPORTED,
+                printPreview.destinationStore_);
+            printPreview.destinationStore_.selectDestination(invalidPrinter);
+            return whenInvalid;
+          })
+          .then(function() {
+            // Should have error message.
+            expectFalse(overlayEl.classList.contains('invisible'));
+            expectFalse(cloudPrintMessageEl.hidden);
 
-        // Reset
-        nativeLayer.reset();
+            // Reset
+            nativeLayer.reset();
 
-        // Reselect the valid cloud destination.
-        const whenSelected = test_util.eventToPromise(
-            print_preview.DestinationStore.EventType.DESTINATION_SELECT,
-            printPreview.destinationStore_);
-        printPreview.destinationStore_.selectDestination(validPrinter);
-        return whenSelected;
-      }).then(function() {
-        // Has active print button.
-        expectFalse(printButton.disabled);
-        // No error message.
-        expectTrue(cloudPrintMessageEl.hidden ||
-                   overlayEl.classList.contains('invisible'));
-      });
+            // Reselect the valid cloud destination.
+            const whenSelected = test_util.eventToPromise(
+                print_preview.DestinationStore.EventType.DESTINATION_SELECT,
+                printPreview.destinationStore_);
+            printPreview.destinationStore_.selectDestination(validPrinter);
+            return whenSelected;
+          })
+          .then(function() {
+            // Has active print button.
+            expectFalse(printButton.disabled);
+            // No error message.
+            expectTrue(
+                cloudPrintMessageEl.hidden ||
+                overlayEl.classList.contains('invisible'));
+          });
     });
 
     // Test that GCP invalid certificate printers disable the print preview when
@@ -1529,55 +1567,60 @@
       // Get references to a few elements for testing.
       const printButton = $('print-header').querySelector('button.print');
       const previewAreaEl = $('preview-area');
-      const overlayEl = previewAreaEl.getElementsByClassName(
-          'preview-area-overlay-layer')[0];
-      const cloudPrintMessageEl =
-          previewAreaEl.
-          getElementsByClassName('preview-area-unsupported-cloud-printer')[0];
+      const overlayEl =
+          previewAreaEl.getElementsByClassName('preview-area-overlay-layer')[0];
+      const cloudPrintMessageEl = previewAreaEl.getElementsByClassName(
+          'preview-area-unsupported-cloud-printer')[0];
 
-      return nativeLayer.whenCalled('getInitialSettings').then(function() {
-        printPreview.destinationStore_.startLoadCloudDestinations();
-        return nativeLayer.whenCalled('getPreview');
-      }).then(function() {
-        // Select the invalid destination and wait for the event.
-        const whenInvalid = test_util.eventToPromise(
-            print_preview.DestinationStore.EventType
-                .SELECTED_DESTINATION_UNSUPPORTED,
-            printPreview.destinationStore_);
-        printPreview.destinationStore_.selectDestination(invalidPrinter);
-        return whenInvalid;
-      }).then(function() {
-        // FooDevice will be selected since it is the most recently used
-        // printer, so the invalid certificate error should be shown.
-        // The overlay must be visible for the message to be seen.
-        expectFalse(overlayEl.classList.contains('invisible'));
-        expectFalse(cloudPrintMessageEl.hidden);
+      return nativeLayer.whenCalled('getInitialSettings')
+          .then(function() {
+            printPreview.destinationStore_.startLoadCloudDestinations();
+            return nativeLayer.whenCalled('getPreview');
+          })
+          .then(function() {
+            // Select the invalid destination and wait for the event.
+            const whenInvalid = test_util.eventToPromise(
+                print_preview.DestinationStore.EventType
+                    .SELECTED_DESTINATION_UNSUPPORTED,
+                printPreview.destinationStore_);
+            printPreview.destinationStore_.selectDestination(invalidPrinter);
+            return whenInvalid;
+          })
+          .then(function() {
+            // FooDevice will be selected since it is the most recently used
+            // printer, so the invalid certificate error should be shown.
+            // The overlay must be visible for the message to be seen.
+            expectFalse(overlayEl.classList.contains('invisible'));
+            expectFalse(cloudPrintMessageEl.hidden);
 
-        // Verify that the print button is disabled
-        checkElementDisplayed(printButton, true);
-        expectTrue(printButton.disabled);
+            // Verify that the print button is disabled
+            checkElementDisplayed(printButton, true);
+            expectTrue(printButton.disabled);
 
-        // Reset
-        nativeLayer.resetResolver('getPreview');
+            // Reset
+            nativeLayer.resetResolver('getPreview');
 
-        // Update the print ticket by changing portrait to landscape and wait
-        // for the event to fire.
-        const whenTicketChanged = test_util.eventToPromise(
-            print_preview.ticket_items.TicketItem.EventType.CHANGE,
-            printPreview.printTicketStore_.landscape);
-        const promise = nativeLayer.whenCalled('getPreview');
-        promise.then(function() { assertTrue(false); });
-        assertFalse(printPreview.printTicketStore_.landscape.getValue());
-        printPreview.printTicketStore_.landscape.updateValue(true);
-        // Wait for update. It should not result in a call to getPreview().
-        return whenTicketChanged;
-      }).then(function() {
-        // Still disabled.
-        expectTrue(printButton.disabled);
-        // Overlay still visible.
-        expectFalse(overlayEl.classList.contains('invisible'));
-        expectFalse(cloudPrintMessageEl.hidden);
-      });
+            // Update the print ticket by changing portrait to landscape and
+            // wait for the event to fire.
+            const whenTicketChanged = test_util.eventToPromise(
+                print_preview.ticket_items.TicketItem.EventType.CHANGE,
+                printPreview.printTicketStore_.landscape);
+            const promise = nativeLayer.whenCalled('getPreview');
+            promise.then(function() {
+              assertTrue(false);
+            });
+            assertFalse(printPreview.printTicketStore_.landscape.getValue());
+            printPreview.printTicketStore_.landscape.updateValue(true);
+            // Wait for update. It should not result in a call to getPreview().
+            return whenTicketChanged;
+          })
+          .then(function() {
+            // Still disabled.
+            expectTrue(printButton.disabled);
+            // Overlay still visible.
+            expectFalse(overlayEl.classList.contains('invisible'));
+            expectFalse(cloudPrintMessageEl.hidden);
+          });
     });
 
     // Test that the policy to use the system default printer by default
@@ -1601,8 +1644,8 @@
 
       // Setup local destinations with the system default + recent.
       localDestinationInfos = [
-        { printerName: 'One', deviceName: 'ID1' },
-        { printerName: 'FooName', deviceName: 'FooDevice' }
+        {printerName: 'One', deviceName: 'ID1'},
+        {printerName: 'FooName', deviceName: 'FooDevice'}
       ];
       nativeLayer.setLocalDestinationCapabilities(
           print_preview_test_utils.getCddTemplate('ID1', 'One'));
@@ -1611,8 +1654,7 @@
         // The system default destination should be used instead of the
         // most recent destination.
         assertEquals(
-            'FooDevice',
-            printPreview.destinationStore_.selectedDestination.id);
+            'FooDevice', printPreview.destinationStore_.selectedDestination.id);
       });
     });
 
@@ -1622,19 +1664,21 @@
       test('MacOpenPDFInPreview', function() {
         const device = getPdfPrinter();
         initialSettings.printerName = device.printer.deviceName;
-        return setupSettingsAndDestinationsWithCapabilities(device).
-            then(function() {
+        return setupSettingsAndDestinationsWithCapabilities(device)
+            .then(function() {
               assertEquals(
-                device.printer.deviceName,
-                printPreview.destinationStore_.selectedDestination.id);
+                  device.printer.deviceName,
+                  printPreview.destinationStore_.selectedDestination.id);
               return nativeLayer.whenCalled('getPreview');
-            }).then(function() {
+            })
+            .then(function() {
               const openPdfPreviewLink = $('open-pdf-in-preview-link');
               checkElementDisplayed(openPdfPreviewLink, true);
               openPdfPreviewLink.click();
               // Should result in a print call and dialog should close.
               return nativeLayer.whenCalled('print');
-            }).then(
+            })
+            .then(
                 /**
                  * @param {string} printTicket The print ticket print() was
                  *     called for.
@@ -1651,59 +1695,65 @@
         const device = getPdfPrinter();
         initialSettings.printerName = device.printer.deviceName;
         const openPdfPreviewLink = $('open-pdf-in-preview-link');
-        return Promise.all([
-          setupSettingsAndDestinationsWithCapabilities(device),
-          nativeLayer.whenCalled('getPreview')
-        ]).then(function() {
-          checkElementDisplayed(openPdfPreviewLink, true);
-          expectFalse(openPdfPreviewLink.disabled);
-          const pageSettings = $('page-settings');
-          checkSectionVisible(pageSettings, true);
-          nativeLayer.resetResolver('getPreview');
+        return Promise
+            .all([
+              setupSettingsAndDestinationsWithCapabilities(device),
+              nativeLayer.whenCalled('getPreview')
+            ])
+            .then(function() {
+              checkElementDisplayed(openPdfPreviewLink, true);
+              expectFalse(openPdfPreviewLink.disabled);
+              const pageSettings = $('page-settings');
+              checkSectionVisible(pageSettings, true);
+              nativeLayer.resetResolver('getPreview');
 
-          // Wait for ticket change.
-          const whenTicketChange = test_util.eventToPromise(
-              print_preview.ticket_items.TicketItem.EventType.CHANGE,
-              printPreview.printTicketStore_.pageRange);
+              // Wait for ticket change.
+              const whenTicketChange = test_util.eventToPromise(
+                  print_preview.ticket_items.TicketItem.EventType.CHANGE,
+                  printPreview.printTicketStore_.pageRange);
 
-          // Set page settings to a bad value
-          pageSettings.querySelector('.page-settings-custom-input').value =
-              'abc';
-          pageSettings.querySelector('.page-settings-custom-radio').click();
+              // Set page settings to a bad value
+              pageSettings.querySelector('.page-settings-custom-input').value =
+                  'abc';
+              pageSettings.querySelector('.page-settings-custom-radio').click();
 
-          // No new preview
-          nativeLayer.whenCalled('getPreview').then(function() {
-            assertTrue(false);
-          });
+              // No new preview
+              nativeLayer.whenCalled('getPreview').then(function() {
+                assertTrue(false);
+              });
 
-          return whenTicketChange;
-        }).then(function() {
-          // Expect disabled print button and Pdf in preview link
-          const printButton = $('print-header').querySelector('button.print');
-          checkElementDisplayed(printButton, true);
-          expectTrue(printButton.disabled);
-          checkElementDisplayed(openPdfPreviewLink, true);
-          expectTrue(openPdfPreviewLink.disabled);
-        });
+              return whenTicketChange;
+            })
+            .then(function() {
+              // Expect disabled print button and Pdf in preview link
+              const printButton =
+                  $('print-header').querySelector('button.print');
+              checkElementDisplayed(printButton, true);
+              expectTrue(printButton.disabled);
+              checkElementDisplayed(openPdfPreviewLink, true);
+              expectTrue(openPdfPreviewLink.disabled);
+            });
       });
     }  // cr.isMac
 
     // Test that the system dialog link works correctly on Windows
     if (cr.isWindows) {
       test('WinSystemDialogLink', function() {
-        return setupSettingsAndDestinationsWithCapabilities().
-            then(function() {
+        return setupSettingsAndDestinationsWithCapabilities()
+            .then(function() {
               assertEquals(
-                'FooDevice',
-                printPreview.destinationStore_.selectedDestination.id);
+                  'FooDevice',
+                  printPreview.destinationStore_.selectedDestination.id);
               return nativeLayer.whenCalled('getPreview');
-            }).then(function() {
+            })
+            .then(function() {
               const systemDialogLink = $('system-dialog-link');
               checkElementDisplayed(systemDialogLink, true);
               systemDialogLink.click();
               // Should result in a print call and dialog should close.
               return nativeLayer.whenCalled('print');
-            }).then(
+            })
+            .then(
                 /**
                  * @param {string} printTicket The print ticket print() was
                  *     called for.
@@ -1718,40 +1768,44 @@
       // print ticket is invalid.
       test('WinSystemDialogLinkBadPrintTicket', function() {
         const systemDialogLink = $('system-dialog-link');
-        return Promise.all([
-          setupSettingsAndDestinationsWithCapabilities(),
-          nativeLayer.whenCalled('getPreview')
-        ]).then(function() {
-          checkElementDisplayed(systemDialogLink, true);
-          expectFalse(systemDialogLink.disabled);
+        return Promise
+            .all([
+              setupSettingsAndDestinationsWithCapabilities(),
+              nativeLayer.whenCalled('getPreview')
+            ])
+            .then(function() {
+              checkElementDisplayed(systemDialogLink, true);
+              expectFalse(systemDialogLink.disabled);
 
-          const pageSettings = $('page-settings');
-          checkSectionVisible(pageSettings, true);
-          nativeLayer.resetResolver('getPreview');
+              const pageSettings = $('page-settings');
+              checkSectionVisible(pageSettings, true);
+              nativeLayer.resetResolver('getPreview');
 
-          // Wait for ticket change.
-          const whenTicketChange = test_util.eventToPromise(
-              print_preview.ticket_items.TicketItem.EventType.CHANGE,
-              printPreview.printTicketStore_.pageRange);
+              // Wait for ticket change.
+              const whenTicketChange = test_util.eventToPromise(
+                  print_preview.ticket_items.TicketItem.EventType.CHANGE,
+                  printPreview.printTicketStore_.pageRange);
 
-          // Set page settings to a bad value
-          pageSettings.querySelector('.page-settings-custom-input').value =
-              'abc';
-          pageSettings.querySelector('.page-settings-custom-radio').click();
+              // Set page settings to a bad value
+              pageSettings.querySelector('.page-settings-custom-input').value =
+                  'abc';
+              pageSettings.querySelector('.page-settings-custom-radio').click();
 
-          // No new preview
-          nativeLayer.whenCalled('getPreview').then(function() {
-            assertTrue(false);
-          });
-          return whenTicketChange;
-        }).then(function() {
-          // Expect disabled print button and Pdf in preview link
-          const printButton = $('print-header').querySelector('button.print');
-          checkElementDisplayed(printButton, true);
-          expectTrue(printButton.disabled);
-          checkElementDisplayed(systemDialogLink, true);
-          expectTrue(systemDialogLink.disabled);
-        });
+              // No new preview
+              nativeLayer.whenCalled('getPreview').then(function() {
+                assertTrue(false);
+              });
+              return whenTicketChange;
+            })
+            .then(function() {
+              // Expect disabled print button and Pdf in preview link
+              const printButton =
+                  $('print-header').querySelector('button.print');
+              checkElementDisplayed(printButton, true);
+              expectTrue(printButton.disabled);
+              checkElementDisplayed(systemDialogLink, true);
+              expectTrue(systemDialogLink.disabled);
+            });
       });
     }  // cr.isWindows
   });
diff --git a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
index a60f2741..95ea8982 100644
--- a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
+++ b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
@@ -67,40 +67,24 @@
 };
 
 // Run each mocha test in isolation (within a new TEST_F() call).
-[
-  'PrinterList',
-  'RestoreLocalDestination',
-  'RestoreMultipleDestinations',
-  'SaveAppState',
-  'DefaultDestinationSelectionRules',
-  'SystemDialogLinkIsHiddenInAppKioskMode',
-  'SectionsDisabled',
-  'PrintToPDFSelectedCapabilities',
-  'SourceIsHTMLCapabilities',
-  'SourceIsPDFCapabilities',
-  'ScalingUnchecksFitToPage',
-  'CheckNumCopiesPrintPreset',
-  'CheckDuplexPrintPreset',
-  'CustomMarginsControlsCheck',
-  'PageLayoutHasNoMarginsHideHeaderFooter',
-  'PageLayoutHasMarginsShowHeaderFooter',
-  'ZeroTopAndBottomMarginsHideHeaderFooter',
-  'ZeroTopAndNonZeroBottomMarginShowHeaderFooter',
-  'SmallPaperSizeHeaderFooter',
-  'ColorSettingsMonochrome',
-  'ColorSettingsCustomMonochrome',
-  'ColorSettingsColor',
-  'ColorSettingsCustomColor',
-  'ColorSettingsBothStandardDefaultColor',
-  'ColorSettingsBothStandardDefaultMonochrome',
-  'ColorSettingsBothCustomDefaultColor',
-  'DuplexSettingsTrue',
-  'DuplexSettingsFalse',
-  'PrinterChangeUpdatesPreview',
-  'NoPDFPluginErrorMessage',
-  'CustomPaperNames',
-  'InitIssuesOneRequest',
-  'InvalidSettingsError',
+['PrinterList', 'RestoreLocalDestination', 'RestoreMultipleDestinations',
+ 'SaveAppState', 'DefaultDestinationSelectionRules',
+ 'SystemDialogLinkIsHiddenInAppKioskMode', 'SectionsDisabled',
+ 'PrintToPDFSelectedCapabilities', 'SourceIsHTMLCapabilities',
+ 'SourceIsPDFCapabilities', 'ScalingUnchecksFitToPage',
+ 'CheckNumCopiesPrintPreset', 'CheckDuplexPrintPreset',
+ 'CustomMarginsControlsCheck', 'PageLayoutHasNoMarginsHideHeaderFooter',
+ 'PageLayoutHasMarginsShowHeaderFooter',
+ 'ZeroTopAndBottomMarginsHideHeaderFooter',
+ 'ZeroTopAndNonZeroBottomMarginShowHeaderFooter', 'SmallPaperSizeHeaderFooter',
+ 'ColorSettingsMonochrome', 'ColorSettingsCustomMonochrome',
+ 'ColorSettingsColor', 'ColorSettingsCustomColor',
+ 'ColorSettingsBothStandardDefaultColor',
+ 'ColorSettingsBothStandardDefaultMonochrome',
+ 'ColorSettingsBothCustomDefaultColor', 'DuplexSettingsTrue',
+ 'DuplexSettingsFalse', 'PrinterChangeUpdatesPreview',
+ 'NoPDFPluginErrorMessage', 'CustomPaperNames', 'InitIssuesOneRequest',
+ 'InvalidSettingsError',
 ].forEach(function(testName) {
   TEST_F('PrintPreviewUIBrowserTest', testName, function() {
     runMochaTest(print_preview_test.suiteName, testName);
@@ -108,21 +92,16 @@
 });
 
 // Disable accessibility errors for some tests.
-[
-  'RestoreAppState',
-  'AdvancedSettings1Option',
-  'AdvancedSettings2Options',
-].forEach(function(testName) {
-  TEST_F('PrintPreviewUIBrowserTest', testName, function() {
-    this.accessibilityIssuesAreErrors = false;
-    runMochaTest(print_preview_test.suiteName, testName);
-  });
-});
+['RestoreAppState', 'AdvancedSettings1Option', 'AdvancedSettings2Options', ]
+    .forEach(function(testName) {
+      TEST_F('PrintPreviewUIBrowserTest', testName, function() {
+        this.accessibilityIssuesAreErrors = false;
+        runMochaTest(print_preview_test.suiteName, testName);
+      });
+    });
 
-[
-  'InvalidCertificateError',
-  'InvalidCertificateErrorReselectDestination',
-  'InvalidCertificateErrorNoPreview',
+['InvalidCertificateError', 'InvalidCertificateErrorReselectDestination',
+ 'InvalidCertificateErrorNoPreview',
 ].forEach(function(testName) {
   TEST_F('PrintPreviewUIBrowserTest', testName, function() {
     loadTimeData.overrideValues({isEnterpriseManaged: false});
@@ -139,10 +118,8 @@
 GEN('#endif');
 
 GEN('#if defined(OS_MACOSX)');
-[
-  'MacOpenPDFInPreview',
-  'MacOpenPDFInPreviewBadPrintTicket',
-].forEach(function(testName) {
+['MacOpenPDFInPreview', 'MacOpenPDFInPreviewBadPrintTicket', ].forEach(function(
+    testName) {
   TEST_F('PrintPreviewUIBrowserTest', testName, function() {
     runMochaTest(print_preview_test.suiteName, testName);
   });
@@ -150,10 +127,8 @@
 GEN('#endif');
 
 GEN('#if defined(OS_WIN)');
-[
-  'WinSystemDialogLink',
-  'WinSystemDialogLinkBadPrintTicket',
-].forEach(function(testName) {
+['WinSystemDialogLink', 'WinSystemDialogLinkBadPrintTicket', ].forEach(function(
+    testName) {
   TEST_F('PrintPreviewUIBrowserTest', testName, function() {
     runMochaTest(print_preview_test.suiteName, testName);
   });
diff --git a/chrome/test/data/webui/print_preview/restore_state_test.js b/chrome/test/data/webui/print_preview/restore_state_test.js
index 3f54894..6c4e609 100644
--- a/chrome/test/data/webui/print_preview/restore_state_test.js
+++ b/chrome/test/data/webui/print_preview/restore_state_test.js
@@ -30,19 +30,23 @@
      *     to verify.
      */
     function verifyStickySettingsApplied(stickySettings) {
-      assertEquals(stickySettings.dpi.horizontal_dpi,
-                   page.settings.dpi.value.horizontal_dpi);
-      assertEquals(stickySettings.dpi.vertical_dpi,
-                   page.settings.dpi.value.vertical_dpi);
-      assertEquals(stickySettings.mediaSize.name,
-                   page.settings.mediaSize.value.name);
-      assertEquals(stickySettings.mediaSize.height_microns,
-                   page.settings.mediaSize.value.height_microns);
-      assertEquals(stickySettings.mediaSize.width_microns,
-                   page.settings.mediaSize.value.width_microns);
+      assertEquals(
+          stickySettings.dpi.horizontal_dpi,
+          page.settings.dpi.value.horizontal_dpi);
+      assertEquals(
+          stickySettings.dpi.vertical_dpi,
+          page.settings.dpi.value.vertical_dpi);
+      assertEquals(
+          stickySettings.mediaSize.name, page.settings.mediaSize.value.name);
+      assertEquals(
+          stickySettings.mediaSize.height_microns,
+          page.settings.mediaSize.value.height_microns);
+      assertEquals(
+          stickySettings.mediaSize.width_microns,
+          page.settings.mediaSize.value.width_microns);
 
-      [['margins', 'marginsType'],
-       ['color', 'isColorEnabled'], ['headerFooter', 'isHeaderFooterEnabled'],
+      [['margins', 'marginsType'], ['color', 'isColorEnabled'],
+       ['headerFooter', 'isHeaderFooterEnabled'],
        ['layout', 'isLandscapeEnabled'], ['collate', 'isCollateEnabled'],
        ['fitToPage', 'isFitToPageEnabled'],
        ['cssBackground', 'isCssBackgroundEnabled'], ['scaling', 'scaling'],
@@ -68,11 +72,13 @@
       previewArea.plugin_ = new print_preview.PDFPluginStub(
           previewArea.onPluginLoad_.bind(previewArea));
       document.body.appendChild(page);
-      return nativeLayer.whenCalled('getInitialSettings').then(function() {
-        return nativeLayer.whenCalled('getPrinterCapabilities');
-      }).then(function() {
-        verifyStickySettingsApplied(stickySettings);
-      });
+      return nativeLayer.whenCalled('getInitialSettings')
+          .then(function() {
+            return nativeLayer.whenCalled('getPrinterCapabilities');
+          })
+          .then(function() {
+            verifyStickySettingsApplied(stickySettings);
+          });
     }
 
     /**
@@ -84,13 +90,15 @@
         version: 2,
         recentDestinations: [],
         dpi: {horizontal_dpi: 100, vertical_dpi: 100},
-        mediaSize: {name: 'CUSTOM_SQUARE',
-                    width_microns: 215900,
-                    height_microns: 215900,
-                    custom_display_name: 'CUSTOM_SQUARE'},
+        mediaSize: {
+          name: 'CUSTOM_SQUARE',
+          width_microns: 215900,
+          height_microns: 215900,
+          custom_display_name: 'CUSTOM_SQUARE'
+        },
         customMargins: {top: 74, right: 74, bottom: 74, left: 74},
         vendorOptions: {},
-        marginsType: 3,  /* custom */
+        marginsType: 3, /* custom */
         scaling: '90',
         isHeaderFooterEnabled: true,
         isCssBackgroundEnabled: true,
@@ -112,14 +120,16 @@
         version: 2,
         recentDestinations: [],
         dpi: {horizontal_dpi: 200, vertical_dpi: 200},
-        mediaSize: {name: 'NA_LETTER',
-                    width_microns: 215900,
-                    height_microns: 279400,
-                    is_default: true,
-                    custom_display_name: 'Letter'},
+        mediaSize: {
+          name: 'NA_LETTER',
+          width_microns: 215900,
+          height_microns: 279400,
+          is_default: true,
+          custom_display_name: 'Letter'
+        },
         customMargins: {},
         vendorOptions: {},
-        marginsType: 0,  /* default */
+        marginsType: 0, /* default */
         scaling: '120',
         isHeaderFooterEnabled: false,
         isCssBackgroundEnabled: false,
@@ -219,29 +229,31 @@
           previewArea.onPluginLoad_.bind(previewArea));
       document.body.appendChild(page);
 
-      return nativeLayer.whenCalled('getInitialSettings').then(function() {
-        return nativeLayer.whenCalled('getPrinterCapabilities');
-      }).then(function() {
-        // Set all the settings sections.
-        testData.forEach((testValue, index) => {
-          if (index == testData.length - 1)
-            nativeLayer.resetResolver('saveAppState');
-          page.$$(testValue.section)
-              .setSetting(testValue.settingName, testValue.value);
-        });
-        // Wait on only the last call to saveAppState, which should
-        // contain all the update settings values.
-        return nativeLayer.whenCalled('saveAppState');
-      })
-      .then(function(serializedSettingsStr) {
-        const serializedSettings = JSON.parse(serializedSettingsStr);
-        // Validate serialized state.
-        testData.forEach(testValue => {
-          expectEquals(
-              JSON.stringify(testValue.value),
-              JSON.stringify(serializedSettings[testValue.key]));
-        });
-      });
+      return nativeLayer.whenCalled('getInitialSettings')
+          .then(function() {
+            return nativeLayer.whenCalled('getPrinterCapabilities');
+          })
+          .then(function() {
+            // Set all the settings sections.
+            testData.forEach((testValue, index) => {
+              if (index == testData.length - 1)
+                nativeLayer.resetResolver('saveAppState');
+              page.$$(testValue.section)
+                  .setSetting(testValue.settingName, testValue.value);
+            });
+            // Wait on only the last call to saveAppState, which should
+            // contain all the update settings values.
+            return nativeLayer.whenCalled('saveAppState');
+          })
+          .then(function(serializedSettingsStr) {
+            const serializedSettings = JSON.parse(serializedSettingsStr);
+            // Validate serialized state.
+            testData.forEach(testValue => {
+              expectEquals(
+                  JSON.stringify(testValue.value),
+                  JSON.stringify(serializedSettings[testValue.key]));
+            });
+          });
     });
   });
 
diff --git a/chrome/test/data/webui/print_preview/settings_section_test.js b/chrome/test/data/webui/print_preview/settings_section_test.js
index e604815..a43984a 100644
--- a/chrome/test/data/webui/print_preview/settings_section_test.js
+++ b/chrome/test/data/webui/print_preview/settings_section_test.js
@@ -51,12 +51,14 @@
       document.body.appendChild(page);
 
       // Wait for initialization to complete.
-      return Promise.all([
-        nativeLayer.whenCalled('getInitialSettings'),
-        nativeLayer.whenCalled('getPrinterCapabilities')
-      ]).then(function() {
-        Polymer.dom.flush();
-      });
+      return Promise
+          .all([
+            nativeLayer.whenCalled('getInitialSettings'),
+            nativeLayer.whenCalled('getPrinterCapabilities')
+          ])
+          .then(function() {
+            Polymer.dom.flush();
+          });
     });
 
     /**
@@ -160,84 +162,93 @@
       // Each of these settings should not show the capability. The value should
       // be the default for settings with multiple options and the only
       // available option otherwise.
-      [
-        {
-          colorCap: null,
-          expectedValue: false,
-        },
-        {
-          colorCap: {option: [{type: 'STANDARD_COLOR', is_default: true}]},
-          expectedValue: true,
-        },
-        {
-          colorCap: { option: [{type: 'STANDARD_COLOR', is_default: true},
-                               {type: 'CUSTOM_COLOR'}]},
-          expectedValue: true,
-        },
-        {
-          colorCap: { option: [{type: 'STANDARD_MONOCHROME', is_default: true},
-                               {type: 'CUSTOM_MONOCHROME'}]},
-          expectedValue: false,
-        },
-        {
-          colorCap: {option: [{type: 'STANDARD_MONOCHROME'}]},
-          expectedValue: false,
-        },
-        {
-          colorCap: {option: [{type: 'CUSTOM_MONOCHROME', vendor_id: '42'}]},
-          expectedValue: false,
-        },
-        {
-          colorCap: {option: [{type: 'CUSTOM_COLOR', vendor_id: '42'}]},
-          expectedValue: true,
-        }
-      ].forEach(capabilityAndValue => {
+      [{
+        colorCap: null,
+        expectedValue: false,
+      },
+       {
+         colorCap: {option: [{type: 'STANDARD_COLOR', is_default: true}]},
+         expectedValue: true,
+       },
+       {
+         colorCap: {
+           option: [
+             {type: 'STANDARD_COLOR', is_default: true},
+             {type: 'CUSTOM_COLOR'}
+           ]
+         },
+         expectedValue: true,
+       },
+       {
+         colorCap: {
+           option: [
+             {type: 'STANDARD_MONOCHROME', is_default: true},
+             {type: 'CUSTOM_MONOCHROME'}
+           ]
+         },
+         expectedValue: false,
+       },
+       {
+         colorCap: {option: [{type: 'STANDARD_MONOCHROME'}]},
+         expectedValue: false,
+       },
+       {
+         colorCap: {option: [{type: 'CUSTOM_MONOCHROME', vendor_id: '42'}]},
+         expectedValue: false,
+       },
+       {
+         colorCap: {option: [{type: 'CUSTOM_COLOR', vendor_id: '42'}]},
+         expectedValue: true,
+       }].forEach(capabilityAndValue => {
         capabilities =
             print_preview_test_utils.getCddTemplate('FooPrinter').capabilities;
         capabilities.printer.color = capabilityAndValue.colorCap;
         // Layout section should now be hidden.
         page.set('destination_.capabilities', capabilities);
         assertTrue(colorElement.hidden);
-        assertEquals(capabilityAndValue.expectedValue,
-                     page.getSettingValue('color'));
+        assertEquals(
+            capabilityAndValue.expectedValue, page.getSettingValue('color'));
       });
 
       // Each of these settings should show the capability with the default
       // value given by expectedValue.
-      [
-        {
-          colorCap: {
-            option: [{type: 'STANDARD_MONOCHROME', is_default: true},
-                     {type: 'STANDARD_COLOR'}]
-          },
-          expectedValue: false,
+      [{
+        colorCap: {
+          option: [
+            {type: 'STANDARD_MONOCHROME', is_default: true},
+            {type: 'STANDARD_COLOR'}
+          ]
         },
-        {
-          colorCap: {
-            option: [{type: 'STANDARD_MONOCHROME'},
-                     {type: 'STANDARD_COLOR', is_default: true}]
-          },
-          expectedValue: true,
-        },
-        {
-          colorCap: {
-            option: [
-              {type: 'CUSTOM_MONOCHROME', vendor_id: '42'},
-              {type: 'CUSTOM_COLOR', is_default: true, vendor_id: '43'}
-            ]
-          },
-          expectedValue: true,
-        }
-      ].forEach(capabilityAndValue => {
+        expectedValue: false,
+      },
+       {
+         colorCap: {
+           option: [
+             {type: 'STANDARD_MONOCHROME'},
+             {type: 'STANDARD_COLOR', is_default: true}
+           ]
+         },
+         expectedValue: true,
+       },
+       {
+         colorCap: {
+           option: [
+             {type: 'CUSTOM_MONOCHROME', vendor_id: '42'},
+             {type: 'CUSTOM_COLOR', is_default: true, vendor_id: '43'}
+           ]
+         },
+         expectedValue: true,
+       }].forEach(capabilityAndValue => {
         capabilities =
             print_preview_test_utils.getCddTemplate('FooPrinter').capabilities;
         capabilities.printer.color = capabilityAndValue.colorCap;
         page.set('destination_.capabilities', capabilities);
         assertFalse(colorElement.hidden);
-        assertEquals(capabilityAndValue.expectedValue ? 'color' : 'bw',
-                     colorElement.$$('select').value);
-        assertEquals(capabilityAndValue.expectedValue,
-                     page.getSettingValue('color'));
+        assertEquals(
+            capabilityAndValue.expectedValue ? 'color' : 'bw',
+            colorElement.$$('select').value);
+        assertEquals(
+            capabilityAndValue.expectedValue, page.getSettingValue('color'));
       });
     });
 
@@ -378,7 +389,7 @@
       let capabilities =
           print_preview_test_utils.getCddTemplate('FooPrinter').capabilities;
       page.set('destination_.capabilities', capabilities);
-      //assertTrue(optionsElement.hidden);
+      // assertTrue(optionsElement.hidden);
 
       // Expanding more settings will show the section.
       toggleMoreSettings();
@@ -446,15 +457,18 @@
       assertFalse(headerFooter.hidden);
 
       // Set margins to NONE
-      page.set('settings.margins.value',
-               print_preview.ticket_items.MarginsTypeValue.NO_MARGINS);
+      page.set(
+          'settings.margins.value',
+          print_preview.ticket_items.MarginsTypeValue.NO_MARGINS);
       assertTrue(headerFooter.hidden);
 
       // Custom margins of 0.
-      page.set('settings.margins.value',
-               print_preview.ticket_items.MarginsTypeValue.CUSTOM);
-      page.set('settings.customMargins.vaue',
-               {marginTop: 0, marginLeft: 0, marginRight: 0, marginBottom: 0});
+      page.set(
+          'settings.margins.value',
+          print_preview.ticket_items.MarginsTypeValue.CUSTOM);
+      page.set(
+          'settings.customMargins.vaue',
+          {marginTop: 0, marginLeft: 0, marginRight: 0, marginBottom: 0});
       assertTrue(headerFooter.hidden);
 
       // Custom margins of 36 -> header/footer available
@@ -480,15 +494,24 @@
           print_preview_test_utils.getCddTemplate('FooPrinter').capabilities;
       capabilities.printer.media_size = {
         'option': [
-          {'name': 'SmallLabel', 'width_microns': 38100,
-            'height_microns': 12700, 'is_default': false},
-          {'name': 'BigLabel', 'width_microns': 50800,
-            'height_microns': 76200, 'is_default': true}
+          {
+            'name': 'SmallLabel',
+            'width_microns': 38100,
+            'height_microns': 12700,
+            'is_default': false
+          },
+          {
+            'name': 'BigLabel',
+            'width_microns': 50800,
+            'height_microns': 76200,
+            'is_default': true
+          }
         ]
       };
       page.set('destination_.capabilities', capabilities);
-      page.set('settings.margins.value',
-               print_preview.ticket_items.MarginsTypeValue.DEFAULT);
+      page.set(
+          'settings.margins.value',
+          print_preview.ticket_items.MarginsTypeValue.DEFAULT);
 
       // Header/footer should be available for default big label
       assertFalse(headerFooter.hidden);
@@ -534,39 +557,41 @@
       allRadio.dispatchEvent(new CustomEvent('change'));
       pagesInput.value = '1-2';
       pagesInput.dispatchEvent(new CustomEvent('input'));
-      return test_util.eventToPromise('input-change', pagesElement).then(
-          function() {
-        validateInputState(false, '1-2', true);
-        assertEquals(1, page.settings.ranges.value.length);
-        expectEquals(1, page.settings.ranges.value[0].from);
-        expectEquals(2, page.settings.ranges.value[0].to);
-        expectEquals(2, page.settings.pages.value.length);
-        assertTrue(page.settings.pages.valid);
+      return test_util.eventToPromise('input-change', pagesElement)
+          .then(function() {
+            validateInputState(false, '1-2', true);
+            assertEquals(1, page.settings.ranges.value.length);
+            expectEquals(1, page.settings.ranges.value[0].from);
+            expectEquals(2, page.settings.ranges.value[0].to);
+            expectEquals(2, page.settings.pages.value.length);
+            assertTrue(page.settings.pages.valid);
 
-        // Select pages 1 and 3
-        pagesInput.value = '1, 3';
-        pagesInput.dispatchEvent(new CustomEvent('input'));
-        return test_util.eventToPromise('input-change', pagesElement);
-      }).then(function() {
-        validateInputState(false, '1, 3', true);
-        assertEquals(2, page.settings.ranges.value.length);
-        expectEquals(1, page.settings.ranges.value[0].from);
-        expectEquals(1, page.settings.ranges.value[0].to);
-        expectEquals(3, page.settings.ranges.value[1].from);
-        expectEquals(3, page.settings.ranges.value[1].to);
-        expectEquals(2, page.settings.pages.value.length);
-        assertTrue(page.settings.pages.valid);
+            // Select pages 1 and 3
+            pagesInput.value = '1, 3';
+            pagesInput.dispatchEvent(new CustomEvent('input'));
+            return test_util.eventToPromise('input-change', pagesElement);
+          })
+          .then(function() {
+            validateInputState(false, '1, 3', true);
+            assertEquals(2, page.settings.ranges.value.length);
+            expectEquals(1, page.settings.ranges.value[0].from);
+            expectEquals(1, page.settings.ranges.value[0].to);
+            expectEquals(3, page.settings.ranges.value[1].from);
+            expectEquals(3, page.settings.ranges.value[1].to);
+            expectEquals(2, page.settings.pages.value.length);
+            assertTrue(page.settings.pages.valid);
 
-        // Enter an out of bounds value.
-        pagesInput.value = '5';
-        pagesInput.dispatchEvent(new CustomEvent('input'));
-        return test_util.eventToPromise('input-change', pagesElement);
-      }).then(function() {
-        // Now the pages settings value should be invalid, and the error
-        // message should be displayed.
-        validateInputState(false, '5', false);
-        assertFalse(page.settings.pages.valid);
-      });
+            // Enter an out of bounds value.
+            pagesInput.value = '5';
+            pagesInput.dispatchEvent(new CustomEvent('input'));
+            return test_util.eventToPromise('input-change', pagesElement);
+          })
+          .then(function() {
+            // Now the pages settings value should be invalid, and the error
+            // message should be displayed.
+            validateInputState(false, '5', false);
+            assertFalse(page.settings.pages.valid);
+          });
     });
 
     test(assert(TestNames.SetCopies), function() {
@@ -583,21 +608,21 @@
       // Change to 2
       copiesInput.value = '2';
       copiesInput.dispatchEvent(new CustomEvent('input'));
-      return test_util.eventToPromise('input-change', copiesElement).then(
-          function() {
-        expectEquals(2, page.settings.copies.value);
+      return test_util.eventToPromise('input-change', copiesElement)
+          .then(function() {
+            expectEquals(2, page.settings.copies.value);
 
-        // Collate is true by default.
-        const collateInput = copiesElement.$.collate;
-        assertTrue(collateInput.checked);
-        assertTrue(page.settings.collate.value);
+            // Collate is true by default.
+            const collateInput = copiesElement.$.collate;
+            assertTrue(collateInput.checked);
+            assertTrue(page.settings.collate.value);
 
-        // Uncheck the box.
-        MockInteractions.tap(collateInput);
-        assertFalse(collateInput.checked);
-        collateInput.dispatchEvent(new CustomEvent('change'));
-        assertFalse(page.settings.collate.value);
-      });
+            // Uncheck the box.
+            MockInteractions.tap(collateInput);
+            assertFalse(collateInput.checked);
+            collateInput.dispatchEvent(new CustomEvent('change'));
+            assertFalse(page.settings.collate.value);
+          });
     });
 
     test(assert(TestNames.SetLayout), function() {
@@ -713,15 +738,14 @@
       const scalingInput =
           scalingElement.$$('print-preview-number-settings-section')
               .$$('input');
-      const fitToPageCheckbox =
-          scalingElement.$$('#fit-to-page-checkbox');
+      const fitToPageCheckbox = scalingElement.$$('#fit-to-page-checkbox');
 
       const validateScalingState = (scalingValue, scalingValid, fitToPage) => {
         // Invalid scalings are always set directly in the input, so no need to
         // verify that the input matches them.
         if (scalingValid) {
-          const scalingDisplay =
-              fitToPage ? page.documentInfo_.fitToPageScaling.toString() :
+          const scalingDisplay = fitToPage ?
+              page.documentInfo_.fitToPageScaling.toString() :
               scalingValue;
           expectEquals(scalingDisplay, scalingInput.value);
         }
@@ -741,42 +765,44 @@
       // Change to 105
       scalingInput.value = '105';
       scalingInput.dispatchEvent(new CustomEvent('input'));
-      return test_util.eventToPromise('input-change', scalingElement).then(
-          function() {
-        validateScalingState('105', true, false);
+      return test_util.eventToPromise('input-change', scalingElement)
+          .then(function() {
+            validateScalingState('105', true, false);
 
-        // Change to fit to page. Should display fit to page scaling but not
-        // alter the scaling setting.
-        fitToPageCheckbox.checked = true;
-        fitToPageCheckbox.dispatchEvent(new CustomEvent('change'));
-        validateScalingState('105', true, true);
+            // Change to fit to page. Should display fit to page scaling but not
+            // alter the scaling setting.
+            fitToPageCheckbox.checked = true;
+            fitToPageCheckbox.dispatchEvent(new CustomEvent('change'));
+            validateScalingState('105', true, true);
 
-        // Set scaling. Should uncheck fit to page and set the settings for
-        // scaling and fit to page.
-        scalingInput.value = '95';
-        scalingInput.dispatchEvent(new CustomEvent('input'));
-        return test_util.eventToPromise('input-change', scalingElement);
-      }).then(function() {
-        validateScalingState('95', true, false);
+            // Set scaling. Should uncheck fit to page and set the settings for
+            // scaling and fit to page.
+            scalingInput.value = '95';
+            scalingInput.dispatchEvent(new CustomEvent('input'));
+            return test_util.eventToPromise('input-change', scalingElement);
+          })
+          .then(function() {
+            validateScalingState('95', true, false);
 
-        // Set scaling to something invalid. Should change setting validity but
-        // not value.
-        scalingInput.value = '5';
-        scalingInput.dispatchEvent(new CustomEvent('input'));
-        return test_util.eventToPromise('input-change', scalingElement);
-      }).then(function() {
-        validateScalingState('95', false, false);
+            // Set scaling to something invalid. Should change setting validity
+            // but not value.
+            scalingInput.value = '5';
+            scalingInput.dispatchEvent(new CustomEvent('input'));
+            return test_util.eventToPromise('input-change', scalingElement);
+          })
+          .then(function() {
+            validateScalingState('95', false, false);
 
-        // Check fit to page. Should set scaling valid.
-        fitToPageCheckbox.checked = true;
-        fitToPageCheckbox.dispatchEvent(new CustomEvent('change'));
-        validateScalingState('95', true, true);
+            // Check fit to page. Should set scaling valid.
+            fitToPageCheckbox.checked = true;
+            fitToPageCheckbox.dispatchEvent(new CustomEvent('change'));
+            validateScalingState('95', true, true);
 
-        // Uncheck fit to page. Should reset scaling to last valid.
-        fitToPageCheckbox.checked = false;
-        fitToPageCheckbox.dispatchEvent(new CustomEvent('change'));
-        validateScalingState('95', true, false);
-      });
+            // Uncheck fit to page. Should reset scaling to last valid.
+            fitToPageCheckbox.checked = false;
+            fitToPageCheckbox.dispatchEvent(new CustomEvent('change'));
+            validateScalingState('95', true, false);
+          });
     });
 
     test(assert(TestNames.SetOther), function() {
@@ -797,12 +823,12 @@
       };
 
       // Check HTML settings
-      const ids =
-          ['headerFooter', 'duplex', 'cssBackground', 'selectionOnly'];
+      const ids = ['headerFooter', 'duplex', 'cssBackground', 'selectionOnly'];
       const defaults = [true, true, false, false];
-      const optionSettings =
-          [page.settings.headerFooter, page.settings.duplex,
-           page.settings.cssBackground, page.settings.selectionOnly];
+      const optionSettings = [
+        page.settings.headerFooter, page.settings.duplex,
+        page.settings.cssBackground, page.settings.selectionOnly
+      ];
 
       optionSettings.forEach((option, index) => {
         testOptionCheckbox(
@@ -845,8 +871,8 @@
       page.setSetting('duplex', print_preview_new.DuplexMode.SIMPLEX);
       const checkbox = optionsElement.$$('#duplex');
       assertFalse(checkbox.checked);
-      assertEquals(print_preview_new.DuplexMode.SIMPLEX,
-                   page.settings.duplex.value);
+      assertEquals(
+          print_preview_new.DuplexMode.SIMPLEX, page.settings.duplex.value);
 
       // Send a preset value of LONG_EDGE
       const duplex = print_preview_new.DuplexMode.LONG_EDGE;
diff --git a/chrome/test/data/webui/print_preview/settings_select_test.js b/chrome/test/data/webui/print_preview/settings_select_test.js
index f183178..706f780 100644
--- a/chrome/test/data/webui/print_preview/settings_select_test.js
+++ b/chrome/test/data/webui/print_preview/settings_select_test.js
@@ -26,9 +26,9 @@
       settingsSelect.settingName = 'mediaSize';
       settingsSelect.capability =
           print_preview_test_utils.getMediaSizeCapabilityWithCustomNames();
-      const customLocalizedMediaName =
-          settingsSelect.capability.option[0].custom_display_name_localized[0]
-              .value;
+      const customLocalizedMediaName = settingsSelect.capability.option[0]
+                                           .custom_display_name_localized[0]
+                                           .value;
       const customMediaName =
           settingsSelect.capability.option[1].custom_display_name;
       Polymer.dom.flush();
@@ -37,10 +37,9 @@
       // Verify that the selected option and names are as expected.
       assertEquals(0, select.selectedIndex);
       assertEquals(2, select.options.length);
-      assertEquals(customLocalizedMediaName,
-                   select.options[0].textContent.trim());
-      assertEquals(customMediaName,
-                   select.options[1].textContent.trim());
+      assertEquals(
+          customLocalizedMediaName, select.options[0].textContent.trim());
+      assertEquals(customMediaName, select.options[1].textContent.trim());
     });
   });
 
diff --git a/chrome/test/data/webui/print_preview/system_dialog_browsertest.js b/chrome/test/data/webui/print_preview/system_dialog_browsertest.js
index 7d43ff4..e60daed7 100644
--- a/chrome/test/data/webui/print_preview/system_dialog_browsertest.js
+++ b/chrome/test/data/webui/print_preview/system_dialog_browsertest.js
@@ -44,18 +44,21 @@
       previewArea.plugin_ = new print_preview.PDFPluginStub(
           previewArea.onPluginLoad_.bind(previewArea));
       document.body.appendChild(page);
-      return Promise.all([
-        nativeLayer.whenCalled('getInitialSettings'),
-        nativeLayer.whenCalled('getPrinterCapabilities'),
-      ]).then(function() {
-        return nativeLayer.whenCalled('getPreview');
-      }).then(function() {
-        assertEquals('FooDevice', page.destination_.id);
-        link = cr.isWindows ?
-            linkContainer.$.systemDialogLink :
-            linkContainer.$.openPdfInPreviewLink;
-        printTicketKey = cr.isWindows ? 'showSystemDialog' : 'OpenPDFInPreview';
-      });
+      return Promise
+          .all([
+            nativeLayer.whenCalled('getInitialSettings'),
+            nativeLayer.whenCalled('getPrinterCapabilities'),
+          ])
+          .then(function() {
+            return nativeLayer.whenCalled('getPreview');
+          })
+          .then(function() {
+            assertEquals('FooDevice', page.destination_.id);
+            link = cr.isWindows ? linkContainer.$.systemDialogLink :
+                                  linkContainer.$.openPdfInPreviewLink;
+            printTicketKey =
+                cr.isWindows ? 'showSystemDialog' : 'OpenPDFInPreview';
+          });
     });
 
     test(assert(TestNames.LinkTriggersLocalPrint), function() {
@@ -79,8 +82,8 @@
 
       // Set page settings to a bad value
       pageSettings.$$('#custom-radio-button').checked = true;
-      pageSettings.$$('#all-radio-button').dispatchEvent(
-        new CustomEvent('change'));
+      pageSettings.$$('#all-radio-button')
+          .dispatchEvent(new CustomEvent('change'));
       const pageSettingsInput = pageSettings.$$('.user-value');
       pageSettingsInput.value = 'abc';
       pageSettingsInput.dispatchEvent(new CustomEvent('input'));
@@ -90,8 +93,8 @@
         assertTrue(false);
       });
 
-      return test_util.eventToPromise('input-change', pageSettings).then(
-          function() {
+      return test_util.eventToPromise('input-change', pageSettings)
+          .then(function() {
             // Expect disabled print button and Pdf in preview link
             const header = page.$$('print-preview-header');
             const printButton = header.$$('.print');
diff --git a/chrome/test/data/webui/profile_window_browsertest.js b/chrome/test/data/webui/profile_window_browsertest.js
index 910d932..e486b0d 100644
--- a/chrome/test/data/webui/profile_window_browsertest.js
+++ b/chrome/test/data/webui/profile_window_browsertest.js
@@ -3,13 +3,14 @@
 // found in the LICENSE file.
 
 function testNoPodFocused() {
-  expectEquals(null, document.querySelector('.pod.focused'),
-               "No pod should be focused.");
+  expectEquals(
+      null, document.querySelector('.pod.focused'),
+      'No pod should be focused.');
 }
 
 function testPodFocused(profilePath) {
   var pods = document.querySelectorAll('.pod.focused');
-  assertEquals(1, pods.length, "Exactly one pod should be focused.");
-  expectEquals(profilePath, pods[0].user.profilePath,
-               "A wrong pod is focused.");
+  assertEquals(1, pods.length, 'Exactly one pod should be focused.');
+  expectEquals(
+      profilePath, pods[0].user.profilePath, 'A wrong pod is focused.');
 }
diff --git a/chrome/test/data/webui/sandboxstatus_browsertest.js b/chrome/test/data/webui/sandboxstatus_browsertest.js
index 1de8c7a..f852b18 100644
--- a/chrome/test/data/webui/sandboxstatus_browsertest.js
+++ b/chrome/test/data/webui/sandboxstatus_browsertest.js
@@ -36,32 +36,33 @@
 /**
  * Test if the SUID sandbox is enabled.
  */
-TEST_F('SandboxStatusUITest',
-       'MAYBE_testSUIDorNamespaceSandboxEnabled', function() {
-  var namespaceyesstring = 'Namespace Sandbox\tYes';
-  var namespacenostring = 'Namespace Sandbox\tNo';
-  var suidyesstring = 'SUID Sandbox\tYes';
-  var suidnostring = 'SUID Sandbox\tNo';
+TEST_F(
+    'SandboxStatusUITest', 'MAYBE_testSUIDorNamespaceSandboxEnabled',
+    function() {
+      var namespaceyesstring = 'Namespace Sandbox\tYes';
+      var namespacenostring = 'Namespace Sandbox\tNo';
+      var suidyesstring = 'SUID Sandbox\tYes';
+      var suidnostring = 'SUID Sandbox\tNo';
 
-  var suidyes = document.body.innerText.match(suidyesstring);
-  var suidno = document.body.innerText.match(suidnostring);
-  var namespaceyes = document.body.innerText.match(namespaceyesstring);
-  var namespaceno = document.body.innerText.match(namespacenostring);
+      var suidyes = document.body.innerText.match(suidyesstring);
+      var suidno = document.body.innerText.match(suidnostring);
+      var namespaceyes = document.body.innerText.match(namespaceyesstring);
+      var namespaceno = document.body.innerText.match(namespacenostring);
 
-  // Exactly one of the namespace or suid sandbox should be enabled.
-  expectTrue(suidyes !== null || namespaceyes !== null);
-  expectFalse(suidyes !== null && namespaceyes !== null);
+      // Exactly one of the namespace or suid sandbox should be enabled.
+      expectTrue(suidyes !== null || namespaceyes !== null);
+      expectFalse(suidyes !== null && namespaceyes !== null);
 
-  if (namespaceyes !== null) {
-    expectEquals(null, namespaceno);
-    expectEquals(namespaceyesstring, namespaceyes[0]);
-  }
+      if (namespaceyes !== null) {
+        expectEquals(null, namespaceno);
+        expectEquals(namespaceyesstring, namespaceyes[0]);
+      }
 
-  if (suidyes !== null) {
-    expectEquals(null, suidno);
-    expectEquals(suidyesstring, suidyes[0]);
-  }
-});
+      if (suidyes !== null) {
+        expectEquals(null, suidno);
+        expectEquals(suidyesstring, suidyes[0]);
+      }
+    });
 
 // The seccomp-bpf sandbox is also not compatible with ASAN.
 GEN('#if !defined(OS_LINUX)');
diff --git a/chrome/test/data/webui/settings/PRESUBMIT.py b/chrome/test/data/webui/settings/PRESUBMIT.py
deleted file mode 100644
index a25a4ec..0000000
--- a/chrome/test/data/webui/settings/PRESUBMIT.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# 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.
-
-
-def _CheckChangeOnUploadAndCommit(input_api, output_api):
-  return input_api.canned_checks.CheckPatchFormatted(input_api, output_api,
-                                                     check_js=True)
-
-
-def CheckChangeOnUpload(input_api, output_api):
-  return _CheckChangeOnUploadAndCommit(input_api, output_api)
-
-
-def CheckChangeOnCommit(input_api, output_api):
-  return _CheckChangeOnUploadAndCommit(input_api, output_api)
diff --git a/chrome/test/data/webui/signin/sync_confirmation_test.js b/chrome/test/data/webui/signin/sync_confirmation_test.js
index 39d0d39d..938be37 100644
--- a/chrome/test/data/webui/signin/sync_confirmation_test.js
+++ b/chrome/test/data/webui/signin/sync_confirmation_test.js
@@ -29,9 +29,9 @@
     setup(function() {
       // This test suite makes comparisons with strings in their default locale,
       // which is en-US.
-      assertEquals('en-US', navigator.language,
-                   'Cannot verify strings for the ' + navigator.language +
-                       'locale.');
+      assertEquals(
+          'en-US', navigator.language,
+          'Cannot verify strings for the ' + navigator.language + 'locale.');
 
       browserProxy = new TestSyncConfirmationBrowserProxy();
       sync.confirmation.SyncConfirmationBrowserProxyImpl.instance_ =
@@ -43,18 +43,18 @@
     });
 
     const STANDARD_CONSENT_DESCRIPTION_TEXT = [
-        'Get even more from Chrome',
-        'Sync your bookmarks, passwords, and history on all your devices',
-        'Get more personalized experiences, such as better ' +
-            'content suggestions and smarter Translate',
-        'Bring powerful Google services like spell check and tap to search ' +
-            'to Chrome',
-        'You can customize what information Google collects in ' +
-            '<a id="settingsLink" href="chrome://settings">Settings</a> ' +
-            'anytime.',
-        'Google may use your browsing activity, content on some sites you ' +
-            'visit, and other browser interactions to personalize Chrome and ' +
-            'other Google services like Translate, Search, and ads.',
+      'Get even more from Chrome',
+      'Sync your bookmarks, passwords, and history on all your devices',
+      'Get more personalized experiences, such as better ' +
+          'content suggestions and smarter Translate',
+      'Bring powerful Google services like spell check and tap to search ' +
+          'to Chrome',
+      'You can customize what information Google collects in ' +
+          '<a id="settingsLink" href="chrome://settings">Settings</a> ' +
+          'anytime.',
+      'Google may use your browsing activity, content on some sites you ' +
+          'visit, and other browser interactions to personalize Chrome and ' +
+          'other Google services like Translate, Search, and ads.',
     ];
 
 
@@ -62,36 +62,36 @@
     // button.
     test('recordConsentOnConfirm', function() {
       app.$$('#confirmButton').click();
-      return browserProxy.whenCalled('confirm').then(
-          function(arguments) {
-              assertEquals(2, arguments.length);
-              var description = arguments[0];
-              var confirmation = arguments[1];
+      return browserProxy.whenCalled('confirm').then(function(arguments) {
+        assertEquals(2, arguments.length);
+        var description = arguments[0];
+        var confirmation = arguments[1];
 
-              assertEquals(JSON.stringify(STANDARD_CONSENT_DESCRIPTION_TEXT),
-                           JSON.stringify(description));
-              assertEquals('Yes, I\'m in', confirmation);
-          });
+        assertEquals(
+            JSON.stringify(STANDARD_CONSENT_DESCRIPTION_TEXT),
+            JSON.stringify(description));
+        assertEquals('Yes, I\'m in', confirmation);
+      });
     });
 
     // Tests that the expected strings are recorded when clicking the Confirm
     // button.
     test('recordConsentOnSettingsLink', function() {
       app.$$('#settingsLink').click();
-      return browserProxy.whenCalled('goToSettings').then(
-          function(arguments) {
-            assertEquals(2, arguments.length);
-            var description = arguments[0];
-            var confirmation = arguments[1];
+      return browserProxy.whenCalled('goToSettings').then(function(arguments) {
+        assertEquals(2, arguments.length);
+        var description = arguments[0];
+        var confirmation = arguments[1];
 
-            assertEquals(JSON.stringify(STANDARD_CONSENT_DESCRIPTION_TEXT),
-                         JSON.stringify(description));
-            assertEquals(
-                'You can customize what information Google collects in ' +
-                    '<a id="settingsLink" href="chrome://settings">Settings' +
-                    '</a> anytime.',
-                confirmation);
-          });
+        assertEquals(
+            JSON.stringify(STANDARD_CONSENT_DESCRIPTION_TEXT),
+            JSON.stringify(description));
+        assertEquals(
+            'You can customize what information Google collects in ' +
+                '<a id="settingsLink" href="chrome://settings">Settings' +
+                '</a> anytime.',
+            confirmation);
+      });
     });
   });
 });
diff --git a/chrome/test/data/webui/sys_internals/sys_internals_browsertest.js b/chrome/test/data/webui/sys_internals/sys_internals_browsertest.js
index b12cc7e1..21b3747 100644
--- a/chrome/test/data/webui/sys_internals/sys_internals_browsertest.js
+++ b/chrome/test/data/webui/sys_internals/sys_internals_browsertest.js
@@ -22,8 +22,7 @@
 
   isAsync: true,
 
-  featureList:
-      ['features::kSysInternals', ''],
+  featureList: ['features::kSysInternals', ''],
 
   extraLibraries: [
     'api_test.js',
diff --git a/chrome/test/data/webui/test_api.js b/chrome/test/data/webui/test_api.js
index 84b6c1d4..cd7628a 100644
--- a/chrome/test/data/webui/test_api.js
+++ b/chrome/test/data/webui/test_api.js
@@ -15,1752 +15,1750 @@
  */
 var testing = {};
 (function(exports) {
-  /**
-   * Holds the original version of the |chrome| object.
-   */
-  var originalChrome = null;
+/**
+ * Holds the original version of the |chrome| object.
+ */
+var originalChrome = null;
 
-  /**
-   * Hold the currentTestCase across between preLoad and run.
-   * @type {TestCase}
-   */
-  var currentTestCase = null;
+/**
+ * Hold the currentTestCase across between preLoad and run.
+ * @type {TestCase}
+ */
+var currentTestCase = null;
 
-  /**
-   * The string representation of the currently running test function.
-   * @type {?string}
-   */
-  var currentTestFunction = null;
+/**
+ * The string representation of the currently running test function.
+ * @type {?string}
+ */
+var currentTestFunction = null;
 
-  /**
-   * The arguments of the currently running test.
-   * @type {Array}
-   */
-  var currentTestArguments = [];
+/**
+ * The arguments of the currently running test.
+ * @type {Array}
+ */
+var currentTestArguments = [];
 
- /**
-   * This class will be exported as testing.Test, and is provided to hold the
-   * fixture's configuration and callback methods for the various phases of
-   * invoking a test. It is called "Test" rather than TestFixture to roughly
-   * mimic the gtest's class names.
-   * @constructor
-   */
-  function Test() {}
+/**
+ * This class will be exported as testing.Test, and is provided to hold the
+ * fixture's configuration and callback methods for the various phases of
+ * invoking a test. It is called "Test" rather than TestFixture to roughly
+ * mimic the gtest's class names.
+ * @constructor
+ */
+function Test() {}
 
-  /**
-   * Make all transitions and animations take 0ms. NOTE: this will completely
-   * disable webkitTransitionEnd events. If your code relies on them firing, it
-   * will break. animationend events should still work.
-   */
-  Test.disableAnimationsAndTransitions = function() {
-    let all = document.body.querySelectorAll('*, * /deep/ *');
-    const ZERO_MS_IMPORTANT = '0ms !important';
-    for (let i = 0, l = all.length; i < l; ++i) {
-      let style = all[i].style;
-      style.animationDelay = ZERO_MS_IMPORTANT;
-      style.animationDuration = ZERO_MS_IMPORTANT;
-      style.transitionDelay = ZERO_MS_IMPORTANT;
-      style.transitionDuration = ZERO_MS_IMPORTANT;
-    }
-
-    var realElementAnimate = Element.prototype.animate;
-    Element.prototype.animate = function(keyframes, opt_options) {
-      if (typeof opt_options == 'object')
-        opt_options.duration = 0;
-      else
-        opt_options = 0;
-      return realElementAnimate.call(this, keyframes, opt_options);
-    };
-    if (document.timeline && document.timeline.play) {
-      var realTimelinePlay = document.timeline.play;
-      document.timeline.play = function(a) {
-        a.timing.duration = 0;
-        return realTimelinePlay.call(document.timeline, a);
-      };
-    }
-  };
-
-  Test.prototype = {
-    /**
-     * The name of the test.
-     */
-    name: null,
-
-    /**
-     * When set to a string value representing a url, generate BrowsePreload
-     * call, which will browse to the url and call fixture.preLoad of the
-     * currentTestCase.
-     * @type {string}
-     */
-    browsePreload: null,
-
-    /**
-     * When set to a string value representing an html page in the test
-     * directory, generate BrowsePrintPreload call, which will browse to a url
-     * representing the file, cause print, and call fixture.preLoad of the
-     * currentTestCase.
-     * @type {string}
-     */
-    browsePrintPreload: null,
-
-    /**
-     * When set to a function, will be called in the context of the test
-     * generation inside the function, after AddLibrary calls and before
-     * generated C++.
-     * @type {function(string,string)}
-     */
-    testGenPreamble: null,
-
-    /**
-     * When set to a function, will be called in the context of the test
-     * generation inside the function, and after any generated C++.
-     * @type {function(string,string)}
-     */
-    testGenPostamble: null,
-
-    /**
-     * When set to a non-null string, auto-generate typedef before generating
-     * TEST*: {@code typedef typedefCppFixture testFixture}.
-     * @type {string}
-     */
-    typedefCppFixture: 'WebUIBrowserTest',
-
-    /**
-     * This should be initialized by the test fixture and can be referenced
-     * during the test run. It holds any mocked handler methods.
-     * @type {?Mock4JS.Mock}
-     */
-    mockHandler: null,
-
-    /**
-     * This should be initialized by the test fixture and can be referenced
-     * during the test run. It holds any mocked global functions.
-     * @type {?Mock4JS.Mock}
-     */
-    mockGlobals: null,
-
-    /**
-     * Value is passed through call to C++ RunJavascriptF to invoke this test.
-     * @type {boolean}
-     */
-    isAsync: false,
-
-    /**
-     * True when the test is expected to fail for testing the test framework.
-     * @type {boolean}
-     */
-    testShouldFail: false,
-
-    /**
-     * Extra libraries to add before loading this test file.
-     * @type {Array<string>}
-     */
-    extraLibraries: [],
-
-    /**
-     * Extra libraries to add before loading this test file.
-     * This list is in the form of Closure library style object
-     * names.  To support this, a closure deps.js file must
-     * be specified when generating the test C++ source.
-     * The specified libraries will be included with their transitive
-     * dependencies according to the deps file.
-     * @type {Array<string>}
-     */
-    closureModuleDeps: [],
-
-    /**
-     * Whether to run the accessibility checks.
-     * @type {boolean}
-     */
-    runAccessibilityChecks: true,
-
-    /**
-     * Configuration for the accessibility audit.
-     * @type {axs.AuditConfiguration}
-     */
-    accessibilityAuditConfig_: null,
-
-    /**
-     * Returns the configuration for the accessibility audit, creating it
-     * on-demand.
-     * @return {!axs.AuditConfiguration}
-     */
-    get accessibilityAuditConfig() {
-      if (!this.accessibilityAuditConfig_) {
-        this.accessibilityAuditConfig_ = new axs.AuditConfiguration();
-
-        this.accessibilityAuditConfig_.showUnsupportedRulesWarning = false;
-
-        this.accessibilityAuditConfig_.auditRulesToIgnore = [
-            // The "elements with meaningful background image" accessibility
-            // audit (AX_IMAGE_01) does not apply, since Chrome doesn't
-            // disable background images in high-contrast mode like some
-            // browsers do.
-            "elementsWithMeaningfulBackgroundImage",
-
-            // Most WebUI pages are inside an IFrame, so the "web page should
-            // have a title that describes topic or purpose" test (AX_TITLE_01)
-            // generally does not apply.
-            "pageWithoutTitle",
-
-            // TODO(aboxhall): re-enable when crbug.com/267035 is fixed.
-            // Until then it's just noise.
-            "lowContrastElements",
-
-            // TODO(apacible): re-enable when following issue is fixed.
-            // github.com/GoogleChrome/accessibility-developer-tools/issues/251
-            "tableHasAppropriateHeaders",
-
-            // TODO(crbug.com/657514): This rule is flaky on Linux/ChromeOS.
-            "requiredOwnedAriaRoleMissing",
-        ];
-      }
-      return this.accessibilityAuditConfig_;
-    },
-
-    /**
-     * Whether to treat accessibility issues (errors or warnings) as test
-     * failures. If true, any accessibility issues will cause the test to fail.
-     * If false, accessibility issues will cause a console.warn.
-     * Off by default to begin with; as we add the ability to suppress false
-     * positives, we will transition this to true.
-     * @type {boolean}
-     */
-    accessibilityIssuesAreErrors: false,
-
-    /**
-     * Holds any accessibility results found during the accessibility audit.
-     * @type {Array<Object>}
-     */
-    a11yResults_: [],
-
-    /**
-     * Gets the list of accessibility errors found during the accessibility
-     * audit. Only for use in testing.
-     * @return {Array<Object>}
-     */
-    getAccessibilityResults: function() {
-      return this.a11yResults_;
-    },
-
-    /**
-     * Run accessibility checks after this test completes.
-     */
-    enableAccessibilityChecks: function() {
-      this.runAccessibilityChecks = true;
-    },
-
-    /**
-     * Don't run accessibility checks after this test completes.
-     */
-    disableAccessibilityChecks: function() {
-      this.runAccessibilityChecks = false;
-    },
-
-    /**
-     * Create a new class to handle |messageNames|, assign it to
-     * |this.mockHandler|, register its messages and return it.
-     * @return {Mock} Mock handler class assigned to |this.mockHandler|.
-     */
-    makeAndRegisterMockHandler: function(messageNames) {
-      var MockClass = makeMockClass(messageNames);
-      this.mockHandler = mock(MockClass);
-      registerMockMessageCallbacks(this.mockHandler, MockClass);
-      return this.mockHandler;
-    },
-
-    /**
-     * Create a new class to handle |functionNames|, assign it to
-     * |this.mockGlobals|, register its global overrides, and return it.
-     * @return {Mock} Mock handler class assigned to |this.mockGlobals|.
-     * @see registerMockGlobals
-     */
-    makeAndRegisterMockGlobals: function(functionNames) {
-      var MockClass = makeMockClass(functionNames);
-      this.mockGlobals = mock(MockClass);
-      registerMockGlobals(this.mockGlobals, MockClass);
-      return this.mockGlobals;
-    },
-
-    /**
-      * Create a container of mocked standalone functions to handle
-      * '.'-separated |apiNames|, assign it to |this.mockApis|, register its API
-      * overrides and return it.
-      * @return {Mock} Mock handler class.
-      * @see makeMockFunctions
-      * @see registerMockApis
-      */
-    makeAndRegisterMockApis: function (apiNames) {
-      var apiMockNames = apiNames.map(function(name) {
-        return name.replace(/\./g, '_');
-      });
-
-      this.mockApis = makeMockFunctions(apiMockNames);
-      registerMockApis(this.mockApis);
-      return this.mockApis;
-    },
-
-    /**
-      * Create a container of mocked standalone functions to handle
-      * |functionNames|, assign it to |this.mockLocalFunctions| and return it.
-      * @param {!Array<string>} functionNames
-      * @return {Mock} Mock handler class.
-      * @see makeMockFunctions
-      */
-    makeMockLocalFunctions: function(functionNames) {
-      this.mockLocalFunctions = makeMockFunctions(functionNames);
-      return this.mockLocalFunctions;
-    },
-
-    /**
-     * Override this method to perform initialization during preload (such as
-     * creating mocks and registering handlers).
-     * @type {Function}
-     */
-    preLoad: function() {},
-
-    /**
-     * Override this method to perform tasks before running your test.
-     * @type {Function}
-     */
-    setUp: function() {
-      // These should be ignored in many of the web UI tests.
-      // user-image-stream and supervised-user-creation-image-stream are
-      // streaming video elements used for capturing a user image so they
-      // won't have captions and should be ignored everywhere.
-      this.accessibilityAuditConfig.ignoreSelectors('videoWithoutCaptions',
-                                                    '.user-image-stream');
-      this.accessibilityAuditConfig.ignoreSelectors(
-          'videoWithoutCaptions', '.supervised-user-creation-image-stream');
-    },
-
-    /**
-     * Override this method to perform tasks after running your test. If you
-     * create a mock class, you must call Mock4JS.verifyAllMocks() in this
-     * phase.
-     * @type {Function}
-     */
-    tearDown: function() {
-      if (typeof document != 'undefined') {
-        var noAnimationStyle = document.getElementById('no-animation');
-        if (noAnimationStyle)
-          noAnimationStyle.parentNode.removeChild(noAnimationStyle);
-      }
-
-      Mock4JS.verifyAllMocks();
-    },
-
-    /**
-     * Called to run the body from the perspective of this fixture.
-     * @type {Function}
-     */
-    runTest: function(testBody) {
-      testBody.call(this);
-    },
-
-    /**
-     * Called to run the accessibility audit from the perspective of this
-     * fixture.
-     */
-    runAccessibilityAudit: function() {
-      if (!this.runAccessibilityChecks || typeof document === 'undefined')
-        return;
-
-      var auditConfig = this.accessibilityAuditConfig;
-      if (!runAccessibilityAudit(this.a11yResults_, auditConfig)) {
-        var report = accessibilityAuditReport(this.a11yResults_);
-        if (this.accessibilityIssuesAreErrors)
-          throw new Error(report);
-        else
-          console.warn(report);
-      }
-    },
-
-    /**
-     * Create a closure function for continuing the test at a later time. May be
-     * used as a listener function.
-     * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
-     *     time.
-     * @param {Function} completion The function to call to complete the test.
-     * @param {...*} var_args Arguments to pass when calling completionAction.
-     * @return {function(): void} Return a function, bound to this test fixture,
-     *     which continues the test.
-     */
-    continueTest: function(whenTestDone, completion) {
-      var savedArgs = new SaveMockArguments();
-      var completionAction = new CallFunctionAction(
-          this, savedArgs, completion,
-          Array.prototype.slice.call(arguments, 2));
-      if (whenTestDone === WhenTestDone.DEFAULT)
-        whenTestDone = WhenTestDone.ASSERT;
-      var runAll = new RunAllAction(
-          true, whenTestDone, [completionAction]);
-      return function() {
-        savedArgs.arguments = Array.prototype.slice.call(arguments);
-        runAll.invoke();
-      };
-    },
-
-    /**
-     * Call this during setUp to defer the call to runTest() until later. The
-     * caller must call the returned function at some point to run the test.
-     * @type {Function}
-     * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
-     *     time.
-     * @param {...*} var_args Arguments to pass when running the
-     *     |currentTestCase|.
-     * @return {function(): void} A function which will run the current body of
-     *     the currentTestCase.
-     */
-    deferRunTest: function(whenTestDone) {
-      if (whenTestDone === WhenTestDone.DEFAULT)
-        whenTestDone = WhenTestDone.ALWAYS;
-
-      return currentTestCase.deferRunTest.apply(
-          currentTestCase, [whenTestDone].concat(
-              Array.prototype.slice.call(arguments, 1)));
-    },
-  };
-
-  /**
-   * This class is not exported and is available to hold the state of the
-   * |currentTestCase| throughout preload and test run.
-   * @param {string} name The name of the test case.
-   * @param {Test} fixture The fixture object for this test case.
-   * @param {Function} body The code to run for the test.
-   * @constructor
-   */
-  function TestCase(name, fixture, body) {
-    this.name = name;
-    this.fixture = fixture;
-    this.body = body;
+/**
+ * Make all transitions and animations take 0ms. NOTE: this will completely
+ * disable webkitTransitionEnd events. If your code relies on them firing, it
+ * will break. animationend events should still work.
+ */
+Test.disableAnimationsAndTransitions = function() {
+  let all = document.body.querySelectorAll('*, * /deep/ *');
+  const ZERO_MS_IMPORTANT = '0ms !important';
+  for (let i = 0, l = all.length; i < l; ++i) {
+    let style = all[i].style;
+    style.animationDelay = ZERO_MS_IMPORTANT;
+    style.animationDuration = ZERO_MS_IMPORTANT;
+    style.transitionDelay = ZERO_MS_IMPORTANT;
+    style.transitionDuration = ZERO_MS_IMPORTANT;
   }
 
-  TestCase.prototype = {
-    /**
-     * The name of this test.
-     * @type {string}
-     */
-    name: null,
-
-    /**
-     * The test fixture to set |this| to when running the test |body|.
-     * @type {testing.Test}
-     */
-    fixture: null,
-
-    /**
-     * The test body to execute in runTest().
-     * @type {Function}
-     */
-    body: null,
-
-    /**
-     * True when the test fixture will run the test later.
-     * @type {boolean}
-     * @private
-     */
-    deferred_: false,
-
-    /**
-     * Called at preload time, proxies to the fixture.
-     * @type {Function}
-     */
-    preLoad: function(name) {
-      if (this.fixture)
-        this.fixture.preLoad();
-    },
-
-    /**
-     * Called before a test runs.
-     */
-    setUp: function() {
-      if (this.fixture)
-        this.fixture.setUp();
-    },
-
-    /**
-     * Called before a test is torn down (by testDone()).
-     */
-    tearDown: function() {
-      if (this.fixture)
-        this.fixture.tearDown();
-    },
-
-    /**
-     * Called to run this test's body.
-     */
-    runTest: function() {
-      if (this.body && this.fixture)
-        this.fixture.runTest(this.body);
-    },
-
-    /**
-     * Called after a test is run (in testDone) to test accessibility.
-     */
-    runAccessibilityAudit: function() {
-      if (this.fixture)
-        this.fixture.runAccessibilityAudit();
-    },
-
-    /**
-     * Runs this test case with |this| set to the |fixture|.
-     *
-     * Note: Tests created with TEST_F may depend upon |this| being set to an
-     * instance of this.fixture. The current implementation of TEST creates a
-     * dummy constructor, but tests created with TEST should not rely on |this|
-     * being set.
-     * @type {Function}
-     */
-    run: function() {
-      try {
-        this.setUp();
-      } catch(e) {
-        // Mock4JSException doesn't inherit from Error, so fall back on
-        // toString().
-        console.error(e.stack || e.toString());
-      }
-
-      if (!this.deferred_)
-        this.runTest();
-
-      // tearDown called by testDone().
-    },
-
-    /**
-     * Cause this TestCase to be deferred (don't call runTest()) until the
-     * returned function is called.
-     * @type {Function}
-     * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
-     *     time.
-     * @param {...*} var_args Arguments to pass when running the
-     *     |currentTestCase|.
-     * @return {function(): void} A function that will run this TestCase when
-     *     called.
-     */
-    deferRunTest: function(whenTestDone) {
-      this.deferred_ = true;
-      var savedArgs = new SaveMockArguments();
-      var completionAction = new CallFunctionAction(
-          this, savedArgs, this.runTest,
-          Array.prototype.slice.call(arguments, 1));
-      var runAll = new RunAllAction(
-          true, whenTestDone, [completionAction]);
-      return function() {
-        savedArgs.arguments = Array.prototype.slice.call(arguments);
-        runAll.invoke();
-      };
-    },
-
-  };
-
-  /**
-   * Registry of javascript-defined callbacks for {@code chrome.send}.
-   * @type {Object}
-   */
-  var sendCallbacks = {};
-
-  /**
-   * Registers the message, object and callback for {@code chrome.send}
-   * @param {string} name The name of the message to route to this |callback|.
-   * @param {Object} messageHandler Pass as |this| when calling the |callback|.
-   * @param {function(...)} callback Called by {@code chrome.send}.
-   * @see sendCallbacks
-   */
-  function registerMessageCallback(name, messageHandler, callback) {
-    sendCallbacks[name] = [messageHandler, callback];
-  }
-
-  /**
-   * Register all methods of {@code mockClass.prototype} with messages of the
-   * same name as the method, using the proxy of the |mockObject| as the
-   * |messageHandler| when registering.
-   * @param {Mock4JS.Mock} mockObject The mock to register callbacks against.
-   * @param {function(new:Object)} mockClAss Constructor for the mocked class.
-   * @see registerMessageCallback
-   * @see overrideChrome
-   */
-  function registerMockMessageCallbacks(mockObject, mockClass) {
-    if (!deferGlobalOverrides && !originalChrome)
-      overrideChrome();
-    var mockProxy = mockObject.proxy();
-    for (var func in mockClass.prototype) {
-      if (typeof mockClass.prototype[func] === 'function') {
-        registerMessageCallback(func, mockProxy, mockProxy[func]);
-      }
-    }
-  }
-
-  /**
-   * Holds the mapping of name -> global override information.
-   * @type {Object}
-   */
-  var globalOverrides = {};
-
-  /**
-   * When preloading JavaScript libraries, this is true until the
-   * DOMContentLoaded event has been received as globals cannot be overridden
-   * until the page has loaded its JavaScript.
-   * @type {boolean}
-   */
-  var deferGlobalOverrides = false;
-
-  /**
-   * Override the global function |funcName| with its registered mock. This
-   * should not be called twice for the same |funcName|.
-   * @param {string} funcName The name of the global function to override.
-   */
-  function overrideGlobal(funcName) {
-    assertNotEquals(undefined, this[funcName]);
-    var globalOverride = globalOverrides[funcName];
-    assertNotEquals(undefined, globalOverride);
-    assertEquals(undefined, globalOverride.original);
-    globalOverride.original = this[funcName];
-    this[funcName] = globalOverride.callback.bind(globalOverride.object);
-  }
-
-  /**
-   * Registers the global function name, object and callback.
-   * @param {string} name The name of the message to route to this |callback|.
-   * @param {Object} object Pass as |this| when calling the |callback|.
-   * @param {function(...)} callback Called by {@code chrome.send}.
-   * @see overrideGlobal
-   */
-  function registerMockGlobal(name, object, callback) {
-    assertEquals(undefined, globalOverrides[name]);
-    globalOverrides[name] = {
-      object: object,
-      callback: callback,
-    };
-
-    if (!deferGlobalOverrides)
-      overrideGlobal(name);
-  }
-
-  /**
-   * Registers the mock API call and its function.
-   * @param {string} name The '_'-separated name of the API call.
-   * @param {function(...)} theFunction Mock function for this API call.
-   */
-  function registerMockApi(name, theFunction) {
-    var path = name.split('_');
-
-    var namespace = this;
-    for(var i = 0; i < path.length - 1; i++) {
-      var fieldName = path[i];
-      if(!namespace[fieldName])
-        namespace[fieldName] = {};
-
-      namespace = namespace[fieldName];
-    }
-
-    var fieldName = path[path.length-1];
-    namespace[fieldName] = theFunction;
-  }
-
-  /**
-   * Empty function for use in making mocks.
-   * @const
-   */
-  function emptyFunction() {}
-
-  /**
-   * Make a mock from the supplied |methodNames| array.
-   * @param {Array<string>} methodNames Array of names of methods to mock.
-   * @return {Function} Constructor with prototype filled in with methods
-   *     matching |methodNames|.
-   */
-  function makeMockClass(methodNames) {
-    function MockConstructor() {}
-    for(var i = 0; i < methodNames.length; i++)
-      MockConstructor.prototype[methodNames[i]] = emptyFunction;
-    return MockConstructor;
-  }
-
-  /**
-    * Create a new class to handle |functionNames|, add method 'functions()'
-    * that returns a container of standalone functions based on the mock class
-    * members, and return it.
-    * @return {Mock} Mock handler class.
-    */
-  function makeMockFunctions(functionNames) {
-    var MockClass = makeMockClass(functionNames);
-    var mockFunctions = mock(MockClass);
-    var mockProxy = mockFunctions.proxy();
-
-    mockFunctions.functions_ = {};
-
-    for (var func in MockClass.prototype) {
-      if (typeof MockClass.prototype[func] === 'function')
-        mockFunctions.functions_[func] = mockProxy[func].bind(mockProxy);
-    }
-
-    mockFunctions.functions = function () {
-      return this.functions_;
-    };
-
-    return mockFunctions;
-  }
-
-  /**
-   * Register all methods of {@code mockClass.prototype} as overrides to global
-   * functions of the same name as the method, using the proxy of the
-   * |mockObject| to handle the functions.
-   * @param {Mock4JS.Mock} mockObject The mock to register callbacks against.
-   * @param {function(new:Object)} mockClass Constructor for the mocked class.
-   * @see registerMockGlobal
-   */
-  function registerMockGlobals(mockObject, mockClass) {
-    var mockProxy = mockObject.proxy();
-    for (var func in mockClass.prototype) {
-      if (typeof mockClass.prototype[func] === 'function')
-        registerMockGlobal(func, mockProxy, mockProxy[func]);
-    }
-  }
-
-  /**
-   * Register all functions in |mockObject.functions()| as global API calls.
-   * @param {Mock4JS.Mock} mockObject The mock to register callbacks against.
-   * @see registerMockApi
-   */
-  function registerMockApis(mockObject) {
-    var functions = mockObject.functions();
-    for (var func in functions) {
-      if (typeof functions[func] === 'function')
-        registerMockApi(func, functions[func]);
-    }
-  }
-
-  /**
-   * Overrides {@code chrome.send} for routing messages to javascript
-   * functions. Also falls back to sending with the original chrome object.
-   * @param {string} messageName The message to route.
-   */
-  function send(messageName) {
-    var callback = sendCallbacks[messageName];
-    if (callback != undefined)
-      callback[1].apply(callback[0], Array.prototype.slice.call(arguments, 1));
+  var realElementAnimate = Element.prototype.animate;
+  Element.prototype.animate = function(keyframes, opt_options) {
+    if (typeof opt_options == 'object')
+      opt_options.duration = 0;
     else
-      this.__proto__.send.apply(this.__proto__, arguments);
+      opt_options = 0;
+    return realElementAnimate.call(this, keyframes, opt_options);
+  };
+  if (document.timeline && document.timeline.play) {
+    var realTimelinePlay = document.timeline.play;
+    document.timeline.play = function(a) {
+      a.timing.duration = 0;
+      return realTimelinePlay.call(document.timeline, a);
+    };
   }
+};
 
+Test.prototype = {
   /**
-   * true when testDone has been called.
-   * @type {boolean}
+   * The name of the test.
    */
-  var testIsDone = false;
+  name: null,
 
   /**
-   * Holds the errors, if any, caught by expects so that the test case can
-   * fail. Cleared when results are reported from runTest() or testDone().
-   * @type {Array<Error>}
-   */
-  var errors = [];
-
-  /**
-   * URL to dummy WebUI page for testing framework.
+   * When set to a string value representing a url, generate BrowsePreload
+   * call, which will browse to the url and call fixture.preLoad of the
+   * currentTestCase.
    * @type {string}
    */
-  var DUMMY_URL = 'chrome://DummyURL';
+  browsePreload: null,
 
   /**
-   * Resets test state by clearing |errors| and |testIsDone| flags.
+   * When set to a string value representing an html page in the test
+   * directory, generate BrowsePrintPreload call, which will browse to a url
+   * representing the file, cause print, and call fixture.preLoad of the
+   * currentTestCase.
+   * @type {string}
    */
-  function resetTestState() {
-    errors.splice(0, errors.length);
-    testIsDone = false;
-  }
+  browsePrintPreload: null,
 
   /**
-   * Notifies the running browser test of the test results. Clears |errors|.
-   * @param {Array<boolean, string>=} result When passed, this is used for the
-   *     testResult message.
+   * When set to a function, will be called in the context of the test
+   * generation inside the function, after AddLibrary calls and before
+   * generated C++.
+   * @type {function(string,string)}
    */
-  function testDone(result) {
-    if (!testIsDone) {
-      testIsDone = true;
-      if (currentTestCase) {
-        var ok = true;
-        ok = createExpect(currentTestCase.runAccessibilityAudit.bind(
-            currentTestCase)).call(null) && ok;
-        ok = createExpect(currentTestCase.tearDown.bind(
-            currentTestCase)).call(null) && ok;
+  testGenPreamble: null,
 
-        if (!ok && result)
-          result = [false, errorsToMessage(errors, result[1])];
+  /**
+   * When set to a function, will be called in the context of the test
+   * generation inside the function, and after any generated C++.
+   * @type {function(string,string)}
+   */
+  testGenPostamble: null,
 
-        currentTestCase = null;
-      }
-      if (!result)
-        result = testResult();
-      if (chrome.send) {
-        // For WebUI tests.
-        chrome.send('testResult', result);
-      } else if (window.domAutomationController.send) {
-        // For extension tests.
-        valueResult = { 'result': result[0], message: result[1] };
-        window.domAutomationController.send(JSON.stringify(valueResult));
-      }
-      errors.splice(0, errors.length);
-    } else {
-      console.warn('testIsDone already');
+  /**
+   * When set to a non-null string, auto-generate typedef before generating
+   * TEST*: {@code typedef typedefCppFixture testFixture}.
+   * @type {string}
+   */
+  typedefCppFixture: 'WebUIBrowserTest',
+
+  /**
+   * This should be initialized by the test fixture and can be referenced
+   * during the test run. It holds any mocked handler methods.
+   * @type {?Mock4JS.Mock}
+   */
+  mockHandler: null,
+
+  /**
+   * This should be initialized by the test fixture and can be referenced
+   * during the test run. It holds any mocked global functions.
+   * @type {?Mock4JS.Mock}
+   */
+  mockGlobals: null,
+
+  /**
+   * Value is passed through call to C++ RunJavascriptF to invoke this test.
+   * @type {boolean}
+   */
+  isAsync: false,
+
+  /**
+   * True when the test is expected to fail for testing the test framework.
+   * @type {boolean}
+   */
+  testShouldFail: false,
+
+  /**
+   * Extra libraries to add before loading this test file.
+   * @type {Array<string>}
+   */
+  extraLibraries: [],
+
+  /**
+   * Extra libraries to add before loading this test file.
+   * This list is in the form of Closure library style object
+   * names.  To support this, a closure deps.js file must
+   * be specified when generating the test C++ source.
+   * The specified libraries will be included with their transitive
+   * dependencies according to the deps file.
+   * @type {Array<string>}
+   */
+  closureModuleDeps: [],
+
+  /**
+   * Whether to run the accessibility checks.
+   * @type {boolean}
+   */
+  runAccessibilityChecks: true,
+
+  /**
+   * Configuration for the accessibility audit.
+   * @type {axs.AuditConfiguration}
+   */
+  accessibilityAuditConfig_: null,
+
+  /**
+   * Returns the configuration for the accessibility audit, creating it
+   * on-demand.
+   * @return {!axs.AuditConfiguration}
+   */
+  get accessibilityAuditConfig() {
+    if (!this.accessibilityAuditConfig_) {
+      this.accessibilityAuditConfig_ = new axs.AuditConfiguration();
+
+      this.accessibilityAuditConfig_.showUnsupportedRulesWarning = false;
+
+      this.accessibilityAuditConfig_.auditRulesToIgnore = [
+        // The "elements with meaningful background image" accessibility
+        // audit (AX_IMAGE_01) does not apply, since Chrome doesn't
+        // disable background images in high-contrast mode like some
+        // browsers do.
+        'elementsWithMeaningfulBackgroundImage',
+
+        // Most WebUI pages are inside an IFrame, so the "web page should
+        // have a title that describes topic or purpose" test (AX_TITLE_01)
+        // generally does not apply.
+        'pageWithoutTitle',
+
+        // TODO(aboxhall): re-enable when crbug.com/267035 is fixed.
+        // Until then it's just noise.
+        'lowContrastElements',
+
+        // TODO(apacible): re-enable when following issue is fixed.
+        // github.com/GoogleChrome/accessibility-developer-tools/issues/251
+        'tableHasAppropriateHeaders',
+
+        // TODO(crbug.com/657514): This rule is flaky on Linux/ChromeOS.
+        'requiredOwnedAriaRoleMissing',
+      ];
     }
-  }
+    return this.accessibilityAuditConfig_;
+  },
 
   /**
-   * Converts each Error in |errors| to a suitable message, adding them to
-   * |message|, and returns the message string.
-   * @param {Array<Error>} errors Array of errors to add to |message|.
-   * @param {string=} opt_message Message to append error messages to.
-   * @return {string} |opt_message| + messages of all |errors|.
+   * Whether to treat accessibility issues (errors or warnings) as test
+   * failures. If true, any accessibility issues will cause the test to fail.
+   * If false, accessibility issues will cause a console.warn.
+   * Off by default to begin with; as we add the ability to suppress false
+   * positives, we will transition this to true.
+   * @type {boolean}
    */
-  function errorsToMessage(errors, opt_message) {
-    var message = '';
-    if (opt_message)
-      message += opt_message + '\n';
-
-    for (var i = 0; i < errors.length; ++i) {
-      var errorMessage = errors[i].stack || errors[i].message;
-      message += 'Failed: ' + currentTestFunction + '(' +
-          currentTestArguments.map(JSON.stringify) +
-          ')\n' + errorMessage;
-    }
-    return message;
-  }
+  accessibilityIssuesAreErrors: false,
 
   /**
-   * Returns [success, message] & clears |errors|.
-   * @param {boolean} errorsOk When true, errors are ok.
-   * @return {Array<boolean, string>}
+   * Holds any accessibility results found during the accessibility audit.
+   * @type {Array<Object>}
    */
-  function testResult(errorsOk) {
-    var result = [true, ''];
-    if (errors.length)
-      result = [!!errorsOk, errorsToMessage(errors)];
-
-    return result;
-  }
-
-  // Asserts.
-  // Use the following assertions to verify a condition within a test.
+  a11yResults_: [],
 
   /**
-   * @param {boolean} value The value to check.
-   * @param {string=} opt_message Additional error message.
-   * @throws {Error}
+   * Gets the list of accessibility errors found during the accessibility
+   * audit. Only for use in testing.
+   * @return {Array<Object>}
    */
-  function assertTrue(value, opt_message) {
-    chai.assert.isTrue(value, opt_message);
-  }
+  getAccessibilityResults: function() {
+    return this.a11yResults_;
+  },
 
   /**
-   * @param {boolean} value The value to check.
-   * @param {string=} opt_message Additional error message.
-   * @throws {Error}
+   * Run accessibility checks after this test completes.
    */
-  function assertFalse(value, opt_message) {
-    chai.assert.isFalse(value, opt_message);
-  }
+  enableAccessibilityChecks: function() {
+    this.runAccessibilityChecks = true;
+  },
 
   /**
-   * @param {number} value1 The first operand.
-   * @param {number} value2 The second operand.
-   * @param {string=} opt_message Additional error message.
-   * @throws {Error}
+   * Don't run accessibility checks after this test completes.
    */
-  function assertGE(value1, value2, opt_message) {
-    chai.expect(value1).to.be.at.least(value2, opt_message);
-  }
+  disableAccessibilityChecks: function() {
+    this.runAccessibilityChecks = false;
+  },
 
   /**
-   * @param {number} value1 The first operand.
-   * @param {number} value2 The second operand.
-   * @param {string=} opt_message Additional error message.
-   * @throws {Error}
+   * Create a new class to handle |messageNames|, assign it to
+   * |this.mockHandler|, register its messages and return it.
+   * @return {Mock} Mock handler class assigned to |this.mockHandler|.
    */
-  function assertGT(value1, value2, opt_message) {
-    chai.assert.isAbove(value1, value2, opt_message);
-  }
+  makeAndRegisterMockHandler: function(messageNames) {
+    var MockClass = makeMockClass(messageNames);
+    this.mockHandler = mock(MockClass);
+    registerMockMessageCallbacks(this.mockHandler, MockClass);
+    return this.mockHandler;
+  },
 
   /**
-   * @param {*} expected The expected value.
-   * @param {*} actual The actual value.
-   * @param {string=} opt_message Additional error message.
-   * @throws {Error}
+   * Create a new class to handle |functionNames|, assign it to
+   * |this.mockGlobals|, register its global overrides, and return it.
+   * @return {Mock} Mock handler class assigned to |this.mockGlobals|.
+   * @see registerMockGlobals
    */
-  function assertEquals(expected, actual, opt_message) {
-    chai.assert.strictEqual(actual, expected, opt_message);
-  }
+  makeAndRegisterMockGlobals: function(functionNames) {
+    var MockClass = makeMockClass(functionNames);
+    this.mockGlobals = mock(MockClass);
+    registerMockGlobals(this.mockGlobals, MockClass);
+    return this.mockGlobals;
+  },
 
   /**
-   * @param {*} expected
-   * @param {*} actual
-   * {string=} opt_message
-   * @throws {Error}
+   * Create a container of mocked standalone functions to handle
+   * '.'-separated |apiNames|, assign it to |this.mockApis|, register its API
+   * overrides and return it.
+   * @return {Mock} Mock handler class.
+   * @see makeMockFunctions
+   * @see registerMockApis
    */
-  function assertDeepEquals(expected, actual, opt_message) {
-    chai.assert.deepEqual(actual, expected, opt_message);
-  }
+  makeAndRegisterMockApis: function(apiNames) {
+    var apiMockNames = apiNames.map(function(name) {
+      return name.replace(/\./g, '_');
+    });
+
+    this.mockApis = makeMockFunctions(apiMockNames);
+    registerMockApis(this.mockApis);
+    return this.mockApis;
+  },
 
   /**
-   * @param {number} value1 The first operand.
-   * @param {number} value2 The second operand.
-   * @param {string=} opt_message Additional error message.
-   * @throws {Error}
+   * Create a container of mocked standalone functions to handle
+   * |functionNames|, assign it to |this.mockLocalFunctions| and return it.
+   * @param {!Array<string>} functionNames
+   * @return {Mock} Mock handler class.
+   * @see makeMockFunctions
    */
-  function assertLE(value1, value2, opt_message) {
-    chai.expect(value1).to.be.at.most(value2, opt_message);
-  }
+  makeMockLocalFunctions: function(functionNames) {
+    this.mockLocalFunctions = makeMockFunctions(functionNames);
+    return this.mockLocalFunctions;
+  },
 
   /**
-   * @param {number} value1 The first operand.
-   * @param {number} value2 The second operand.
-   * @param {string=} opt_message Additional error message.
-   * @throws {Error}
-   */
-  function assertLT(value1, value2, opt_message) {
-    chai.assert.isBelow(value1, value2, opt_message);
-  }
-
-  /**
-   * @param {*} expected The expected value.
-   * @param {*} actual The actual value.
-   * @param {string=} opt_message Additional error message.
-   * @throws {Error}
-   */
-  function assertNotEquals(expected, actual, opt_message) {
-    chai.assert.notStrictEqual(actual, expected, opt_message);
-  }
-
-  /**
-   * @param {string=} opt_message Additional error message.
-   * @throws {Error}
-   */
-  function assertNotReached(opt_message) {
-    chai.assert.fail(null, null, opt_message);
-  }
-
-  /**
-   * @param {Function} testFunction
-   * @param {Function=|string=|RegExp=} opt_expected The expected Error
-   *     constructor, partial or complete error message string, or RegExp to
-   *     test the error message.
-   * @param {string=} opt_message Additional error message.
-   * @throws {Error}
-   */
-  function assertThrows(testFunction, opt_expected, opt_message) {
-    chai.assert.throws(testFunction, opt_expected, opt_message);
-  }
-
-  /**
-   * Run an accessibility audit on the current page state.
+   * Override this method to perform initialization during preload (such as
+   * creating mocks and registering handlers).
    * @type {Function}
-   * @param {Array} a11yResults
-   * @param {axs.AuditConfiguration=} opt_config
-   * @return {boolean} Whether there were any errors or warnings
+   */
+  preLoad: function() {},
+
+  /**
+   * Override this method to perform tasks before running your test.
+   * @type {Function}
+   */
+  setUp: function() {
+    // These should be ignored in many of the web UI tests.
+    // user-image-stream and supervised-user-creation-image-stream are
+    // streaming video elements used for capturing a user image so they
+    // won't have captions and should be ignored everywhere.
+    this.accessibilityAuditConfig.ignoreSelectors(
+        'videoWithoutCaptions', '.user-image-stream');
+    this.accessibilityAuditConfig.ignoreSelectors(
+        'videoWithoutCaptions', '.supervised-user-creation-image-stream');
+  },
+
+  /**
+   * Override this method to perform tasks after running your test. If you
+   * create a mock class, you must call Mock4JS.verifyAllMocks() in this
+   * phase.
+   * @type {Function}
+   */
+  tearDown: function() {
+    if (typeof document != 'undefined') {
+      var noAnimationStyle = document.getElementById('no-animation');
+      if (noAnimationStyle)
+        noAnimationStyle.parentNode.removeChild(noAnimationStyle);
+    }
+
+    Mock4JS.verifyAllMocks();
+  },
+
+  /**
+   * Called to run the body from the perspective of this fixture.
+   * @type {Function}
+   */
+  runTest: function(testBody) {
+    testBody.call(this);
+  },
+
+  /**
+   * Called to run the accessibility audit from the perspective of this
+   * fixture.
+   */
+  runAccessibilityAudit: function() {
+    if (!this.runAccessibilityChecks || typeof document === 'undefined')
+      return;
+
+    var auditConfig = this.accessibilityAuditConfig;
+    if (!runAccessibilityAudit(this.a11yResults_, auditConfig)) {
+      var report = accessibilityAuditReport(this.a11yResults_);
+      if (this.accessibilityIssuesAreErrors)
+        throw new Error(report);
+      else
+        console.warn(report);
+    }
+  },
+
+  /**
+   * Create a closure function for continuing the test at a later time. May be
+   * used as a listener function.
+   * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
+   *     time.
+   * @param {Function} completion The function to call to complete the test.
+   * @param {...*} var_args Arguments to pass when calling completionAction.
+   * @return {function(): void} Return a function, bound to this test fixture,
+   *     which continues the test.
+   */
+  continueTest: function(whenTestDone, completion) {
+    var savedArgs = new SaveMockArguments();
+    var completionAction = new CallFunctionAction(
+        this, savedArgs, completion, Array.prototype.slice.call(arguments, 2));
+    if (whenTestDone === WhenTestDone.DEFAULT)
+      whenTestDone = WhenTestDone.ASSERT;
+    var runAll = new RunAllAction(true, whenTestDone, [completionAction]);
+    return function() {
+      savedArgs.arguments = Array.prototype.slice.call(arguments);
+      runAll.invoke();
+    };
+  },
+
+  /**
+   * Call this during setUp to defer the call to runTest() until later. The
+   * caller must call the returned function at some point to run the test.
+   * @type {Function}
+   * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
+   *     time.
+   * @param {...*} var_args Arguments to pass when running the
+   *     |currentTestCase|.
+   * @return {function(): void} A function which will run the current body of
+   *     the currentTestCase.
+   */
+  deferRunTest: function(whenTestDone) {
+    if (whenTestDone === WhenTestDone.DEFAULT)
+      whenTestDone = WhenTestDone.ALWAYS;
+
+    return currentTestCase.deferRunTest.apply(
+        currentTestCase,
+        [whenTestDone].concat(Array.prototype.slice.call(arguments, 1)));
+  },
+};
+
+/**
+ * This class is not exported and is available to hold the state of the
+ * |currentTestCase| throughout preload and test run.
+ * @param {string} name The name of the test case.
+ * @param {Test} fixture The fixture object for this test case.
+ * @param {Function} body The code to run for the test.
+ * @constructor
+ */
+function TestCase(name, fixture, body) {
+  this.name = name;
+  this.fixture = fixture;
+  this.body = body;
+}
+
+TestCase.prototype = {
+  /**
+   * The name of this test.
+   * @type {string}
+   */
+  name: null,
+
+  /**
+   * The test fixture to set |this| to when running the test |body|.
+   * @type {testing.Test}
+   */
+  fixture: null,
+
+  /**
+   * The test body to execute in runTest().
+   * @type {Function}
+   */
+  body: null,
+
+  /**
+   * True when the test fixture will run the test later.
+   * @type {boolean}
    * @private
    */
-  function runAccessibilityAudit(a11yResults, opt_config) {
-    var auditResults = axs.Audit.run(opt_config);
-    for (var i = 0; i < auditResults.length; i++) {
-      var auditResult = auditResults[i];
-      if (auditResult.result == axs.constants.AuditResult.FAIL) {
-        var auditRule = auditResult.rule;
-        // TODO(aboxhall): more useful error messages (sadly non-trivial)
-        a11yResults.push(auditResult);
-      }
+  deferred_: false,
+
+  /**
+   * Called at preload time, proxies to the fixture.
+   * @type {Function}
+   */
+  preLoad: function(name) {
+    if (this.fixture)
+      this.fixture.preLoad();
+  },
+
+  /**
+   * Called before a test runs.
+   */
+  setUp: function() {
+    if (this.fixture)
+      this.fixture.setUp();
+  },
+
+  /**
+   * Called before a test is torn down (by testDone()).
+   */
+  tearDown: function() {
+    if (this.fixture)
+      this.fixture.tearDown();
+  },
+
+  /**
+   * Called to run this test's body.
+   */
+  runTest: function() {
+    if (this.body && this.fixture)
+      this.fixture.runTest(this.body);
+  },
+
+  /**
+   * Called after a test is run (in testDone) to test accessibility.
+   */
+  runAccessibilityAudit: function() {
+    if (this.fixture)
+      this.fixture.runAccessibilityAudit();
+  },
+
+  /**
+   * Runs this test case with |this| set to the |fixture|.
+   *
+   * Note: Tests created with TEST_F may depend upon |this| being set to an
+   * instance of this.fixture. The current implementation of TEST creates a
+   * dummy constructor, but tests created with TEST should not rely on |this|
+   * being set.
+   * @type {Function}
+   */
+  run: function() {
+    try {
+      this.setUp();
+    } catch (e) {
+      // Mock4JSException doesn't inherit from Error, so fall back on
+      // toString().
+      console.error(e.stack || e.toString());
     }
-    // TODO(aboxhall): have strict (no errors or warnings) vs non-strict
-    // (warnings ok)
-    // TODO(aboxhall): some kind of info logging for warnings only??
-    return (a11yResults.length == 0);
-  }
+
+    if (!this.deferred_)
+      this.runTest();
+
+    // tearDown called by testDone().
+  },
 
   /**
-   * Concatenates the accessibility error messages for each result in
-   * |a11yResults| and
-   * |a11yWarnings| in to an accessibility report, appends it to the given
-   * |message| and returns the resulting message string.
-   * @param {Array<string>} a11yResults The list of accessibility results
-   * @return {string} |message| + accessibility report.
+   * Cause this TestCase to be deferred (don't call runTest()) until the
+   * returned function is called.
+   * @type {Function}
+   * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
+   *     time.
+   * @param {...*} var_args Arguments to pass when running the
+   *     |currentTestCase|.
+   * @return {function(): void} A function that will run this TestCase when
+   *     called.
    */
-  function accessibilityAuditReport(a11yResults, message) {
-    message = message ? message + '\n\n' : '\n';
-    message += 'Accessibility issues found on ' + window.location.href + '\n';
-    message += axs.Audit.createReport(a11yResults);
-    return message;
-  }
-
-  /**
-   * Asserts that the current page state passes the accessibility audit.
-   * @param {Array=} opt_results Array to fill with results, if desired.
-   */
-  function assertAccessibilityOk(opt_results) {
-    var a11yResults = opt_results || [];
-    var auditConfig = currentTestCase.fixture.accessibilityAuditConfig;
-    if (!runAccessibilityAudit(a11yResults, auditConfig))
-      throw new Error(accessibilityAuditReport(a11yResults));
-  }
-
-  /**
-   * Creates a function based upon a function that throws an exception on
-   * failure. The new function stuffs any errors into the |errors| array for
-   * checking by runTest. This allows tests to continue running other checks,
-   * while failing the overall test if any errors occurred.
-   * @param {Function} assertFunc The function which may throw an Error.
-   * @return {function(...*):bool} A function that applies its arguments to
-   *     |assertFunc| and returns true if |assertFunc| passes.
-   * @see errors
-   * @see runTestFunction
-   */
-  function createExpect(assertFunc) {
+  deferRunTest: function(whenTestDone) {
+    this.deferred_ = true;
+    var savedArgs = new SaveMockArguments();
+    var completionAction = new CallFunctionAction(
+        this, savedArgs, this.runTest,
+        Array.prototype.slice.call(arguments, 1));
+    var runAll = new RunAllAction(true, whenTestDone, [completionAction]);
     return function() {
-      try {
-        assertFunc.apply(null, arguments);
-      } catch (e) {
-        errors.push(e);
-        return false;
-      }
-      return true;
+      savedArgs.arguments = Array.prototype.slice.call(arguments);
+      runAll.invoke();
     };
+  },
+
+};
+
+/**
+ * Registry of javascript-defined callbacks for {@code chrome.send}.
+ * @type {Object}
+ */
+var sendCallbacks = {};
+
+/**
+ * Registers the message, object and callback for {@code chrome.send}
+ * @param {string} name The name of the message to route to this |callback|.
+ * @param {Object} messageHandler Pass as |this| when calling the |callback|.
+ * @param {function(...)} callback Called by {@code chrome.send}.
+ * @see sendCallbacks
+ */
+function registerMessageCallback(name, messageHandler, callback) {
+  sendCallbacks[name] = [messageHandler, callback];
+}
+
+/**
+ * Register all methods of {@code mockClass.prototype} with messages of the
+ * same name as the method, using the proxy of the |mockObject| as the
+ * |messageHandler| when registering.
+ * @param {Mock4JS.Mock} mockObject The mock to register callbacks against.
+ * @param {function(new:Object)} mockClAss Constructor for the mocked class.
+ * @see registerMessageCallback
+ * @see overrideChrome
+ */
+function registerMockMessageCallbacks(mockObject, mockClass) {
+  if (!deferGlobalOverrides && !originalChrome)
+    overrideChrome();
+  var mockProxy = mockObject.proxy();
+  for (var func in mockClass.prototype) {
+    if (typeof mockClass.prototype[func] === 'function') {
+      registerMessageCallback(func, mockProxy, mockProxy[func]);
+    }
+  }
+}
+
+/**
+ * Holds the mapping of name -> global override information.
+ * @type {Object}
+ */
+var globalOverrides = {};
+
+/**
+ * When preloading JavaScript libraries, this is true until the
+ * DOMContentLoaded event has been received as globals cannot be overridden
+ * until the page has loaded its JavaScript.
+ * @type {boolean}
+ */
+var deferGlobalOverrides = false;
+
+/**
+ * Override the global function |funcName| with its registered mock. This
+ * should not be called twice for the same |funcName|.
+ * @param {string} funcName The name of the global function to override.
+ */
+function overrideGlobal(funcName) {
+  assertNotEquals(undefined, this[funcName]);
+  var globalOverride = globalOverrides[funcName];
+  assertNotEquals(undefined, globalOverride);
+  assertEquals(undefined, globalOverride.original);
+  globalOverride.original = this[funcName];
+  this[funcName] = globalOverride.callback.bind(globalOverride.object);
+}
+
+/**
+ * Registers the global function name, object and callback.
+ * @param {string} name The name of the message to route to this |callback|.
+ * @param {Object} object Pass as |this| when calling the |callback|.
+ * @param {function(...)} callback Called by {@code chrome.send}.
+ * @see overrideGlobal
+ */
+function registerMockGlobal(name, object, callback) {
+  assertEquals(undefined, globalOverrides[name]);
+  globalOverrides[name] = {
+    object: object,
+    callback: callback,
+  };
+
+  if (!deferGlobalOverrides)
+    overrideGlobal(name);
+}
+
+/**
+ * Registers the mock API call and its function.
+ * @param {string} name The '_'-separated name of the API call.
+ * @param {function(...)} theFunction Mock function for this API call.
+ */
+function registerMockApi(name, theFunction) {
+  var path = name.split('_');
+
+  var namespace = this;
+  for (var i = 0; i < path.length - 1; i++) {
+    var fieldName = path[i];
+    if (!namespace[fieldName])
+    namespace[fieldName] = {};
+
+    namespace = namespace[fieldName];
   }
 
-  /**
-   * This is the starting point for tests run by WebUIBrowserTest.  If an error
-   * occurs, it reports a failure and a message created by joining individual
-   * error messages. This supports sync tests and async tests by calling
-   * testDone() when |isAsync| is not true, relying on async tests to call
-   * testDone() when they complete.
-   * @param {boolean} isAsync When false, call testDone() with the test result
-   *     otherwise only when assertions are caught.
-   * @param {string} testFunction The function name to call.
-   * @param {Array} testArguments The arguments to call |testFunction| with.
-   * @return {boolean} true always to signal successful execution (but not
-   *     necessarily successful results) of this test.
-   * @see errors
-   * @see runTestFunction
-   */
-  function runTest(isAsync, testFunction, testArguments) {
-    // Avoid eval() if at all possible, since it will not work on pages
-    // that have enabled content-security-policy.
-    var testBody = this[testFunction];    // global object -- not a method.
-    var testName = testFunction;
+  var fieldName = path[path.length - 1];
+  namespace[fieldName] = theFunction;
+}
 
-    // Depending on how we were called, |this| might not resolve to the global
-    // context.
-    if (testName == 'RUN_TEST_F' && testBody === undefined)
-      testBody = RUN_TEST_F;
+/**
+ * Empty function for use in making mocks.
+ * @const
+ */
+function emptyFunction() {}
 
-    if (typeof testBody === "undefined") {
-      testBody = eval(testFunction);
-      testName = testBody.toString();
+/**
+ * Make a mock from the supplied |methodNames| array.
+ * @param {Array<string>} methodNames Array of names of methods to mock.
+ * @return {Function} Constructor with prototype filled in with methods
+ *     matching |methodNames|.
+ */
+function makeMockClass(methodNames) {
+  function MockConstructor() {}
+  for (var i = 0; i < methodNames.length; i++)
+    MockConstructor.prototype[methodNames[i]] = emptyFunction;
+  return MockConstructor;
+}
+
+/**
+ * Create a new class to handle |functionNames|, add method 'functions()'
+ * that returns a container of standalone functions based on the mock class
+ * members, and return it.
+ * @return {Mock} Mock handler class.
+ */
+function makeMockFunctions(functionNames) {
+  var MockClass = makeMockClass(functionNames);
+  var mockFunctions = mock(MockClass);
+  var mockProxy = mockFunctions.proxy();
+
+  mockFunctions.functions_ = {};
+
+  for (var func in MockClass.prototype) {
+    if (typeof MockClass.prototype[func] === 'function')
+      mockFunctions.functions_[func] = mockProxy[func].bind(mockProxy);
+  }
+
+  mockFunctions.functions = function() {
+    return this.functions_;
+  };
+
+  return mockFunctions;
+}
+
+/**
+ * Register all methods of {@code mockClass.prototype} as overrides to global
+ * functions of the same name as the method, using the proxy of the
+ * |mockObject| to handle the functions.
+ * @param {Mock4JS.Mock} mockObject The mock to register callbacks against.
+ * @param {function(new:Object)} mockClass Constructor for the mocked class.
+ * @see registerMockGlobal
+ */
+function registerMockGlobals(mockObject, mockClass) {
+  var mockProxy = mockObject.proxy();
+  for (var func in mockClass.prototype) {
+    if (typeof mockClass.prototype[func] === 'function')
+      registerMockGlobal(func, mockProxy, mockProxy[func]);
+  }
+}
+
+/**
+ * Register all functions in |mockObject.functions()| as global API calls.
+ * @param {Mock4JS.Mock} mockObject The mock to register callbacks against.
+ * @see registerMockApi
+ */
+function registerMockApis(mockObject) {
+  var functions = mockObject.functions();
+  for (var func in functions) {
+    if (typeof functions[func] === 'function')
+      registerMockApi(func, functions[func]);
+  }
+}
+
+/**
+ * Overrides {@code chrome.send} for routing messages to javascript
+ * functions. Also falls back to sending with the original chrome object.
+ * @param {string} messageName The message to route.
+ */
+function send(messageName) {
+  var callback = sendCallbacks[messageName];
+  if (callback != undefined)
+    callback[1].apply(callback[0], Array.prototype.slice.call(arguments, 1));
+  else
+    this.__proto__.send.apply(this.__proto__, arguments);
+}
+
+/**
+ * true when testDone has been called.
+ * @type {boolean}
+ */
+var testIsDone = false;
+
+/**
+ * Holds the errors, if any, caught by expects so that the test case can
+ * fail. Cleared when results are reported from runTest() or testDone().
+ * @type {Array<Error>}
+ */
+var errors = [];
+
+/**
+ * URL to dummy WebUI page for testing framework.
+ * @type {string}
+ */
+var DUMMY_URL = 'chrome://DummyURL';
+
+/**
+ * Resets test state by clearing |errors| and |testIsDone| flags.
+ */
+function resetTestState() {
+  errors.splice(0, errors.length);
+  testIsDone = false;
+}
+
+/**
+ * Notifies the running browser test of the test results. Clears |errors|.
+ * @param {Array<boolean, string>=} result When passed, this is used for the
+ *     testResult message.
+ */
+function testDone(result) {
+  if (!testIsDone) {
+    testIsDone = true;
+    if (currentTestCase) {
+      var ok = true;
+      ok = createExpect(
+               currentTestCase.runAccessibilityAudit.bind(currentTestCase))
+               .call(null) &&
+          ok;
+      ok = createExpect(currentTestCase.tearDown.bind(currentTestCase))
+               .call(null) &&
+          ok;
+
+      if (!ok && result)
+        result = [false, errorsToMessage(errors, result[1])];
+
+      currentTestCase = null;
     }
-    if (testBody != RUN_TEST_F) {
-      console.log('Running test ' + testName);
+    if (!result)
+      result = testResult();
+    if (chrome.send) {
+      // For WebUI tests.
+      chrome.send('testResult', result);
+    } else if (window.domAutomationController.send) {
+      // For extension tests.
+      valueResult = {'result': result[0], message: result[1]};
+      window.domAutomationController.send(JSON.stringify(valueResult));
     }
+    errors.splice(0, errors.length);
+  } else {
+    console.warn('testIsDone already');
+  }
+}
 
-    // Async allow expect errors, but not assert errors.
-    var result = runTestFunction(testFunction, testBody, testArguments,
-                                 isAsync);
-    if (!isAsync || !result[0])
-      testDone(result);
+/**
+ * Converts each Error in |errors| to a suitable message, adding them to
+ * |message|, and returns the message string.
+ * @param {Array<Error>} errors Array of errors to add to |message|.
+ * @param {string=} opt_message Message to append error messages to.
+ * @return {string} |opt_message| + messages of all |errors|.
+ */
+function errorsToMessage(errors, opt_message) {
+  var message = '';
+  if (opt_message)
+    message += opt_message + '\n';
+
+  for (var i = 0; i < errors.length; ++i) {
+    var errorMessage = errors[i].stack || errors[i].message;
+    message += 'Failed: ' + currentTestFunction + '(' +
+        currentTestArguments.map(JSON.stringify) + ')\n' + errorMessage;
+  }
+  return message;
+}
+
+/**
+ * Returns [success, message] & clears |errors|.
+ * @param {boolean} errorsOk When true, errors are ok.
+ * @return {Array<boolean, string>}
+ */
+function testResult(errorsOk) {
+  var result = [true, ''];
+  if (errors.length)
+    result = [!!errorsOk, errorsToMessage(errors)];
+
+  return result;
+}
+
+// Asserts.
+// Use the following assertions to verify a condition within a test.
+
+/**
+ * @param {boolean} value The value to check.
+ * @param {string=} opt_message Additional error message.
+ * @throws {Error}
+ */
+function assertTrue(value, opt_message) {
+  chai.assert.isTrue(value, opt_message);
+}
+
+/**
+ * @param {boolean} value The value to check.
+ * @param {string=} opt_message Additional error message.
+ * @throws {Error}
+ */
+function assertFalse(value, opt_message) {
+  chai.assert.isFalse(value, opt_message);
+}
+
+/**
+ * @param {number} value1 The first operand.
+ * @param {number} value2 The second operand.
+ * @param {string=} opt_message Additional error message.
+ * @throws {Error}
+ */
+function assertGE(value1, value2, opt_message) {
+  chai.expect(value1).to.be.at.least(value2, opt_message);
+}
+
+/**
+ * @param {number} value1 The first operand.
+ * @param {number} value2 The second operand.
+ * @param {string=} opt_message Additional error message.
+ * @throws {Error}
+ */
+function assertGT(value1, value2, opt_message) {
+  chai.assert.isAbove(value1, value2, opt_message);
+}
+
+/**
+ * @param {*} expected The expected value.
+ * @param {*} actual The actual value.
+ * @param {string=} opt_message Additional error message.
+ * @throws {Error}
+ */
+function assertEquals(expected, actual, opt_message) {
+  chai.assert.strictEqual(actual, expected, opt_message);
+}
+
+/**
+ * @param {*} expected
+ * @param {*} actual
+ * {string=} opt_message
+ * @throws {Error}
+ */
+function assertDeepEquals(expected, actual, opt_message) {
+  chai.assert.deepEqual(actual, expected, opt_message);
+}
+
+/**
+ * @param {number} value1 The first operand.
+ * @param {number} value2 The second operand.
+ * @param {string=} opt_message Additional error message.
+ * @throws {Error}
+ */
+function assertLE(value1, value2, opt_message) {
+  chai.expect(value1).to.be.at.most(value2, opt_message);
+}
+
+/**
+ * @param {number} value1 The first operand.
+ * @param {number} value2 The second operand.
+ * @param {string=} opt_message Additional error message.
+ * @throws {Error}
+ */
+function assertLT(value1, value2, opt_message) {
+  chai.assert.isBelow(value1, value2, opt_message);
+}
+
+/**
+ * @param {*} expected The expected value.
+ * @param {*} actual The actual value.
+ * @param {string=} opt_message Additional error message.
+ * @throws {Error}
+ */
+function assertNotEquals(expected, actual, opt_message) {
+  chai.assert.notStrictEqual(actual, expected, opt_message);
+}
+
+/**
+ * @param {string=} opt_message Additional error message.
+ * @throws {Error}
+ */
+function assertNotReached(opt_message) {
+  chai.assert.fail(null, null, opt_message);
+}
+
+/**
+ * @param {Function} testFunction
+ * @param {Function=|string=|RegExp=} opt_expected The expected Error
+ *     constructor, partial or complete error message string, or RegExp to
+ *     test the error message.
+ * @param {string=} opt_message Additional error message.
+ * @throws {Error}
+ */
+function assertThrows(testFunction, opt_expected, opt_message) {
+  chai.assert.throws(testFunction, opt_expected, opt_message);
+}
+
+/**
+ * Run an accessibility audit on the current page state.
+ * @type {Function}
+ * @param {Array} a11yResults
+ * @param {axs.AuditConfiguration=} opt_config
+ * @return {boolean} Whether there were any errors or warnings
+ * @private
+ */
+function runAccessibilityAudit(a11yResults, opt_config) {
+  var auditResults = axs.Audit.run(opt_config);
+  for (var i = 0; i < auditResults.length; i++) {
+    var auditResult = auditResults[i];
+    if (auditResult.result == axs.constants.AuditResult.FAIL) {
+      var auditRule = auditResult.rule;
+      // TODO(aboxhall): more useful error messages (sadly non-trivial)
+      a11yResults.push(auditResult);
+    }
+  }
+  // TODO(aboxhall): have strict (no errors or warnings) vs non-strict
+  // (warnings ok)
+  // TODO(aboxhall): some kind of info logging for warnings only??
+  return (a11yResults.length == 0);
+}
+
+/**
+ * Concatenates the accessibility error messages for each result in
+ * |a11yResults| and
+ * |a11yWarnings| in to an accessibility report, appends it to the given
+ * |message| and returns the resulting message string.
+ * @param {Array<string>} a11yResults The list of accessibility results
+ * @return {string} |message| + accessibility report.
+ */
+function accessibilityAuditReport(a11yResults, message) {
+  message = message ? message + '\n\n' : '\n';
+  message += 'Accessibility issues found on ' + window.location.href + '\n';
+  message += axs.Audit.createReport(a11yResults);
+  return message;
+}
+
+/**
+ * Asserts that the current page state passes the accessibility audit.
+ * @param {Array=} opt_results Array to fill with results, if desired.
+ */
+function assertAccessibilityOk(opt_results) {
+  var a11yResults = opt_results || [];
+  var auditConfig = currentTestCase.fixture.accessibilityAuditConfig;
+  if (!runAccessibilityAudit(a11yResults, auditConfig))
+    throw new Error(accessibilityAuditReport(a11yResults));
+}
+
+/**
+ * Creates a function based upon a function that throws an exception on
+ * failure. The new function stuffs any errors into the |errors| array for
+ * checking by runTest. This allows tests to continue running other checks,
+ * while failing the overall test if any errors occurred.
+ * @param {Function} assertFunc The function which may throw an Error.
+ * @return {function(...*):bool} A function that applies its arguments to
+ *     |assertFunc| and returns true if |assertFunc| passes.
+ * @see errors
+ * @see runTestFunction
+ */
+function createExpect(assertFunc) {
+  return function() {
+    try {
+      assertFunc.apply(null, arguments);
+    } catch (e) {
+      errors.push(e);
+      return false;
+    }
     return true;
+  };
+}
+
+/**
+ * This is the starting point for tests run by WebUIBrowserTest.  If an error
+ * occurs, it reports a failure and a message created by joining individual
+ * error messages. This supports sync tests and async tests by calling
+ * testDone() when |isAsync| is not true, relying on async tests to call
+ * testDone() when they complete.
+ * @param {boolean} isAsync When false, call testDone() with the test result
+ *     otherwise only when assertions are caught.
+ * @param {string} testFunction The function name to call.
+ * @param {Array} testArguments The arguments to call |testFunction| with.
+ * @return {boolean} true always to signal successful execution (but not
+ *     necessarily successful results) of this test.
+ * @see errors
+ * @see runTestFunction
+ */
+function runTest(isAsync, testFunction, testArguments) {
+  // Avoid eval() if at all possible, since it will not work on pages
+  // that have enabled content-security-policy.
+  var testBody = this[testFunction];  // global object -- not a method.
+  var testName = testFunction;
+
+  // Depending on how we were called, |this| might not resolve to the global
+  // context.
+  if (testName == 'RUN_TEST_F' && testBody === undefined)
+    testBody = RUN_TEST_F;
+
+  if (typeof testBody === 'undefined') {
+    testBody = eval(testFunction);
+    testName = testBody.toString();
+  }
+  if (testBody != RUN_TEST_F) {
+    console.log('Running test ' + testName);
   }
 
-  /**
-   * This is the guts of WebUIBrowserTest. It runs the test surrounded by an
-   * expect to catch Errors. If |errors| is non-empty, it reports a failure and
-   * a message by joining |errors|. Consumers can use this to use assert/expect
-   * functions asynchronously, but are then responsible for reporting errors to
-   * the browser themselves through testDone().
-   * @param {string} testFunction The function name to report on failure.
-   * @param {Function} testBody The function to call.
-   * @param {Array} testArguments The arguments to call |testBody| with.
-   * @param {boolean} onlyAssertFails When true, only assertions cause failing
-   *     testResult.
-   * @return {Array<boolean, string>} [test-succeeded, message-if-failed]
-   * @see createExpect
-   * @see testResult
-   */
-  function runTestFunction(testFunction, testBody, testArguments,
-                           onlyAssertFails) {
-    currentTestFunction = testFunction;
-    currentTestArguments = testArguments;
-    var ok = createExpect(testBody).apply(null, testArguments);
-    return testResult(onlyAssertFails && ok);
+  // Async allow expect errors, but not assert errors.
+  var result = runTestFunction(testFunction, testBody, testArguments, isAsync);
+  if (!isAsync || !result[0])
+    testDone(result);
+  return true;
+}
+
+/**
+ * This is the guts of WebUIBrowserTest. It runs the test surrounded by an
+ * expect to catch Errors. If |errors| is non-empty, it reports a failure and
+ * a message by joining |errors|. Consumers can use this to use assert/expect
+ * functions asynchronously, but are then responsible for reporting errors to
+ * the browser themselves through testDone().
+ * @param {string} testFunction The function name to report on failure.
+ * @param {Function} testBody The function to call.
+ * @param {Array} testArguments The arguments to call |testBody| with.
+ * @param {boolean} onlyAssertFails When true, only assertions cause failing
+ *     testResult.
+ * @return {Array<boolean, string>} [test-succeeded, message-if-failed]
+ * @see createExpect
+ * @see testResult
+ */
+function runTestFunction(
+    testFunction, testBody, testArguments, onlyAssertFails) {
+  currentTestFunction = testFunction;
+  currentTestArguments = testArguments;
+  var ok = createExpect(testBody).apply(null, testArguments);
+  return testResult(onlyAssertFails && ok);
+}
+
+/**
+ * Creates a new test case for the given |testFixture| and |testName|. Assumes
+ * |testFixture| describes a globally available subclass of type Test.
+ * @param {string} testFixture The fixture for this test case.
+ * @param {string} testName The name for this test case.
+ * @return {TestCase} A newly created TestCase.
+ */
+function createTestCase(testFixture, testName) {
+  var fixtureConstructor = this[testFixture];
+  assertTrue(
+      !!fixtureConstructor,
+      `The testFixture \'${testFixture}\' was not found.`);
+  var testBody = fixtureConstructor.testCaseBodies[testName];
+  assertTrue(
+      !!testBody, `Test \'${testName} was not found in \'${testFixture}\'.`);
+  var fixture = new fixtureConstructor();
+  fixture.name = testFixture;
+  return new TestCase(testName, fixture, testBody);
+}
+
+/**
+ * Overrides the |chrome| object to enable mocking calls to chrome.send().
+ */
+function overrideChrome() {
+  if (originalChrome) {
+    console.error('chrome object already overridden');
+    return;
   }
 
-  /**
-   * Creates a new test case for the given |testFixture| and |testName|. Assumes
-   * |testFixture| describes a globally available subclass of type Test.
-   * @param {string} testFixture The fixture for this test case.
-   * @param {string} testName The name for this test case.
-   * @return {TestCase} A newly created TestCase.
-   */
-  function createTestCase(testFixture, testName) {
-    var fixtureConstructor = this[testFixture];
-    assertTrue(
-        !!fixtureConstructor,
-        `The testFixture \'${testFixture}\' was not found.`);
-    var testBody = fixtureConstructor.testCaseBodies[testName];
-    assertTrue(
-        !!testBody, `Test \'${testName} was not found in \'${testFixture}\'.`);
-    var fixture = new fixtureConstructor();
-    fixture.name = testFixture;
-    return new TestCase(testName, fixture, testBody);
-  }
+  originalChrome = chrome;
+  chrome = {
+    __proto__: originalChrome,
+    send: send,
+    originalSend: originalChrome.send.bind(originalChrome),
+  };
+}
 
-  /**
-   * Overrides the |chrome| object to enable mocking calls to chrome.send().
-   */
-  function overrideChrome() {
-    if (originalChrome) {
-      console.error('chrome object already overridden');
-      return;
-    }
+/**
+ * Used by WebUIBrowserTest to preload the javascript libraries at the
+ * appropriate time for javascript injection into the current page. This
+ * creates a test case and calls its preLoad for any early initialization such
+ * as registering handlers before the page's javascript runs it's OnLoad
+ * method. This is called before the page is loaded, so the |chrome| object is
+ * not yet bound and this DOMContentLoaded listener will be called first to
+ * override |chrome| in order to route messages registered in |sendCallbacks|.
+ * @param {string} testFixture The test fixture name.
+ * @param {string} testName The test name.
+ * @see sendCallbacks
+ */
+function preloadJavascriptLibraries(testFixture, testName) {
+  deferGlobalOverrides = true;
 
-    originalChrome = chrome;
-    chrome = {
-      __proto__: originalChrome,
-      send: send,
-      originalSend: originalChrome.send.bind(originalChrome),
+  // The document seems to change from the point of preloading to the point of
+  // events (and doesn't fire), whereas the window does not. Listening to the
+  // capture phase allows this event to fire first.
+  window.addEventListener('DOMContentLoaded', function() {
+    overrideChrome();
+
+    // Override globals at load time so they will be defined.
+    assertTrue(deferGlobalOverrides);
+    deferGlobalOverrides = false;
+    for (var funcName in globalOverrides)
+      overrideGlobal(funcName);
+  }, true);
+  currentTestCase = createTestCase(testFixture, testName);
+  currentTestCase.preLoad();
+}
+
+/**
+ * During generation phase, this outputs; do nothing at runtime.
+ */
+function GEN() {}
+
+/**
+ * During generation phase, this outputs; do nothing at runtime.
+ */
+function GEN_INCLUDE() {}
+
+/**
+ * At runtime, register the testName with a test fixture. Since this method
+ * doesn't have a test fixture, create a dummy fixture to hold its |name|
+ * and |testCaseBodies|.
+ * @param {string} testCaseName The name of the test case.
+ * @param {string} testName The name of the test function.
+ * @param {Function} testBody The body to execute when running this test.
+ */
+function TEST(testCaseName, testName, testBody) {
+  var fixtureConstructor = this[testCaseName];
+  if (fixtureConstructor === undefined) {
+    fixtureConstructor = function() {};
+    this[testCaseName] = fixtureConstructor;
+    fixtureConstructor.prototype = {
+      __proto__: Test.prototype,
+      name: testCaseName,
     };
+    fixtureConstructor.testCaseBodies = {};
   }
+  fixtureConstructor.testCaseBodies[testName] = testBody;
+}
 
-  /**
-   * Used by WebUIBrowserTest to preload the javascript libraries at the
-   * appropriate time for javascript injection into the current page. This
-   * creates a test case and calls its preLoad for any early initialization such
-   * as registering handlers before the page's javascript runs it's OnLoad
-   * method. This is called before the page is loaded, so the |chrome| object is
-   * not yet bound and this DOMContentLoaded listener will be called first to
-   * override |chrome| in order to route messages registered in |sendCallbacks|.
-   * @param {string} testFixture The test fixture name.
-   * @param {string} testName The test name.
-   * @see sendCallbacks
-   */
-  function preloadJavascriptLibraries(testFixture, testName) {
-    deferGlobalOverrides = true;
+/**
+ * At runtime, register the testName with its fixture. Stuff the |name| into
+ * the |testFixture|'s prototype, if needed, and the |testCaseBodies| into its
+ * constructor.
+ * @param {string} testFixture The name of the test fixture class.
+ * @param {string} testName The name of the test function.
+ * @param {Function} testBody The body to execute when running this test.
+ */
+function TEST_F(testFixture, testName, testBody) {
+  var fixtureConstructor = this[testFixture];
+  if (!fixtureConstructor.prototype.name)
+    fixtureConstructor.prototype.name = testFixture;
+  if (fixtureConstructor['testCaseBodies'] === undefined)
+    fixtureConstructor.testCaseBodies = {};
+  fixtureConstructor.testCaseBodies[testName] = testBody;
+}
 
-    // The document seems to change from the point of preloading to the point of
-    // events (and doesn't fire), whereas the window does not. Listening to the
-    // capture phase allows this event to fire first.
-    window.addEventListener('DOMContentLoaded', function() {
-      overrideChrome();
-
-      // Override globals at load time so they will be defined.
-      assertTrue(deferGlobalOverrides);
-      deferGlobalOverrides = false;
-      for (var funcName in globalOverrides)
-        overrideGlobal(funcName);
-    }, true);
+/**
+ * RunJavascriptTestF uses this as the |testFunction| when invoking
+ * runTest. If |currentTestCase| is non-null at this point, verify that
+ * |testFixture| and |testName| agree with the preloaded values. Create
+ * |currentTestCase|, if needed, run it, and clear the |currentTestCase|.
+ * @param {string} testFixture The name of the test fixture class.
+ * @param {string} testName The name of the test function.
+ * @see preloadJavascriptLibraries
+ * @see runTest
+ */
+function RUN_TEST_F(testFixture, testName) {
+  if (!currentTestCase)
     currentTestCase = createTestCase(testFixture, testName);
-    currentTestCase.preLoad();
-  }
+  assertEquals(currentTestCase.name, testName);
+  assertEquals(currentTestCase.fixture.name, testFixture);
+  console.log('Running TestCase ' + testFixture + '.' + testName);
+  currentTestCase.run();
+}
+
+/**
+ * This Mock4JS matcher object pushes each |actualArgument| parameter to
+ * match() calls onto |args|.
+ * @param {Array} args The array to push |actualArgument| onto.
+ * @param {Object} realMatcher The real matcher check arguments with.
+ * @constructor
+ * @extends {realMatcher}
+ */
+function SaveMockArgumentMatcher(args, realMatcher) {
+  this.arguments_ = args;
+  this.realMatcher_ = realMatcher;
+}
+
+SaveMockArgumentMatcher.prototype = {
+  /**
+   * Holds the arguments to push each |actualArgument| onto.
+   * @type {Array}
+   * @private
+   */
+  arguments_: null,
 
   /**
-   * During generation phase, this outputs; do nothing at runtime.
+   * The real Mock4JS matcher object to check arguments with.
+   * @type {Object}
    */
-  function GEN() {}
+  realMatcher_: null,
 
   /**
-   * During generation phase, this outputs; do nothing at runtime.
+   * Pushes |actualArgument| onto |arguments_| and call |realMatcher_|. Clears
+   * |arguments_| on non-match.
+   * @param {*} actualArgument The argument to match and save.
+   * @return {boolean} Result of calling the |realMatcher|.
    */
-  function GEN_INCLUDE() {}
+  argumentMatches: function(actualArgument) {
+    this.arguments_.push(actualArgument);
+    var match = this.realMatcher_.argumentMatches(actualArgument);
+    if (!match)
+      this.arguments_.splice(0, this.arguments_.length);
+
+    return match;
+  },
 
   /**
-   * At runtime, register the testName with a test fixture. Since this method
-   * doesn't have a test fixture, create a dummy fixture to hold its |name|
-   * and |testCaseBodies|.
-   * @param {string} testCaseName The name of the test case.
-   * @param {string} testName The name of the test function.
-   * @param {Function} testBody The body to execute when running this test.
+   * Proxy to |realMatcher_| for description.
+   * @return {string} Description of this Mock4JS matcher.
    */
-  function TEST(testCaseName, testName, testBody) {
-    var fixtureConstructor = this[testCaseName];
-    if (fixtureConstructor === undefined) {
-      fixtureConstructor = function() {};
-      this[testCaseName] = fixtureConstructor;
-      fixtureConstructor.prototype = {
-        __proto__: Test.prototype,
-        name: testCaseName,
-      };
-      fixtureConstructor.testCaseBodies = {};
+  describe: function() {
+    return this.realMatcher_.describe();
+  },
+};
+
+/**
+ * Actions invoked by Mock4JS's "will()" syntax do not receive arguments from
+ * the mocked method. This class works with SaveMockArgumentMatcher to save
+ * arguments so that the invoked Action can pass arguments through to the
+ * invoked function.
+ * @param {!Object} realMatcher The real matcher to perform matching with.
+ * @constructor
+ */
+function SaveMockArguments() {
+  this.arguments = [];
+}
+
+SaveMockArguments.prototype = {
+  /**
+   * Wraps the |realMatcher| with an object which will push its argument onto
+   * |arguments| and call realMatcher.
+   * @param {Object} realMatcher A Mock4JS matcher object for this argument.
+   * @return {SaveMockArgumentMatcher} A new matcher which will push its
+   *     argument onto |arguments|.
+   */
+  match: function(realMatcher) {
+    return new SaveMockArgumentMatcher(this.arguments, realMatcher);
+  },
+
+  /**
+   * Remember the argument passed to this stub invocation.
+   * @type {Array}
+   */
+  arguments: null,
+};
+
+/**
+ * CallFunctionAction is provided to allow mocks to have side effects.
+ * @param {Object} obj The object to set |this| to when calling |func_|.
+ * @param {?SaveMockArguments} savedArgs when non-null, saved arguments are
+ *     passed to |func|.
+ * @param {Function} func The function to call.
+ * @param {Array=} args Any arguments to pass to func.
+ * @constructor
+ */
+function CallFunctionAction(obj, savedArgs, func, args) {
+  this.obj_ = obj;
+  this.savedArgs_ = savedArgs;
+  this.func_ = func;
+  this.args_ = args ? args : [];
+}
+
+CallFunctionAction.prototype = {
+  /**
+   * Set |this| to |obj_| when calling |func_|.
+   * @type {?Object}
+   */
+  obj_: null,
+
+  /**
+   * The SaveMockArguments to hold arguments when invoking |func_|.
+   * @type {?SaveMockArguments}
+   * @private
+   */
+  savedArgs_: null,
+
+  /**
+   * The function to call when invoked.
+   * @type {!Function}
+   * @private
+   */
+  func_: null,
+
+  /**
+   * Arguments to pass to |func_| when invoked.
+   * @type {!Array}
+   */
+  args_: null,
+
+  /**
+   * Accessor for |func_|.
+   * @return {Function} The function to invoke.
+   */
+  get func() {
+    return this.func_;
+  },
+
+  /**
+   * Called by Mock4JS when using .will() to specify actions for stubs() or
+   * expects(). Clears |savedArgs_| so it can be reused.
+   * @return The results of calling |func_| with the concatenation of
+   *     |savedArgs_| and |args_|.
+   */
+  invoke: function() {
+    var prependArgs = [];
+    if (this.savedArgs_) {
+      prependArgs =
+          this.savedArgs_.arguments.splice(0, this.savedArgs_.arguments.length);
     }
-    fixtureConstructor.testCaseBodies[testName] = testBody;
-  }
+    return this.func.apply(this.obj_, prependArgs.concat(this.args_));
+  },
 
   /**
-   * At runtime, register the testName with its fixture. Stuff the |name| into
-   * the |testFixture|'s prototype, if needed, and the |testCaseBodies| into its
-   * constructor.
-   * @param {string} testFixture The name of the test fixture class.
-   * @param {string} testName The name of the test function.
-   * @param {Function} testBody The body to execute when running this test.
+   * Describe this action to Mock4JS.
+   * @return {string} A description of this action.
    */
-  function TEST_F(testFixture, testName, testBody) {
-    var fixtureConstructor = this[testFixture];
-    if (!fixtureConstructor.prototype.name)
-      fixtureConstructor.prototype.name = testFixture;
-    if (fixtureConstructor['testCaseBodies'] === undefined)
-      fixtureConstructor.testCaseBodies = {};
-    fixtureConstructor.testCaseBodies[testName] = testBody;
+  describe: function() {
+    return 'calls the given function with saved arguments and ' + this.args_;
   }
+};
+
+/**
+ * Syntactic sugar for use with will() on a Mock4JS.Mock.
+ * @param {Function} func The function to call when the method is invoked.
+ * @param {...*} var_args Arguments to pass when calling func.
+ * @return {CallFunctionAction} Action for use in will.
+ */
+function callFunction(func) {
+  return new CallFunctionAction(
+      null, null, func, Array.prototype.slice.call(arguments, 1));
+}
+
+/**
+ * Syntactic sugar for use with will() on a Mock4JS.Mock.
+ * @param {SaveMockArguments} savedArgs Arguments saved with this object
+ *     are passed to |func|.
+ * @param {Function} func The function to call when the method is invoked.
+ * @param {...*} var_args Arguments to pass when calling func.
+ * @return {CallFunctionAction} Action for use in will.
+ */
+function callFunctionWithSavedArgs(savedArgs, func) {
+  return new CallFunctionAction(
+      null, savedArgs, func, Array.prototype.slice.call(arguments, 2));
+}
+
+/**
+ * CallGlobalAction as a subclass of CallFunctionAction looks up the original
+ * global object in |globalOverrides| using |funcName| as the key. This allows
+ * tests, which need to wait until a global function to be called in order to
+ * start the test to run the original function. When used with runAllActions
+ * or runAllActionsAsync, Mock4JS expectations may call start or continue the
+ * test after calling the original function.
+ * @param {?SaveMockArguments} savedArgs when non-null, saved arguments are
+ *     passed to the global function |funcName|.
+ * @param {string} funcName The name of the global function to call.
+ * @param {Array} args Any arguments to pass to func.
+ * @constructor
+ * @extends {CallFunctionAction}
+ * @see globalOverrides
+ */
+function CallGlobalAction(savedArgs, funcName, args) {
+  CallFunctionAction.call(this, null, savedArgs, funcName, args);
+}
+
+CallGlobalAction.prototype = {
+  __proto__: CallFunctionAction.prototype,
 
   /**
-   * RunJavascriptTestF uses this as the |testFunction| when invoking
-   * runTest. If |currentTestCase| is non-null at this point, verify that
-   * |testFixture| and |testName| agree with the preloaded values. Create
-   * |currentTestCase|, if needed, run it, and clear the |currentTestCase|.
-   * @param {string} testFixture The name of the test fixture class.
-   * @param {string} testName The name of the test function.
-   * @see preloadJavascriptLibraries
-   * @see runTest
+   * Fetch and return the original global function to call.
+   * @return {Function} The global function to invoke.
+   * @override
    */
-  function RUN_TEST_F(testFixture, testName) {
-    if (!currentTestCase)
-      currentTestCase = createTestCase(testFixture, testName);
-    assertEquals(currentTestCase.name, testName);
-    assertEquals(currentTestCase.fixture.name, testFixture);
-    console.log('Running TestCase ' + testFixture + '.' + testName);
-    currentTestCase.run();
-  }
+  get func() {
+    var func = globalOverrides[this.func_].original;
+    assertNotEquals(undefined, func);
+    return func;
+  },
+};
+
+/**
+ * Syntactic sugar for use with will() on a Mock4JS.Mock.
+ * @param {SaveMockArguments} savedArgs Arguments saved with this object
+ *     are passed to the global function |funcName|.
+ * @param {string} funcName The name of a registered mock global function to
+ *     call when the method is invoked.
+ * @param {...*} var_args Arguments to pass when calling func.
+ * @return {CallGlobalAction} Action for use in Mock4JS will().
+ */
+function callGlobalWithSavedArgs(savedArgs, funcName) {
+  return new CallGlobalAction(
+      savedArgs, funcName, Array.prototype.slice.call(arguments, 2));
+}
+
+/**
+ * When to call testDone().
+ * @enum {number}
+ */
+var WhenTestDone = {
+  /**
+   * Default for the method called.
+   */
+  DEFAULT: -1,
 
   /**
-   * This Mock4JS matcher object pushes each |actualArgument| parameter to
-   * match() calls onto |args|.
-   * @param {Array} args The array to push |actualArgument| onto.
-   * @param {Object} realMatcher The real matcher check arguments with.
-   * @constructor
-   * @extends {realMatcher}
+   * Never call testDone().
    */
-  function SaveMockArgumentMatcher(args, realMatcher) {
-    this.arguments_ = args;
-    this.realMatcher_ = realMatcher;
-  }
-
-  SaveMockArgumentMatcher.prototype = {
-    /**
-     * Holds the arguments to push each |actualArgument| onto.
-     * @type {Array}
-     * @private
-     */
-    arguments_: null,
-
-    /**
-     * The real Mock4JS matcher object to check arguments with.
-     * @type {Object}
-     */
-    realMatcher_: null,
-
-    /**
-     * Pushes |actualArgument| onto |arguments_| and call |realMatcher_|. Clears
-     * |arguments_| on non-match.
-     * @param {*} actualArgument The argument to match and save.
-     * @return {boolean} Result of calling the |realMatcher|.
-     */
-    argumentMatches: function(actualArgument) {
-      this.arguments_.push(actualArgument);
-      var match = this.realMatcher_.argumentMatches(actualArgument);
-      if (!match)
-        this.arguments_.splice(0, this.arguments_.length);
-
-      return match;
-    },
-
-    /**
-     * Proxy to |realMatcher_| for description.
-     * @return {string} Description of this Mock4JS matcher.
-     */
-    describe: function() {
-      return this.realMatcher_.describe();
-    },
-  };
+  NEVER: 0,
 
   /**
-   * Actions invoked by Mock4JS's "will()" syntax do not receive arguments from
-   * the mocked method. This class works with SaveMockArgumentMatcher to save
-   * arguments so that the invoked Action can pass arguments through to the
-   * invoked function.
-   * @param {!Object} realMatcher The real matcher to perform matching with.
-   * @constructor
+   * Call testDone() on assert failure.
    */
-  function SaveMockArguments() {
-    this.arguments = [];
-  }
-
-  SaveMockArguments.prototype = {
-    /**
-     * Wraps the |realMatcher| with an object which will push its argument onto
-     * |arguments| and call realMatcher.
-     * @param {Object} realMatcher A Mock4JS matcher object for this argument.
-     * @return {SaveMockArgumentMatcher} A new matcher which will push its
-     *     argument onto |arguments|.
-     */
-    match: function(realMatcher) {
-      return new SaveMockArgumentMatcher(this.arguments, realMatcher);
-    },
-
-    /**
-     * Remember the argument passed to this stub invocation.
-     * @type {Array}
-     */
-    arguments: null,
-  };
+  ASSERT: 1,
 
   /**
-   * CallFunctionAction is provided to allow mocks to have side effects.
-   * @param {Object} obj The object to set |this| to when calling |func_|.
-   * @param {?SaveMockArguments} savedArgs when non-null, saved arguments are
-   *     passed to |func|.
-   * @param {Function} func The function to call.
-   * @param {Array=} args Any arguments to pass to func.
-   * @constructor
+   * Call testDone() if there are any assert or expect failures.
    */
-  function CallFunctionAction(obj, savedArgs, func, args) {
-    this.obj_ = obj;
-    this.savedArgs_ = savedArgs;
-    this.func_ = func;
-    this.args_ = args ? args : [];
-  }
+  EXPECT: 2,
 
-  CallFunctionAction.prototype = {
-    /**
-     * Set |this| to |obj_| when calling |func_|.
-     * @type {?Object}
-     */
-    obj_: null,
+  /**
+   * Always call testDone().
+   */
+  ALWAYS: 3,
+};
 
-    /**
-     * The SaveMockArguments to hold arguments when invoking |func_|.
-     * @type {?SaveMockArguments}
-     * @private
-     */
-    savedArgs_: null,
+/**
+ * Runs all |actions|.
+ * @param {boolean} isAsync When true, call testDone() on Errors.
+ * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
+ *     time.
+ * @param {Array<Object>} actions Actions to run.
+ * @constructor
+ */
+function RunAllAction(isAsync, whenTestDone, actions) {
+  this.isAsync_ = isAsync;
+  this.whenTestDone_ = whenTestDone;
+  this.actions_ = actions;
+}
 
-    /**
-     * The function to call when invoked.
-     * @type {!Function}
-     * @private
-     */
-    func_: null,
+RunAllAction.prototype = {
+  /**
+   * When true, call testDone() on Errors.
+   * @type {boolean}
+   * @private
+   */
+  isAsync_: false,
 
-    /**
-     * Arguments to pass to |func_| when invoked.
-     * @type {!Array}
-     */
-    args_: null,
+  /**
+   * Call testDone() at appropriate time.
+   * @type {WhenTestDone}
+   * @private
+   * @see WhenTestDone
+   */
+  whenTestDone_: WhenTestDone.ASSERT,
 
-    /**
-     * Accessor for |func_|.
-     * @return {Function} The function to invoke.
-     */
-    get func() {
-      return this.func_;
-    },
+  /**
+   * Holds the actions to execute when invoked.
+   * @type {Array}
+   * @private
+   */
+  actions_: null,
 
-    /**
-     * Called by Mock4JS when using .will() to specify actions for stubs() or
-     * expects(). Clears |savedArgs_| so it can be reused.
-     * @return The results of calling |func_| with the concatenation of
-     *     |savedArgs_| and |args_|.
-     */
-    invoke: function() {
-      var prependArgs = [];
-      if (this.savedArgs_) {
-        prependArgs = this.savedArgs_.arguments.splice(
-            0, this.savedArgs_.arguments.length);
-      }
-      return this.func.apply(this.obj_, prependArgs.concat(this.args_));
-    },
+  /**
+   * Runs all |actions_|, returning the last one. When running in sync mode,
+   * throws any exceptions to be caught by runTest() or
+   * runTestFunction(). Call testDone() according to |whenTestDone_| setting.
+   */
+  invoke: function() {
+    try {
+      var result;
+      for (var i = 0; i < this.actions_.length; ++i)
+        result = this.actions_[i].invoke();
 
-    /**
-     * Describe this action to Mock4JS.
-     * @return {string} A description of this action.
-     */
-    describe: function() {
-      return 'calls the given function with saved arguments and ' + this.args_;
+      if ((this.whenTestDone_ == WhenTestDone.EXPECT && errors.length) ||
+          this.whenTestDone_ == WhenTestDone.ALWAYS)
+        testDone();
+
+      return result;
+    } catch (e) {
+      if (!(e instanceof Error))
+        e = new Error(e.toString());
+
+      if (!this.isAsync_)
+        throw e;
+
+      errors.push(e);
+      if (this.whenTestDone_ != WhenTestDone.NEVER)
+        testDone();
     }
-  };
+  },
 
   /**
-   * Syntactic sugar for use with will() on a Mock4JS.Mock.
-   * @param {Function} func The function to call when the method is invoked.
-   * @param {...*} var_args Arguments to pass when calling func.
-   * @return {CallFunctionAction} Action for use in will.
+   * Describe this action to Mock4JS.
+   * @return {string} A description of this action.
    */
-  function callFunction(func) {
-    return new CallFunctionAction(
-        null, null, func, Array.prototype.slice.call(arguments, 1));
-  }
+  describe: function() {
+    return 'Calls all actions: ' + this.actions_;
+  },
+};
 
+/**
+ * Syntactic sugar for use with will() on a Mock4JS.Mock.
+ * @param {...Object} var_actions Actions to run.
+ * @return {RunAllAction} Action for use in will.
+ */
+function runAllActions() {
+  return new RunAllAction(
+      false, WhenTestDone.NEVER, Array.prototype.slice.call(arguments));
+}
+
+/**
+ * Syntactic sugar for use with will() on a Mock4JS.Mock.
+ * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
+ *     time.
+ * @param {...Object} var_actions Actions to run.
+ * @return {RunAllAction} Action for use in will.
+ */
+function runAllActionsAsync(whenTestDone) {
+  return new RunAllAction(
+      true, whenTestDone, Array.prototype.slice.call(arguments, 1));
+}
+
+/**
+ * Syntactic sugar for use with will() on a Mock4JS.Mock.
+ * Creates an action for will() that invokes a callback that the tested code
+ * passes to a mocked function.
+ * @param {SaveMockArguments} savedArgs Arguments that will contain the
+ *     callback once the mocked function is called.
+ * @param {number} callbackParameter Index of the callback parameter in
+ *     |savedArgs|.
+ * @param {...Object} var_args Arguments to pass to the callback.
+ * @return {CallFunctionAction} Action for use in will().
+ */
+function invokeCallback(savedArgs, callbackParameter, var_args) {
+  var callbackArguments = Array.prototype.slice.call(arguments, 2);
+  return callFunction(function() {
+    savedArgs.arguments[callbackParameter].apply(null, callbackArguments);
+
+    // Mock4JS does not clear the saved args after invocation.
+    // To allow reuse of the same SaveMockArguments for multiple
+    // invocations with similar arguments, clear them here.
+    savedArgs.arguments.splice(0, savedArgs.arguments.length);
+  });
+}
+
+/**
+ * Mock4JS matcher object that matches the actual argument and the expected
+ * value iff their JSON representations are same.
+ * @param {Object} expectedValue
+ * @constructor
+ */
+function MatchJSON(expectedValue) {
+  this.expectedValue_ = expectedValue;
+}
+
+MatchJSON.prototype = {
   /**
-   * Syntactic sugar for use with will() on a Mock4JS.Mock.
-   * @param {SaveMockArguments} savedArgs Arguments saved with this object
-   *     are passed to |func|.
-   * @param {Function} func The function to call when the method is invoked.
-   * @param {...*} var_args Arguments to pass when calling func.
-   * @return {CallFunctionAction} Action for use in will.
+   * Checks that JSON representation of the actual and expected arguments are
+   * same.
+   * @param {Object} actualArgument The argument to match.
+   * @return {boolean} Result of the comparison.
    */
-  function callFunctionWithSavedArgs(savedArgs, func) {
-    return new CallFunctionAction(
-        null, savedArgs, func, Array.prototype.slice.call(arguments, 2));
-  }
+  argumentMatches: function(actualArgument) {
+    return JSON.stringify(this.expectedValue_) ===
+        JSON.stringify(actualArgument);
+  },
 
   /**
-   * CallGlobalAction as a subclass of CallFunctionAction looks up the original
-   * global object in |globalOverrides| using |funcName| as the key. This allows
-   * tests, which need to wait until a global function to be called in order to
-   * start the test to run the original function. When used with runAllActions
-   * or runAllActionsAsync, Mock4JS expectations may call start or continue the
-   * test after calling the original function.
-   * @param {?SaveMockArguments} savedArgs when non-null, saved arguments are
-   *     passed to the global function |funcName|.
-   * @param {string} funcName The name of the global function to call.
-   * @param {Array} args Any arguments to pass to func.
-   * @constructor
-   * @extends {CallFunctionAction}
-   * @see globalOverrides
+   * Describes the matcher.
+   * @return {string} Description of this Mock4JS matcher.
    */
-  function CallGlobalAction(savedArgs, funcName, args) {
-    CallFunctionAction.call(this, null, savedArgs, funcName, args);
-  }
+  describe: function() {
+    return 'eqJSON(' + JSON.stringify(this.expectedValue_) + ')';
+  },
+};
 
-  CallGlobalAction.prototype = {
-    __proto__: CallFunctionAction.prototype,
+/**
+ * Builds a MatchJSON argument matcher for a given expected value.
+ * @param {Object} expectedValue
+ * @return {MatchJSON} Resulting Mock4JS matcher.
+ */
+function eqJSON(expectedValue) {
+  return new MatchJSON(expectedValue);
+}
 
-    /**
-     * Fetch and return the original global function to call.
-     * @return {Function} The global function to invoke.
-     * @override
-     */
-    get func() {
-      var func = globalOverrides[this.func_].original;
-      assertNotEquals(undefined, func);
-      return func;
-    },
-  };
+/**
+ * Mock4JS matcher object that matches the actual argument and the expected
+ * value iff the the string representation of the actual argument is equal to
+ * the expected value.
+ * @param {string} expectedValue
+ * @constructor
+ */
+function MatchToString(expectedValue) {
+  this.expectedValue_ = expectedValue;
+}
 
+MatchToString.prototype = {
   /**
-   * Syntactic sugar for use with will() on a Mock4JS.Mock.
-   * @param {SaveMockArguments} savedArgs Arguments saved with this object
-   *     are passed to the global function |funcName|.
-   * @param {string} funcName The name of a registered mock global function to
-   *     call when the method is invoked.
-   * @param {...*} var_args Arguments to pass when calling func.
-   * @return {CallGlobalAction} Action for use in Mock4JS will().
-   */
-  function callGlobalWithSavedArgs(savedArgs, funcName) {
-    return new CallGlobalAction(
-        savedArgs, funcName, Array.prototype.slice.call(arguments, 2));
-  }
-
-  /**
-   * When to call testDone().
-   * @enum {number}
-   */
-  var WhenTestDone = {
-    /**
-     * Default for the method called.
-     */
-    DEFAULT: -1,
-
-    /**
-     * Never call testDone().
-     */
-    NEVER: 0,
-
-    /**
-     * Call testDone() on assert failure.
-     */
-    ASSERT: 1,
-
-    /**
-     * Call testDone() if there are any assert or expect failures.
-     */
-    EXPECT: 2,
-
-    /**
-     * Always call testDone().
-     */
-    ALWAYS: 3,
-  };
-
-  /**
-   * Runs all |actions|.
-   * @param {boolean} isAsync When true, call testDone() on Errors.
-   * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
-   *     time.
-   * @param {Array<Object>} actions Actions to run.
-   * @constructor
-   */
-  function RunAllAction(isAsync, whenTestDone, actions) {
-    this.isAsync_ = isAsync;
-    this.whenTestDone_ = whenTestDone;
-    this.actions_ = actions;
-  }
-
-  RunAllAction.prototype = {
-    /**
-     * When true, call testDone() on Errors.
-     * @type {boolean}
-     * @private
-     */
-    isAsync_: false,
-
-    /**
-     * Call testDone() at appropriate time.
-     * @type {WhenTestDone}
-     * @private
-     * @see WhenTestDone
-     */
-    whenTestDone_: WhenTestDone.ASSERT,
-
-    /**
-     * Holds the actions to execute when invoked.
-     * @type {Array}
-     * @private
-     */
-    actions_: null,
-
-    /**
-     * Runs all |actions_|, returning the last one. When running in sync mode,
-     * throws any exceptions to be caught by runTest() or
-     * runTestFunction(). Call testDone() according to |whenTestDone_| setting.
-     */
-    invoke: function() {
-      try {
-        var result;
-        for(var i = 0; i < this.actions_.length; ++i)
-          result = this.actions_[i].invoke();
-
-        if ((this.whenTestDone_ == WhenTestDone.EXPECT && errors.length) ||
-            this.whenTestDone_ == WhenTestDone.ALWAYS)
-          testDone();
-
-        return result;
-      } catch (e) {
-        if (!(e instanceof Error))
-          e = new Error(e.toString());
-
-        if (!this.isAsync_)
-          throw e;
-
-        errors.push(e);
-        if (this.whenTestDone_ != WhenTestDone.NEVER)
-          testDone();
-      }
-    },
-
-    /**
-     * Describe this action to Mock4JS.
-     * @return {string} A description of this action.
-     */
-    describe: function() {
-      return 'Calls all actions: ' + this.actions_;
-    },
-  };
-
-  /**
-   * Syntactic sugar for use with will() on a Mock4JS.Mock.
-   * @param {...Object} var_actions Actions to run.
-   * @return {RunAllAction} Action for use in will.
-   */
-  function runAllActions() {
-    return new RunAllAction(false, WhenTestDone.NEVER,
-                            Array.prototype.slice.call(arguments));
-  }
-
-  /**
-   * Syntactic sugar for use with will() on a Mock4JS.Mock.
-   * @param {WhenTestDone} whenTestDone Call testDone() at the appropriate
-   *     time.
-   * @param {...Object} var_actions Actions to run.
-   * @return {RunAllAction} Action for use in will.
-   */
-  function runAllActionsAsync(whenTestDone) {
-    return new RunAllAction(true, whenTestDone,
-                            Array.prototype.slice.call(arguments, 1));
-  }
-
-  /**
-   * Syntactic sugar for use with will() on a Mock4JS.Mock.
-   * Creates an action for will() that invokes a callback that the tested code
-   * passes to a mocked function.
-   * @param {SaveMockArguments} savedArgs Arguments that will contain the
-   *     callback once the mocked function is called.
-   * @param {number} callbackParameter Index of the callback parameter in
-   *     |savedArgs|.
-   * @param {...Object} var_args Arguments to pass to the callback.
-   * @return {CallFunctionAction} Action for use in will().
-   */
-  function invokeCallback(savedArgs, callbackParameter, var_args) {
-    var callbackArguments = Array.prototype.slice.call(arguments, 2);
-    return callFunction(function() {
-      savedArgs.arguments[callbackParameter].apply(null, callbackArguments);
-
-      // Mock4JS does not clear the saved args after invocation.
-      // To allow reuse of the same SaveMockArguments for multiple
-      // invocations with similar arguments, clear them here.
-      savedArgs.arguments.splice(0, savedArgs.arguments.length);
-    });
-  }
-
-  /**
-   * Mock4JS matcher object that matches the actual argument and the expected
-   * value iff their JSON representations are same.
-   * @param {Object} expectedValue
-   * @constructor
-   */
-  function MatchJSON(expectedValue) {
-    this.expectedValue_ = expectedValue;
-  }
-
-  MatchJSON.prototype = {
-    /**
-     * Checks that JSON representation of the actual and expected arguments are
-     * same.
-     * @param {Object} actualArgument The argument to match.
-     * @return {boolean} Result of the comparison.
-     */
-    argumentMatches: function(actualArgument) {
-      return JSON.stringify(this.expectedValue_) ===
-          JSON.stringify(actualArgument);
-    },
-
-    /**
-     * Describes the matcher.
-     * @return {string} Description of this Mock4JS matcher.
-     */
-    describe: function() {
-      return 'eqJSON(' + JSON.stringify(this.expectedValue_) + ')';
-    },
-  };
-
-  /**
-   * Builds a MatchJSON argument matcher for a given expected value.
-   * @param {Object} expectedValue
-   * @return {MatchJSON} Resulting Mock4JS matcher.
-   */
-  function eqJSON(expectedValue) {
-    return new MatchJSON(expectedValue);
-  }
-
-  /**
-   * Mock4JS matcher object that matches the actual argument and the expected
-   * value iff the the string representation of the actual argument is equal to
+   * Checks that the the string representation of the actual argument matches
    * the expected value.
-   * @param {string} expectedValue
-   * @constructor
+   * @param {*} actualArgument The argument to match.
+   * @return {boolean} Result of the comparison.
    */
-  function MatchToString(expectedValue) {
-    this.expectedValue_ = expectedValue;
-  }
-
-  MatchToString.prototype = {
-    /**
-     * Checks that the the string representation of the actual argument matches
-     * the expected value.
-     * @param {*} actualArgument The argument to match.
-     * @return {boolean} Result of the comparison.
-     */
-    argumentMatches: function(actualArgument) {
-      return this.expectedValue_ === String(actualArgument);
-    },
-
-    /**
-     * Describes the matcher.
-     * @return {string} Description of this Mock4JS matcher.
-     */
-    describe: function() {
-      return 'eqToString("' + this.expectedValue_ + '")';
-    },
-  };
+  argumentMatches: function(actualArgument) {
+    return this.expectedValue_ === String(actualArgument);
+  },
 
   /**
-   * Builds a MatchToString argument matcher for a given expected value.
-   * @param {Object} expectedValue
-   * @return {MatchToString} Resulting Mock4JS matcher.
+   * Describes the matcher.
+   * @return {string} Description of this Mock4JS matcher.
    */
-  function eqToString(expectedValue) {
-    return new MatchToString(expectedValue);
-  }
+  describe: function() {
+    return 'eqToString("' + this.expectedValue_ + '")';
+  },
+};
 
-  /**
-   * Exports assertion methods. All assertion methods delegate to the chai.js
-   * assertion library.
-   */
-  function exportChaiAsserts() {
-    exports.assertTrue = assertTrue;
-    exports.assertFalse = assertFalse;
-    exports.assertGE = assertGE;
-    exports.assertGT = assertGT;
-    exports.assertEquals = assertEquals;
-    exports.assertDeepEquals = assertDeepEquals;
-    exports.assertLE = assertLE;
-    exports.assertLT = assertLT;
-    exports.assertNotEquals = assertNotEquals;
-    exports.assertNotReached = assertNotReached;
-    exports.assertThrows = assertThrows;
-  }
+/**
+ * Builds a MatchToString argument matcher for a given expected value.
+ * @param {Object} expectedValue
+ * @return {MatchToString} Resulting Mock4JS matcher.
+ */
+function eqToString(expectedValue) {
+  return new MatchToString(expectedValue);
+}
 
-  /**
-   * Exports expect methods. 'expect*' methods allow tests to run until the end
-   * even in the presence of failures.
-   */
-  function exportExpects() {
-    exports.expectTrue = createExpect(assertTrue);
-    exports.expectFalse = createExpect(assertFalse);
-    exports.expectGE = createExpect(assertGE);
-    exports.expectGT = createExpect(assertGT);
-    exports.expectEquals = createExpect(assertEquals);
-    exports.expectDeepEquals = createExpect(assertDeepEquals);
-    exports.expectLE = createExpect(assertLE);
-    exports.expectLT = createExpect(assertLT);
-    exports.expectNotEquals = createExpect(assertNotEquals);
-    exports.expectNotReached = createExpect(assertNotReached);
-    exports.expectAccessibilityOk = createExpect(assertAccessibilityOk);
-    exports.expectThrows = createExpect(assertThrows);
-  }
+/**
+ * Exports assertion methods. All assertion methods delegate to the chai.js
+ * assertion library.
+ */
+function exportChaiAsserts() {
+  exports.assertTrue = assertTrue;
+  exports.assertFalse = assertFalse;
+  exports.assertGE = assertGE;
+  exports.assertGT = assertGT;
+  exports.assertEquals = assertEquals;
+  exports.assertDeepEquals = assertDeepEquals;
+  exports.assertLE = assertLE;
+  exports.assertLT = assertLT;
+  exports.assertNotEquals = assertNotEquals;
+  exports.assertNotReached = assertNotReached;
+  exports.assertThrows = assertThrows;
+}
 
-  /**
-   * Exports methods related to Mock4JS mocking.
-   */
-  function exportMock4JsHelpers() {
-    exports.callFunction = callFunction;
-    exports.callFunctionWithSavedArgs = callFunctionWithSavedArgs;
-    exports.callGlobalWithSavedArgs = callGlobalWithSavedArgs;
-    exports.eqJSON = eqJSON;
-    exports.eqToString = eqToString;
-    exports.invokeCallback = invokeCallback;
-    exports.SaveMockArguments = SaveMockArguments;
+/**
+ * Exports expect methods. 'expect*' methods allow tests to run until the end
+ * even in the presence of failures.
+ */
+function exportExpects() {
+  exports.expectTrue = createExpect(assertTrue);
+  exports.expectFalse = createExpect(assertFalse);
+  exports.expectGE = createExpect(assertGE);
+  exports.expectGT = createExpect(assertGT);
+  exports.expectEquals = createExpect(assertEquals);
+  exports.expectDeepEquals = createExpect(assertDeepEquals);
+  exports.expectLE = createExpect(assertLE);
+  exports.expectLT = createExpect(assertLT);
+  exports.expectNotEquals = createExpect(assertNotEquals);
+  exports.expectNotReached = createExpect(assertNotReached);
+  exports.expectAccessibilityOk = createExpect(assertAccessibilityOk);
+  exports.expectThrows = createExpect(assertThrows);
+}
 
-    // Import the Mock4JS helpers.
-    Mock4JS.addMockSupport(exports);
-  }
+/**
+ * Exports methods related to Mock4JS mocking.
+ */
+function exportMock4JsHelpers() {
+  exports.callFunction = callFunction;
+  exports.callFunctionWithSavedArgs = callFunctionWithSavedArgs;
+  exports.callGlobalWithSavedArgs = callGlobalWithSavedArgs;
+  exports.eqJSON = eqJSON;
+  exports.eqToString = eqToString;
+  exports.invokeCallback = invokeCallback;
+  exports.SaveMockArguments = SaveMockArguments;
 
-  // Exports.
-  testing.Test = Test;
-  exports.testDone = testDone;
-  exportChaiAsserts();
-  exports.assertAccessibilityOk = assertAccessibilityOk;
-  exportExpects();
-  exportMock4JsHelpers();
-  exports.preloadJavascriptLibraries = preloadJavascriptLibraries;
-  exports.registerMessageCallback = registerMessageCallback;
-  exports.registerMockGlobals = registerMockGlobals;
-  exports.registerMockMessageCallbacks = registerMockMessageCallbacks;
-  exports.resetTestState = resetTestState;
-  exports.runAccessibilityAudit = runAccessibilityAudit;
-  exports.runAllActions = runAllActions;
-  exports.runAllActionsAsync = runAllActionsAsync;
-  exports.runTest = runTest;
-  exports.runTestFunction = runTestFunction;
-  exports.DUMMY_URL = DUMMY_URL;
-  exports.TEST = TEST;
-  exports.TEST_F = TEST_F;
-  exports.RUNTIME_TEST_F = TEST_F;
-  exports.GEN = GEN;
-  exports.GEN_INCLUDE = GEN_INCLUDE;
-  exports.WhenTestDone = WhenTestDone;
+  // Import the Mock4JS helpers.
+  Mock4JS.addMockSupport(exports);
+}
+
+// Exports.
+testing.Test = Test;
+exports.testDone = testDone;
+exportChaiAsserts();
+exports.assertAccessibilityOk = assertAccessibilityOk;
+exportExpects();
+exportMock4JsHelpers();
+exports.preloadJavascriptLibraries = preloadJavascriptLibraries;
+exports.registerMessageCallback = registerMessageCallback;
+exports.registerMockGlobals = registerMockGlobals;
+exports.registerMockMessageCallbacks = registerMockMessageCallbacks;
+exports.resetTestState = resetTestState;
+exports.runAccessibilityAudit = runAccessibilityAudit;
+exports.runAllActions = runAllActions;
+exports.runAllActionsAsync = runAllActionsAsync;
+exports.runTest = runTest;
+exports.runTestFunction = runTestFunction;
+exports.DUMMY_URL = DUMMY_URL;
+exports.TEST = TEST;
+exports.TEST_F = TEST_F;
+exports.RUNTIME_TEST_F = TEST_F;
+exports.GEN = GEN;
+exports.GEN_INCLUDE = GEN_INCLUDE;
+exports.WhenTestDone = WhenTestDone;
 })(this);
diff --git a/chrome/test/data/webui/test_browser_proxy.js b/chrome/test/data/webui/test_browser_proxy.js
index 728c0a1..a20a8cec 100644
--- a/chrome/test/data/webui/test_browser_proxy.js
+++ b/chrome/test/data/webui/test_browser_proxy.js
@@ -111,8 +111,7 @@
     // Tip: check that the |methodName| is being passed to |this.constructor|.
     const methodData = this.resolverMap_.get(methodName);
     assert(
-        !!methodData,
-        `Method '${methodName}' not found in TestBrowserProxy.`);
+        !!methodData, `Method '${methodName}' not found in TestBrowserProxy.`);
     return methodData;
   }
 
@@ -123,7 +122,6 @@
    */
   createMethodData_(methodName) {
     this.resolverMap_.set(
-        methodName,
-        {resolver: new PromiseResolver(), callCount: 0});
+        methodName, {resolver: new PromiseResolver(), callCount: 0});
   }
 }
diff --git a/chrome/test/data/webui/webui_resource_async_browsertest.js b/chrome/test/data/webui/webui_resource_async_browsertest.js
index 1184b6a..e8bb3bf1 100644
--- a/chrome/test/data/webui/webui_resource_async_browsertest.js
+++ b/chrome/test/data/webui/webui_resource_async_browsertest.js
@@ -65,12 +65,14 @@
             null, [callbackId, !rejectPromises].concat(args.slice(1)));
       });
     });
-    teardown(function() { rejectPromises = false; });
+    teardown(function() {
+      rejectPromises = false;
+    });
 
     test('sendWithPromise_ResponseObject', function() {
       var expectedResponse = {'foo': 'bar'};
-      return cr.sendWithPromise(CHROME_SEND_NAME, expectedResponse).then(
-          function(response) {
+      return cr.sendWithPromise(CHROME_SEND_NAME, expectedResponse)
+          .then(function(response) {
             assertEquals(
                 JSON.stringify(expectedResponse), JSON.stringify(response));
           });
@@ -78,8 +80,8 @@
 
     test('sendWithPromise_ResponseArray', function() {
       var expectedResponse = ['foo', 'bar'];
-      return cr.sendWithPromise(CHROME_SEND_NAME, expectedResponse).then(
-          function(response) {
+      return cr.sendWithPromise(CHROME_SEND_NAME, expectedResponse)
+          .then(function(response) {
             assertEquals(
                 JSON.stringify(expectedResponse), JSON.stringify(response));
           });
@@ -87,8 +89,8 @@
 
     test('sendWithPromise_ResponsePrimitive', function() {
       var expectedResponse = 1234;
-      return cr.sendWithPromise(CHROME_SEND_NAME, expectedResponse).then(
-          function(response) {
+      return cr.sendWithPromise(CHROME_SEND_NAME, expectedResponse)
+          .then(function(response) {
             assertEquals(expectedResponse, response);
           });
     });
@@ -102,13 +104,14 @@
     test('sendWithPromise_Reject', function() {
       rejectPromises = true;
       var expectedResponse = 1234;
-      return cr.sendWithPromise(CHROME_SEND_NAME, expectedResponse).then(
-          function() {
-            assertNotReached('should have rejected promise');
-          },
-          function(error) {
-            assertEquals(expectedResponse, error);
-          });
+      return cr.sendWithPromise(CHROME_SEND_NAME, expectedResponse)
+          .then(
+              function() {
+                assertNotReached('should have rejected promise');
+              },
+              function(error) {
+                assertEquals(expectedResponse, error);
+              });
     });
   });
 
@@ -156,8 +159,9 @@
           assertEquals(expectedObject, o);
           resolve();
         });
-        cr.webUIListenerCallback(EVENT_NAME, expectedString, expectedNumber,
-            expectedArray, expectedObject);
+        cr.webUIListenerCallback(
+            EVENT_NAME, expectedString, expectedNumber, expectedArray,
+            expectedObject);
       });
     });
 
diff --git a/chrome/test/data/webui/webview_content_script_test.js b/chrome/test/data/webui/webview_content_script_test.js
index 08afbbd..65d5269 100644
--- a/chrome/test/data/webui/webview_content_script_test.js
+++ b/chrome/test/data/webui/webview_content_script_test.js
@@ -21,15 +21,15 @@
   var webview = createWebview();
 
   var onSetBackgroundExecuted = function() {
-    webview.executeScript({
-      code: 'document.body.style.backgroundColor;'
-    }, onGetBackgroundExecuted);
+    webview.executeScript(
+        {code: 'document.body.style.backgroundColor;'},
+        onGetBackgroundExecuted);
   };
 
   var onLoadStop = function() {
-    webview.executeScript({
-      code: 'document.body.style.backgroundColor = \'red\';'
-    }, onSetBackgroundExecuted);
+    webview.executeScript(
+        {code: 'document.body.style.backgroundColor = \'red\';'},
+        onSetBackgroundExecuted);
   };
 
   webview.addEventListener('loadstop', onLoadStop);
@@ -40,15 +40,14 @@
   var webview = createWebview();
 
   var onSetBackgroundExecuted = function() {
-    webview.executeScript({
-      code: 'document.body.style.backgroundColor;'
-    }, onGetBackgroundExecuted);
+    webview.executeScript(
+        {code: 'document.body.style.backgroundColor;'},
+        onGetBackgroundExecuted);
   };
 
   var onLoadStop = function() {
-    webview.executeScript({
-      file: 'test/webview_execute_script.js'
-    }, onSetBackgroundExecuted);
+    webview.executeScript(
+        {file: 'test/webview_execute_script.js'}, onSetBackgroundExecuted);
   };
 
   webview.addEventListener('loadstop', onLoadStop);
@@ -62,14 +61,14 @@
   var webview = document.createElement('webview');
 
   console.log('Step 1: call <webview>.addContentScripts.');
-  webview.addContentScripts(
-      [{name: 'myrule',
-        matches: ['http://*/empty*'],
-        js: {
-          files: ['test/inject_comm_channel.js',
-                  'test/inject_comm_channel_2.js']
-        },
-        run_at: 'document_start'}]);
+  webview.addContentScripts([{
+    name: 'myrule',
+    matches: ['http://*/empty*'],
+    js: {
+      files: ['test/inject_comm_channel.js', 'test/inject_comm_channel_2.js']
+    },
+    run_at: 'document_start'
+  }]);
 
   webview.addEventListener('loadstop', function() {
     console.log('Step 2: postMessage to build connection.');
@@ -87,7 +86,7 @@
       chrome.send('testResult', [true]);
       return;
     }
-    console.log('Unexpected message: \'' + data[0]  + '\'');
+    console.log('Unexpected message: \'' + data[0] + '\'');
     chrome.send('testResult', [false]);
   });
 
@@ -102,19 +101,20 @@
   var webview = document.createElement('webview');
 
   console.log('Step 1: call <webview>.addContentScripts(myrule1 & myrule2)');
-  webview.addContentScripts(
-      [{name: 'myrule1',
-        matches: ['http://*/empty*'],
-        js: {
-          files: ['test/inject_comm_channel.js']
-        },
-        run_at: 'document_start'},
-       {name: 'myrule2',
-        matches: ['http://*/empty*'],
-        js: {
-          files: ['test/inject_comm_channel_2.js']
-        },
-        run_at: 'document_start'}]);
+  webview.addContentScripts([
+    {
+      name: 'myrule1',
+      matches: ['http://*/empty*'],
+      js: {files: ['test/inject_comm_channel.js']},
+      run_at: 'document_start'
+    },
+    {
+      name: 'myrule2',
+      matches: ['http://*/empty*'],
+      js: {files: ['test/inject_comm_channel_2.js']},
+      run_at: 'document_start'
+    }
+  ]);
 
   webview.addEventListener('loadstop', function() {
     console.log('Step 2: postMessage to build connection.');
@@ -146,7 +146,7 @@
         chrome.send('testResult', [true]);
       return;
     }
-    console.log('Unexpected message: \'' + data[0]  + '\'');
+    console.log('Unexpected message: \'' + data[0] + '\'');
     chrome.send('testResult', [false]);
   });
 
@@ -163,13 +163,12 @@
   var webview = document.createElement('webview');
 
   console.log('Step 1: call <webview>.addContentScripts(myrule1)');
-  webview.addContentScripts(
-      [{name: 'myrule1',
-        matches: ['http://*/empty*'],
-        js: {
-          files: ['test/inject_comm_channel.js']
-        },
-        run_at: 'document_start'}]);
+  webview.addContentScripts([{
+    name: 'myrule1',
+    matches: ['http://*/empty*'],
+    js: {files: ['test/inject_comm_channel.js']},
+    run_at: 'document_start'
+  }]);
   var connect_script_1 = true;
   var connect_script_2 = false;
 
@@ -194,17 +193,16 @@
     if (data == RESPONSE_FROM_COMM_CHANNEL_1) {
       if (should_get_response_from_script_1) {
         console.log(
-            'Step 2: A communication channel has been established with webview.'
-            );
-        console.log('Step 3: <webview>.addContentScripts() with a updated' +
+            'Step 2: A communication channel has been established with webview.');
+        console.log(
+            'Step 3: <webview>.addContentScripts() with a updated' +
             ' \'myrule1\'');
-        webview.addContentScripts(
-            [{name: 'myrule1',
-              matches: ['http://*/empty*'],
-              js: {
-                files: ['test/inject_comm_channel_2.js']
-              },
-              run_at: 'document_start'}]);
+        webview.addContentScripts([{
+          name: 'myrule1',
+          matches: ['http://*/empty*'],
+          js: {files: ['test/inject_comm_channel_2.js']},
+          run_at: 'document_start'
+        }]);
         connect_script_2 = true;
         should_get_response_from_script_1 = false;
         webview.src = url;
@@ -221,7 +219,7 @@
       }, 0);
       return;
     }
-    console.log('Unexpected message: \'' + data[0]  + '\'');
+    console.log('Unexpected message: \'' + data[0] + '\'');
     chrome.send('testResult', [false]);
   });
 
@@ -237,13 +235,12 @@
   var webview2 = document.createElement('webview');
 
   console.log('Step 1: call <webview1>.addContentScripts.');
-  webview1.addContentScripts(
-      [{name: 'myrule',
-        matches: ['http://*/empty*'],
-        js: {
-          files: ['test/inject_comm_channel.js']
-        },
-        run_at: 'document_start'}]);
+  webview1.addContentScripts([{
+    name: 'myrule',
+    matches: ['http://*/empty*'],
+    js: {files: ['test/inject_comm_channel.js']},
+    run_at: 'document_start'
+  }]);
 
   webview2.addEventListener('loadstop', function() {
     console.log('Step 2: webview2 requests to build communication channel.');
@@ -262,7 +259,7 @@
       chrome.send('testResult', [false]);
       return;
     }
-    console.log('Unexpected message: \'' + data[0]  + '\'');
+    console.log('Unexpected message: \'' + data[0] + '\'');
     chrome.send('testResult', [false]);
   });
 
@@ -281,13 +278,12 @@
   var webview = document.createElement('webview');
 
   console.log('Step 1: call <webview>.addContentScripts.');
-  webview.addContentScripts(
-      [{name: 'myrule',
-        matches: ['http://*/empty*'],
-        js: {
-          files: ['test/inject_comm_channel.js']
-        },
-        run_at: 'document_start'}]);
+  webview.addContentScripts([{
+    name: 'myrule',
+    matches: ['http://*/empty*'],
+    js: {files: ['test/inject_comm_channel.js']},
+    run_at: 'document_start'
+  }]);
 
   var should_get_response_from_script_1 = true;
 
@@ -314,16 +310,16 @@
     var data = JSON.parse(e.data);
     if (data[0] == RESPONSE_FROM_COMM_CHANNEL_1 &&
         should_get_response_from_script_1) {
-        console.log('Step 3: A communication channel has been established ' +
-            'with webview.');
-        should_get_response_from_script_1 = false;
       console.log(
-          'Step 4: call <webview>.removeContentScripts and navigate.');
+          'Step 3: A communication channel has been established ' +
+          'with webview.');
+      should_get_response_from_script_1 = false;
+      console.log('Step 4: call <webview>.removeContentScripts and navigate.');
       webview.removeContentScripts();
       webview.src = url;
       return;
     }
-    console.log('Unexpected message: \'' + data[0]  + '\'');
+    console.log('Unexpected message: \'' + data[0] + '\'');
     chrome.send('testResult', [false]);
   });
 
@@ -342,17 +338,17 @@
     newwebview = document.createElement('webview');
 
     console.log('Step 2: call newwebview.addContentScripts.');
-    newwebview.addContentScripts(
-        [{name: 'myrule',
-          matches: ['http://*/guest_from_opener*'],
-          js: {
-            files: ['test/inject_comm_channel.js']
-          },
-          run_at: 'document_start'}]);
+    newwebview.addContentScripts([{
+      name: 'myrule',
+      matches: ['http://*/guest_from_opener*'],
+      js: {files: ['test/inject_comm_channel.js']},
+      run_at: 'document_start'
+    }]);
 
     newwebview.addEventListener('loadstop', function(evt) {
       var msg = [REQUEST_TO_COMM_CHANNEL_1];
-      console.log('Step 4: new webview postmessage to build communication ' +
+      console.log(
+          'Step 4: new webview postmessage to build communication ' +
           'channel.');
       newwebview.contentWindow.postMessage(JSON.stringify(msg), '*');
     });
@@ -369,7 +365,8 @@
     var data = JSON.parse(e.data);
     if (data == RESPONSE_FROM_COMM_CHANNEL_1 &&
         e.source == newwebview.contentWindow) {
-      console.log('Step 5: a communication channel has been established ' +
+      console.log(
+          'Step 5: a communication channel has been established ' +
           'with the new webview.');
       chrome.send('testResult', [true]);
       return;
@@ -377,7 +374,7 @@
       chrome.send('testResult', [false]);
       return;
     }
-    console.log('Unexpected message: \'' + data[0]  + '\'');
+    console.log('Unexpected message: \'' + data[0] + '\'');
     chrome.send('testResult', [false]);
   });
 
@@ -392,13 +389,12 @@
   var webview = document.createElement('webview');
 
   console.log('Step 1: call <webview>.addContentScripts.');
-  webview.addContentScripts(
-      [{name: 'myrule',
-        matches: ['http://*/empty*'],
-        js: {
-          files: ['test/webview_execute_script.js']
-        },
-        run_at: 'document_end'}]);
+  webview.addContentScripts([{
+    name: 'myrule',
+    matches: ['http://*/empty*'],
+    js: {files: ['test/webview_execute_script.js']},
+    run_at: 'document_end'
+  }]);
 
   var count = 0;
   webview.addEventListener('loadstop', function() {
@@ -409,9 +405,9 @@
       return;
     } else if (count == 1) {
       console.log('Step 4: call <webview>.executeScript to check result.');
-      webview.executeScript({
-        code: 'document.body.style.backgroundColor;'
-      }, onGetBackgroundExecuted);
+      webview.executeScript(
+          {code: 'document.body.style.backgroundColor;'},
+          onGetBackgroundExecuted);
     }
   });
 
@@ -430,35 +426,33 @@
   var webview = document.createElement('webview');
 
   console.log('Step 1: call <webview>.addContentScripts.');
-  webview.addContentScripts(
-      [{name: 'myrule',
-        matches: ['http://*/empty*'],
-        js: {
-          files: ['test/webview_execute_script.js']
-        },
-        run_at: 'document_end'}]);
+  webview.addContentScripts([{
+    name: 'myrule',
+    matches: ['http://*/empty*'],
+    js: {files: ['test/webview_execute_script.js']},
+    run_at: 'document_end'
+  }]);
 
   var count = 0;
   webview.addEventListener('loadstop', function() {
     if (count == 0) {
       console.log('Step 2: check the result of content script injected.');
-      webview.executeScript({
-        code: 'document.body.style.backgroundColor;'
-      }, function(results) {
-        assertEquals(1, results.length);
-        assertEquals('red', results[0]);
+      webview.executeScript(
+          {code: 'document.body.style.backgroundColor;'}, function(results) {
+            assertEquals(1, results.length);
+            assertEquals('red', results[0]);
 
-        console.log('Step 3: remove webview from the DOM.');
-        document.body.removeChild(webview);
-        console.log('Step 4: add webview back to the DOM.');
-        document.body.appendChild(webview);
-        ++count;
-      });
+            console.log('Step 3: remove webview from the DOM.');
+            document.body.removeChild(webview);
+            console.log('Step 4: add webview back to the DOM.');
+            document.body.appendChild(webview);
+            ++count;
+          });
     } else if (count == 1) {
       console.log('Step 5: check the result of content script injected again.');
-      webview.executeScript({
-        code: 'document.body.style.backgroundColor;'
-      }, onGetBackgroundExecuted);
+      webview.executeScript(
+          {code: 'document.body.style.backgroundColor;'},
+          onGetBackgroundExecuted);
     }
   });
 
@@ -470,19 +464,18 @@
   var webview = document.createElement('webview');
 
   console.log('Step 1: call <webview>.addContentScripts.');
-  webview.addContentScripts(
-      [{name: 'myrule',
-        matches: ['http://*/empty*'],
-        js: {
-          code: 'document.body.style.backgroundColor = \'red\';'
-        },
-        run_at: 'document_end'}]);
+  webview.addContentScripts([{
+    name: 'myrule',
+    matches: ['http://*/empty*'],
+    js: {code: 'document.body.style.backgroundColor = \'red\';'},
+    run_at: 'document_end'
+  }]);
 
   webview.addEventListener('loadstop', function() {
     console.log('Step 2: call webview.executeScript() to check result.');
-    webview.executeScript({
-      code: 'document.body.style.backgroundColor;'
-    }, onGetBackgroundExecuted);
+    webview.executeScript(
+        {code: 'document.body.style.backgroundColor;'},
+        onGetBackgroundExecuted);
   });
 
   webview.src = url;
@@ -490,24 +483,24 @@
 }
 
 function testDragAndDropToInput() {
-  var css = document.createElement("style");
-  css.type = "text/css";
-  css.innerHTML = "html, body { height: 400px }";
+  var css = document.createElement('style');
+  css.type = 'text/css';
+  css.innerHTML = 'html, body { height: 400px }';
   document.body.appendChild(css);
 
-  var contents = document.getElementById("contents");
+  var contents = document.getElementById('contents');
   while (contents.childElementCount) {
     contents.removeChild(contents.firstChild);
   }
   var webview = document.createElement('webview');
 
   webview.id = 'webview';
-  webview.style = "width:640px; height:480px";
+  webview.style = 'width:640px; height:480px';
 
-  window.addEventListener('message', function (e) {
+  window.addEventListener('message', function(e) {
     var data = JSON.parse(e.data)[0];
-    console.log("get message: " + data);
-    if (data === "connected") {
+    console.log('get message: ' + data);
+    if (data === 'connected') {
       chrome.send('testResult', [true]);
       return;
     }
@@ -515,20 +508,20 @@
     chrome.send(data);
   });
 
-  webview.addEventListener('loadstop', function (e) {
+  webview.addEventListener('loadstop', function(e) {
     if (webview.src != 'about:blank')
       return;
-    console.log("load stop of src = :" + webview.src);
-    webview.executeScript({ file: 'test/draganddroptoinput.js' },
-      function (results) {
-      console.log("finish guest load");
-      webview.contentWindow.postMessage(
-        JSON.stringify(['create-channel']), '*');
-    });
+    console.log('load stop of src = :' + webview.src);
+    webview.executeScript(
+        {file: 'test/draganddroptoinput.js'}, function(results) {
+          console.log('finish guest load');
+          webview.contentWindow.postMessage(
+              JSON.stringify(['create-channel']), '*');
+        });
   });
 
   // For debug messages from guests.
-  webview.addEventListener('consolemessage', function (e) {
+  webview.addEventListener('consolemessage', function(e) {
     console.log('[Guest]: ' + e.message);
   });
 
diff --git a/chrome/test/data/webui/webview_execute_script.js b/chrome/test/data/webui/webview_execute_script.js
index 1a4989e..1634abb 100644
--- a/chrome/test/data/webui/webview_execute_script.js
+++ b/chrome/test/data/webui/webview_execute_script.js
@@ -2,4 +2,4 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-document.body.style.backgroundColor="red";
+document.body.style.backgroundColor = 'red';
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 8c6aa0ad..508ef73 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-10681.0.0
\ No newline at end of file
+10683.0.0
\ No newline at end of file
diff --git a/components/arc/common/notifications.mojom b/components/arc/common/notifications.mojom
index 2a1e0fa..ffcbcc5b 100644
--- a/components/arc/common/notifications.mojom
+++ b/components/arc/common/notifications.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Next MinVersion: 16
+// Next MinVersion: 17
 
 module arc.mojom;
 
@@ -141,7 +141,7 @@
   string? package_name;
 };
 
-// Next Method ID: 6
+// Next Method ID: 7
 interface NotificationsHost {
   // Tells the Chrome that a notification is posted (created or updated) on
   // Android. If you know that the notification exists, please consider to use
@@ -156,6 +156,10 @@
   [MinVersion=13]
   // Notifies that an existing notiication is updated on Android.
   OnNotificationUpdated@5(ArcNotificationData notification_data);
+
+  [MinVersion=16]
+  // Opens the Chrome OS message center.
+  OpenMessageCenter@6();
 };
 
 // Next Method ID: 6
diff --git a/components/drive/change_list_loader_unittest.cc b/components/drive/change_list_loader_unittest.cc
index 4dbbb0c..497ae9a 100644
--- a/components/drive/change_list_loader_unittest.cc
+++ b/components/drive/change_list_loader_unittest.cc
@@ -21,6 +21,7 @@
 #include "components/drive/chromeos/file_cache.h"
 #include "components/drive/chromeos/loader_controller.h"
 #include "components/drive/chromeos/resource_metadata.h"
+#include "components/drive/chromeos/start_page_token_loader.h"
 #include "components/drive/event_logger.h"
 #include "components/drive/file_change.h"
 #include "components/drive/file_system_core_util.h"
@@ -110,14 +111,13 @@
     ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());
 
     about_resource_loader_.reset(new AboutResourceLoader(scheduler_.get()));
+    start_page_token_loader_.reset(new StartPageTokenLoader(
+        drive::util::kTeamDriveIdDefaultCorpus, scheduler_.get()));
     loader_controller_.reset(new LoaderController);
-    change_list_loader_.reset(
-        new ChangeListLoader(logger_.get(),
-                             base::ThreadTaskRunnerHandle::Get().get(),
-                             metadata_.get(),
-                             scheduler_.get(),
-                             about_resource_loader_.get(),
-                             loader_controller_.get()));
+    change_list_loader_.reset(new ChangeListLoader(
+        logger_.get(), base::ThreadTaskRunnerHandle::Get().get(),
+        metadata_.get(), scheduler_.get(), about_resource_loader_.get(),
+        start_page_token_loader_.get(), loader_controller_.get()));
   }
 
   void SetUpForTeamDrives() {
@@ -154,6 +154,7 @@
   std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
   std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_;
   std::unique_ptr<AboutResourceLoader> about_resource_loader_;
+  std::unique_ptr<StartPageTokenLoader> start_page_token_loader_;
   std::unique_ptr<LoaderController> loader_controller_;
   std::unique_ptr<ChangeListLoader> change_list_loader_;
 };
@@ -174,9 +175,9 @@
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   EXPECT_FALSE(change_list_loader_->IsRefreshing());
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_LT(0, changestamp);
+  std::string start_page_token;
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_FALSE(start_page_token.empty());
   EXPECT_EQ(0, drive_service_->team_drive_list_load_count());
   EXPECT_EQ(1, drive_service_->file_list_load_count());
   EXPECT_EQ(1, drive_service_->about_resource_load_count());
@@ -218,9 +219,9 @@
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   EXPECT_FALSE(change_list_loader_->IsRefreshing());
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_LT(0, changestamp);
+  std::string start_page_token;
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_FALSE(start_page_token.empty());
   EXPECT_EQ(1, drive_service_->team_drive_list_load_count());
   EXPECT_EQ(1, drive_service_->file_list_load_count());
   EXPECT_EQ(1, drive_service_->about_resource_load_count());
@@ -253,13 +254,12 @@
 
   // Reset loader.
   about_resource_loader_.reset(new AboutResourceLoader(scheduler_.get()));
-  change_list_loader_.reset(
-      new ChangeListLoader(logger_.get(),
-                           base::ThreadTaskRunnerHandle::Get().get(),
-                           metadata_.get(),
-                           scheduler_.get(),
-                           about_resource_loader_.get(),
-                           loader_controller_.get()));
+  start_page_token_loader_.reset(new StartPageTokenLoader(
+      drive::util::kTeamDriveIdDefaultCorpus, scheduler_.get()));
+  change_list_loader_.reset(new ChangeListLoader(
+      logger_.get(), base::ThreadTaskRunnerHandle::Get().get(), metadata_.get(),
+      scheduler_.get(), about_resource_loader_.get(),
+      start_page_token_loader_.get(), loader_controller_.get()));
 
   // Add a file to the service.
   std::unique_ptr<google_apis::FileResource> gdata_entry =
@@ -282,9 +282,10 @@
   EXPECT_EQ(1, observer.initial_load_complete_count());
 
   // Update should be checked by Load().
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(drive_service_->about_resource().largest_change_id(), changestamp);
+  std::string start_page_token;
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_EQ(drive_service_->start_page_token().start_page_token(),
+            start_page_token);
   EXPECT_EQ(1, drive_service_->change_list_load_count());
   EXPECT_EQ(1, observer.load_from_server_complete_count());
   EXPECT_TRUE(
@@ -307,9 +308,9 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(FILE_ERROR_FAILED,
             check_for_updates_error);  // Callback was not run.
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(0, changestamp);
+  std::string start_page_token;
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_TRUE(start_page_token.empty());
   EXPECT_EQ(0, drive_service_->file_list_load_count());
   EXPECT_EQ(0, drive_service_->about_resource_load_count());
 
@@ -328,13 +329,11 @@
   EXPECT_FALSE(change_list_loader_->IsRefreshing());
   EXPECT_EQ(FILE_ERROR_OK, load_error);
   EXPECT_EQ(FILE_ERROR_OK, check_for_updates_error);
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_LT(0, changestamp);
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_FALSE(start_page_token.empty());
   EXPECT_EQ(1, drive_service_->file_list_load_count());
 
-  int64_t previous_changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK,
-            metadata_->GetLargestChangestamp(&previous_changestamp));
+  std::string previous_start_page_token = start_page_token;
   // CheckForUpdates() results in no update.
   change_list_loader_->CheckForUpdates(
       google_apis::test_util::CreateCopyResultCallback(
@@ -342,8 +341,8 @@
   EXPECT_TRUE(change_list_loader_->IsRefreshing());
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(change_list_loader_->IsRefreshing());
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(previous_changestamp, changestamp);
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_EQ(previous_start_page_token, start_page_token);
 
   // Add a file to the service.
   std::unique_ptr<google_apis::FileResource> gdata_entry =
@@ -358,8 +357,8 @@
   EXPECT_TRUE(change_list_loader_->IsRefreshing());
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(change_list_loader_->IsRefreshing());
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_LT(previous_changestamp, changestamp);
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_NE(previous_start_page_token, start_page_token);
   EXPECT_EQ(1, observer.load_from_server_complete_count());
   EXPECT_TRUE(
       observer.changed_files().CountDirectory(util::GetDriveMyDriveRootPath()));
diff --git a/components/drive/change_list_processor_unittest.cc b/components/drive/change_list_processor_unittest.cc
index 6f2e4946..ee19eea 100644
--- a/components/drive/change_list_processor_unittest.cc
+++ b/components/drive/change_list_processor_unittest.cc
@@ -32,7 +32,7 @@
 
 namespace {
 
-constexpr int64_t kBaseResourceListChangestamp = 123;
+constexpr char kBaseStartPageToken[] = "123";
 constexpr char kRootId[] = "fake_root";
 
 enum FileOrDirectory {
@@ -100,7 +100,7 @@
   change_lists[0]->mutable_entries()->push_back(file);
   change_lists[0]->mutable_parent_resource_ids()->push_back("");
 
-  change_lists[0]->set_largest_changestamp(kBaseResourceListChangestamp);
+  change_lists[0]->set_new_start_page_token(kBaseStartPageToken);
   return change_lists;
 }
 
@@ -127,54 +127,30 @@
     ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());
   }
 
-  // Applies the |changes| to |metadata_| as a full resource list of changestamp
-  // |kBaseResourceListChangestamp|.
+  // Applies the |changes| to |metadata_| as a full resource list of
+  // start page token |kBaseStartPageToken|.
   FileError ApplyFullResourceList(
       std::vector<std::unique_ptr<ChangeList>> changes) {
-    std::unique_ptr<google_apis::AboutResource> about_resource(
-        new google_apis::AboutResource);
-    about_resource->set_largest_change_id(kBaseResourceListChangestamp);
-    about_resource->set_root_folder_id(kRootId);
-
     ChangeListProcessor processor(metadata_.get(), nullptr);
-    return processor.ApplyUserChangeList(std::move(about_resource),
+    return processor.ApplyUserChangeList(kBaseStartPageToken, kRootId,
                                          std::move(changes),
                                          false /* is_delta_update */);
   }
 
   // Applies |changes| to |metadata_| as a delta update. The |changes| are
   // treated as user's changelists. Delta changelists should contain their
-  // changestamp in themselves.
+  // start page token in themselves.
   FileError ApplyUserChangeList(
       std::vector<std::unique_ptr<ChangeList>> changes,
       FileChange* changed_files) {
-    std::unique_ptr<google_apis::AboutResource> about_resource(
-        new google_apis::AboutResource);
-    about_resource->set_largest_change_id(kBaseResourceListChangestamp);
-    about_resource->set_root_folder_id(kRootId);
-
     ChangeListProcessor processor(metadata_.get(), nullptr);
-    FileError error = processor.ApplyUserChangeList(std::move(about_resource),
-                                                    std::move(changes),
+    FileError error = processor.ApplyUserChangeList(kBaseStartPageToken,
+                                                    kRootId, std::move(changes),
                                                     true /* is_delta_update */);
     *changed_files = processor.changed_files();
     return error;
   }
 
-  // Applies the |changes| to |metadata_| as a delta update. Delta changelists
-  // should contain their changestamp in themselves. |team_drive_id| is the
-  // Team Drive's ID which is giving the change.
-  FileError ApplyTeamDriveChangeList(
-      const std::string& team_drive_id,
-      std::vector<std::unique_ptr<ChangeList>> changes,
-      FileChange* changed_files) {
-    ChangeListProcessor processor(metadata_.get(), nullptr);
-    FileError error =
-        processor.ApplyTeamDriveChangeList(team_drive_id, std::move(changes));
-    *changed_files = processor.changed_files();
-    return error;
-  }
-
   // Gets the resource entry for the path from |metadata_| synchronously.
   // Returns null if the entry does not exist.
   std::unique_ptr<ResourceEntry> GetResourceEntry(const std::string& path) {
@@ -237,9 +213,9 @@
               entry->file_info().is_directory() ? DIRECTORY : FILE);
   }
 
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(kBaseResourceListChangestamp, changestamp);
+  std::string start_page_token;
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_EQ(kBaseStartPageToken, start_page_token);
 }
 
 TEST_F(ChangeListProcessorTest, DeltaFileAddedInNewDirectory) {
@@ -260,7 +236,7 @@
   change_lists[0]->mutable_parent_resource_ids()->push_back(
       new_folder.resource_id());
 
-  change_lists[0]->set_largest_changestamp(16730);
+  change_lists[0]->set_new_start_page_token("16730");
 
   // Apply the changelist and check the effect.
   EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
@@ -269,9 +245,9 @@
   EXPECT_EQ(FILE_ERROR_OK,
             ApplyUserChangeList(std::move(change_lists), &changed_files));
 
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(16730, changestamp);
+  std::string start_page_token;
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_EQ("16730", start_page_token);
   EXPECT_TRUE(GetResourceEntry("drive/root/New Directory"));
   EXPECT_TRUE(GetResourceEntry(
       "drive/root/New Directory/File in new dir.txt"));
@@ -283,88 +259,6 @@
       base::FilePath::FromUTF8Unsafe("drive/root/New Directory")));
 }
 
-TEST_F(ChangeListProcessorTest, DeltaFileAddedInNewDirectoryByTeamDriveChange) {
-  constexpr int64_t kBaseResourceListChangestampForTeamDrive = 12;
-  constexpr char kTeamDriveId[] = "theTeamDriveId";
-
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  // Set up a Team Drive root directory.
-  ResourceEntry team_drive;
-  team_drive.set_title("My Team Drive");
-  team_drive.set_resource_id(kTeamDriveId);
-  team_drive.set_parent_local_id(util::kDriveTeamDrivesDirLocalId);
-  team_drive.mutable_file_info()->set_is_directory(true);
-
-  change_lists.push_back(std::make_unique<ChangeList>());
-  change_lists[0]->mutable_entries()->push_back(team_drive);
-  change_lists[0]->set_largest_changestamp(kBaseResourceListChangestamp);
-  change_lists[0]->mutable_parent_resource_ids()->push_back("");
-
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-  FileChange changed_files;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files));
-  std::unique_ptr<ResourceEntry> team_drive_root =
-      GetResourceEntry("drive/team_drives/My Team Drive");
-  ASSERT_TRUE(team_drive_root);
-  EXPECT_FALSE(team_drive_root->local_id().empty());
-  change_lists.clear();
-  change_lists.push_back(std::make_unique<ChangeList>());
-
-  // Add files to the Team Drive directory.
-  ResourceEntry new_folder;
-  new_folder.set_resource_id("new_folder_resource_id");
-  new_folder.set_title("New Directory");
-  new_folder.mutable_file_info()->set_is_directory(true);
-  change_lists[0]->mutable_entries()->push_back(new_folder);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(kTeamDriveId);
-
-  ResourceEntry new_file;
-  new_file.set_resource_id("file_added_in_new_dir_id");
-  new_file.set_title("File in new dir.txt");
-  change_lists[0]->mutable_entries()->push_back(new_file);
-  change_lists[0]->mutable_parent_resource_ids()->push_back(
-      new_folder.resource_id());
-
-  change_lists[0]->set_largest_changestamp(
-      kBaseResourceListChangestampForTeamDrive);
-
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyTeamDriveChangeList(kTeamDriveId, std::move(change_lists),
-                                     &changed_files));
-
-  std::unique_ptr<ResourceEntry> result_team_drive_root =
-      GetResourceEntry("drive/team_drives/My Team Drive");
-  EXPECT_EQ(kBaseResourceListChangestampForTeamDrive,
-            result_team_drive_root->directory_specific_info().changestamp());
-
-  // The "My Drive" root directory entry should be kept unchanged.
-  std::unique_ptr<ResourceEntry> result_drive_root =
-      GetResourceEntry("drive/root");
-  EXPECT_EQ(kBaseResourceListChangestamp,
-            result_drive_root->directory_specific_info().changestamp());
-
-  // The largest changestamp in the header, which holds next change ID of the
-  // user's change list, should also be kept unchanged. Otherwise loading Team
-  // Drive's change list would break the syncing of the user's change.
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(kBaseResourceListChangestamp, changestamp);
-
-  EXPECT_TRUE(
-      GetResourceEntry("drive/team_drives/My Team Drive/New Directory"));
-  EXPECT_TRUE(GetResourceEntry(
-      "drive/team_drives/My Team Drive/New Directory/File in new dir.txt"));
-
-  EXPECT_EQ(2U, changed_files.size());
-  EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe(
-      "drive/team_drives/My Team Drive/New Directory/File in new dir.txt")));
-  EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe(
-      "drive/team_drives/My Team Drive/New Directory")));
-}
-
 TEST_F(ChangeListProcessorTest, DeltaDirMovedFromRootToDirectory) {
   std::vector<std::unique_ptr<ChangeList>> change_lists;
   change_lists.push_back(std::make_unique<ChangeList>());
@@ -377,7 +271,7 @@
   change_lists[0]->mutable_parent_resource_ids()->push_back(
       "sub_dir_folder_2_self_link");
 
-  change_lists[0]->set_largest_changestamp(16809);
+  change_lists[0]->set_new_start_page_token("16809");
 
   // Apply the changelist and check the effect.
   EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
@@ -386,9 +280,9 @@
   EXPECT_EQ(FILE_ERROR_OK,
             ApplyUserChangeList(std::move(change_lists), &changed_files));
 
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(16809, changestamp);
+  std::string start_page_token;
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_EQ("16809", start_page_token);
   EXPECT_FALSE(GetResourceEntry("drive/root/Directory 1"));
   EXPECT_TRUE(GetResourceEntry(
       "drive/root/Directory 2 excludeDir-test/Directory 1"));
@@ -414,7 +308,7 @@
   change_lists[0]->mutable_entries()->push_back(entry);
   change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
 
-  change_lists[0]->set_largest_changestamp(16815);
+  change_lists[0]->set_new_start_page_token("16815");
 
   // Apply the changelist and check the effect.
   EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
@@ -422,9 +316,9 @@
   EXPECT_EQ(FILE_ERROR_OK,
             ApplyUserChangeList(std::move(change_lists), &changed_files));
 
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(16815, changestamp);
+  std::string start_page_token;
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_EQ("16815", start_page_token);
   EXPECT_FALSE(GetResourceEntry(
       "drive/root/Directory 1/SubDirectory File 1.txt"));
   EXPECT_TRUE(GetResourceEntry("drive/root/SubDirectory File 1.txt"));
@@ -447,7 +341,7 @@
   change_lists[0]->mutable_parent_resource_ids()->push_back(
       "1_folder_resource_id");
 
-  change_lists[0]->set_largest_changestamp(16767);
+  change_lists[0]->set_new_start_page_token("16767");
 
   // Apply the changelist and check the effect.
   EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
@@ -460,9 +354,9 @@
   EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe(
       "drive/root/Directory 1/New SubDirectory File 1.txt")));
 
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(16767, changestamp);
+  std::string start_page_token;
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_EQ("16767", start_page_token);
   EXPECT_FALSE(GetResourceEntry(
       "drive/root/Directory 1/SubDirectory File 1.txt"));
   std::unique_ptr<ResourceEntry> new_entry(
@@ -486,7 +380,7 @@
   change_lists[0]->mutable_entries()->push_back(entry);
   change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
 
-  change_lists[0]->set_largest_changestamp(16683);
+  change_lists[0]->set_new_start_page_token("16683");
 
   // Apply.
   EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
@@ -494,9 +388,9 @@
   EXPECT_EQ(FILE_ERROR_OK,
             ApplyUserChangeList(std::move(change_lists), &changed_files));
 
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(16683, changestamp);
+  std::string start_page_token;
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_EQ("16683", start_page_token);
   EXPECT_TRUE(GetResourceEntry("drive/root/Added file.txt"));
   EXPECT_EQ(1U, changed_files.size());
   EXPECT_TRUE(changed_files.count(
@@ -509,13 +403,13 @@
   change_lists[0]->mutable_entries()->push_back(entry);
   change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
 
-  change_lists[0]->set_largest_changestamp(16687);
+  change_lists[0]->set_new_start_page_token("16687");
 
   // Apply.
   EXPECT_EQ(FILE_ERROR_OK,
             ApplyUserChangeList(std::move(change_lists), &changed_files));
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(16687, changestamp);
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_EQ("16687", start_page_token);
   EXPECT_FALSE(GetResourceEntry("drive/root/Added file.txt"));
   EXPECT_EQ(1U, changed_files.size());
   EXPECT_TRUE(changed_files.count(
@@ -535,16 +429,16 @@
   change_lists[0]->mutable_parent_resource_ids()->push_back(
       "1_folder_resource_id");
 
-  change_lists[0]->set_largest_changestamp(16730);
+  change_lists[0]->set_new_start_page_token("16730");
 
   // Apply.
   EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
   FileChange changed_files;
   EXPECT_EQ(FILE_ERROR_OK,
             ApplyUserChangeList(std::move(change_lists), &changed_files));
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(16730, changestamp);
+  std::string start_page_token;
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_EQ("16730", start_page_token);
   EXPECT_TRUE(GetResourceEntry("drive/root/Directory 1/Added file.txt"));
 
   EXPECT_EQ(1U, changed_files.size());
@@ -559,13 +453,13 @@
   change_lists[0]->mutable_parent_resource_ids()->push_back(
       "1_folder_resource_id");
 
-  change_lists[0]->set_largest_changestamp(16770);
+  change_lists[0]->set_new_start_page_token("16770");
 
   // Apply.
   EXPECT_EQ(FILE_ERROR_OK,
             ApplyUserChangeList(std::move(change_lists), &changed_files));
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(16770, changestamp);
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_EQ("16770", start_page_token);
   EXPECT_FALSE(GetResourceEntry("drive/root/Directory 1/Added file.txt"));
 
   EXPECT_EQ(1U, changed_files.size());
@@ -597,7 +491,7 @@
   change_lists[0]->mutable_entries()->push_back(directory);
   change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
 
-  change_lists[0]->set_largest_changestamp(16730);
+  change_lists[0]->set_new_start_page_token("16730");
 
   // Apply the changelist and check the effect.
   EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
@@ -605,9 +499,9 @@
   EXPECT_EQ(FILE_ERROR_OK,
             ApplyUserChangeList(std::move(change_lists), &changed_files));
 
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(16730, changestamp);
+  std::string start_page_token;
+  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token));
+  EXPECT_EQ("16730", start_page_token);
   EXPECT_FALSE(GetResourceEntry("drive/root/New Directory/new_pdf_file.pdf"));
 
   EXPECT_TRUE(changed_files.empty());
@@ -639,13 +533,13 @@
   ResourceEntry root;
   EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
       util::GetDriveMyDriveRootPath(), &root));
-  const int64_t kNewChangestamp = 12345;
+  const std::string kNewStartpageToken = "12345";
   ResourceEntryVector refreshed_entries;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ChangeListProcessor::RefreshDirectory(
-                metadata_.get(),
-                DirectoryFetchInfo(root.local_id(), kRootId, kNewChangestamp),
-                std::move(change_list), &refreshed_entries));
+  EXPECT_EQ(FILE_ERROR_OK, ChangeListProcessor::RefreshDirectory(
+                               metadata_.get(),
+                               DirectoryFetchInfo(root.local_id(), kRootId,
+                                                  kNewStartpageToken),
+                               std::move(change_list), &refreshed_entries));
 
   // "new_file" should be added.
   ResourceEntry entry;
@@ -676,13 +570,13 @@
   ResourceEntry root;
   EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(
       util::GetDriveMyDriveRootPath(), &root));
-  const int64_t kNewChangestamp = 12345;
+  const std::string kNewStartpageToken = "12345";
   ResourceEntryVector refreshed_entries;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ChangeListProcessor::RefreshDirectory(
-                metadata_.get(),
-                DirectoryFetchInfo(root.local_id(), kRootId, kNewChangestamp),
-                std::move(change_list), &refreshed_entries));
+  EXPECT_EQ(FILE_ERROR_OK, ChangeListProcessor::RefreshDirectory(
+                               metadata_.get(),
+                               DirectoryFetchInfo(root.local_id(), kRootId,
+                                                  kNewStartpageToken),
+                               std::move(change_list), &refreshed_entries));
 
   // "new_file" should not be added.
   ResourceEntry entry;
@@ -704,7 +598,7 @@
   new_file.set_resource_id("new_file_id");
   change_lists[0]->mutable_entries()->push_back(new_file);
   change_lists[0]->mutable_parent_resource_ids()->push_back("nonexisting");
-  change_lists[0]->set_largest_changestamp(kBaseResourceListChangestamp + 1);
+  change_lists[0]->set_new_start_page_token("123");
 
   FileChange changed_files;
   EXPECT_EQ(FILE_ERROR_OK,
@@ -732,7 +626,7 @@
 
   change_lists[0]->mutable_entries()->push_back(new_file_remote);
   change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId);
-  change_lists[0]->set_largest_changestamp(kBaseResourceListChangestamp + 1);
+  change_lists[0]->set_new_start_page_token("123");
 
   // Add the same file locally, but with a different name, a dirty metadata
   // state, and a newer modification date.
@@ -761,72 +655,5 @@
   EXPECT_EQ(new_file_local.title(), entry.title());
 }
 
-TEST_F(ChangeListProcessorTest, DeltaTeamDriveChange) {
-  const char kTeamDriveId[] = "ID_OF_TEAM_DRIVE";
-  const char kOldName[] = "Old Name";
-  const char kNewName[] = "New Name";
-
-  ResourceEntry team_drive;
-  team_drive.set_title(kOldName);
-  team_drive.set_resource_id(kTeamDriveId);
-  team_drive.set_parent_local_id(util::kDriveTeamDrivesDirLocalId);
-
-  std::vector<std::unique_ptr<ChangeList>> change_lists;
-  change_lists.push_back(std::make_unique<ChangeList>());
-  change_lists[0]->mutable_entries()->push_back(team_drive);
-  change_lists[0]->set_largest_changestamp(kBaseResourceListChangestamp + 1);
-  change_lists[0]->mutable_parent_resource_ids()->push_back("");
-
-  // Apply the changelist and check the effect.
-  EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList()));
-
-  FileChange changed_files;
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files));
-
-  int64_t changestamp = 0;
-  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetLargestChangestamp(&changestamp));
-  EXPECT_EQ(kBaseResourceListChangestamp + 1, changestamp);
-
-  ResourceEntry entry;
-  EXPECT_EQ(
-      FILE_ERROR_OK,
-      metadata_->GetResourceEntryByPath(
-          util::GetDriveTeamDrivesRootPath().AppendASCII(kOldName), &entry));
-  EXPECT_EQ(kTeamDriveId, entry.resource_id());
-
-  // Change to Team Drive entry is also conted as a file change.
-  EXPECT_EQ(1U, changed_files.size());
-
-  // Second change, which updates Team Drive name
-  change_lists.clear();
-  change_lists.push_back(std::make_unique<ChangeList>());
-  team_drive.set_title(kNewName);
-  change_lists[0]->mutable_entries()->push_back(team_drive);
-  change_lists[0]->set_largest_changestamp(kBaseResourceListChangestamp + 2);
-  change_lists[0]->mutable_parent_resource_ids()->push_back("");
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files));
-  EXPECT_EQ(
-      FILE_ERROR_OK,
-      metadata_->GetResourceEntryByPath(
-          util::GetDriveTeamDrivesRootPath().AppendASCII(kNewName), &entry));
-  EXPECT_EQ(kTeamDriveId, entry.resource_id());
-
-  // Delete the team drive.
-  change_lists.clear();
-  change_lists.push_back(std::make_unique<ChangeList>());
-  change_lists[0]->set_largest_changestamp(kBaseResourceListChangestamp + 3);
-  team_drive.set_deleted(true);
-  change_lists[0]->mutable_parent_resource_ids()->push_back("");
-  change_lists[0]->mutable_entries()->push_back(team_drive);
-  EXPECT_EQ(FILE_ERROR_OK,
-            ApplyUserChangeList(std::move(change_lists), &changed_files));
-  EXPECT_EQ(
-      FILE_ERROR_NOT_FOUND,
-      metadata_->GetResourceEntryByPath(
-          util::GetDriveTeamDrivesRootPath().AppendASCII(kNewName), &entry));
-}
-
 }  // namespace internal
 }  // namespace drive
diff --git a/components/drive/chromeos/change_list_loader.cc b/components/drive/chromeos/change_list_loader.cc
index 94a248d5..ae2f23c5 100644
--- a/components/drive/chromeos/change_list_loader.cc
+++ b/components/drive/chromeos/change_list_loader.cc
@@ -6,7 +6,6 @@
 
 #include <stddef.h>
 
-#include <memory>
 #include <set>
 #include <utility>
 
@@ -23,6 +22,7 @@
 #include "components/drive/chromeos/change_list_processor.h"
 #include "components/drive/chromeos/loader_controller.h"
 #include "components/drive/chromeos/resource_metadata.h"
+#include "components/drive/chromeos/start_page_token_loader.h"
 #include "components/drive/drive_api_util.h"
 #include "components/drive/event_logger.h"
 #include "components/drive/file_system_core_util.h"
@@ -168,9 +168,12 @@
 // Fetches the delta changes since |start_change_id|.
 class DeltaFeedFetcher : public ChangeListLoader::FeedFetcher {
  public:
-  DeltaFeedFetcher(JobScheduler* scheduler, int64_t start_change_id)
+  DeltaFeedFetcher(JobScheduler* scheduler,
+                   const std::string& team_drive_id,
+                   const std::string& start_page_token)
       : scheduler_(scheduler),
-        start_change_id_(start_change_id),
+        team_drive_id_(team_drive_id),
+        start_page_token_(start_page_token),
         weak_ptr_factory_(this) {}
 
   ~DeltaFeedFetcher() override = default;
@@ -180,7 +183,7 @@
     DCHECK(callback);
 
     scheduler_->GetChangeList(
-        start_change_id_,
+        team_drive_id_, start_page_token_,
         base::Bind(&DeltaFeedFetcher::OnChangeListFetched,
                    weak_ptr_factory_.GetWeakPtr(), callback));
   }
@@ -218,7 +221,8 @@
   }
 
   JobScheduler* scheduler_;
-  int64_t start_change_id_;
+  const std::string team_drive_id_;
+  const std::string start_page_token_;
   std::vector<std::unique_ptr<ChangeList>> change_lists_;
   THREAD_CHECKER(thread_checker_);
   base::WeakPtrFactory<DeltaFeedFetcher> weak_ptr_factory_;
@@ -227,13 +231,13 @@
 
 }  // namespace
 
-
 ChangeListLoader::ChangeListLoader(
     EventLogger* logger,
     base::SequencedTaskRunner* blocking_task_runner,
     ResourceMetadata* resource_metadata,
     JobScheduler* scheduler,
     AboutResourceLoader* about_resource_loader,
+    StartPageTokenLoader* start_page_token_loader,
     LoaderController* loader_controller)
     : logger_(logger),
       blocking_task_runner_(blocking_task_runner),
@@ -241,10 +245,10 @@
       resource_metadata_(resource_metadata),
       scheduler_(scheduler),
       about_resource_loader_(about_resource_loader),
+      start_page_token_loader_(start_page_token_loader),
       loader_controller_(loader_controller),
       loaded_(false),
-      weak_ptr_factory_(this) {
-}
+      weak_ptr_factory_(this) {}
 
 ChangeListLoader::~ChangeListLoader() {
   in_shutdown_->Set();
@@ -279,9 +283,9 @@
   if (!loaded_ && !IsRefreshing())
     return;
 
-  // For each CheckForUpdates() request, always refresh the changestamp info.
-  about_resource_loader_->UpdateAboutResource(
-      base::Bind(&ChangeListLoader::OnAboutResourceUpdated,
+  // For each CheckForUpdates() request, always refresh the start_page_token.
+  start_page_token_loader_->UpdateStartPageToken(
+      base::Bind(&ChangeListLoader::OnStartPageTokenLoaderUpdated,
                  weak_ptr_factory_.GetWeakPtr()));
 
   if (IsRefreshing()) {
@@ -321,31 +325,29 @@
     return;
 
   // Check the current status of local metadata, and start loading if needed.
-  int64_t* local_changestamp = new int64_t(0);
+  std::string* start_page_token = new std::string();
   base::PostTaskAndReplyWithResult(
-      blocking_task_runner_.get(),
-      FROM_HERE,
-      base::Bind(&ResourceMetadata::GetLargestChangestamp,
-                 base::Unretained(resource_metadata_),
-                 local_changestamp),
-      base::Bind(&ChangeListLoader::LoadAfterGetLargestChangestamp,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 is_initial_load,
-                 base::Owned(local_changestamp)));
+      blocking_task_runner_.get(), FROM_HERE,
+      base::Bind(&ResourceMetadata::GetStartPageToken,
+                 base::Unretained(resource_metadata_), start_page_token),
+      base::Bind(&ChangeListLoader::LoadAfterGetLocalStartPageToken,
+                 weak_ptr_factory_.GetWeakPtr(), is_initial_load,
+                 base::Owned(start_page_token)));
 }
 
-void ChangeListLoader::LoadAfterGetLargestChangestamp(
+void ChangeListLoader::LoadAfterGetLocalStartPageToken(
     bool is_initial_load,
-    const int64_t* local_changestamp,
+    const std::string* local_start_page_token,
     FileError error) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(local_start_page_token);
 
   if (error != FILE_ERROR_OK) {
     OnChangeListLoadComplete(error);
     return;
   }
 
-  if (is_initial_load && *local_changestamp > 0) {
+  if (is_initial_load && !local_start_page_token->empty()) {
     // The local data is usable. Flush callbacks to tell loading was successful.
     OnChangeListLoadComplete(FILE_ERROR_OK);
 
@@ -356,12 +358,11 @@
 
   about_resource_loader_->GetAboutResource(
       base::Bind(&ChangeListLoader::LoadAfterGetAboutResource,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 *local_changestamp));
+                 weak_ptr_factory_.GetWeakPtr(), *local_start_page_token));
 }
 
 void ChangeListLoader::LoadAfterGetAboutResource(
-    int64_t local_changestamp,
+    const std::string& local_start_page_token,
     google_apis::DriveApiErrorCode status,
     std::unique_ptr<google_apis::AboutResource> about_resource) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -375,19 +376,41 @@
 
   DCHECK(about_resource);
 
+  start_page_token_loader_->GetStartPageToken(
+      base::Bind(&ChangeListLoader::LoadAfterGetStartPageToken,
+                 weak_ptr_factory_.GetWeakPtr(), local_start_page_token,
+                 about_resource->root_folder_id()));
+}
+
+void ChangeListLoader::LoadAfterGetStartPageToken(
+    const std::string& local_start_page_token,
+    const std::string& root_folder_id,
+    google_apis::DriveApiErrorCode status,
+    std::unique_ptr<google_apis::StartPageToken> start_page_token) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+  FileError error = GDataToFileError(status);
+  if (error != FILE_ERROR_OK) {
+    OnChangeListLoadComplete(error);
+    return;
+  }
+
+  DCHECK(start_page_token);
+
   // Fetch Team Drive before File list, so that files can be stored under root
   // directories of each Team Drive like /team_drive/My Team Drive/.
   if (google_apis::GetTeamDrivesIntegrationSwitch() ==
       google_apis::TEAM_DRIVES_INTEGRATION_ENABLED) {
     change_feed_fetcher_ = std::make_unique<TeamDriveListFetcher>(scheduler_);
 
-    change_feed_fetcher_->Run(
-        base::Bind(&ChangeListLoader::LoadChangeListFromServer,
-                   weak_ptr_factory_.GetWeakPtr(),
-                   base::Passed(&about_resource), local_changestamp));
+    change_feed_fetcher_->Run(base::Bind(
+        &ChangeListLoader::LoadChangeListFromServer,
+        weak_ptr_factory_.GetWeakPtr(), start_page_token->start_page_token(),
+        local_start_page_token, root_folder_id));
   } else {
     // If there are no team drives listings, the changelist starts as empty.
-    LoadChangeListFromServer(std::move(about_resource), local_changestamp,
+    LoadChangeListFromServer(start_page_token->start_page_token(),
+                             local_start_page_token, root_folder_id,
                              FILE_ERROR_OK,
                              std::vector<std::unique_ptr<ChangeList>>());
   }
@@ -402,10 +425,9 @@
       observer.OnInitialLoadComplete();
   }
 
-  for (size_t i = 0; i < pending_load_callback_.size(); ++i) {
-    base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::Bind(pending_load_callback_[i], error));
+  for (auto& callback : pending_load_callback_) {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                  base::Bind(callback, error));
   }
   pending_load_callback_.clear();
 
@@ -416,50 +438,43 @@
   }
 }
 
-void ChangeListLoader::OnAboutResourceUpdated(
+void ChangeListLoader::OnStartPageTokenLoaderUpdated(
     google_apis::DriveApiErrorCode error,
-    std::unique_ptr<google_apis::AboutResource> resource) {
+    std::unique_ptr<google_apis::StartPageToken> start_page_token) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   if (drive::GDataToFileError(error) != drive::FILE_ERROR_OK) {
     logger_->Log(logging::LOG_ERROR,
-                 "Failed to update the about resource: %s",
+                 "Failed to update the start page token: %s",
                  google_apis::DriveApiErrorCodeToString(error).c_str());
     return;
   }
   logger_->Log(logging::LOG_INFO,
-               "About resource updated to: %s",
-               base::Int64ToString(resource->largest_change_id()).c_str());
+               "Start page token for default corpus updated to: %s",
+               start_page_token->start_page_token().c_str());
 }
 
 void ChangeListLoader::LoadChangeListFromServer(
-    std::unique_ptr<google_apis::AboutResource> about_resource,
-    int64_t local_changestamp,
+    const std::string& remote_start_page_token,
+    const std::string& local_start_page_token,
+    const std::string& root_resource_id,
     FileError error,
     std::vector<std::unique_ptr<ChangeList>> team_drives_change_lists) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  DCHECK(about_resource);
 
   if (error != FILE_ERROR_OK) {
     OnChangeListLoadComplete(error);
     return;
   }
 
-  int64_t remote_changestamp = about_resource->largest_change_id();
-  int64_t start_changestamp = local_changestamp > 0 ? local_changestamp + 1 : 0;
-  if (local_changestamp >= remote_changestamp) {
-    if (local_changestamp > remote_changestamp) {
-      LOG(WARNING) << "Local resource metadata is fresher than server, "
-                   << "local = " << local_changestamp
-                   << ", server = " << remote_changestamp;
-    }
-
+  if (local_start_page_token == remote_start_page_token) {
     // If there are team drives change lists, update those without running a
     // feed fetcher.
     if (!team_drives_change_lists.empty()) {
       LoadChangeListFromServerAfterLoadChangeList(
-          std::move(about_resource), true, std::move(team_drives_change_lists),
-          FILE_ERROR_OK, std::vector<std::unique_ptr<ChangeList>>());
+          local_start_page_token, root_resource_id, true,
+          std::move(team_drives_change_lists), FILE_ERROR_OK,
+          std::vector<std::unique_ptr<ChangeList>>());
       return;
     }
 
@@ -469,30 +484,29 @@
   }
 
   // Set up feed fetcher.
-  bool is_delta_update = start_changestamp != 0;
+  bool is_delta_update = !local_start_page_token.empty();
   if (is_delta_update) {
-    change_feed_fetcher_ =
-        std::make_unique<DeltaFeedFetcher>(scheduler_, start_changestamp);
+    change_feed_fetcher_.reset(
+        new DeltaFeedFetcher(scheduler_, drive::util::kTeamDriveIdDefaultCorpus,
+                             local_start_page_token));
   } else {
-    change_feed_fetcher_ = std::make_unique<FullFeedFetcher>(scheduler_);
+    change_feed_fetcher_.reset(new FullFeedFetcher(scheduler_));
   }
 
-  // Make a copy of cached_about_resource_ to remember at which changestamp we
-  // are fetching change list.
-  change_feed_fetcher_->Run(
-      base::Bind(&ChangeListLoader::LoadChangeListFromServerAfterLoadChangeList,
-                 weak_ptr_factory_.GetWeakPtr(), base::Passed(&about_resource),
-                 is_delta_update, base::Passed(&team_drives_change_lists)));
+  change_feed_fetcher_->Run(base::Bind(
+      &ChangeListLoader::LoadChangeListFromServerAfterLoadChangeList,
+      weak_ptr_factory_.GetWeakPtr(), remote_start_page_token, root_resource_id,
+      is_delta_update, base::Passed(&team_drives_change_lists)));
 }
 
 void ChangeListLoader::LoadChangeListFromServerAfterLoadChangeList(
-    std::unique_ptr<google_apis::AboutResource> about_resource,
+    const std::string& start_page_token,
+    const std::string& root_resource_id,
     bool is_delta_update,
     std::vector<std::unique_ptr<ChangeList>> team_drives_change_lists,
     FileError error,
     std::vector<std::unique_ptr<ChangeList>> change_lists) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  DCHECK(about_resource);
 
   // Delete the fetcher first.
   change_feed_fetcher_.reset();
@@ -525,9 +539,9 @@
       &drive::util::RunAsyncTask, base::RetainedRef(blocking_task_runner_),
       FROM_HERE,
       base::Bind(&ChangeListProcessor::ApplyUserChangeList,
-                 base::Unretained(change_list_processor),
-                 base::Passed(&about_resource),
-                 base::Passed(&merged_change_lists), is_delta_update),
+                 base::Unretained(change_list_processor), start_page_token,
+                 root_resource_id, base::Passed(&merged_change_lists),
+                 is_delta_update),
       base::Bind(&ChangeListLoader::LoadChangeListFromServerAfterUpdate,
                  weak_ptr_factory_.GetWeakPtr(),
                  base::Owned(change_list_processor),
diff --git a/components/drive/chromeos/change_list_loader.h b/components/drive/chromeos/change_list_loader.h
index 56f5a12..f9e71b4 100644
--- a/components/drive/chromeos/change_list_loader.h
+++ b/components/drive/chromeos/change_list_loader.h
@@ -28,6 +28,7 @@
 
 namespace google_apis {
 class AboutResource;
+class StartPageToken;
 }  // namespace google_apis
 
 namespace drive {
@@ -43,6 +44,7 @@
 class ChangeListProcessor;
 class LoaderController;
 class ResourceMetadata;
+class StartPageTokenLoader;
 
 // ChangeListLoader is used to load the change list, the full resource list,
 // and directory contents, from Google Drive API.  The class also updates the
@@ -63,6 +65,7 @@
                    ResourceMetadata* resource_metadata,
                    JobScheduler* scheduler,
                    AboutResourceLoader* about_resource_loader,
+                   StartPageTokenLoader* start_page_token_loader,
                    LoaderController* apply_task_controller);
   ~ChangeListLoader();
 
@@ -93,45 +96,53 @@
  private:
   // Starts the resource metadata loading and calls |callback| when it's done.
   void Load(const FileOperationCallback& callback);
-  void LoadAfterGetLargestChangestamp(bool is_initial_load,
-                                      const int64_t* local_changestamp,
-                                      FileError error);
+  void LoadAfterGetLocalStartPageToken(
+      bool is_initial_load,
+      const std::string* local_start_page_token,
+      FileError error);
   void LoadAfterGetAboutResource(
-      int64_t local_changestamp,
+      const std::string& local_start_page_token,
       google_apis::DriveApiErrorCode status,
       std::unique_ptr<google_apis::AboutResource> about_resource);
 
+  void LoadAfterGetStartPageToken(
+      const std::string& local_start_page_token,
+      const std::string& root_folder_id,
+      google_apis::DriveApiErrorCode status,
+      std::unique_ptr<google_apis::StartPageToken> start_page_token);
+
   // Part of Load().
   // This function should be called when the change list load is complete.
   // Flushes the callbacks for change list loading and all directory loading.
   void OnChangeListLoadComplete(FileError error);
 
-  // Called when the loading about_resource_loader_->UpdateAboutResource is
-  // completed.
-  void OnAboutResourceUpdated(
+  // Called when loading the start page token is completed.
+  void OnStartPageTokenLoaderUpdated(
       google_apis::DriveApiErrorCode error,
-      std::unique_ptr<google_apis::AboutResource> resource);
+      std::unique_ptr<google_apis::StartPageToken> start_page_token);
 
   // ================= Implementation for change list loading =================
 
   // Part of LoadFromServerIfNeeded().
-  // Starts loading the change list since |local_changestamp|, or the full
-  // resource list if |start_changestamp| is zero. If there's no changes since
-  // then, and there are no new team drives changes to apply from
+  // Starts loading the change list since |local_start_page_token|, or the full
+  // resource list if |local_start_page_token| is empty. If there's no changes
+  // since then, and there are no new team drives changes to apply from
   // team_drives_change_lists, finishes early.
   // TODO(sashab): Currently, team_drives_change_lists always contains all of
   // the team drives. Update this so team_drives_change_lists is only filled
   // when the TD flag is newly turned on or local data cleared. crbug.com/829154
   void LoadChangeListFromServer(
-      std::unique_ptr<google_apis::AboutResource> about_resource,
-      int64_t local_changestamp,
+      const std::string& remote_start_page_token,
+      const std::string& local_start_page_token,
+      const std::string& root_resource_id,
       FileError error,
       std::vector<std::unique_ptr<ChangeList>> team_drives_change_lists);
 
   // Part of LoadChangeListFromServer().
   // Called when the entire change list is loaded.
   void LoadChangeListFromServerAfterLoadChangeList(
-      std::unique_ptr<google_apis::AboutResource> about_resource,
+      const std::string& start_page_token,
+      const std::string& root_resource_id,
       bool is_delta_update,
       std::vector<std::unique_ptr<ChangeList>> team_drives_change_lists,
       FileError error,
@@ -151,12 +162,15 @@
   ResourceMetadata* resource_metadata_;  // Not owned.
   JobScheduler* scheduler_;  // Not owned.
   AboutResourceLoader* about_resource_loader_;  // Not owned.
+  StartPageTokenLoader* start_page_token_loader_;  // Not owned.
   LoaderController* loader_controller_;  // Not owned.
   base::ObserverList<ChangeListLoaderObserver> observers_;
   std::vector<FileOperationCallback> pending_load_callback_;
   FileOperationCallback pending_update_check_callback_;
 
   // Running feed fetcher.
+  // TODO(slangley): Do not make this stateful by changing the feed_fetcher
+  // to be base::Owned by the callback.
   std::unique_ptr<FeedFetcher> change_feed_fetcher_;
 
   // True if the full resource list is loaded (i.e. the resource metadata is
diff --git a/components/drive/chromeos/change_list_processor.cc b/components/drive/chromeos/change_list_processor.cc
index f904f34..f025c5d 100644
--- a/components/drive/chromeos/change_list_processor.cc
+++ b/components/drive/chromeos/change_list_processor.cc
@@ -38,9 +38,8 @@
 }  // namespace
 
 std::string DirectoryFetchInfo::ToString() const {
-  return ("local_id: " + local_id_ +
-          ", resource_id: " + resource_id_ +
-          ", changestamp: " + base::Int64ToString(changestamp_));
+  return ("local_id: " + local_id_ + ", resource_id: " + resource_id_ +
+          ", start_page_token: " + start_page_token_);
 }
 
 ChangeList::ChangeList() = default;
@@ -57,7 +56,7 @@
 
 ChangeList::ChangeList(const google_apis::ChangeList& change_list)
     : next_url_(change_list.next_link()),
-      largest_changestamp_(change_list.largest_change_id()) {
+      new_start_page_token_(change_list.new_start_page_token()) {
   const std::vector<std::unique_ptr<google_apis::ChangeResource>>& items =
       change_list.items();
   entries_.resize(items.size());
@@ -75,8 +74,7 @@
 }
 
 ChangeList::ChangeList(const google_apis::FileList& file_list)
-    : next_url_(file_list.next_link()),
-      largest_changestamp_(0) {
+    : next_url_(file_list.next_link()) {
   const std::vector<std::unique_ptr<google_apis::FileResource>>& items =
       file_list.items();
   entries_.resize(items.size());
@@ -124,30 +122,23 @@
                                          base::CancellationFlag* in_shutdown)
     : resource_metadata_(resource_metadata),
       in_shutdown_(in_shutdown),
-      changed_files_(new FileChange) {
-}
+      changed_files_(new FileChange) {}
 
 ChangeListProcessor::~ChangeListProcessor() = default;
 
 FileError ChangeListProcessor::ApplyUserChangeList(
-    std::unique_ptr<google_apis::AboutResource> about_resource,
+    const std::string& start_page_token,
+    const std::string& root_resource_id,
     std::vector<std::unique_ptr<ChangeList>> change_lists,
     bool is_delta_update) {
-  DCHECK(about_resource);
-
-  int64_t largest_changestamp = 0;
+  std::string new_start_page_token = start_page_token;
   if (is_delta_update) {
     if (!change_lists.empty()) {
-      // The changestamp appears in the first page of the change list.
-      // The changestamp does not appear in the full resource list.
-      largest_changestamp = change_lists[0]->largest_changestamp();
-      DCHECK_GE(change_lists[0]->largest_changestamp(), 0);
+      // The start_page_token appears in the first page of the change list.
+      // The start_page_token does not appear in the full resource list.
+      new_start_page_token = change_lists[0]->new_start_page_token();
+      DCHECK(!new_start_page_token.empty());
     }
-  } else {
-    largest_changestamp = about_resource->largest_change_id();
-
-    DVLOG(1) << "Root folder ID is " << about_resource->root_folder_id();
-    DCHECK(!about_resource->root_folder_id().empty());
   }
 
   ResourceEntry root;
@@ -158,7 +149,7 @@
     LOG(ERROR) << "Failed to get root entry: " << FileErrorToString(error);
     return error;
   }
-  root.set_resource_id(about_resource->root_folder_id());
+  root.set_resource_id(root_resource_id);
   error = resource_metadata_->RefreshEntry(root);
   if (error != FILE_ERROR_OK) {
     LOG(ERROR) << "Failed to update root entry: " << FileErrorToString(error);
@@ -166,15 +157,15 @@
   }
 
   ChangeListToEntryMapUMAStats uma_stats;
-  error = ApplyChangeListInternal(std::move(change_lists), largest_changestamp,
+  error = ApplyChangeListInternal(std::move(change_lists), new_start_page_token,
                                   &root, &uma_stats);
   if (error != FILE_ERROR_OK)
     return error;
 
-  // Update changestamp in the metadata header.
-  error = resource_metadata_->SetLargestChangestamp(largest_changestamp);
+  // Update start_page_token in the metadata header.
+  error = resource_metadata_->SetStartPageToken(new_start_page_token);
   if (error != FILE_ERROR_OK) {
-    DLOG(ERROR) << "SetLargestChangeStamp failed: " << FileErrorToString(error);
+    DLOG(ERROR) << "SetStartPageToken failed: " << FileErrorToString(error);
     return error;
   }
 
@@ -185,57 +176,20 @@
   return FILE_ERROR_OK;
 }
 
-FileError ChangeListProcessor::ApplyTeamDriveChangeList(
-    const std::string& team_drive_id,
-    std::vector<std::unique_ptr<ChangeList>> change_lists) {
-  DCHECK(!change_lists.empty());
-  int64_t largest_changestamp = 0;
-  // The changestamp appears in the first page of the change list.
-  // The changestamp does not appear in the full resource list.
-  largest_changestamp = change_lists[0]->largest_changestamp();
-  if (change_lists[0]->largest_changestamp() < 0) {
-    LOG(ERROR) << "Received changeList with invalid largestChangestamp: "
-               << largest_changestamp << " (team_drive_id=" << team_drive_id
-               << "). Ignored.";
-    return FILE_ERROR_FAILED;
-  }
-
-  std::string local_id;
-  FileError error =
-      resource_metadata_->GetIdByResourceId(team_drive_id, &local_id);
-  if (error != FILE_ERROR_OK) {
-    LOG(ERROR) << "Failed to get local ID of a Team Drive root entry: "
-               << FileErrorToString(error);
-    return error;
-  }
-  ResourceEntry root;
-  error = resource_metadata_->GetResourceEntryById(local_id, &root);
-  if (error != FILE_ERROR_OK) {
-    LOG(ERROR) << "Failed to get Team Drive root entry: "
-               << FileErrorToString(error);
-    return error;
-  }
-
-  ChangeListToEntryMapUMAStats uma_stats;
-  error = ApplyChangeListInternal(std::move(change_lists), largest_changestamp,
-                                  &root, &uma_stats);
-  return error;
-}
-
 FileError ChangeListProcessor::ApplyChangeListInternal(
     std::vector<std::unique_ptr<ChangeList>> change_lists,
-    int64_t largest_changestamp,
+    const std::string& start_page_token,
     ResourceEntry* root,
     ChangeListToEntryMapUMAStats* uma_stats) {
-  ConvertChangeListsToMap(std::move(change_lists), largest_changestamp,
-                          uma_stats);
+  ConvertChangeListsToMap(std::move(change_lists), start_page_token, uma_stats);
   FileError error = ApplyEntryMap(root->resource_id());
   if (error != FILE_ERROR_OK) {
     DLOG(ERROR) << "ApplyEntryMap failed: " << FileErrorToString(error);
     return error;
   }
-  // Update changestamp of the root entry.
-  root->mutable_directory_specific_info()->set_changestamp(largest_changestamp);
+  // Update start_page_token of the root entry.
+  root->mutable_directory_specific_info()->set_start_page_token(
+      start_page_token);
   error = resource_metadata_->RefreshEntry(*root);
   if (error != FILE_ERROR_OK)
     DLOG(ERROR) << "RefreshEntry failed: " << FileErrorToString(error);
@@ -244,7 +198,7 @@
 
 void ChangeListProcessor::ConvertChangeListsToMap(
     std::vector<std::unique_ptr<ChangeList>> change_lists,
-    int64_t largest_changestamp,
+    const std::string& start_page_token,
     ChangeListToEntryMapUMAStats* uma_stats) {
   for (size_t i = 0; i < change_lists.size(); ++i) {
     ChangeList* change_list = change_lists[i].get();
@@ -266,12 +220,12 @@
     }
   }
 
-  // Add the largest changestamp for directories.
+  // Add the largest start_page_token for directories.
   for (ResourceEntryMap::iterator it = entry_map_.begin();
        it != entry_map_.end(); ++it) {
     if (it->second.file_info().is_directory()) {
-      it->second.mutable_directory_specific_info()->set_changestamp(
-          largest_changestamp);
+      it->second.mutable_directory_specific_info()->set_start_page_token(
+          start_page_token);
     }
   }
 }
@@ -438,10 +392,10 @@
         error = resource_metadata_->RefreshEntry(new_entry);
       } else {
         if (entry.file_info().is_directory()) {
-          // No need to refresh, but update the changestamp.
+          // No need to refresh, but update the start_page_token.
           new_entry = existing_entry;
-          new_entry.mutable_directory_specific_info()->set_changestamp(
-              new_entry.directory_specific_info().changestamp());
+          new_entry.mutable_directory_specific_info()->set_start_page_token(
+              new_entry.directory_specific_info().start_page_token());
           error = resource_metadata_->RefreshEntry(new_entry);
         }
         DVLOG(1) << "Change was discarded for: " << entry.resource_id();
diff --git a/components/drive/chromeos/change_list_processor.h b/components/drive/chromeos/change_list_processor.h
index 2bb6cba..adf4c14 100644
--- a/components/drive/chromeos/change_list_processor.h
+++ b/components/drive/chromeos/change_list_processor.h
@@ -23,7 +23,6 @@
 }  // namespace base
 
 namespace google_apis {
-class AboutResource;
 class ChangeList;
 class FileList;
 class TeamDriveList;
@@ -42,13 +41,14 @@
 // This object is copyable.
 class DirectoryFetchInfo {
  public:
-  DirectoryFetchInfo() : changestamp_(0) {}
+  DirectoryFetchInfo() = default;
+
   DirectoryFetchInfo(const std::string& local_id,
                      const std::string& resource_id,
-                     int64_t changestamp)
+                     const std::string& start_page_token)
       : local_id_(local_id),
         resource_id_(resource_id),
-        changestamp_(changestamp) {}
+        start_page_token_(start_page_token) {}
 
   // Returns true if the object is empty.
   bool empty() const { return local_id_.empty(); }
@@ -59,9 +59,9 @@
   // Resource ID of the directory.
   const std::string& resource_id() const { return resource_id_; }
 
-  // Changestamp of the directory. The changestamp is used to determine if
-  // the directory contents should be fetched.
-  int64_t changestamp() const { return changestamp_; }
+  // Start Page Token of the directory. The start page token is used to
+  // determine if the directory contents should be fetched.
+  const std::string& start_page_token() const { return start_page_token_; }
 
   // Returns a string representation of this object.
   std::string ToString() const;
@@ -69,7 +69,7 @@
  private:
   const std::string local_id_;
   const std::string resource_id_;
-  const int64_t changestamp_;
+  const std::string start_page_token_;
 };
 
 // Class to represent a change list.
@@ -90,17 +90,20 @@
     return &parent_resource_ids_;
   }
   const GURL& next_url() const { return next_url_; }
-  int64_t largest_changestamp() const { return largest_changestamp_; }
 
-  void set_largest_changestamp(int64_t largest_changestamp) {
-    largest_changestamp_ = largest_changestamp;
+  const std::string& new_start_page_token() const {
+    return new_start_page_token_;
+  }
+
+  void set_new_start_page_token(const std::string& start_page_token) {
+    new_start_page_token_ = start_page_token;
   }
 
  private:
   std::vector<ResourceEntry> entries_;
   std::vector<std::string> parent_resource_ids_;
   GURL next_url_;
-  int64_t largest_changestamp_;
+  std::string new_start_page_token_;
 
   DISALLOW_COPY_AND_ASSIGN(ChangeList);
 };
@@ -122,21 +125,11 @@
   //
   // Must be run on the same task runner as |resource_metadata_| uses.
   FileError ApplyUserChangeList(
-      std::unique_ptr<google_apis::AboutResource> about_resource,
+      const std::string& start_page_token,
+      const std::string& root_resource_id,
       std::vector<std::unique_ptr<ChangeList>> change_lists,
       bool is_delta_update);
 
-  // Applies Team Drive's change lists to |resource_metadata_|.
-  //
-  // |change_lists| must not be an empty list, although it can consist of a
-  // single ChangeList object whose |items_| is emtpy.
-  // |team_drive_id| is the Team Drive's ID which gave the change lists.
-  //
-  // Must be run on the same task runner as |resource_metadata_| uses.
-  FileError ApplyTeamDriveChangeList(
-      const std::string& team_drive_id,
-      std::vector<std::unique_ptr<ChangeList>> change_lists);
-
   // The set of changed files as a result of change list processing.
   const FileChange& changed_files() const { return *changed_files_; }
 
@@ -165,7 +158,7 @@
   // Applies the |change_lists| to |resource_metadta_|.
   FileError ApplyChangeListInternal(
       std::vector<std::unique_ptr<ChangeList>> change_lists,
-      int64_t largest_changestamp,
+      const std::string& start_page_token,
       ResourceEntry* root,
       ChangeListToEntryMapUMAStats* uma_stats);
 
@@ -173,7 +166,7 @@
   // to be applied by ApplyEntryMap() later.
   void ConvertChangeListsToMap(
       std::vector<std::unique_ptr<ChangeList>> change_lists,
-      int64_t largest_changestamp,
+      const std::string& start_page_token,
       ChangeListToEntryMapUMAStats* uma_stats);
 
   // Applies the pre-processed metadata from entry_map_ onto the resource
@@ -186,10 +179,6 @@
   // Adds the directories changed by the update on |entry| to |changed_dirs_|.
   void UpdateChangedDirs(const ResourceEntry& entry);
 
-  // Sets the largest changestamp of a Team Drive's change list.
-  FileError SetTeamDriveLargestChangestamp(const std::string& team_drive_id,
-                                           int64_t value);
-
   ResourceMetadata* resource_metadata_;  // Not owned.
   base::CancellationFlag* in_shutdown_;  // Not owned.
 
diff --git a/components/drive/chromeos/directory_loader.cc b/components/drive/chromeos/directory_loader.cc
index 869d071..95a8fad 100644
--- a/components/drive/chromeos/directory_loader.cc
+++ b/components/drive/chromeos/directory_loader.cc
@@ -21,6 +21,7 @@
 #include "components/drive/chromeos/change_list_processor.h"
 #include "components/drive/chromeos/loader_controller.h"
 #include "components/drive/chromeos/resource_metadata.h"
+#include "components/drive/chromeos/start_page_token_loader.h"
 #include "components/drive/drive_api_util.h"
 #include "components/drive/event_logger.h"
 #include "components/drive/file_system_core_util.h"
@@ -34,13 +35,14 @@
 namespace {
 
 // Minimum changestamp gap required to start loading directory.
-const int kMinimumChangestampGap = 50;
+constexpr int kMinimumChangestampGap = 50;
 
 FileError CheckLocalState(ResourceMetadata* resource_metadata,
-                          const google_apis::AboutResource& about_resource,
+                          const std::string& root_folder_id,
                           const std::string& local_id,
                           ResourceEntry* entry,
-                          int64_t* local_changestamp) {
+                          std::string* start_page_token) {
+  DCHECK(start_page_token);
   // Fill My Drive resource ID.
   ResourceEntry mydrive;
   FileError error = resource_metadata->GetResourceEntryByPath(
@@ -49,7 +51,7 @@
     return error;
 
   if (mydrive.resource_id().empty()) {
-    mydrive.set_resource_id(about_resource.root_folder_id());
+    mydrive.set_resource_id(root_folder_id);
     error = resource_metadata->RefreshEntry(mydrive);
     if (error != FILE_ERROR_OK)
       return error;
@@ -60,14 +62,14 @@
   if (error != FILE_ERROR_OK)
     return error;
 
-  // Get the local changestamp.
-  return resource_metadata->GetLargestChangestamp(local_changestamp);
+  // Get the local start page token..
+  return resource_metadata->GetStartPageToken(start_page_token);
 }
 
-FileError UpdateChangestamp(ResourceMetadata* resource_metadata,
-                            const DirectoryFetchInfo& directory_fetch_info,
-                            base::FilePath* directory_path) {
-  // Update the directory changestamp.
+FileError UpdateStartPageToken(ResourceMetadata* resource_metadata,
+                               const DirectoryFetchInfo& directory_fetch_info,
+                               base::FilePath* directory_path) {
+  // Update the directory start page token.
   ResourceEntry directory;
   FileError error = resource_metadata->GetResourceEntryById(
       directory_fetch_info.local_id(), &directory);
@@ -77,8 +79,8 @@
   if (!directory.file_info().is_directory())
     return FILE_ERROR_NOT_A_DIRECTORY;
 
-  directory.mutable_directory_specific_info()->set_changestamp(
-      directory_fetch_info.changestamp());
+  directory.mutable_directory_specific_info()->set_start_page_token(
+      directory_fetch_info.start_page_token());
   error = resource_metadata->RefreshEntry(directory);
   if (error != FILE_ERROR_OK)
     return error;
@@ -201,15 +203,16 @@
     ResourceMetadata* resource_metadata,
     JobScheduler* scheduler,
     AboutResourceLoader* about_resource_loader,
+    StartPageTokenLoader* start_page_token_loader,
     LoaderController* loader_controller)
     : logger_(logger),
       blocking_task_runner_(blocking_task_runner),
       resource_metadata_(resource_metadata),
       scheduler_(scheduler),
       about_resource_loader_(about_resource_loader),
+      start_page_token_loader_(start_page_token_loader),
       loader_controller_(loader_controller),
-      weak_ptr_factory_(this) {
-}
+      weak_ptr_factory_(this) {}
 
 DirectoryLoader::~DirectoryLoader() = default;
 
@@ -281,9 +284,8 @@
   }
 
   DirectoryFetchInfo directory_fetch_info(
-      entry->local_id(),
-      entry->resource_id(),
-      entry->directory_specific_info().changestamp());
+      entry->local_id(), entry->resource_id(),
+      entry->directory_specific_info().start_page_token());
 
   // Register the callback function to be called when it is loaded.
   const std::string& local_id = directory_fetch_info.local_id();
@@ -345,28 +347,48 @@
 
   DCHECK(about_resource);
 
+  start_page_token_loader_->GetStartPageToken(
+      base::Bind(&DirectoryLoader::ReadDirectoryAfterGetStartPageToken,
+                 weak_ptr_factory_.GetWeakPtr(), local_id,
+                 about_resource->root_folder_id()));
+}
+
+void DirectoryLoader::ReadDirectoryAfterGetStartPageToken(
+    const std::string& local_id,
+    const std::string& root_folder_id,
+    google_apis::DriveApiErrorCode status,
+    std::unique_ptr<google_apis::StartPageToken> start_page_token) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+  FileError error = GDataToFileError(status);
+  if (error != FILE_ERROR_OK) {
+    OnDirectoryLoadComplete(local_id, error);
+    return;
+  }
+
+  DCHECK(start_page_token);
+
   // Check the current status of local metadata, and start loading if needed.
-  google_apis::AboutResource* about_resource_ptr = about_resource.get();
   ResourceEntry* entry = new ResourceEntry;
-  int64_t* local_changestamp = new int64_t;
+  std::string* local_start_page_token = new std::string();
   base::PostTaskAndReplyWithResult(
       blocking_task_runner_.get(), FROM_HERE,
-      base::BindOnce(&CheckLocalState, resource_metadata_, *about_resource_ptr,
-                     local_id, entry, local_changestamp),
+      base::BindOnce(&CheckLocalState, resource_metadata_, root_folder_id,
+                     local_id, entry, local_start_page_token),
       base::BindOnce(&DirectoryLoader::ReadDirectoryAfterCheckLocalState,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(about_resource),
-                     local_id, base::Owned(entry),
-                     base::Owned(local_changestamp)));
+                     weak_ptr_factory_.GetWeakPtr(),
+                     start_page_token->start_page_token(), local_id,
+                     base::Owned(entry), base::Owned(local_start_page_token)));
 }
 
 void DirectoryLoader::ReadDirectoryAfterCheckLocalState(
-    std::unique_ptr<google_apis::AboutResource> about_resource,
+    const std::string& remote_start_page_token,
     const std::string& local_id,
     const ResourceEntry* entry,
-    const int64_t* local_changestamp,
+    const std::string* local_start_page_token,
     FileError error) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  DCHECK(about_resource);
+  DCHECK(local_start_page_token);
 
   if (error != FILE_ERROR_OK) {
     OnDirectoryLoadComplete(local_id, error);
@@ -378,21 +400,54 @@
     return;
   }
 
-  int64_t remote_changestamp = about_resource->largest_change_id();
+  // Start loading the directory.
+  const std::string& directory_start_page_token =
+      entry->directory_specific_info().start_page_token();
+
+  DirectoryFetchInfo directory_fetch_info(local_id, entry->resource_id(),
+                                          remote_start_page_token);
+
+  int64_t directory_changestamp = 0;
+  // The directory_specific_info may be enpty, so default changestamp to 0.
+  if (!directory_start_page_token.empty() &&
+      !drive::util::ConvertStartPageTokenToChangestamp(
+          directory_start_page_token, &directory_changestamp)) {
+    logger_->Log(
+        logging::LOG_ERROR,
+        "Unable to covert directory start page tokens to changestamps, will "
+        "load directory from server %s; directory start page token: %s ",
+        directory_fetch_info.ToString().c_str(),
+        directory_start_page_token.c_str());
+    LoadDirectoryFromServer(directory_fetch_info);
+    return;
+  }
+
+  int64_t remote_changestamp = 0;
+  int64_t local_changestamp = 0;
+  if (!drive::util::ConvertStartPageTokenToChangestamp(remote_start_page_token,
+                                                       &remote_changestamp) ||
+      !drive::util::ConvertStartPageTokenToChangestamp(*local_start_page_token,
+                                                       &local_changestamp)) {
+    logger_->Log(
+        logging::LOG_ERROR,
+        "Unable to covert start page tokens to changestamps, will load "
+        "directory from server %s; local start page token: %s; "
+        "remove start page token: %s",
+        directory_fetch_info.ToString().c_str(),
+        local_start_page_token->c_str(), remote_start_page_token.c_str());
+    LoadDirectoryFromServer(directory_fetch_info);
+    return;
+  }
 
   // Start loading the directory.
-  int64_t directory_changestamp = std::max(
-      entry->directory_specific_info().changestamp(), *local_changestamp);
-
-  DirectoryFetchInfo directory_fetch_info(
-      local_id, entry->resource_id(), remote_changestamp);
+  directory_changestamp = std::max(directory_changestamp, local_changestamp);
 
   // If the directory's changestamp is up to date or the global changestamp of
   // the metadata DB is new enough (which means the normal changelist loading
   // should finish very soon), just schedule to run the callback, as there is no
   // need to fetch the directory.
   if (directory_changestamp >= remote_changestamp ||
-      *local_changestamp + kMinimumChangestampGap > remote_changestamp) {
+      local_changestamp + kMinimumChangestampGap > remote_changestamp) {
     OnDirectoryLoadComplete(local_id, FILE_ERROR_OK);
   } else {
     // Start fetching the directory content, and mark it with the changestamp
@@ -483,16 +538,19 @@
   DCHECK(!directory_fetch_info.empty());
   DVLOG(1) << "Start loading directory: " << directory_fetch_info.ToString();
 
+  const google_apis::StartPageToken* start_page_token =
+      start_page_token_loader_->cached_start_page_token();
+  DCHECK(start_page_token);
+
+  logger_->Log(logging::LOG_INFO,
+               "Fast-fetch start: %s; Server start page token: %s",
+               directory_fetch_info.ToString().c_str(),
+               start_page_token->start_page_token().c_str());
+
   const google_apis::AboutResource* about_resource =
       about_resource_loader_->cached_about_resource();
   DCHECK(about_resource);
 
-  logger_->Log(logging::LOG_INFO,
-               "Fast-fetch start: %s; Server changestamp: %s",
-               directory_fetch_info.ToString().c_str(),
-               base::Int64ToString(
-                   about_resource->largest_change_id()).c_str());
-
   FeedFetcher* fetcher = new FeedFetcher(this,
                                          directory_fetch_info,
                                          about_resource->root_folder_id());
@@ -532,23 +590,19 @@
     return;
   }
 
-  // Update changestamp and get the directory path.
+  // Update start page token and get the directory path.
   base::FilePath* directory_path = new base::FilePath;
   base::PostTaskAndReplyWithResult(
-      blocking_task_runner_.get(),
-      FROM_HERE,
-      base::Bind(&UpdateChangestamp,
-                 resource_metadata_,
-                 directory_fetch_info,
-                 directory_path),
+      blocking_task_runner_.get(), FROM_HERE,
+      base::Bind(&UpdateStartPageToken, resource_metadata_,
+                 directory_fetch_info, directory_path),
       base::Bind(
-          &DirectoryLoader::LoadDirectoryFromServerAfterUpdateChangestamp,
-          weak_ptr_factory_.GetWeakPtr(),
-          directory_fetch_info,
+          &DirectoryLoader::LoadDirectoryFromServerAfterUpdateStartPageToken,
+          weak_ptr_factory_.GetWeakPtr(), directory_fetch_info,
           base::Owned(directory_path)));
 }
 
-void DirectoryLoader::LoadDirectoryFromServerAfterUpdateChangestamp(
+void DirectoryLoader::LoadDirectoryFromServerAfterUpdateStartPageToken(
     const DirectoryFetchInfo& directory_fetch_info,
     const base::FilePath* directory_path,
     FileError error) {
diff --git a/components/drive/chromeos/directory_loader.h b/components/drive/chromeos/directory_loader.h
index 88eff34..4d85ba3 100644
--- a/components/drive/chromeos/directory_loader.h
+++ b/components/drive/chromeos/directory_loader.h
@@ -44,6 +44,7 @@
 class DirectoryFetchInfo;
 class LoaderController;
 class ResourceMetadata;
+class StartPageTokenLoader;
 
 // DirectoryLoader is used to load directory contents.
 class DirectoryLoader {
@@ -53,6 +54,7 @@
                   ResourceMetadata* resource_metadata,
                   JobScheduler* scheduler,
                   AboutResourceLoader* about_resource_loader,
+                  StartPageTokenLoader* start_page_token_loader,
                   LoaderController* apply_task_controller);
   ~DirectoryLoader();
 
@@ -88,11 +90,17 @@
       const std::string& local_id,
       google_apis::DriveApiErrorCode status,
       std::unique_ptr<google_apis::AboutResource> about_resource);
+  void ReadDirectoryAfterGetStartPageToken(
+      const std::string& local_id,
+      const std::string& root_folder_id,
+      google_apis::DriveApiErrorCode status,
+      std::unique_ptr<google_apis::StartPageToken> start_page_token);
+
   void ReadDirectoryAfterCheckLocalState(
-      std::unique_ptr<google_apis::AboutResource> about_resource,
+      const std::string& remote_start_page_token,
       const std::string& local_id,
       const ResourceEntry* entry,
-      const int64_t* local_changestamp,
+      const std::string* local_start_page_token,
       FileError error);
 
   // Part of ReadDirectory().
@@ -119,7 +127,7 @@
       FileError error);
 
   // Part of LoadDirectoryFromServer().
-  void LoadDirectoryFromServerAfterUpdateChangestamp(
+  void LoadDirectoryFromServerAfterUpdateStartPageToken(
       const DirectoryFetchInfo& directory_fetch_info,
       const base::FilePath* directory_path,
       FileError error);
@@ -129,6 +137,7 @@
   ResourceMetadata* resource_metadata_;  // Not owned.
   JobScheduler* scheduler_;  // Not owned.
   AboutResourceLoader* about_resource_loader_;  // Not owned.
+  StartPageTokenLoader* start_page_token_loader_;  // Not owned
   LoaderController* loader_controller_;  // Not owned.
   base::ObserverList<ChangeListLoaderObserver> observers_;
   typedef std::map<std::string, std::vector<ReadDirectoryCallbackState> >
diff --git a/components/drive/chromeos/file_system.cc b/components/drive/chromeos/file_system.cc
index bbe98d6..a527d489 100644
--- a/components/drive/chromeos/file_system.cc
+++ b/components/drive/chromeos/file_system.cc
@@ -5,7 +5,6 @@
 #include "components/drive/chromeos/file_system.h"
 
 #include <stddef.h>
-#include <memory>
 #include <utility>
 
 #include "base/bind.h"
@@ -32,10 +31,12 @@
 #include "components/drive/chromeos/loader_controller.h"
 #include "components/drive/chromeos/remove_stale_cache_files.h"
 #include "components/drive/chromeos/search_metadata.h"
+#include "components/drive/chromeos/start_page_token_loader.h"
 #include "components/drive/chromeos/sync_client.h"
 #include "components/drive/drive.pb.h"
 #include "components/drive/drive_pref_names.h"
 #include "components/drive/file_change.h"
+#include "components/drive/file_system_core_util.h"
 #include "components/drive/job_scheduler.h"
 #include "components/drive/resource_entry_conversion.h"
 #include "components/prefs/pref_service.h"
@@ -353,14 +354,18 @@
 
   about_resource_loader_ =
       std::make_unique<internal::AboutResourceLoader>(scheduler_);
+  start_page_token_loader_ = std::make_unique<internal::StartPageTokenLoader>(
+      drive::util::kTeamDriveIdDefaultCorpus, scheduler_);
   loader_controller_ = std::make_unique<internal::LoaderController>();
   change_list_loader_ = std::make_unique<internal::ChangeListLoader>(
       logger_, blocking_task_runner_.get(), resource_metadata_, scheduler_,
-      about_resource_loader_.get(), loader_controller_.get());
+      about_resource_loader_.get(), start_page_token_loader_.get(),
+      loader_controller_.get());
   change_list_loader_->AddObserver(this);
   directory_loader_ = std::make_unique<internal::DirectoryLoader>(
       logger_, blocking_task_runner_.get(), resource_metadata_, scheduler_,
-      about_resource_loader_.get(), loader_controller_.get());
+      about_resource_loader_.get(), start_page_token_loader_.get(),
+      loader_controller_.get());
   directory_loader_->AddObserver(this);
 
   sync_client_ = std::make_unique<internal::SyncClient>(
diff --git a/components/drive/chromeos/file_system.h b/components/drive/chromeos/file_system.h
index dc085e8..531d2afe 100644
--- a/components/drive/chromeos/file_system.h
+++ b/components/drive/chromeos/file_system.h
@@ -45,6 +45,7 @@
 class FileCache;
 class LoaderController;
 class ResourceMetadata;
+class StartPageTokenLoader;
 class SyncClient;
 }  // namespace internal
 
@@ -270,6 +271,9 @@
   // Used to load about resource.
   std::unique_ptr<internal::AboutResourceLoader> about_resource_loader_;
 
+  // Used to load the start page token for the users default corpus
+  std::unique_ptr<internal::StartPageTokenLoader> start_page_token_loader_;
+
   // Used to control ChangeListLoader.
   std::unique_ptr<internal::LoaderController> loader_controller_;
 
diff --git a/components/drive/chromeos/file_system/copy_operation.cc b/components/drive/chromeos/file_system/copy_operation.cc
index 853b60fc..c6ce2d43 100644
--- a/components/drive/chromeos/file_system/copy_operation.cc
+++ b/components/drive/chromeos/file_system/copy_operation.cc
@@ -301,15 +301,15 @@
 }
 
 CopyOperation::~CopyOperation() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 }
 
 void CopyOperation::Copy(const base::FilePath& src_file_path,
                          const base::FilePath& dest_file_path,
                          bool preserve_last_modified,
                          const FileOperationCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   CopyParams* params = new CopyParams;
   params->src_file_path = src_file_path;
@@ -337,8 +337,8 @@
     const bool* directory_changed,
     const bool* should_copy_on_server,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!params->callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(params->callback);
 
   for (const auto& id : *updated_local_ids) {
     // Syncing for copy should be done in background, so pass the BACKGROUND
@@ -374,8 +374,8 @@
 
 void CopyOperation::CopyAfterParentSync(const CopyParams& params,
                                         FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!params.callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(params.callback);
 
   if (error != FILE_ERROR_OK) {
     params.callback.Run(error);
@@ -399,8 +399,8 @@
 void CopyOperation::CopyAfterGetParentResourceId(const CopyParams& params,
                                                  const ResourceEntry* parent,
                                                  FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!params.callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(params.callback);
 
   if (error != FILE_ERROR_OK) {
     params.callback.Run(error);
@@ -428,8 +428,8 @@
     const base::FilePath& local_src_path,
     const base::FilePath& remote_dest_path,
     const FileOperationCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   std::string* gdoc_resource_id = new std::string;
   ResourceEntry* parent_entry = new ResourceEntry;
@@ -454,8 +454,8 @@
     std::string* gdoc_resource_id,
     ResourceEntry* parent_entry,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (error != FILE_ERROR_OK) {
     callback.Run(error);
@@ -491,7 +491,7 @@
 void CopyOperation::TransferJsonGdocFileAfterLocalWork(
     TransferJsonGdocParams* params,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   if (error != FILE_ERROR_OK) {
     params->callback.Run(error);
@@ -549,8 +549,8 @@
     const std::string& new_title,
     const base::Time& last_modified,
     const FileOperationCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   scheduler_->CopyResource(
       resource_id, parent_resource_id, new_title, last_modified,
@@ -563,8 +563,8 @@
     const FileOperationCallback& callback,
     google_apis::DriveApiErrorCode status,
     std::unique_ptr<google_apis::FileResource> entry) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   FileError error = GDataToFileError(status);
   if (error != FILE_ERROR_OK) {
@@ -591,8 +591,8 @@
     base::FilePath* file_path,
     const ResourceEntry* entry,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (error == FILE_ERROR_OK) {
     FileChange changed_file;
@@ -607,8 +607,8 @@
     const base::FilePath& local_src_path,
     const base::FilePath& remote_dest_path,
     const FileOperationCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   create_file_operation_->CreateFile(
       remote_dest_path,
@@ -624,8 +624,8 @@
     const base::FilePath& remote_dest_path,
     const FileOperationCallback& callback,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (error != FILE_ERROR_OK) {
     callback.Run(error);
@@ -659,8 +659,8 @@
     const ResourceEntry* entry,
     std::string* local_id,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (error == FILE_ERROR_OK) {
     FileChange changed_file;
diff --git a/components/drive/chromeos/file_system/copy_operation.h b/components/drive/chromeos/file_system/copy_operation.h
index 494b169..6d0fba1 100644
--- a/components/drive/chromeos/file_system/copy_operation.h
+++ b/components/drive/chromeos/file_system/copy_operation.h
@@ -169,7 +169,7 @@
   // Uploading a new file is internally implemented by creating a dirty file.
   std::unique_ptr<CreateFileOperation> create_file_operation_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate the weak pointers before any other members are destroyed.
diff --git a/components/drive/chromeos/file_system/create_directory_operation.cc b/components/drive/chromeos/file_system/create_directory_operation.cc
index 6fe5af63..1258384d 100644
--- a/components/drive/chromeos/file_system/create_directory_operation.cc
+++ b/components/drive/chromeos/file_system/create_directory_operation.cc
@@ -133,7 +133,7 @@
 }
 
 CreateDirectoryOperation::~CreateDirectoryOperation() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 }
 
 void CreateDirectoryOperation::CreateDirectory(
@@ -141,8 +141,8 @@
     bool is_exclusive,
     bool is_recursive,
     const FileOperationCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   std::set<std::string>* updated_local_ids = new std::set<std::string>;
   FileChange* changed_files(new FileChange);
@@ -169,8 +169,8 @@
     const std::set<std::string>* updated_local_ids,
     const FileChange* changed_files,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   for (const auto& id : *updated_local_ids) {
     delegate_->OnEntryUpdatedByOperation(ClientContext(USER_INITIATED), id);
diff --git a/components/drive/chromeos/file_system/create_directory_operation.h b/components/drive/chromeos/file_system/create_directory_operation.h
index de9fb09b..9a55b4e 100644
--- a/components/drive/chromeos/file_system/create_directory_operation.h
+++ b/components/drive/chromeos/file_system/create_directory_operation.h
@@ -64,7 +64,7 @@
   OperationDelegate* delegate_;
   internal::ResourceMetadata* metadata_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate the weak pointers before any other members are destroyed.
diff --git a/components/drive/chromeos/file_system/create_file_operation.cc b/components/drive/chromeos/file_system/create_file_operation.cc
index 43f6b5f..9cc7173e 100644
--- a/components/drive/chromeos/file_system/create_file_operation.cc
+++ b/components/drive/chromeos/file_system/create_file_operation.cc
@@ -79,15 +79,15 @@
 }
 
 CreateFileOperation::~CreateFileOperation() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 }
 
 void CreateFileOperation::CreateFile(const base::FilePath& file_path,
                                      bool is_exclusive,
                                      const std::string& mime_type,
                                      const FileOperationCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   ResourceEntry* entry = new ResourceEntry;
   base::PostTaskAndReplyWithResult(
@@ -112,8 +112,8 @@
     bool is_exclusive,
     ResourceEntry* entry,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (error == FILE_ERROR_EXISTS) {
     // Error if an exclusive mode is requested, or the entry is not a file.
diff --git a/components/drive/chromeos/file_system/create_file_operation.h b/components/drive/chromeos/file_system/create_file_operation.h
index e761b7a..fa875645 100644
--- a/components/drive/chromeos/file_system/create_file_operation.h
+++ b/components/drive/chromeos/file_system/create_file_operation.h
@@ -62,7 +62,7 @@
   OperationDelegate* delegate_;
   internal::ResourceMetadata* metadata_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate the weak pointers before any other members are destroyed.
diff --git a/components/drive/chromeos/file_system/download_operation.cc b/components/drive/chromeos/file_system/download_operation.cc
index ed5b19a3..5a91624 100644
--- a/components/drive/chromeos/file_system/download_operation.cc
+++ b/components/drive/chromeos/file_system/download_operation.cc
@@ -353,8 +353,7 @@
       weak_ptr_factory_(this) {
 }
 
-DownloadOperation::~DownloadOperation() {
-}
+DownloadOperation::~DownloadOperation() = default;
 
 base::Closure DownloadOperation::EnsureFileDownloadedByLocalId(
     const std::string& local_id,
@@ -362,7 +361,7 @@
     const GetFileContentInitializedCallback& initialized_callback,
     const google_apis::GetContentCallback& get_content_callback,
     const GetFileCallback& completion_callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!completion_callback.is_null());
 
   CheckPreconditionForEnsureFileDownloadedParams params;
@@ -396,7 +395,7 @@
     const GetFileContentInitializedCallback& initialized_callback,
     const google_apis::GetContentCallback& get_content_callback,
     const GetFileCallback& completion_callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!completion_callback.is_null());
 
   CheckPreconditionForEnsureFileDownloadedParams params;
@@ -431,7 +430,7 @@
     base::FilePath* cache_file_path,
     base::FilePath* temp_download_file_path,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(params);
   DCHECK(drive_file_path);
   DCHECK(cache_file_path);
@@ -478,7 +477,7 @@
     std::unique_ptr<DownloadParams> params,
     google_apis::DriveApiErrorCode gdata_error,
     const base::FilePath& downloaded_file_path) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   DownloadParams* params_ptr = params.get();
   ResourceEntry* entry_after_update = new ResourceEntry;
@@ -500,7 +499,7 @@
     std::unique_ptr<ResourceEntry> entry_after_update,
     base::FilePath* cache_file_path,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   if (error != FILE_ERROR_OK) {
     params->OnError(error);
diff --git a/components/drive/chromeos/file_system/download_operation.h b/components/drive/chromeos/file_system/download_operation.h
index 300b415..21eb09e 100644
--- a/components/drive/chromeos/file_system/download_operation.h
+++ b/components/drive/chromeos/file_system/download_operation.h
@@ -120,7 +120,7 @@
   internal::FileCache* cache_;
   const base::FilePath temporary_file_directory_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
diff --git a/components/drive/chromeos/file_system/get_file_for_saving_operation.cc b/components/drive/chromeos/file_system/get_file_for_saving_operation.cc
index c7a1730..ac84f7bf 100644
--- a/components/drive/chromeos/file_system/get_file_for_saving_operation.cc
+++ b/components/drive/chromeos/file_system/get_file_for_saving_operation.cc
@@ -61,14 +61,13 @@
       cache_(cache),
       weak_ptr_factory_(this) {}
 
-GetFileForSavingOperation::~GetFileForSavingOperation() {
-}
+GetFileForSavingOperation::~GetFileForSavingOperation() = default;
 
 void GetFileForSavingOperation::GetFileForSaving(
     const base::FilePath& file_path,
     const GetFileCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   create_file_operation_->CreateFile(
       file_path,
@@ -84,8 +83,8 @@
     const base::FilePath& file_path,
     const GetFileCallback& callback,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (error != FILE_ERROR_OK) {
     callback.Run(error, base::FilePath(), std::unique_ptr<ResourceEntry>());
@@ -107,8 +106,8 @@
     FileError error,
     const base::FilePath& cache_path,
     std::unique_ptr<ResourceEntry> entry) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (error != FILE_ERROR_OK) {
     callback.Run(error, base::FilePath(), std::unique_ptr<ResourceEntry>());
@@ -135,8 +134,8 @@
     std::unique_ptr<ResourceEntry> entry,
     std::unique_ptr<base::ScopedClosureRunner>* file_closer,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (error != FILE_ERROR_OK) {
     callback.Run(error, base::FilePath(), std::unique_ptr<ResourceEntry>());
@@ -162,8 +161,8 @@
     const base::FilePath& cache_path,
     std::unique_ptr<ResourceEntry> entry,
     bool success) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   logger_->Log(logging::LOG_INFO, "Started watching modification to %s [%s].",
                entry->local_id().c_str(),
diff --git a/components/drive/chromeos/file_system/get_file_for_saving_operation.h b/components/drive/chromeos/file_system/get_file_for_saving_operation.h
index e7548014..284dc18a 100644
--- a/components/drive/chromeos/file_system/get_file_for_saving_operation.h
+++ b/components/drive/chromeos/file_system/get_file_for_saving_operation.h
@@ -95,7 +95,7 @@
   internal::ResourceMetadata* metadata_;
   internal::FileCache* cache_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate the weak pointers before any other members are destroyed.
diff --git a/components/drive/chromeos/file_system/move_operation.cc b/components/drive/chromeos/file_system/move_operation.cc
index 5a392077..4b99c09 100644
--- a/components/drive/chromeos/file_system/move_operation.cc
+++ b/components/drive/chromeos/file_system/move_operation.cc
@@ -75,14 +75,14 @@
 }
 
 MoveOperation::~MoveOperation() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 }
 
 void MoveOperation::Move(const base::FilePath& src_file_path,
                          const base::FilePath& dest_file_path,
                          const FileOperationCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   FileChange* changed_files = new FileChange;
   std::string* local_id = new std::string;
@@ -107,7 +107,7 @@
     const FileChange* changed_files,
     const std::string* local_id,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (error == FILE_ERROR_OK) {
     // Notify the change of directory.
     delegate_->OnFileChangedByOperation(*changed_files);
diff --git a/components/drive/chromeos/file_system/move_operation.h b/components/drive/chromeos/file_system/move_operation.h
index 123318e..8f86fd0 100644
--- a/components/drive/chromeos/file_system/move_operation.h
+++ b/components/drive/chromeos/file_system/move_operation.h
@@ -65,7 +65,7 @@
   OperationDelegate* delegate_;
   internal::ResourceMetadata* metadata_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate the weak pointers before any other members are destroyed.
diff --git a/components/drive/chromeos/file_system/open_file_operation.cc b/components/drive/chromeos/file_system/open_file_operation.cc
index d1e4f6e..10e699b 100644
--- a/components/drive/chromeos/file_system/open_file_operation.cc
+++ b/components/drive/chromeos/file_system/open_file_operation.cc
@@ -40,15 +40,14 @@
       weak_ptr_factory_(this) {
 }
 
-OpenFileOperation::~OpenFileOperation() {
-}
+OpenFileOperation::~OpenFileOperation() = default;
 
 void OpenFileOperation::OpenFile(const base::FilePath& file_path,
                                  OpenMode open_mode,
                                  const std::string& mime_type,
                                  const OpenFileCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   switch (open_mode) {
     case OPEN_FILE:
@@ -80,8 +79,8 @@
     const base::FilePath& file_path,
     const OpenFileCallback& callback,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (error != FILE_ERROR_OK) {
     callback.Run(error, base::FilePath(), base::Closure());
@@ -103,8 +102,8 @@
     FileError error,
     const base::FilePath& local_file_path,
     std::unique_ptr<ResourceEntry> entry) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (error == FILE_ERROR_OK) {
     DCHECK(entry);
@@ -142,8 +141,8 @@
     const OpenFileCallback& callback,
     std::unique_ptr<base::ScopedClosureRunner>* file_closer,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (error != FILE_ERROR_OK) {
     callback.Run(error, base::FilePath(), base::Closure());
@@ -161,7 +160,7 @@
 void OpenFileOperation::CloseFile(
     const std::string& local_id,
     std::unique_ptr<base::ScopedClosureRunner> file_closer) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK_GT(open_files_[local_id], 0);
 
   if (--open_files_[local_id] == 0) {
diff --git a/components/drive/chromeos/file_system/open_file_operation.h b/components/drive/chromeos/file_system/open_file_operation.h
index a64ddd72..e7271198 100644
--- a/components/drive/chromeos/file_system/open_file_operation.h
+++ b/components/drive/chromeos/file_system/open_file_operation.h
@@ -95,7 +95,7 @@
   // the file is opened.
   std::map<std::string, int> open_files_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
diff --git a/components/drive/chromeos/file_system/remove_operation.cc b/components/drive/chromeos/file_system/remove_operation.cc
index 813f11e0..d4e065f 100644
--- a/components/drive/chromeos/file_system/remove_operation.cc
+++ b/components/drive/chromeos/file_system/remove_operation.cc
@@ -70,14 +70,14 @@
 }
 
 RemoveOperation::~RemoveOperation() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 }
 
 void RemoveOperation::Remove(const base::FilePath& path,
                              bool is_recursive,
                              const FileOperationCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   std::string* local_id = new std::string;
   base::FilePath* changed_path = new base::FilePath;
@@ -107,8 +107,8 @@
     const ResourceEntry* entry,
     const base::FilePath* changed_path,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (!changed_path->empty()) {
     FileChange changed_file;
diff --git a/components/drive/chromeos/file_system/remove_operation.h b/components/drive/chromeos/file_system/remove_operation.h
index 17ce7f0b..aea4560 100644
--- a/components/drive/chromeos/file_system/remove_operation.h
+++ b/components/drive/chromeos/file_system/remove_operation.h
@@ -64,7 +64,7 @@
   internal::ResourceMetadata* metadata_;
   internal::FileCache* cache_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate the weak pointers before any other members are destroyed.
diff --git a/components/drive/chromeos/file_system/search_operation.cc b/components/drive/chromeos/file_system/search_operation.cc
index e527e07..8fece0e 100644
--- a/components/drive/chromeos/file_system/search_operation.cc
+++ b/components/drive/chromeos/file_system/search_operation.cc
@@ -93,14 +93,13 @@
       weak_ptr_factory_(this) {
 }
 
-SearchOperation::~SearchOperation() {
-}
+SearchOperation::~SearchOperation() = default;
 
 void SearchOperation::Search(const std::string& search_query,
                              const GURL& next_link,
                              const SearchCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (next_link.is_empty()) {
     // This is first request for the |search_query|.
@@ -121,8 +120,8 @@
     const SearchCallback& callback,
     google_apis::DriveApiErrorCode gdata_error,
     std::unique_ptr<google_apis::FileList> file_list) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   FileError error = GDataToFileError(gdata_error);
   if (error != FILE_ERROR_OK) {
@@ -163,8 +162,8 @@
     const GURL& next_link,
     std::unique_ptr<std::vector<SearchResultInfo>> result,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
   DCHECK(result);
 
   if (error != FILE_ERROR_OK) {
diff --git a/components/drive/chromeos/file_system/search_operation.h b/components/drive/chromeos/file_system/search_operation.h
index 7193f6d..8209bf6 100644
--- a/components/drive/chromeos/file_system/search_operation.h
+++ b/components/drive/chromeos/file_system/search_operation.h
@@ -72,7 +72,7 @@
   internal::ResourceMetadata* metadata_;
   internal::LoaderController* loader_controller_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate the weak pointers before any other members are destroyed.
diff --git a/components/drive/chromeos/file_system/set_property_operation.cc b/components/drive/chromeos/file_system/set_property_operation.cc
index 72387b9..4e56e57 100644
--- a/components/drive/chromeos/file_system/set_property_operation.cc
+++ b/components/drive/chromeos/file_system/set_property_operation.cc
@@ -78,8 +78,7 @@
       weak_ptr_factory_(this) {
 }
 
-SetPropertyOperation::~SetPropertyOperation() {
-}
+SetPropertyOperation::~SetPropertyOperation() = default;
 
 void SetPropertyOperation::SetProperty(
     const base::FilePath& file_path,
@@ -87,8 +86,8 @@
     const std::string& key,
     const std::string& value,
     const FileOperationCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   ResourceEntry* entry = new ResourceEntry;
   base::PostTaskAndReplyWithResult(
@@ -103,8 +102,8 @@
     const FileOperationCallback& callback,
     const ResourceEntry* entry,
     FileError result) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (result == FILE_ERROR_OK) {
     // Do not notify about the file change, as properties are write only and
diff --git a/components/drive/chromeos/file_system/set_property_operation.h b/components/drive/chromeos/file_system/set_property_operation.h
index 41fd8fd..2eb4935 100644
--- a/components/drive/chromeos/file_system/set_property_operation.h
+++ b/components/drive/chromeos/file_system/set_property_operation.h
@@ -56,7 +56,7 @@
   OperationDelegate* delegate_;
   internal::ResourceMetadata* metadata_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate the weak pointers before any other members are destroyed.
diff --git a/components/drive/chromeos/file_system/touch_operation.cc b/components/drive/chromeos/file_system/touch_operation.cc
index 3ba7996..bb66604f 100644
--- a/components/drive/chromeos/file_system/touch_operation.cc
+++ b/components/drive/chromeos/file_system/touch_operation.cc
@@ -52,15 +52,14 @@
       weak_ptr_factory_(this) {
 }
 
-TouchOperation::~TouchOperation() {
-}
+TouchOperation::~TouchOperation() = default;
 
 void TouchOperation::TouchFile(const base::FilePath& file_path,
                                const base::Time& last_access_time,
                                const base::Time& last_modified_time,
                                const FileOperationCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   ResourceEntry* entry = new ResourceEntry;
   base::PostTaskAndReplyWithResult(
@@ -77,8 +76,8 @@
     const FileOperationCallback& callback,
     const ResourceEntry* entry,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   FileChange changed_files;
   changed_files.Update(file_path, entry->file_info().is_directory()
diff --git a/components/drive/chromeos/file_system/touch_operation.h b/components/drive/chromeos/file_system/touch_operation.h
index c67bf760..6177fb35 100644
--- a/components/drive/chromeos/file_system/touch_operation.h
+++ b/components/drive/chromeos/file_system/touch_operation.h
@@ -54,7 +54,7 @@
   OperationDelegate* delegate_;
   internal::ResourceMetadata* metadata_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate the weak pointers before any other members are destroyed.
diff --git a/components/drive/chromeos/file_system/truncate_operation.cc b/components/drive/chromeos/file_system/truncate_operation.cc
index e47afb9..c981e892 100644
--- a/components/drive/chromeos/file_system/truncate_operation.cc
+++ b/components/drive/chromeos/file_system/truncate_operation.cc
@@ -71,14 +71,13 @@
       weak_ptr_factory_(this) {
 }
 
-TruncateOperation::~TruncateOperation() {
-}
+TruncateOperation::~TruncateOperation() = default;
 
 void TruncateOperation::Truncate(const base::FilePath& file_path,
                                  int64_t length,
                                  const FileOperationCallback& callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (length < 0) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -104,8 +103,8 @@
     FileError error,
     const base::FilePath& local_file_path,
     std::unique_ptr<ResourceEntry> entry) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   if (error != FILE_ERROR_OK) {
     callback.Run(error);
@@ -133,8 +132,8 @@
     const std::string& local_id,
     const FileOperationCallback& callback,
     FileError error) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!callback.is_null());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  DCHECK(callback);
 
   delegate_->OnEntryUpdatedByOperation(ClientContext(USER_INITIATED), local_id);
 
diff --git a/components/drive/chromeos/file_system/truncate_operation.h b/components/drive/chromeos/file_system/truncate_operation.h
index ee60310..766cc24 100644
--- a/components/drive/chromeos/file_system/truncate_operation.h
+++ b/components/drive/chromeos/file_system/truncate_operation.h
@@ -78,7 +78,7 @@
 
   std::unique_ptr<DownloadOperation> download_operation_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate the weak pointers before any other members are destroyed.
diff --git a/components/drive/chromeos/file_system_interface.h b/components/drive/chromeos/file_system_interface.h
index 66bb335..9332d32 100644
--- a/components/drive/chromeos/file_system_interface.h
+++ b/components/drive/chromeos/file_system_interface.h
@@ -194,7 +194,7 @@
 // The interface is defined to make FileSystem mockable.
 class FileSystemInterface {
  public:
-  virtual ~FileSystemInterface() = default;
+  virtual ~FileSystemInterface() {}
 
   // Adds and removes the observer.
   virtual void AddObserver(FileSystemObserver* observer) = 0;
diff --git a/components/drive/chromeos/file_system_observer.h b/components/drive/chromeos/file_system_observer.h
index 714943c3..7b9379f 100644
--- a/components/drive/chromeos/file_system_observer.h
+++ b/components/drive/chromeos/file_system_observer.h
@@ -33,7 +33,7 @@
                                 const base::FilePath& file_path) {}
 
  protected:
-  virtual ~FileSystemObserver() = default;
+  virtual ~FileSystemObserver() {}
 };
 
 }  // namespace drive
diff --git a/components/drive/directory_loader_unittest.cc b/components/drive/directory_loader_unittest.cc
index c7d8676a..d44bdfe6 100644
--- a/components/drive/directory_loader_unittest.cc
+++ b/components/drive/directory_loader_unittest.cc
@@ -18,6 +18,7 @@
 #include "components/drive/chromeos/file_cache.h"
 #include "components/drive/chromeos/loader_controller.h"
 #include "components/drive/chromeos/resource_metadata.h"
+#include "components/drive/chromeos/start_page_token_loader.h"
 #include "components/drive/event_logger.h"
 #include "components/drive/file_system_core_util.h"
 #include "components/drive/job_scheduler.h"
@@ -99,14 +100,13 @@
     ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());
 
     about_resource_loader_.reset(new AboutResourceLoader(scheduler_.get()));
+    start_page_token_loader_.reset(new StartPageTokenLoader(
+        drive::util::kTeamDriveIdDefaultCorpus, scheduler_.get()));
     loader_controller_.reset(new LoaderController);
-    directory_loader_.reset(
-        new DirectoryLoader(logger_.get(),
-                             base::ThreadTaskRunnerHandle::Get().get(),
-                             metadata_.get(),
-                             scheduler_.get(),
-                             about_resource_loader_.get(),
-                             loader_controller_.get()));
+    directory_loader_.reset(new DirectoryLoader(
+        logger_.get(), base::ThreadTaskRunnerHandle::Get().get(),
+        metadata_.get(), scheduler_.get(), about_resource_loader_.get(),
+        start_page_token_loader_.get(), loader_controller_.get()));
   }
 
   // Adds a new file to the root directory of the service.
@@ -137,6 +137,7 @@
   std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
   std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_;
   std::unique_ptr<AboutResourceLoader> about_resource_loader_;
+  std::unique_ptr<StartPageTokenLoader> start_page_token_loader_;
   std::unique_ptr<LoaderController> loader_controller_;
   std::unique_ptr<DirectoryLoader> directory_loader_;
 };
@@ -191,8 +192,8 @@
             metadata_->GetResourceEntryByPath(util::GetDriveMyDriveRootPath(),
                                               &entry));
   EXPECT_EQ(drive_service_->GetRootResourceId(), entry.resource_id());
-  EXPECT_EQ(drive_service_->about_resource().largest_change_id(),
-            entry.directory_specific_info().changestamp());
+  EXPECT_EQ(drive_service_->start_page_token().start_page_token(),
+            entry.directory_specific_info().start_page_token());
 
   // My Drive's child is present.
   base::FilePath file_path =
diff --git a/components/drive/drive.proto b/components/drive/drive.proto
index a997cfb8..8600fc25 100644
--- a/components/drive/drive.proto
+++ b/components/drive/drive.proto
@@ -79,8 +79,8 @@
   // changestamp of ResourceMetadata, if this directory was
   // "fast-fetched". See crbug.com/178348 for details about the "fast-fetch"
   // feature.
-  // TODO(slangley): Deprecate and remove changestamp.
-  optional int64 changestamp = 1;
+  // TODO(slangley): Remove changestamp once migration code can be removed.
+  optional int64 changestamp = 1 [deprecated = true];
 
   // The start page token of this directory. This value may not match the
   // start_page_token of ResourceMetadata if the directory was "fast-fetched".
@@ -168,8 +168,8 @@
   // drive_resource_metadata_storage.h defines the current version.
   optional int32 version = 1;
 
-  // TODO(slangley): Deprecate and remove changestamp.
-  optional int64 largest_changestamp = 2;
+  // TODO(slangley): Remove changestamp once migration code can be removed.
+  optional int64 largest_changestamp = 2 [deprecated = true];
 
   // The argument with ID 3 (starred_property_initialized) had been used, but
   // got deleted.
diff --git a/components/drive/file_system/operation_test_base.cc b/components/drive/file_system/operation_test_base.cc
index 4fe6587..990c549 100644
--- a/components/drive/file_system/operation_test_base.cc
+++ b/components/drive/file_system/operation_test_base.cc
@@ -12,8 +12,10 @@
 #include "components/drive/chromeos/file_system/operation_delegate.h"
 #include "components/drive/chromeos/loader_controller.h"
 #include "components/drive/chromeos/resource_metadata.h"
+#include "components/drive/chromeos/start_page_token_loader.h"
 #include "components/drive/event_logger.h"
 #include "components/drive/file_change.h"
+#include "components/drive/file_system_core_util.h"
 #include "components/drive/job_scheduler.h"
 #include "components/drive/service/fake_drive_service.h"
 #include "components/drive/service/test_util.h"
@@ -120,14 +122,13 @@
   // Makes sure the FakeDriveService's content is loaded to the metadata_.
   about_resource_loader_.reset(new internal::AboutResourceLoader(
       scheduler_.get()));
+  start_page_token_loader_.reset(new internal::StartPageTokenLoader(
+      drive::util::kTeamDriveIdDefaultCorpus, scheduler_.get()));
   loader_controller_.reset(new internal::LoaderController);
   change_list_loader_.reset(new internal::ChangeListLoader(
-      logger_.get(),
-      blocking_task_runner_.get(),
-      metadata_.get(),
-      scheduler_.get(),
-      about_resource_loader_.get(),
-      loader_controller_.get()));
+      logger_.get(), blocking_task_runner_.get(), metadata_.get(),
+      scheduler_.get(), about_resource_loader_.get(),
+      start_page_token_loader_.get(), loader_controller_.get()));
   change_list_loader_->LoadIfNeeded(
       google_apis::test_util::CreateCopyResultCallback(&error));
   content::RunAllTasksUntilIdle();
diff --git a/components/drive/file_system/operation_test_base.h b/components/drive/file_system/operation_test_base.h
index 3b2da8b..c06ad6f 100644
--- a/components/drive/file_system/operation_test_base.h
+++ b/components/drive/file_system/operation_test_base.h
@@ -36,6 +36,7 @@
 class LoaderController;
 class ResourceMetadata;
 class ResourceMetadataStorage;
+class StartPageTokenLoader;
 }  // namespace internal
 
 namespace file_system {
@@ -157,6 +158,7 @@
   std::unique_ptr<internal::ResourceMetadata, test_util::DestroyHelperForTests>
       metadata_;
   std::unique_ptr<internal::AboutResourceLoader> about_resource_loader_;
+  std::unique_ptr<internal::StartPageTokenLoader> start_page_token_loader_;
   std::unique_ptr<internal::LoaderController> loader_controller_;
   std::unique_ptr<internal::ChangeListLoader> change_list_loader_;
 };
diff --git a/components/drive/file_system_core_util.cc b/components/drive/file_system_core_util.cc
index 1ab0c661..0332592 100644
--- a/components/drive/file_system_core_util.cc
+++ b/components/drive/file_system_core_util.cc
@@ -119,6 +119,21 @@
   return base::NumberToString(changestamp + 1);
 }
 
+// Convers a start page token to a numerical changestamp
+bool ConvertStartPageTokenToChangestamp(const std::string& start_page_token,
+                                        int64_t* changestamp) {
+  DCHECK(changestamp);
+  int64_t result;
+  if (base::StringToInt64(start_page_token, &result)) {
+    // The minimum valid start_page_token is 1.
+    if (result > 0) {
+      *changestamp = result - 1;
+      return true;
+    }
+  }
+  return false;
+}
+
 std::string NormalizeFileName(const std::string& input) {
   DCHECK(base::IsStringUTF8(input));
 
diff --git a/components/drive/file_system_core_util.h b/components/drive/file_system_core_util.h
index 63541027..c4f1013 100644
--- a/components/drive/file_system_core_util.h
+++ b/components/drive/file_system_core_util.h
@@ -36,6 +36,9 @@
 const char kDriveTeamDrivesDirName[] = "team_drives";
 const char kDriveTrashDirName[] = "trash";
 
+// The team_drive_id value that signifies the users default corpus.
+constexpr char kTeamDriveIdDefaultCorpus[] = "";
+
 // Returns the path of the top root of the pseudo tree.
 const base::FilePath& GetDriveGrandRootPath();
 
@@ -56,6 +59,10 @@
 // Converts a numerical changestamp value to a start page token.
 std::string ConvertChangestampToStartPageToken(int64_t changestamp);
 
+// Convers a start page token to a numerical changestamp
+bool ConvertStartPageTokenToChangestamp(const std::string& stat_page_token,
+                                        int64_t* changestamp);
+
 // Converts the given string to a form suitable as a file name. Specifically,
 // - Normalizes in Unicode Normalization Form C.
 // - Replaces slashes '/' with '_'.
diff --git a/components/drive/file_system_unittest.cc b/components/drive/file_system_unittest.cc
index 2339f0c..d11f1a7 100644
--- a/components/drive/file_system_unittest.cc
+++ b/components/drive/file_system_unittest.cc
@@ -215,7 +215,7 @@
   // Sets up a filesystem with directories: drive/root, drive/root/Dir1,
   // drive/root/Dir1/SubDir2 and files drive/root/File1, drive/root/Dir1/File2,
   // drive/root/Dir1/SubDir2/File3. If |use_up_to_date_timestamp| is true, sets
-  // the changestamp to that of FakeDriveService, indicating the cache is
+  // the start_page_token to that of FakeDriveService, indicating the cache is
   // holding the latest file system info.
   void SetUpTestFileSystem(SetUpTestFileSystemParam param) {
     // Destroy the existing resource metadata to close DB.
@@ -242,12 +242,12 @@
 
     ASSERT_EQ(FILE_ERROR_OK, resource_metadata->Initialize());
 
-    const int64_t changestamp =
+    const std::string start_page_token =
         param == USE_SERVER_TIMESTAMP
-            ? fake_drive_service_->about_resource().largest_change_id()
-            : 1;
+            ? fake_drive_service_->start_page_token().start_page_token()
+            : "2";
     ASSERT_EQ(FILE_ERROR_OK,
-              resource_metadata->SetLargestChangestamp(changestamp));
+              resource_metadata->SetStartPageToken(start_page_token));
 
     // drive/root
     ResourceEntry root;
@@ -720,19 +720,19 @@
   EXPECT_TRUE(ReadDirectorySync(util::GetDriveMyDriveRootPath()));
 
   // SetUpTestFileSystem and FakeDriveService have the same
-  // changestamp (i.e. the local metadata is up to date), so no request for
+  // start_page_token (i.e. the local metadata is up to date), so no request for
   // new resource list (i.e., call to GetResourceList) should happen.
   EXPECT_EQ(0, fake_drive_service_->file_list_load_count());
 
   // Since the file system has verified that it holds the latest snapshot,
   // it should change its state to "loaded", which admits periodic refresh.
   // To test it, call CheckForUpdates and verify it does try to check updates.
-  const int about_resource_load_count_before =
-      fake_drive_service_->about_resource_load_count();
+  const int start_page_toke_load_count_before =
+      fake_drive_service_->start_page_token_load_count();
   file_system_->CheckForUpdates();
   content::RunAllTasksUntilIdle();
-  EXPECT_LT(about_resource_load_count_before,
-            fake_drive_service_->about_resource_load_count());
+  EXPECT_LT(start_page_toke_load_count_before,
+            fake_drive_service_->start_page_token_load_count());
 }
 
 TEST_F(FileSystemTest, LoadFileSystemFromCacheWhileOffline) {
@@ -745,12 +745,12 @@
 
   // Load the root.
   EXPECT_TRUE(ReadDirectorySync(util::GetDriveGrandRootPath()));
-  // Loading of about resource should not happen as it's offline.
-  EXPECT_EQ(0, fake_drive_service_->about_resource_load_count());
+  // Loading of start page token should not happen as it's offline.
+  EXPECT_EQ(0, fake_drive_service_->start_page_token_load_count());
 
   // Load "My Drive".
   EXPECT_TRUE(ReadDirectorySync(util::GetDriveMyDriveRootPath()));
-  EXPECT_EQ(0, fake_drive_service_->about_resource_load_count());
+  EXPECT_EQ(0, fake_drive_service_->start_page_token_load_count());
 
   // Tests that cached data can be loaded even if the server is not reachable.
   EXPECT_TRUE(EntryExists(base::FilePath(
@@ -773,7 +773,7 @@
   file_system_->CheckForUpdates();
 
   content::RunAllTasksUntilIdle();
-  EXPECT_EQ(1, fake_drive_service_->about_resource_load_count());
+  EXPECT_EQ(1, fake_drive_service_->start_page_token_load_count());
   EXPECT_EQ(1, fake_drive_service_->change_list_load_count());
 
   ASSERT_LE(0u, mock_directory_observer_->changed_directories().size());
diff --git a/components/drive/service/fake_drive_service.cc b/components/drive/service/fake_drive_service.cc
index 7a2bb4c8..d7b7acd5 100644
--- a/components/drive/service/fake_drive_service.cc
+++ b/components/drive/service/fake_drive_service.cc
@@ -26,6 +26,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
 #include "components/drive/drive_api_util.h"
+#include "components/drive/file_system_core_util.h"
 #include "google_apis/drive/drive_api_parser.h"
 #include "google_apis/drive/test_util.h"
 #include "net/base/escape.h"
@@ -1851,7 +1852,10 @@
 
   std::unique_ptr<ChangeList> change_list(new ChangeList);
   if (start_changestamp > 0 && start_offset == 0) {
-    change_list->set_largest_change_id(about_resource_->largest_change_id());
+    auto largest_change_id = about_resource_->largest_change_id();
+    change_list->set_largest_change_id(largest_change_id);
+    change_list->set_new_start_page_token(
+        drive::util::ConvertChangestampToStartPageToken(largest_change_id));
   }
 
   // If |max_results| is set, trim the entries if the number exceeded the max
@@ -1922,6 +1926,7 @@
 
 void FakeDriveService::UpdateLatestChangelistId(int64_t change_list_id) {
   about_resource_->set_largest_change_id(change_list_id);
-  start_page_token_->set_start_page_token(base::NumberToString(change_list_id));
+  start_page_token_->set_start_page_token(
+      drive::util::ConvertChangestampToStartPageToken(change_list_id));
 }
 }  // namespace drive
diff --git a/components/drive/service/fake_drive_service_unittest.cc b/components/drive/service/fake_drive_service_unittest.cc
index 9b944ac7..235c75f 100644
--- a/components/drive/service/fake_drive_service_unittest.cc
+++ b/components/drive/service/fake_drive_service_unittest.cc
@@ -19,6 +19,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "components/drive/file_system_core_util.h"
 #include "components/drive/service/test_util.h"
 #include "google_apis/drive/drive_api_parser.h"
 #include "google_apis/drive/test_util.h"
@@ -779,7 +780,8 @@
 
   ASSERT_TRUE(start_page_token);
   // Do some sanity check.
-  EXPECT_EQ(base::NumberToString(GetLargestChangeByAboutResource()),
+  EXPECT_EQ(drive::util::ConvertChangestampToStartPageToken(
+                GetLargestChangeByAboutResource()),
             start_page_token->start_page_token());
   EXPECT_EQ(1, fake_service_.start_page_token_load_count());
 }
diff --git a/components/drive/sync/entry_update_performer_unittest.cc b/components/drive/sync/entry_update_performer_unittest.cc
index 833cf84..2e2be3c8c 100644
--- a/components/drive/sync/entry_update_performer_unittest.cc
+++ b/components/drive/sync/entry_update_performer_unittest.cc
@@ -265,8 +265,8 @@
   const std::string kTestFileContent = "I'm being uploaded! Yay!";
   EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
 
-  int64_t original_changestamp =
-      fake_service()->about_resource().largest_change_id();
+  const std::string original_start_page_token =
+      fake_service()->start_page_token().start_page_token();
 
   // The callback will be called upon completion of UpdateEntry().
   FileError error = FILE_ERROR_FAILED;
@@ -278,8 +278,8 @@
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Check that the server has received an update.
-  EXPECT_LT(original_changestamp,
-            fake_service()->about_resource().largest_change_id());
+  EXPECT_NE(original_start_page_token,
+            fake_service()->start_page_token().start_page_token());
 
   // Check that the file size is updated to that of the updated content.
   google_apis::DriveApiErrorCode gdata_error = google_apis::DRIVE_OTHER_ERROR;
@@ -309,8 +309,8 @@
   const std::string kTestFileContent = "I'm being uploaded! Yay!";
   EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
 
-  int64_t original_changestamp =
-      fake_service()->about_resource().largest_change_id();
+  std::string original_start_page_token =
+      fake_service()->start_page_token().start_page_token();
 
   // The callback will be called upon completion of UpdateEntry().
   FileError error = FILE_ERROR_FAILED;
@@ -322,8 +322,8 @@
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Check that the server has received an update.
-  EXPECT_LT(original_changestamp,
-            fake_service()->about_resource().largest_change_id());
+  EXPECT_NE(original_start_page_token,
+            fake_service()->start_page_token().start_page_token());
 
   // Check that the file size is updated to that of the updated content.
   google_apis::DriveApiErrorCode gdata_error = google_apis::DRIVE_OTHER_ERROR;
@@ -360,7 +360,8 @@
   // And call UpdateEntry again.
   // In this case, although the file is marked as dirty, but the content
   // hasn't been changed. Thus, the actual uploading should be skipped.
-  original_changestamp = fake_service()->about_resource().largest_change_id();
+  original_start_page_token =
+      fake_service()->start_page_token().start_page_token();
   error = FILE_ERROR_FAILED;
   performer_->UpdateEntry(
       local_id,
@@ -369,8 +370,8 @@
   content::RunAllTasksUntilIdle();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
-  EXPECT_EQ(original_changestamp,
-            fake_service()->about_resource().largest_change_id());
+  EXPECT_EQ(original_start_page_token,
+            fake_service()->start_page_token().start_page_token());
 
   // Make sure that the cache is no longer dirty.
   EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
diff --git a/components/drive/sync_client_unittest.cc b/components/drive/sync_client_unittest.cc
index 04f61d2..9a40532 100644
--- a/components/drive/sync_client_unittest.cc
+++ b/components/drive/sync_client_unittest.cc
@@ -23,6 +23,7 @@
 #include "components/drive/chromeos/file_system/remove_operation.h"
 #include "components/drive/chromeos/loader_controller.h"
 #include "components/drive/chromeos/resource_metadata.h"
+#include "components/drive/chromeos/start_page_token_loader.h"
 #include "components/drive/drive.pb.h"
 #include "components/drive/event_logger.h"
 #include "components/drive/file_change.h"
@@ -137,14 +138,13 @@
     ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());
 
     about_resource_loader_.reset(new AboutResourceLoader(scheduler_.get()));
+    start_page_token_loader_.reset(new StartPageTokenLoader(
+        drive::util::kTeamDriveIdDefaultCorpus, scheduler_.get()));
     loader_controller_.reset(new LoaderController);
     change_list_loader_.reset(new ChangeListLoader(
-        logger_.get(),
-        base::ThreadTaskRunnerHandle::Get().get(),
-        metadata_.get(),
-        scheduler_.get(),
-        about_resource_loader_.get(),
-        loader_controller_.get()));
+        logger_.get(), base::ThreadTaskRunnerHandle::Get().get(),
+        metadata_.get(), scheduler_.get(), about_resource_loader_.get(),
+        start_page_token_loader_.get(), loader_controller_.get()));
     ASSERT_NO_FATAL_FAILURE(SetUpTestData());
 
     sync_client_.reset(
@@ -261,6 +261,7 @@
   std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
   std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_;
   std::unique_ptr<AboutResourceLoader> about_resource_loader_;
+  std::unique_ptr<StartPageTokenLoader> start_page_token_loader_;
   std::unique_ptr<LoaderController> loader_controller_;
   std::unique_ptr<ChangeListLoader> change_list_loader_;
   std::unique_ptr<SyncClient> sync_client_;
diff --git a/components/ntp_snippets/content_suggestions_service.cc b/components/ntp_snippets/content_suggestions_service.cc
index ce663a2..0e320f7 100644
--- a/components/ntp_snippets/content_suggestions_service.cc
+++ b/components/ntp_snippets/content_suggestions_service.cc
@@ -534,16 +534,13 @@
 // history::HistoryServiceObserver implementation.
 void ContentSuggestionsService::OnURLsDeleted(
     history::HistoryService* history_service,
-    bool all_history,
-    bool expired,
-    const history::URLRows& deleted_rows,
-    const std::set<GURL>& favicon_urls) {
+    const history::DeletionInfo& deletion_info) {
   // We don't care about expired entries.
-  if (expired) {
+  if (deletion_info.is_from_expiration()) {
     return;
   }
 
-  if (all_history) {
+  if (deletion_info.IsAllHistory()) {
     base::Callback<bool(const GURL& url)> filter =
         base::Bind([](const GURL& url) { return true; });
     ClearHistory(base::Time(), base::Time::Max(), filter);
@@ -554,11 +551,11 @@
     // basis. However this depends on the provider's details and thus cannot be
     // done here. Introduce a OnURLsDeleted() method on the providers to move
     // this decision further down.
-    if (deleted_rows.size() < 2) {
+    if (deletion_info.deleted_rows().size() < 2) {
       return;
     }
     std::set<GURL> deleted_urls;
-    for (const history::URLRow& row : deleted_rows) {
+    for (const history::URLRow& row : deletion_info.deleted_rows()) {
       deleted_urls.insert(row.url());
     }
     base::Callback<bool(const GURL& url)> filter =
diff --git a/components/ntp_snippets/content_suggestions_service.h b/components/ntp_snippets/content_suggestions_service.h
index 6cc866c..00ec36b 100644
--- a/components/ntp_snippets/content_suggestions_service.h
+++ b/components/ntp_snippets/content_suggestions_service.h
@@ -294,10 +294,7 @@
 
   // history::HistoryServiceObserver implementation.
   void OnURLsDeleted(history::HistoryService* history_service,
-                     bool all_history,
-                     bool expired,
-                     const history::URLRows& deleted_rows,
-                     const std::set<GURL>& favicon_urls) override;
+                     const history::DeletionInfo& deletion_info) override;
   void HistoryServiceBeingDeleted(
       history::HistoryService* history_service) override;
 
diff --git a/components/ntp_snippets/content_suggestions_service_unittest.cc b/components/ntp_snippets/content_suggestions_service_unittest.cc
index 9c2246a4..8df09e4 100644
--- a/components/ntp_snippets/content_suggestions_service_unittest.cc
+++ b/components/ntp_snippets/content_suggestions_service_unittest.cc
@@ -576,8 +576,7 @@
       MakeRegisteredMockProvider(category);
   EXPECT_CALL(*provider, ClearHistory(base::Time(), base::Time::Max(), _));
   static_cast<history::HistoryServiceObserver*>(service())->OnURLsDeleted(
-      /*history_service=*/nullptr, /*all_history=*/true, /*expired=*/false,
-      history::URLRows(), /*favicon_urls=*/std::set<GURL>());
+      /*history_service=*/nullptr, history::DeletionInfo::ForAllHistory());
 
   service()->RemoveObserver(&observer);
 }
@@ -590,15 +589,19 @@
   service()->AddObserver(&observer);
 
   static_cast<history::HistoryServiceObserver*>(service())->OnURLsDeleted(
-      /*history_service=*/nullptr, /*all_history=*/true,
-      /*expired=*/true, history::URLRows(),
-      /*favicon_urls=*/std::set<GURL>());
+      /*history_service=*/nullptr,
+      history::DeletionInfo(history::DeletionTimeRange::AllTime(),
+                            /*expired=*/true, history::URLRows(),
+                            /*favicon_urls=*/std::set<GURL>(),
+                            /*restrict_urls=*/base::nullopt));
   static_cast<history::HistoryServiceObserver*>(service())->OnURLsDeleted(
-      /*history_service=*/nullptr, /*all_history=*/false,
-      /*expired=*/true,
-      history::URLRows({history::URLRow(GURL("http://google.com")),
-                        history::URLRow(GURL("http://maps.google.com"))}),
-      /*favicon_urls=*/std::set<GURL>());
+      /*history_service=*/nullptr,
+      history::DeletionInfo(history::DeletionTimeRange::Invalid(),
+                            /*expired=*/true,
+                            {history::URLRow(GURL("http://google.com")),
+                             history::URLRow(GURL("http://maps.google.com"))},
+                            /*favicon_urls=*/std::set<GURL>(),
+                            /*restrict_urls=*/base::nullopt));
 
   service()->RemoveObserver(&observer);
 }
@@ -607,9 +610,7 @@
   Category category = Category::FromKnownCategory(KnownCategories::DOWNLOADS);
   MakeRegisteredMockProvider(category);
   static_cast<history::HistoryServiceObserver*>(service())->OnURLsDeleted(
-      /*history_service=*/nullptr, /*all_history=*/false,
-      /*expired=*/false, history::URLRows(),
-      /*favicon_urls=*/std::set<GURL>());
+      /*history_service=*/nullptr, history::DeletionInfo::ForUrls({}, {}));
 }
 
 TEST_F(ContentSuggestionsServiceTest,
@@ -618,10 +619,10 @@
   MakeRegisteredMockProvider(category);
   // Single URLs should not trigger
   static_cast<history::HistoryServiceObserver*>(service())->OnURLsDeleted(
-      /*history_service=*/nullptr, /*all_history=*/false,
-      /*expired=*/false,
-      history::URLRows({history::URLRow(GURL("http://google.com"))}),
-      /*favicon_urls=*/std::set<GURL>());
+      /*history_service=*/nullptr,
+      history::DeletionInfo::ForUrls(
+          {history::URLRow(GURL("http://google.com"))},
+          /*favicon_urls=*/std::set<GURL>()));
 }
 
 TEST_F(ContentSuggestionsServiceTest,
@@ -636,11 +637,11 @@
   EXPECT_CALL(*provider, ClearHistory(base::Time(), base::Time::Max(), _));
 
   static_cast<history::HistoryServiceObserver*>(service())->OnURLsDeleted(
-      /*history_service=*/nullptr, /*all_history=*/false,
-      /*expired=*/false,
-      history::URLRows({history::URLRow(GURL("http://google.com")),
-                        history::URLRow(GURL("http://youtube.com"))}),
-      /*favicon_urls=*/std::set<GURL>());
+      /*history_service=*/nullptr,
+      history::DeletionInfo::ForUrls(
+          {history::URLRow(GURL("http://google.com")),
+           history::URLRow(GURL("http://youtube.com"))},
+          /*favicon_urls=*/std::set<GURL>()));
 
   service()->RemoveObserver(&observer);
 }
diff --git a/components/omnibox/browser/omnibox_edit_model.h b/components/omnibox/browser/omnibox_edit_model.h
index 557f888..35c92c9 100644
--- a/components/omnibox/browser/omnibox_edit_model.h
+++ b/components/omnibox/browser/omnibox_edit_model.h
@@ -349,6 +349,9 @@
   // Called when the current match has changed in the OmniboxController.
   void OnCurrentMatchChanged();
 
+  // Used for testing purposes only.
+  base::string16 GetUserTextForTesting() const { return user_text_; }
+
   // Name of the histogram tracking cut or copy omnibox commands.
   static const char kCutOrCopyAllTextHistogram[];
 
diff --git a/components/safe_browsing/password_protection/password_protection_service.cc b/components/safe_browsing/password_protection/password_protection_service.cc
index 5470a611..cf13fd0 100644
--- a/components/safe_browsing/password_protection/password_protection_service.cc
+++ b/components/safe_browsing/password_protection/password_protection_service.cc
@@ -559,19 +559,18 @@
 
 void PasswordProtectionService::OnURLsDeleted(
     history::HistoryService* history_service,
-    bool all_history,
-    bool expired,
-    const history::URLRows& deleted_rows,
-    const std::set<GURL>& favicon_urls) {
+    const history::DeletionInfo& deletion_info) {
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
       base::Bind(&PasswordProtectionService::RemoveContentSettingsOnURLsDeleted,
-                 GetWeakPtr(), all_history, deleted_rows));
+                 GetWeakPtr(), deletion_info.IsAllHistory(),
+                 deletion_info.deleted_rows()));
   BrowserThread::PostTask(
       BrowserThread::UI, FROM_HERE,
       base::Bind(&PasswordProtectionService::
                      RemoveUnhandledSyncPasswordReuseOnURLsDeleted,
-                 GetWeakPtr(), all_history, deleted_rows));
+                 GetWeakPtr(), deletion_info.IsAllHistory(),
+                 deletion_info.deleted_rows()));
 }
 
 void PasswordProtectionService::HistoryServiceBeingDeleted(
diff --git a/components/safe_browsing/password_protection/password_protection_service.h b/components/safe_browsing/password_protection/password_protection_service.h
index 2a047f6..370edfc0 100644
--- a/components/safe_browsing/password_protection/password_protection_service.h
+++ b/components/safe_browsing/password_protection/password_protection_service.h
@@ -362,10 +362,7 @@
 
   // Overridden from history::HistoryServiceObserver.
   void OnURLsDeleted(history::HistoryService* history_service,
-                     bool all_history,
-                     bool expired,
-                     const history::URLRows& deleted_rows,
-                     const std::set<GURL>& favicon_urls) override;
+                     const history::DeletionInfo& deletion_info) override;
 
   void HistoryServiceBeingDeleted(
       history::HistoryService* history_service) override;
diff --git a/components/ukm/observers/history_delete_observer.cc b/components/ukm/observers/history_delete_observer.cc
index 00b6f983..da42600 100644
--- a/components/ukm/observers/history_delete_observer.cc
+++ b/components/ukm/observers/history_delete_observer.cc
@@ -21,11 +21,8 @@
 
 void HistoryDeleteObserver::OnURLsDeleted(
     history::HistoryService* history_service,
-    bool all_history,
-    bool expired,
-    const history::URLRows& deleted_rows,
-    const std::set<GURL>& favicon_urls) {
-  if (!expired)
+    const history::DeletionInfo& deletion_info) {
+  if (!deletion_info.is_from_expiration())
     OnHistoryDeleted();
 }
 
diff --git a/components/ukm/observers/history_delete_observer.h b/components/ukm/observers/history_delete_observer.h
index eb39e50a7..ea48bfc 100644
--- a/components/ukm/observers/history_delete_observer.h
+++ b/components/ukm/observers/history_delete_observer.h
@@ -24,10 +24,7 @@
 
   // history::HistoryServiceObserver
   void OnURLsDeleted(history::HistoryService* history_service,
-                     bool all_history,
-                     bool expired,
-                     const history::URLRows& deleted_rows,
-                     const std::set<GURL>& favicon_urls) override;
+                     const history::DeletionInfo& deletion_info) override;
   void HistoryServiceBeingDeleted(
       history::HistoryService* history_service) override;
 
diff --git a/components/url_formatter/idn_spoof_checker.cc b/components/url_formatter/idn_spoof_checker.cc
index 97b1171..95560dc 100644
--- a/components/url_formatter/idn_spoof_checker.cc
+++ b/components/url_formatter/idn_spoof_checker.cc
@@ -155,12 +155,16 @@
       UTRANS_FORWARD, parse_error, status));
 
   // Supplement the Unicode confusable list by the following mapping.
+  //   - {U+00E6 (æ), U+04D5 (ӕ)}  => "ae"
   //   - {U+00FE (þ), U+03FC (ϼ), U+048F (ҏ)} => p
   //   - {U+0127 (ħ), U+043D (н), U+045B (ћ), U+04A3 (ң), U+04A5 (ҥ),
   //      U+04C8 (ӈ), U+04CA (ӊ), U+050B (ԋ), U+0527 (ԧ), U+0529 (ԩ)} => h
   //   - {U+0138 (ĸ), U+03BA (κ), U+043A (к), U+049B (қ), U+049D (ҝ),
   //      U+049F (ҟ), U+04A1(ҡ), U+04C4 (ӄ), U+051F (ԟ)} => k
-  //   - {U+014B (ŋ), U+043F (п)} => n
+  //   - {U+014B (ŋ), U+043F (п), U+0525 (ԥ)} => n
+  //   - U+0153 (œ) => "ce"
+  //     TODO: see https://crbug.com/843352 for further work on
+  //     U+0525 and U+0153.
   //   - {U+0167 (ŧ), U+0442 (т), U+04AD (ҭ), U+050F (ԏ)} => t
   //   - {U+0185 (ƅ), U+044C (ь), U+048D (ҍ), U+0432 (в)} => b
   //   - {U+03C9 (ω), U+0448 (ш), U+0449 (щ), U+0E1F (ฟ)} => w
@@ -175,16 +179,17 @@
   //   - {U+050D (ԍ), U+100c (ဌ)} => g
   //   - {U+0D1F (ട), U+0E23 (ร)} => s
   //   - U+1042 (၂) => j
-  //   - {U+0437 (з), U+04E1 (ӡ)} => 3
+  //   - {U+0437 (з), U+0499 (ҙ), U+04E1 (ӡ)} => 3
   extra_confusable_mapper_.reset(icu::Transliterator::createFromRules(
       UNICODE_STRING_SIMPLE("ExtraConf"),
-      icu::UnicodeString::fromUTF8("[þϼҏ] > p; [ħнћңҥӈӊԋԧԩ] > h;"
-                                   "[ĸκкқҝҟҡӄԟ] > k; [ŋп] > n; [ŧтҭԏ] > t;"
-                                   "[ƅьҍв] > b;  [ωшщฟ] > w; [мӎ] > m;"
-                                   "[єҽҿၔ] > e; ґ > r; [ғӻ] > f; [ҫင] > c;"
-                                   "ұ > y; [χҳӽӿ] > x;"
-                                   "ԃ  > d; [ԍဌ] > g; [ടร] > s; ၂ > j;"
-                                   "[зӡ] > 3"),
+      icu::UnicodeString::fromUTF8(
+          "[æӕ] > ae; [þϼҏ] > p; [ħнћңҥӈӊԋԧԩ] > h;"
+          "[ĸκкқҝҟҡӄԟ] > k; [ŋпԥ] > n; œ > ce;"
+          "[ŧтҭԏ] > t; [ƅьҍв] > b;  [ωшщฟ] > w;"
+          "[мӎ] > m; [єҽҿၔ] > e; ґ > r; [ғӻ] > f;"
+          "[ҫင] > c; ұ > y; [χҳӽӿ] > x;"
+          "ԃ  > d; [ԍဌ] > g; [ടร] > s; ၂ > j;"
+          "[зҙӡ] > 3"),
       UTRANS_FORWARD, parse_error, status));
   DCHECK(U_SUCCESS(status))
       << "Spoofchecker initalization failed due to an error: "
@@ -274,8 +279,6 @@
     // - Disallow three Hiragana letters (U+307[8-A]) or Katakana letters
     //   (U+30D[8-A]) that look exactly like each other when they're used in a
     //   label otherwise entirely in Katakna or Hiragana.
-    // - Disallow U+0585 (Armenian Small Letter Oh) and U+0581 (Armenian Small
-    //   Letter Co) to be next to Latin.
     // - Disallow combining diacritical mark (U+0300-U+0339) after a non-LGC
     //   character. Other combining diacritical marks are not in the allowed
     //   character set.
diff --git a/components/url_formatter/top_domains/test_domains.list b/components/url_formatter/top_domains/test_domains.list
index 0f0be0e..7f5df3d 100644
--- a/components/url_formatter/top_domains/test_domains.list
+++ b/components/url_formatter/top_domains/test_domains.list
@@ -18,3 +18,5 @@
 cegjo.com
 wsws.com
 1234567890.com
+aece.com
+aen.com
diff --git a/components/url_formatter/top_domains/test_skeletons.gperf b/components/url_formatter/top_domains/test_skeletons.gperf
index 0646188..9d508ad 100644
--- a/components/url_formatter/top_domains/test_skeletons.gperf
+++ b/components/url_formatter/top_domains/test_skeletons.gperf
@@ -28,4 +28,6 @@
 cegjo.corn, 1
 wsws.corn, 1
 l23456789O.corn, 1
+aece.corn, 1
+aen.corn, 1
 %%
diff --git a/components/url_formatter/url_formatter_unittest.cc b/components/url_formatter/url_formatter_unittest.cc
index 054dbae..a01a52a 100644
--- a/components/url_formatter/url_formatter_unittest.cc
+++ b/components/url_formatter/url_formatter_unittest.cc
@@ -527,6 +527,8 @@
     {"xn--13457890-e7g0943b.com", L"1\x14bf" L"345\x0431" L"7890.com", false},
     // 12з4567890.com
     {"xn--124567890-10h.com", L"12\x0437" L"4567890.com", false},
+    // 12ҙ4567890.com
+    {"xn--124567890-1ti.com", L"12\x0499" L"4567890.com", false},
     // 12ӡ4567890.com
     {"xn--124567890-mfj.com", L"12\x04e1" L"4567890.com", false},
     // 123Ꮞ567890.com
@@ -540,6 +542,15 @@
     // 123456789ꓳ.com
     {"xn--123456789-tx75a.com", L"123456789\xa4f3.com", false},
 
+    // aeœ.com
+    {"xn--ae-fsa.com", L"ae\x0153.com", false},
+    // æce.com
+    {"xn--ce-0ia.com", L"\x00e6" L"ce.com", false},
+    // æœ.com
+    {"xn--6ca2t.com", L"\x00e6\x0153.com", false},
+    // ӕԥ.com
+    {"xn--y5a4n.com", L"\x04d5\x0525.com", false},
+
     // ငၔဌ၂ဝ.com (entirely made of Myanmar characters)
     {"xn--ridq5c9hnd.com", L"\x1004\x1054\x100c" L"\x1042\x101d.com", false},
 
diff --git a/components/viz/common/surfaces/child_local_surface_id_allocator.cc b/components/viz/common/surfaces/child_local_surface_id_allocator.cc
index e773ae92..f39a547 100644
--- a/components/viz/common/surfaces/child_local_surface_id_allocator.cc
+++ b/components/viz/common/surfaces/child_local_surface_id_allocator.cc
@@ -15,7 +15,7 @@
                                 kInitialChildSequenceNumber,
                                 base::UnguessableToken()) {}
 
-const LocalSurfaceId& ChildLocalSurfaceIdAllocator::UpdateFromParent(
+bool ChildLocalSurfaceIdAllocator::UpdateFromParent(
     const LocalSurfaceId& parent_allocated_local_surface_id) {
   if (parent_allocated_local_surface_id.parent_sequence_number() >
       current_local_surface_id_.parent_sequence_number()) {
@@ -23,8 +23,9 @@
         parent_allocated_local_surface_id.parent_sequence_number_;
     current_local_surface_id_.embed_token_ =
         parent_allocated_local_surface_id.embed_token_;
+    return true;
   }
-  return current_local_surface_id_;
+  return false;
 }
 
 const LocalSurfaceId& ChildLocalSurfaceIdAllocator::GenerateId() {
diff --git a/components/viz/common/surfaces/child_local_surface_id_allocator.h b/components/viz/common/surfaces/child_local_surface_id_allocator.h
index bc1317a..2ca71d6 100644
--- a/components/viz/common/surfaces/child_local_surface_id_allocator.h
+++ b/components/viz/common/surfaces/child_local_surface_id_allocator.h
@@ -30,8 +30,9 @@
 
   // When a parent-allocated LocalSurfaceId arrives in the child, the child
   // needs to update its understanding of the last generated message so the
-  // messages can continue to monotonically increase.
-  const LocalSurfaceId& UpdateFromParent(
+  // messages can continue to monotonically increase. Returns whether the
+  // current LocalSurfaceId has been updated.
+  bool UpdateFromParent(
       const LocalSurfaceId& parent_allocated_local_surface_id);
 
   const LocalSurfaceId& GenerateId();
diff --git a/components/viz/common/surfaces/child_local_surface_id_allocator_unittest.cc b/components/viz/common/surfaces/child_local_surface_id_allocator_unittest.cc
index abddd5d..99dd27a 100644
--- a/components/viz/common/surfaces/child_local_surface_id_allocator_unittest.cc
+++ b/components/viz/common/surfaces/child_local_surface_id_allocator_unittest.cc
@@ -91,9 +91,9 @@
   EXPECT_NE(preupdate_local_surface_id.embed_token(),
             parent_allocated_local_surface_id.embed_token());
 
-  const LocalSurfaceId& returned_local_surface_id =
-      parent_updated_child_allocator.UpdateFromParent(
-          parent_allocated_local_surface_id);
+  bool changed = parent_updated_child_allocator.UpdateFromParent(
+      parent_allocated_local_surface_id);
+  EXPECT_TRUE(changed);
 
   const LocalSurfaceId& postupdate_local_surface_id =
       parent_updated_child_allocator.GetCurrentLocalSurfaceId();
@@ -103,8 +103,6 @@
             parent_allocated_local_surface_id.child_sequence_number());
   EXPECT_EQ(postupdate_local_surface_id.embed_token(),
             parent_allocated_local_surface_id.embed_token());
-  EXPECT_EQ(returned_local_surface_id,
-            parent_updated_child_allocator.GetCurrentLocalSurfaceId());
 }
 
 // GenerateId() on a child allocator should monotonically increment the child
diff --git a/components/viz/common/surfaces/parent_local_surface_id_allocator.cc b/components/viz/common/surfaces/parent_local_surface_id_allocator.cc
index 2f952a9..4258655 100644
--- a/components/viz/common/surfaces/parent_local_surface_id_allocator.cc
+++ b/components/viz/common/surfaces/parent_local_surface_id_allocator.cc
@@ -17,15 +17,16 @@
                                 kInitialChildSequenceNumber,
                                 base::UnguessableToken::Create()) {}
 
-const LocalSurfaceId& ParentLocalSurfaceIdAllocator::UpdateFromChild(
+bool ParentLocalSurfaceIdAllocator::UpdateFromChild(
     const LocalSurfaceId& child_allocated_local_surface_id) {
   if (child_allocated_local_surface_id.child_sequence_number() >
       current_local_surface_id_.child_sequence_number()) {
     current_local_surface_id_.child_sequence_number_ =
         child_allocated_local_surface_id.child_sequence_number_;
     is_invalid_ = false;
+    return true;
   }
-  return current_local_surface_id_;
+  return false;
 }
 
 void ParentLocalSurfaceIdAllocator::Reset(
diff --git a/components/viz/common/surfaces/parent_local_surface_id_allocator.h b/components/viz/common/surfaces/parent_local_surface_id_allocator.h
index d90e38f..2dab7b6 100644
--- a/components/viz/common/surfaces/parent_local_surface_id_allocator.h
+++ b/components/viz/common/surfaces/parent_local_surface_id_allocator.h
@@ -30,9 +30,9 @@
 
   // When a child-allocated LocalSurfaceId arrives in the parent, the parent
   // needs to update its understanding of the last generated message so the
-  // messages can continue to monotonically increase.
-  const LocalSurfaceId& UpdateFromChild(
-      const LocalSurfaceId& child_allocated_local_surface_id);
+  // messages can continue to monotonically increase. Returns whether the
+  // current LocalSurfaceId has been updated.
+  bool UpdateFromChild(const LocalSurfaceId& child_allocated_local_surface_id);
 
   // Resets this allocator with the provided |local_surface_id| as a seed.
   void Reset(const LocalSurfaceId& local_surface_id);
diff --git a/components/viz/common/surfaces/parent_local_surface_id_allocator_unittest.cc b/components/viz/common/surfaces/parent_local_surface_id_allocator_unittest.cc
index 9cde1a0..77837ea 100644
--- a/components/viz/common/surfaces/parent_local_surface_id_allocator_unittest.cc
+++ b/components/viz/common/surfaces/parent_local_surface_id_allocator_unittest.cc
@@ -97,9 +97,9 @@
   EXPECT_EQ(preupdate_local_surface_id.embed_token(),
             child_allocated_local_surface_id.embed_token());
 
-  const LocalSurfaceId& returned_local_surface_id =
-      child_updated_parent_allocator.UpdateFromChild(
-          child_allocated_local_surface_id);
+  bool changed = child_updated_parent_allocator.UpdateFromChild(
+      child_allocated_local_surface_id);
+  EXPECT_TRUE(changed);
 
   const LocalSurfaceId& postupdate_local_surface_id =
       child_updated_parent_allocator.GetCurrentLocalSurfaceId();
@@ -109,8 +109,6 @@
             child_allocated_local_surface_id.child_sequence_number());
   EXPECT_EQ(postupdate_local_surface_id.embed_token(),
             child_allocated_local_surface_id.embed_token());
-  EXPECT_EQ(returned_local_surface_id,
-            child_updated_parent_allocator.GetCurrentLocalSurfaceId());
   EXPECT_FALSE(child_updated_parent_allocator.is_allocation_suppressed());
 }
 
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 2d20fa3..233bab9 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -2078,8 +2078,6 @@
       "android/gesture_listener_manager.h",
       "android/ime_adapter_android.cc",
       "android/ime_adapter_android.h",
-      "android/interstitial_page_delegate_android.cc",
-      "android/interstitial_page_delegate_android.h",
       "android/java/gin_java_bound_object.cc",
       "android/java/gin_java_bound_object.h",
       "android/java/gin_java_bound_object_delegate.cc",
@@ -2172,6 +2170,7 @@
     deps += [
       ":reflection_jni_headers",
       "//content/public/android:jni",
+      "//device/gamepad/public/mojom",
       "//media",
       "//media/capture/content/android",
       "//media/capture/video/android",
diff --git a/content/browser/background_fetch/background_fetch_job_controller.cc b/content/browser/background_fetch/background_fetch_job_controller.cc
index c87cc00..c06ab4ae 100644
--- a/content/browser/background_fetch/background_fetch_job_controller.cc
+++ b/content/browser/background_fetch/background_fetch_job_controller.cc
@@ -147,7 +147,15 @@
   for (const auto& pair : active_request_download_bytes_)
     aborted_guids.push_back(pair.first);
   request_manager_->OnJobAborted(registration_id(), std::move(aborted_guids));
-  Finish(true /* aborted */);
+  if (!cancel_download) {
+    // Don't call Finish() here, so that we don't mark data for deletion while
+    // there are active fetches.
+    // Once the controller finishes processing, this function will be called
+    // again. (BackgroundFetchScheduler's finished_callback_ will call
+    // BackgroundFetchJobController::Abort() with |cancel_download| set to
+    // true.)
+    Finish(true /* aborted */);
+  }
 }
 
 }  // namespace content
diff --git a/content/browser/background_fetch/background_fetch_scheduler.cc b/content/browser/background_fetch/background_fetch_scheduler.cc
index 1b96430..fb13ada 100644
--- a/content/browser/background_fetch/background_fetch_scheduler.cc
+++ b/content/browser/background_fetch/background_fetch_scheduler.cc
@@ -21,6 +21,7 @@
 
 void BackgroundFetchScheduler::Controller::Finish(bool abort) {
   DCHECK(abort || !HasMoreRequests());
+
   std::move(finished_callback_).Run(registration_id_, abort);
 }
 
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc
index 58fa019..114a656 100644
--- a/content/browser/devtools/protocol/network_handler.cc
+++ b/content/browser/devtools/protocol/network_handler.cc
@@ -626,34 +626,45 @@
     return net::ERR_INTERNET_DISCONNECTED;
   if (error == Network::ErrorReasonEnum::AddressUnreachable)
     return net::ERR_ADDRESS_UNREACHABLE;
+  if (error == Network::ErrorReasonEnum::BlockedByClient)
+    return net::ERR_BLOCKED_BY_CLIENT;
+  if (error == Network::ErrorReasonEnum::BlockedByResponse)
+    return net::ERR_BLOCKED_BY_RESPONSE;
   *ok = false;
   return net::ERR_FAILED;
 }
 
 String NetErrorToString(int net_error) {
-  if (net_error == net::ERR_ABORTED)
-    return Network::ErrorReasonEnum::Aborted;
-  if (net_error == net::ERR_TIMED_OUT)
-    return Network::ErrorReasonEnum::TimedOut;
-  if (net_error == net::ERR_ACCESS_DENIED)
-    return Network::ErrorReasonEnum::AccessDenied;
-  if (net_error == net::ERR_CONNECTION_CLOSED)
-    return Network::ErrorReasonEnum::ConnectionClosed;
-  if (net_error == net::ERR_CONNECTION_RESET)
-    return Network::ErrorReasonEnum::ConnectionReset;
-  if (net_error == net::ERR_CONNECTION_REFUSED)
-    return Network::ErrorReasonEnum::ConnectionRefused;
-  if (net_error == net::ERR_CONNECTION_ABORTED)
-    return Network::ErrorReasonEnum::ConnectionAborted;
-  if (net_error == net::ERR_CONNECTION_FAILED)
-    return Network::ErrorReasonEnum::ConnectionFailed;
-  if (net_error == net::ERR_NAME_NOT_RESOLVED)
-    return Network::ErrorReasonEnum::NameNotResolved;
-  if (net_error == net::ERR_INTERNET_DISCONNECTED)
-    return Network::ErrorReasonEnum::InternetDisconnected;
-  if (net_error == net::ERR_ADDRESS_UNREACHABLE)
-    return Network::ErrorReasonEnum::AddressUnreachable;
-  return Network::ErrorReasonEnum::Failed;
+  switch (net_error) {
+    case net::ERR_ABORTED:
+      return Network::ErrorReasonEnum::Aborted;
+    case net::ERR_TIMED_OUT:
+      return Network::ErrorReasonEnum::TimedOut;
+    case net::ERR_ACCESS_DENIED:
+      return Network::ErrorReasonEnum::AccessDenied;
+    case net::ERR_CONNECTION_CLOSED:
+      return Network::ErrorReasonEnum::ConnectionClosed;
+    case net::ERR_CONNECTION_RESET:
+      return Network::ErrorReasonEnum::ConnectionReset;
+    case net::ERR_CONNECTION_REFUSED:
+      return Network::ErrorReasonEnum::ConnectionRefused;
+    case net::ERR_CONNECTION_ABORTED:
+      return Network::ErrorReasonEnum::ConnectionAborted;
+    case net::ERR_CONNECTION_FAILED:
+      return Network::ErrorReasonEnum::ConnectionFailed;
+    case net::ERR_NAME_NOT_RESOLVED:
+      return Network::ErrorReasonEnum::NameNotResolved;
+    case net::ERR_INTERNET_DISCONNECTED:
+      return Network::ErrorReasonEnum::InternetDisconnected;
+    case net::ERR_ADDRESS_UNREACHABLE:
+      return Network::ErrorReasonEnum::AddressUnreachable;
+    case net::ERR_BLOCKED_BY_CLIENT:
+      return Network::ErrorReasonEnum::BlockedByClient;
+    case net::ERR_BLOCKED_BY_RESPONSE:
+      return Network::ErrorReasonEnum::BlockedByResponse;
+    default:
+      return Network::ErrorReasonEnum::Failed;
+  }
 }
 
 bool AddInterceptedResourceType(
diff --git a/content/browser/media/forwarding_audio_stream_factory.cc b/content/browser/media/forwarding_audio_stream_factory.cc
index 2868b67..b2616789 100644
--- a/content/browser/media/forwarding_audio_stream_factory.cc
+++ b/content/browser/media/forwarding_audio_stream_factory.cc
@@ -6,7 +6,6 @@
 
 #include <utility>
 
-#include "content/browser/media/capture/audio_mirroring_manager.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_handle.h"
@@ -83,7 +82,7 @@
   outputs_
       .insert(broker_factory_->CreateAudioOutputStreamBroker(
           process_id, frame_id, ++stream_id_counter_, device_id, params,
-          AudioMirroringManager::ToGroupId(process_id, frame_id),
+          group_id_,
           base::BindOnce(&ForwardingAudioStreamFactory::RemoveOutput,
                          base::Unretained(this)),
           std::move(client)))
diff --git a/content/browser/picture_in_picture/overlay_surface_embedder.cc b/content/browser/picture_in_picture/overlay_surface_embedder.cc
index 5a7da3d..5e8617b1 100644
--- a/content/browser/picture_in_picture/overlay_surface_embedder.cc
+++ b/content/browser/picture_in_picture/overlay_surface_embedder.cc
@@ -51,15 +51,19 @@
 }
 
 void OverlaySurfaceEmbedder::AddControlsLayers() {
+  // These control layers are expected to be set up by |window_|.
   controls_background_layer_ = window_->GetControlsBackgroundLayer();
+  DCHECK(controls_background_layer_);
   controls_background_layer_->SetBounds(
       gfx::Rect(gfx::Point(0, 0), window_->GetBounds().size()));
 
   close_controls_layer_ = window_->GetCloseControlsLayer();
+  DCHECK(close_controls_layer_);
   close_controls_layer_->SetFillsBoundsOpaquely(false);
   close_controls_layer_->SetBounds(window_->GetCloseControlsBounds());
 
   play_pause_controls_layer_ = window_->GetPlayPauseControlsLayer();
+  DCHECK(play_pause_controls_layer_);
   play_pause_controls_layer_->SetFillsBoundsOpaquely(false);
   play_pause_controls_layer_->SetBounds(window_->GetPlayPauseControlsBounds());
 
diff --git a/content/browser/picture_in_picture/overlay_surface_embedder.h b/content/browser/picture_in_picture/overlay_surface_embedder.h
index d4b977f..dd0f277 100644
--- a/content/browser/picture_in_picture/overlay_surface_embedder.h
+++ b/content/browser/picture_in_picture/overlay_surface_embedder.h
@@ -36,6 +36,7 @@
   std::unique_ptr<ui::Layer> surface_layer_;
 
   // Owned by the OverlayWindow implementation.
+  // These are set in AddControlsLayer(), which is called in the constructor.
   ui::Layer* video_layer_ = nullptr;
   ui::Layer* controls_background_layer_ = nullptr;
   ui::Layer* close_controls_layer_ = nullptr;
diff --git a/content/browser/speech/speech_recognizer_impl_android.cc b/content/browser/speech/speech_recognizer_impl_android.cc
index 19bec76..2a6e0ca 100644
--- a/content/browser/speech/speech_recognizer_impl_android.cc
+++ b/content/browser/speech/speech_recognizer_impl_android.cc
@@ -18,7 +18,7 @@
 #include "content/public/browser/speech_recognition_session_config.h"
 #include "content/public/common/speech_recognition_grammar.h"
 #include "content/public/common/speech_recognition_result.h"
-#include "jni/SpeechRecognition_jni.h"
+#include "jni/SpeechRecognitionImpl_jni.h"
 
 using base::android::AppendJavaStringArrayToStringVector;
 using base::android::AttachCurrentThread;
@@ -58,9 +58,9 @@
     bool interim_results) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   JNIEnv* env = AttachCurrentThread();
-  j_recognition_.Reset(Java_SpeechRecognition_createSpeechRecognition(
+  j_recognition_.Reset(Java_SpeechRecognitionImpl_createSpeechRecognition(
       env, reinterpret_cast<intptr_t>(this)));
-  Java_SpeechRecognition_startRecognition(
+  Java_SpeechRecognitionImpl_startRecognition(
       env, j_recognition_, ConvertUTF8ToJavaString(env, language), continuous,
       interim_results);
 }
@@ -75,7 +75,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   JNIEnv* env = AttachCurrentThread();
   if (!j_recognition_.is_null())
-    Java_SpeechRecognition_abortRecognition(env, j_recognition_);
+    Java_SpeechRecognitionImpl_abortRecognition(env, j_recognition_);
 }
 
 void SpeechRecognizerImplAndroid::StopAudioCapture() {
@@ -87,7 +87,7 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   JNIEnv* env = AttachCurrentThread();
   if (!j_recognition_.is_null())
-    Java_SpeechRecognition_stopRecognition(env, j_recognition_);
+    Java_SpeechRecognitionImpl_stopRecognition(env, j_recognition_);
 }
 
 bool SpeechRecognizerImplAndroid::IsActive() const {
diff --git a/content/browser/web_contents/web_contents_android.cc b/content/browser/web_contents/web_contents_android.cc
index eca651e3..de7908b 100644
--- a/content/browser/web_contents/web_contents_android.cc
+++ b/content/browser/web_contents/web_contents_android.cc
@@ -22,7 +22,6 @@
 #include "content/browser/accessibility/browser_accessibility_android.h"
 #include "content/browser/accessibility/browser_accessibility_manager_android.h"
 #include "content/browser/android/content_view_core.h"
-#include "content/browser/android/interstitial_page_delegate_android.h"
 #include "content/browser/android/java/gin_java_bridge_dispatcher_host.h"
 #include "content/browser/frame_host/interstitial_page_impl.h"
 #include "content/browser/media/android/browser_media_player_manager.h"
@@ -424,19 +423,6 @@
   web_contents_->SetAudioMuted(mute);
 }
 
-void WebContentsAndroid::ShowInterstitialPage(JNIEnv* env,
-                                              const JavaParamRef<jobject>& obj,
-                                              const JavaParamRef<jstring>& jurl,
-                                              jlong delegate_ptr) {
-  GURL url(base::android::ConvertJavaStringToUTF8(env, jurl));
-  InterstitialPageDelegateAndroid* delegate =
-      reinterpret_cast<InterstitialPageDelegateAndroid*>(delegate_ptr);
-  InterstitialPage* interstitial = InterstitialPage::Create(
-      web_contents_, false, url, delegate);
-  delegate->set_interstitial_page(interstitial);
-  interstitial->Show();
-}
-
 jboolean WebContentsAndroid::IsShowingInterstitialPage(
     JNIEnv* env,
     const JavaParamRef<jobject>& obj) {
diff --git a/content/browser/web_contents/web_contents_android.h b/content/browser/web_contents/web_contents_android.h
index 52b0769..04455bd0 100644
--- a/content/browser/web_contents/web_contents_android.h
+++ b/content/browser/web_contents/web_contents_android.h
@@ -100,10 +100,6 @@
                      const base::android::JavaParamRef<jobject>& jobj,
                      jboolean mute);
 
-  void ShowInterstitialPage(JNIEnv* env,
-                            const base::android::JavaParamRef<jobject>& obj,
-                            const base::android::JavaParamRef<jstring>& jurl,
-                            jlong delegate_ptr);
   jboolean IsShowingInterstitialPage(
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& obj);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 2d1375e..41a70f4 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1395,6 +1395,9 @@
 }
 
 bool WebContentsImpl::IsAudioMuted() const {
+  if (base::FeatureList::IsEnabled(features::kAudioServiceAudioStreams)) {
+    return audio_stream_factory_ && audio_stream_factory_->IsMuted();
+  }
   return audio_muter_.get() && audio_muter_->is_muting();
 }
 
@@ -1405,13 +1408,17 @@
   if (mute == IsAudioMuted())
     return;
 
-  if (mute) {
-    if (!audio_muter_)
-      audio_muter_.reset(new WebContentsAudioMuter(this));
-    audio_muter_->StartMuting();
+  if (base::FeatureList::IsEnabled(features::kAudioServiceAudioStreams)) {
+    GetAudioStreamFactory()->SetMuted(mute);
   } else {
-    DCHECK(audio_muter_);
-    audio_muter_->StopMuting();
+    if (mute) {
+      if (!audio_muter_)
+        audio_muter_.reset(new WebContentsAudioMuter(this));
+      audio_muter_->StartMuting();
+    } else {
+      DCHECK(audio_muter_);
+      audio_muter_->StopMuting();
+    }
   }
 
   for (auto& observer : observers_)
diff --git a/content/browser/web_package/signed_exchange_consts.h b/content/browser/web_package/signed_exchange_consts.h
index 9b3f413..9dedf00f 100644
--- a/content/browser/web_package/signed_exchange_consts.h
+++ b/content/browser/web_package/signed_exchange_consts.h
@@ -16,11 +16,14 @@
 // https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#application-signed-exchange
 
 constexpr char kCertSha256Key[] = "certSha256";
+constexpr char kCertUrl[] = "certUrl";
 constexpr char kDateKey[] = "date";
 constexpr char kExpiresKey[] = "expires";
 constexpr char kHeadersKey[] = "headers";
+constexpr char kIntegrity[] = "integrity";
 constexpr char kMethodKey[] = ":method";
 constexpr char kSignature[] = "signature";
+constexpr char kSig[] = "sig";
 constexpr char kStatusKey[] = ":status";
 constexpr char kUrlKey[] = ":url";
 constexpr char kValidityUrlKey[] = "validityUrl";
diff --git a/content/browser/web_package/signed_exchange_header_parser.cc b/content/browser/web_package/signed_exchange_header_parser.cc
index 96e26d3..97cc0a4 100644
--- a/content/browser/web_package/signed_exchange_header_parser.cc
+++ b/content/browser/web_package/signed_exchange_header_parser.cc
@@ -215,21 +215,21 @@
     signatures.push_back(Signature());
     Signature& sig = signatures.back();
     sig.label = value.label;
-    sig.sig = value.params["sig"];
+    sig.sig = value.params[kSig];
     if (sig.sig.empty()) {
       signed_exchange_utils::ReportErrorAndEndTraceEvent(
           devtools_proxy, "SignedExchangeHeaderParser::ParseSignature",
           "'sig' parameter is not set,");
       return base::nullopt;
     }
-    sig.integrity = value.params["integrity"];
+    sig.integrity = value.params[kIntegrity];
     if (sig.integrity.empty()) {
       signed_exchange_utils::ReportErrorAndEndTraceEvent(
           devtools_proxy, "SignedExchangeHeaderParser::ParseSignature",
           "'integrity' parameter is not set.");
       return base::nullopt;
     }
-    sig.cert_url = GURL(value.params["certUrl"]);
+    sig.cert_url = GURL(value.params[kCertUrl]);
     if (!sig.cert_url.is_valid() || sig.cert_url.has_ref()) {
       // TODO(https://crbug.com/819467) : When we will support "ed25519Key", the
       // params may not have "certUrl".
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
index 79cb126..4fcbd79 100644
--- a/content/public/android/BUILD.gn
+++ b/content/public/android/BUILD.gn
@@ -127,7 +127,6 @@
     "java/src/org/chromium/content/browser/GestureListenerManagerImpl.java",
     "java/src/org/chromium/content/browser/GpuProcessCallback.java",
     "java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java",
-    "java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java",
     "java/src/org/chromium/content/browser/JavascriptInjectorImpl.java",
     "java/src/org/chromium/content/browser/JavascriptInterface.java",
     "java/src/org/chromium/content/browser/JoystickHandler.java",
@@ -142,7 +141,7 @@
     "java/src/org/chromium/content/browser/RenderCoordinatesImpl.java",
     "java/src/org/chromium/content/browser/ScreenOrientationProvider.java",
     "java/src/org/chromium/content/browser/SpareChildConnection.java",
-    "java/src/org/chromium/content/browser/SpeechRecognition.java",
+    "java/src/org/chromium/content/browser/SpeechRecognitionImpl.java",
     "java/src/org/chromium/content/browser/SyntheticGestureTarget.java",
     "java/src/org/chromium/content/browser/TapDisambiguator.java",
     "java/src/org/chromium/content/browser/TracingControllerAndroid.java",
@@ -254,6 +253,7 @@
     "java/src/org/chromium/content_public/browser/SelectionMetricsLogger.java",
     "java/src/org/chromium/content_public/browser/SelectionPopupController.java",
     "java/src/org/chromium/content_public/browser/SmartClipProvider.java",
+    "java/src/org/chromium/content_public/browser/SpeechRecognition.java",
     "java/src/org/chromium/content_public/browser/RenderCoordinates.java",
     "java/src/org/chromium/content_public/browser/WebContents.java",
     "java/src/org/chromium/content_public/browser/WebContentsAccessibility.java",
@@ -363,14 +363,13 @@
     "java/src/org/chromium/content/browser/GestureListenerManagerImpl.java",
     "java/src/org/chromium/content/browser/GpuProcessCallback.java",
     "java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java",
-    "java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java",
     "java/src/org/chromium/content/browser/JavascriptInjectorImpl.java",
     "java/src/org/chromium/content/browser/LauncherThread.java",
     "java/src/org/chromium/content/browser/MediaSessionImpl.java",
     "java/src/org/chromium/content/browser/MemoryMonitorAndroid.java",
     "java/src/org/chromium/content/browser/NfcHost.java",
     "java/src/org/chromium/content/browser/ScreenOrientationProvider.java",
-    "java/src/org/chromium/content/browser/SpeechRecognition.java",
+    "java/src/org/chromium/content/browser/SpeechRecognitionImpl.java",
     "java/src/org/chromium/content/browser/SyntheticGestureTarget.java",
     "java/src/org/chromium/content/browser/TapDisambiguator.java",
     "java/src/org/chromium/content/browser/TracingControllerAndroid.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/SpeechRecognition.java b/content/public/android/java/src/org/chromium/content/browser/SpeechRecognitionImpl.java
similarity index 95%
rename from content/public/android/java/src/org/chromium/content/browser/SpeechRecognition.java
rename to content/public/android/java/src/org/chromium/content/browser/SpeechRecognitionImpl.java
index f2eb964..9d6923d 100644
--- a/content/public/android/java/src/org/chromium/content/browser/SpeechRecognition.java
+++ b/content/public/android/java/src/org/chromium/content/browser/SpeechRecognitionImpl.java
@@ -22,18 +22,17 @@
 import org.chromium.base.PackageUtils;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.content_public.browser.SpeechRecognition;
 import org.chromium.content_public.common.SpeechRecognitionErrorCode;
 
 import java.util.ArrayList;
 import java.util.List;
 
 /**
- * This class uses Android's SpeechRecognizer to perform speech recognition for the Web Speech API
- * on Android. Using Android's platform recognizer offers several benefits, like good quality and
- * good local fallback when no data connection is available.
+ * Implementation of {@link SpeechRecognition}.
  */
 @JNINamespace("content")
-public class SpeechRecognition {
+public class SpeechRecognitionImpl {
     private static final String TAG = "SpeechRecog";
 
     // Constants describing the speech recognition provider we depend on.
@@ -204,7 +203,7 @@
         return false;
     }
 
-    private SpeechRecognition(long nativeSpeechRecognizerImplAndroid) {
+    private SpeechRecognitionImpl(long nativeSpeechRecognizerImplAndroid) {
         mContinuous = false;
         mNativeSpeechRecognizerImplAndroid = nativeSpeechRecognizerImplAndroid;
         mListener = new Listener();
@@ -255,9 +254,9 @@
     }
 
     @CalledByNative
-    private static SpeechRecognition createSpeechRecognition(
+    private static SpeechRecognitionImpl createSpeechRecognition(
             long nativeSpeechRecognizerImplAndroid) {
-        return new SpeechRecognition(nativeSpeechRecognizerImplAndroid);
+        return new SpeechRecognitionImpl(nativeSpeechRecognizerImplAndroid);
     }
 
     @CalledByNative
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
index edd12fd..1cc500f 100644
--- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
@@ -429,12 +429,6 @@
     }
 
     @Override
-    public void showInterstitialPage(
-            String url, long interstitialPageDelegateAndroid) {
-        nativeShowInterstitialPage(mNativeWebContentsAndroid, url, interstitialPageDelegateAndroid);
-    }
-
-    @Override
     public boolean isShowingInterstitialPage() {
         return nativeIsShowingInterstitialPage(mNativeWebContentsAndroid);
     }
@@ -876,8 +870,6 @@
     private native void nativeSuspendAllMediaPlayers(long nativeWebContentsAndroid);
     private native void nativeSetAudioMuted(long nativeWebContentsAndroid, boolean mute);
     private native int nativeGetBackgroundColor(long nativeWebContentsAndroid);
-    private native void nativeShowInterstitialPage(long nativeWebContentsAndroid,
-            String url, long nativeInterstitialPageDelegateAndroid);
     private native boolean nativeIsShowingInterstitialPage(long nativeWebContentsAndroid);
     private native boolean nativeFocusLocationBarByDefault(long nativeWebContentsAndroid);
     private native boolean nativeIsRenderWidgetHostViewReady(long nativeWebContentsAndroid);
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/SpeechRecognition.java b/content/public/android/java/src/org/chromium/content_public/browser/SpeechRecognition.java
new file mode 100644
index 0000000..07baecf2
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content_public/browser/SpeechRecognition.java
@@ -0,0 +1,27 @@
+// 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.
+
+package org.chromium.content_public.browser;
+
+import android.content.Context;
+
+import org.chromium.content.browser.SpeechRecognitionImpl;
+
+/**
+ * This class uses Android's SpeechRecognizer to perform speech recognition for the Web Speech API
+ * on Android. Using Android's platform recognizer offers several benefits, like good quality and
+ * good local fallback when no data connection is available.
+ */
+public final class SpeechRecognition {
+    private SpeechRecognition() {}
+
+    /**
+     * This method must be called before any instance of SpeechRecognition can be created. It will
+     * query Android's package manager to find a suitable speech recognition provider that supports
+     * continuous recognition.
+     */
+    public static boolean initialize(Context context) {
+        return SpeechRecognitionImpl.initialize(context);
+    }
+}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
index 094a9b9..45dcf837 100644
--- a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
+++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
@@ -211,16 +211,6 @@
     int getBackgroundColor();
 
     /**
-     * Shows an interstitial page driven by the passed in delegate.
-     *
-     * @param url The URL being blocked by the interstitial.
-     * @param interstitialPageDelegateAndroid The delegate handling the interstitial.
-     */
-    @VisibleForTesting
-    void showInterstitialPage(
-            String url, long interstitialPageDelegateAndroid);
-
-    /**
      * @return Whether the page is currently showing an interstitial, such as a bad HTTPS page.
      */
     boolean isShowingInterstitialPage();
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/InterstitialPageTest.java b/content/public/android/javatests/src/org/chromium/content/browser/InterstitialPageTest.java
index e0800ff..60d06dc 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/InterstitialPageTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/InterstitialPageTest.java
@@ -17,6 +17,7 @@
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.UrlUtils;
+import org.chromium.content.browser.test.InterstitialPageDelegateAndroid;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content.browser.test.util.TouchCommon;
@@ -117,8 +118,7 @@
                 new Callable<TestWebContentsObserver>() {
                     @Override
                     public TestWebContentsObserver call() throws Exception {
-                        mActivityTestRule.getWebContents().showInterstitialPage(
-                                URL, delegate.getNative());
+                        delegate.showInterstitialPage(URL, mActivityTestRule.getWebContents());
                         return new TestWebContentsObserver(mActivityTestRule.getWebContents());
                     }
                 });
diff --git a/content/public/test/android/BUILD.gn b/content/public/test/android/BUILD.gn
index beebfd7..08de4404 100644
--- a/content/public/test/android/BUILD.gn
+++ b/content/public/test/android/BUILD.gn
@@ -33,6 +33,7 @@
     "javatests/src/org/chromium/content/browser/test/ChildProcessAllocatorSettings.java",
     "javatests/src/org/chromium/content/browser/test/ChildProcessAllocatorSettingsHook.java",
     "javatests/src/org/chromium/content/browser/test/ContentJUnit4ClassRunner.java",
+    "javatests/src/org/chromium/content/browser/test/InterstitialPageDelegateAndroid.java",
     "javatests/src/org/chromium/content/browser/test/NativeLibraryTestRule.java",
     "javatests/src/org/chromium/content/browser/test/mock/MockRenderFrameHost.java",
     "javatests/src/org/chromium/content/browser/test/mock/MockWebContents.java",
@@ -56,3 +57,26 @@
     "javatests/src/org/chromium/content/browser/test/util/UiUtils.java",
   ]
 }
+
+generate_jni("content_test_jni") {
+  testonly = true
+  jni_package = "content/public/test"
+  sources = [
+    "javatests/src/org/chromium/content/browser/test/InterstitialPageDelegateAndroid.java",
+  ]
+}
+
+static_library("content_native_test_support") {
+  testonly = true
+  sources = [
+    "interstitial_page_delegate_android.cc",
+    "interstitial_page_delegate_android.h",
+  ]
+  deps = [
+    ":content_test_jni",
+    "//base",
+    "//content/public/browser",
+    "//device/gamepad",
+    "//media/midi",
+  ]
+}
diff --git a/content/browser/android/interstitial_page_delegate_android.cc b/content/public/test/android/interstitial_page_delegate_android.cc
similarity index 76%
rename from content/browser/android/interstitial_page_delegate_android.cc
rename to content/public/test/android/interstitial_page_delegate_android.cc
index 81b57c0f..d59c07d 100644
--- a/content/browser/android/interstitial_page_delegate_android.cc
+++ b/content/public/test/android/interstitial_page_delegate_android.cc
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/browser/android/interstitial_page_delegate_android.h"
+#include "content/public/test/android/interstitial_page_delegate_android.h"
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
 #include "content/public/browser/interstitial_page.h"
+#include "content/public/browser/web_contents.h"
 #include "jni/InterstitialPageDelegateAndroid_jni.h"
 
 using base::android::AttachCurrentThread;
@@ -20,10 +21,7 @@
     JNIEnv* env,
     jobject obj,
     const std::string& html_content)
-    : weak_java_obj_(env, obj),
-      html_content_(html_content),
-      page_(NULL) {
-}
+    : weak_java_obj_(env, obj), html_content_(html_content), page_(NULL) {}
 
 InterstitialPageDelegateAndroid::~InterstitialPageDelegateAndroid() {
   JNIEnv* env = AttachCurrentThread();
@@ -46,6 +44,20 @@
     page_->DontProceed();
 }
 
+void InterstitialPageDelegateAndroid::ShowInterstitialPage(
+    JNIEnv* env,
+    const JavaParamRef<jobject>& obj,
+    const JavaParamRef<jstring>& jurl,
+    const JavaParamRef<jobject>& jweb_contents) {
+  WebContents* web_contents = WebContents::FromJavaWebContents(jweb_contents);
+  DCHECK(web_contents);
+  GURL url(base::android::ConvertJavaStringToUTF8(env, jurl));
+  InterstitialPage* interstitial =
+      InterstitialPage::Create(web_contents, false, url, this);
+  set_interstitial_page(interstitial);
+  interstitial->Show();
+}
+
 std::string InterstitialPageDelegateAndroid::GetHTMLContents() {
   return html_content_;
 }
@@ -72,8 +84,8 @@
     std::string sanitized_command(command);
     // The JSONified response has quotes, remove them.
     if (sanitized_command.length() > 1 && sanitized_command[0] == '"') {
-      sanitized_command = sanitized_command.substr(
-          1, sanitized_command.length() - 2);
+      sanitized_command =
+          sanitized_command.substr(1, sanitized_command.length() - 2);
     }
 
     Java_InterstitialPageDelegateAndroid_commandReceived(
diff --git a/content/browser/android/interstitial_page_delegate_android.h b/content/public/test/android/interstitial_page_delegate_android.h
similarity index 77%
rename from content/browser/android/interstitial_page_delegate_android.h
rename to content/public/test/android/interstitial_page_delegate_android.h
index b4900e2..a2ef9f0 100644
--- a/content/browser/android/interstitial_page_delegate_android.h
+++ b/content/public/test/android/interstitial_page_delegate_android.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_BROWSER_ANDROID_INTERSTITIAL_PAGE_DELEGATE_ANDROID_H_
-#define CONTENT_BROWSER_ANDROID_INTERSTITIAL_PAGE_DELEGATE_ANDROID_H_
+#ifndef CONTENT_PUBLIC_TEST_ANDROID_INTERSTITIAL_PAGE_DELEGATE_ANDROID_H_
+#define CONTENT_PUBLIC_TEST_ANDROID_INTERSTITIAL_PAGE_DELEGATE_ANDROID_H_
 
 #include <jni.h>
 #include <string>
@@ -11,7 +11,6 @@
 #include "base/android/jni_weak_ref.h"
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "content/common/content_export.h"
 #include "content/public/browser/interstitial_page_delegate.h"
 
 namespace content {
@@ -33,6 +32,11 @@
   void Proceed(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
   void DontProceed(JNIEnv* env,
                    const base::android::JavaParamRef<jobject>& obj);
+  void ShowInterstitialPage(
+      JNIEnv* env,
+      const base::android::JavaParamRef<jobject>& obj,
+      const base::android::JavaParamRef<jstring>& jurl,
+      const base::android::JavaParamRef<jobject>& jweb_contents);
 
   // Implementation of InterstitialPageDelegate
   std::string GetHTMLContents() override;
@@ -51,4 +55,4 @@
 
 }  // namespace content
 
-#endif  // CONTENT_BROWSER_ANDROID_INTERSTITIAL_PAGE_DELEGATE_ANDROID_H_
+#endif  // CONTENT_PUBLIC_TEST_ANDROID_INTERSTITIAL_PAGE_DELEGATE_ANDROID_H_
diff --git a/content/public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/InterstitialPageDelegateAndroid.java
similarity index 71%
rename from content/public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java
rename to content/public/test/android/javatests/src/org/chromium/content/browser/test/InterstitialPageDelegateAndroid.java
index 9af0cd5..b952f78 100644
--- a/content/public/android/java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java
+++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/InterstitialPageDelegateAndroid.java
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.content.browser;
+package org.chromium.content.browser.test;
 
 import org.chromium.base.VisibleForTesting;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.content_public.browser.WebContents;
 
 /**
  * Allows the specification and handling of Interstitial pages in java.
  */
 @JNINamespace("content")
 public class InterstitialPageDelegateAndroid {
-
     private long mNativePtr;
 
     /**
@@ -27,26 +27,16 @@
     }
 
     /**
-     * @return The pointer to the underlying native counterpart.
-     */
-    @VisibleForTesting
-    public long getNative() {
-        return mNativePtr;
-    }
-
-    /**
      * Called when "proceed" is triggered on the interstitial.
      */
     @CalledByNative
-    protected void onProceed() {
-    }
+    protected void onProceed() {}
 
     /**
      * Called when "dont' proceed" is triggered on the interstitial.
      */
     @CalledByNative
-    protected void onDontProceed() {
-    }
+    protected void onDontProceed() {}
 
     /**
      * Called when a command has been received from the interstitial.
@@ -54,8 +44,7 @@
      * @param command The command that was received.
      */
     @CalledByNative
-    protected void commandReceived(String command) {
-    }
+    protected void commandReceived(String command) {}
 
     @CalledByNative
     private void onNativeDestroyed() {
@@ -76,7 +65,19 @@
         if (mNativePtr != 0) nativeDontProceed(mNativePtr);
     }
 
+    /**
+     * Shows an interstitial page driven by this delegate.
+     *
+     * @param url The URL being blocked by the interstitial.
+     * @param webContents The {@link WebContents} the interstitial to show on.
+     */
+    public void showInterstitialPage(String url, WebContents webContents) {
+        if (mNativePtr != 0) nativeShowInterstitialPage(mNativePtr, url, webContents);
+    }
+
     private native long nativeInit(String htmlContent);
     private native void nativeProceed(long nativeInterstitialPageDelegateAndroid);
     private native void nativeDontProceed(long nativeInterstitialPageDelegateAndroid);
+    private native void nativeShowInterstitialPage(
+            long nativeInterstitialPageDelegateAndroid, String url, WebContents webContents);
 }
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/mock/MockWebContents.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/mock/MockWebContents.java
index afbd264..e12e265 100644
--- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/mock/MockWebContents.java
+++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/mock/MockWebContents.java
@@ -127,9 +127,6 @@
     }
 
     @Override
-    public void showInterstitialPage(String url, long interstitialPageDelegateAndroid) {}
-
-    @Override
     public boolean isShowingInterstitialPage() {
         return false;
     }
diff --git a/content/public/test/content_browser_test.cc b/content/public/test/content_browser_test.cc
index db7f9252..6ff6b86 100644
--- a/content/public/test/content_browser_test.cc
+++ b/content/public/test/content_browser_test.cc
@@ -67,7 +67,7 @@
     // setting a global that may be used after ContentBrowserTest is
     // destroyed.
     ContentRendererClient* old_client =
-        switches::IsRunLayoutTestSwitchPresent()
+        switches::IsRunWebTestsSwitchPresent()
             ? SetRendererClientForTesting(new LayoutTestContentRendererClient)
             : SetRendererClientForTesting(new ShellContentRendererClient);
     // No-one should have set this value before we did.
@@ -114,7 +114,7 @@
 }
 
 void ContentBrowserTest::PreRunTestOnMainThread() {
-  if (!switches::IsRunLayoutTestSwitchPresent()) {
+  if (!switches::IsRunWebTestsSwitchPresent()) {
     CHECK_EQ(Shell::windows().size(), 1u);
     shell_ = Shell::windows()[0];
     SetInitialWebContents(shell_->web_contents());
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn
index 89dd771..a0560dd 100644
--- a/content/shell/android/BUILD.gn
+++ b/content/shell/android/BUILD.gn
@@ -52,6 +52,20 @@
   ]
 }
 
+shared_library("libcontent_native_test") {
+  testonly = true
+  deps = [
+    ":content_test_jni_registration",
+    "//base",
+    "//content/public/test/android:content_native_test_support",
+    "//content/shell:content_shell_lib",
+  ]
+
+  sources = [
+    "shell_test_library_loader.cc",
+  ]
+}
+
 android_resources("content_shell_java_resources") {
   testonly = true
   resource_dirs = [ "java/res" ]
@@ -197,6 +211,13 @@
   ]
 }
 
+generate_jni_registration("content_test_jni_registration") {
+  testonly = true
+  target = ":content_shell_test_apk__apk"
+  output = "$root_gen_dir/content/shell/android/${target_name}.h"
+  exception_files = jni_exception_files
+}
+
 instrumentation_test_apk("content_shell_test_apk") {
   deps = [
     "//base:base_java_test_support",
@@ -207,6 +228,7 @@
   ]
   apk_under_test = ":content_shell_apk"
   apk_name = "ContentShellTest"
+  shared_libraries = [ ":libcontent_native_test" ]
   android_manifest = "javatests/AndroidManifest.xml"
 }
 
diff --git a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java
index ff6b1fc..e1d0d31 100644
--- a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java
+++ b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellActivity.java
@@ -34,8 +34,8 @@
     private static final String ACTIVE_SHELL_URL_KEY = "activeUrl";
     public static final String COMMAND_LINE_ARGS_KEY = "commandLineArgs";
 
-    // Native switch - shell_switches::kRunLayoutTest
-    private static final String RUN_LAYOUT_TEST_SWITCH = "run-layout-test";
+    // Native switch - shell_switches::kRunWebTests
+    private static final String RUN_WEB_TESTS_SWITCH = "run-web-tests";
 
     private ShellManager mShellManager;
     private ActivityWindowAndroid mWindowAndroid;
@@ -83,7 +83,7 @@
             mShellManager.setStartupUrl(Shell.sanitizeUrl(mStartupUrl));
         }
 
-        if (CommandLine.getInstance().hasSwitch(RUN_LAYOUT_TEST_SWITCH)) {
+        if (CommandLine.getInstance().hasSwitch(RUN_WEB_TESTS_SWITCH)) {
             try {
                 BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER)
                         .startBrowserProcessesSync(false);
diff --git a/content/shell/android/shell_test_library_loader.cc b/content/shell/android/shell_test_library_loader.cc
new file mode 100644
index 0000000..7b47e54c
--- /dev/null
+++ b/content/shell/android/shell_test_library_loader.cc
@@ -0,0 +1,31 @@
+// 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/android/jni_android.h"
+#include "base/android/jni_utils.h"
+#include "content/public/app/content_jni_onload.h"
+#include "content/public/app/content_main.h"
+#include "content/public/browser/android/compositor.h"
+#include "content/shell/android/content_test_jni_registration.h"
+#include "content/shell/app/shell_main_delegate.h"
+
+// This is called by the VM when the shared library is first loaded.
+JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+  base::android::InitVM(vm);
+  JNIEnv* env = base::android::AttachCurrentThread();
+  if (!base::android::IsSelectiveJniRegistrationEnabled(env)) {
+    if (!RegisterNonMainDexNatives(env)) {
+      return -1;
+    }
+  }
+
+  if (!RegisterMainDexNatives(env)) {
+    return -1;
+  }
+  if (!content::android::OnJNIOnLoadInit())
+    return -1;
+  content::Compositor::Initialize();
+  content::SetContentMainDelegate(new content::ShellMainDelegate());
+  return JNI_VERSION_1_4;
+}
diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc
index b35543a..51b161db 100644
--- a/content/shell/app/shell_main_delegate.cc
+++ b/content/shell/app/shell_main_delegate.cc
@@ -4,6 +4,8 @@
 
 #include "content/shell/app/shell_main_delegate.h"
 
+#include <iostream>
+
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/cpu.h"
@@ -179,7 +181,14 @@
     }
   }
 
-  if (command_line.HasSwitch(switches::kRunLayoutTest)) {
+  if (command_line.HasSwitch("run-layout-test")) {
+    std::cerr << "The switch --run-layout-test is obsolete. Please use --"
+              << switches::kRunWebTests << " instead.\n";
+    *exit_code = 1;
+    return true;
+  }
+
+  if (command_line.HasSwitch(switches::kRunWebTests)) {
     EnableBrowserLayoutTestMode();
 
 #if BUILDFLAG(ENABLE_PLUGINS)
@@ -265,8 +274,7 @@
     }
   }
 
-  content_client_.reset(base::CommandLine::ForCurrentProcess()->HasSwitch(
-                            switches::kRunLayoutTest)
+  content_client_.reset(switches::IsRunWebTestsSwitchPresent()
                             ? new LayoutTestContentClient
                             : new ShellContentClient);
   SetContentClient(content_client_.get());
@@ -329,7 +337,7 @@
 
   browser_runner_.reset(BrowserMainRunner::Create());
   base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
-  return command_line.HasSwitch(switches::kRunLayoutTest) ||
+  return command_line.HasSwitch(switches::kRunWebTests) ||
                  command_line.HasSwitch(switches::kCheckLayoutTestSysDeps)
              ? LayoutTestBrowserMain(main_function_params, browser_runner_)
              : ShellBrowserMain(main_function_params, browser_runner_);
@@ -390,8 +398,7 @@
 }
 
 ContentBrowserClient* ShellMainDelegate::CreateContentBrowserClient() {
-  browser_client_.reset(base::CommandLine::ForCurrentProcess()->HasSwitch(
-                            switches::kRunLayoutTest)
+  browser_client_.reset(switches::IsRunWebTestsSwitchPresent()
                             ? new LayoutTestContentBrowserClient
                             : new ShellContentBrowserClient);
 
@@ -404,8 +411,7 @@
 }
 
 ContentRendererClient* ShellMainDelegate::CreateContentRendererClient() {
-  renderer_client_.reset(base::CommandLine::ForCurrentProcess()->HasSwitch(
-                             switches::kRunLayoutTest)
+  renderer_client_.reset(switches::IsRunWebTestsSwitchPresent()
                              ? new LayoutTestContentRendererClient
                              : new ShellContentRendererClient);
 
diff --git a/content/shell/app/shell_main_delegate_mac.mm b/content/shell/app/shell_main_delegate_mac.mm
index 298475c..6b66365 100644
--- a/content/shell/app/shell_main_delegate_mac.mm
+++ b/content/shell/app/shell_main_delegate_mac.mm
@@ -28,15 +28,15 @@
       [[NSMutableDictionary alloc]
           initWithContentsOfFile:base::mac::FilePathToNSString(info_plist)]);
 
-  bool running_layout_tests = switches::IsRunLayoutTestSwitchPresent();
+  bool running_web_tests = switches::IsRunWebTestsSwitchPresent();
   bool not_high_resolution_capable =
       [info_dict objectForKey:kHighResolutionCapable] &&
       [[info_dict objectForKey:kHighResolutionCapable] isEqualToNumber:@(NO)];
-  if (running_layout_tests == not_high_resolution_capable)
+  if (running_web_tests == not_high_resolution_capable)
     return;
 
   // We need to update our Info.plist before we can continue.
-  [info_dict setObject:@(!running_layout_tests) forKey:kHighResolutionCapable];
+  [info_dict setObject:@(!running_web_tests) forKey:kHighResolutionCapable];
   CHECK([info_dict writeToFile:base::mac::FilePathToNSString(info_plist)
                     atomically:YES]);
 
diff --git a/content/shell/browser/layout_test/layout_test_content_browser_client.cc b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
index f601736..3a908d7 100644
--- a/content/shell/browser/layout_test/layout_test_content_browser_client.cc
+++ b/content/shell/browser/layout_test/layout_test_content_browser_client.cc
@@ -178,7 +178,7 @@
 void LayoutTestContentBrowserClient::AppendExtraCommandLineSwitches(
     base::CommandLine* command_line,
     int child_process_id) {
-  command_line->AppendSwitch(switches::kRunLayoutTest);
+  command_line->AppendSwitch(switches::kRunWebTests);
   ShellContentBrowserClient::AppendExtraCommandLineSwitches(command_line,
                                                             child_process_id);
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/content/shell/browser/layout_test/layout_test_url_request_context_getter.cc b/content/shell/browser/layout_test/layout_test_url_request_context_getter.cc
index c4524d4b..dea88c6 100644
--- a/content/shell/browser/layout_test/layout_test_url_request_context_getter.cc
+++ b/content/shell/browser/layout_test/layout_test_url_request_context_getter.cc
@@ -49,7 +49,7 @@
 std::unique_ptr<net::CertVerifier>
 LayoutTestURLRequestContextGetter::GetCertVerifier() {
   return network::IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
-      *base::CommandLine::ForCurrentProcess(), switches::kRunLayoutTest,
+      *base::CommandLine::ForCurrentProcess(), switches::kRunWebTests,
       net::CertVerifier::CreateDefault());
 }
 
diff --git a/content/shell/browser/renderer_host/shell_render_widget_host_view_mac_delegate.mm b/content/shell/browser/renderer_host/shell_render_widget_host_view_mac_delegate.mm
index 5019d41..099a70e 100644
--- a/content/shell/browser/renderer_host/shell_render_widget_host_view_mac_delegate.mm
+++ b/content/shell/browser/renderer_host/shell_render_widget_host_view_mac_delegate.mm
@@ -5,7 +5,7 @@
 #import "content/shell/browser/renderer_host/shell_render_widget_host_view_mac_delegate.h"
 
 #include "base/command_line.h"
-#include "content/shell/common/layout_test/layout_test_switches.h"
+#include "content/shell/common/shell_switches.h"
 
 @interface ShellRenderWidgetHostViewMacDelegate () {
   BOOL drop_events_;
@@ -18,8 +18,7 @@
   if ((self = [super init])) {
     // Throw out all native input events if we are running with layout test
     // enabled.
-    drop_events_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
-        switches::kRunLayoutTest);
+    drop_events_ = switches::IsRunWebTestsSwitchPresent();
   }
   return self;
 }
diff --git a/content/shell/browser/shell.cc b/content/shell/browser/shell.cc
index 61a248f6..1c9bf11d 100644
--- a/content/shell/browser/shell.cc
+++ b/content/shell/browser/shell.cc
@@ -86,7 +86,7 @@
       hide_toolbar_(false) {
   web_contents_->SetDelegate(this);
 
-  if (switches::IsRunLayoutTestSwitchPresent()) {
+  if (switches::IsRunWebTestsSwitchPresent()) {
     headless_ = true;
     // In a headless shell, disable occlusion tracking. Otherwise, WebContents
     // would always behave as if they were occluded, i.e. would not render
@@ -144,7 +144,7 @@
   // Note: Do not make RenderFrameHost or RenderViewHost specific state changes
   // here, because they will be forgotten after a cross-process navigation. Use
   // RenderFrameCreated or RenderViewCreated instead.
-  if (switches::IsRunLayoutTestSwitchPresent()) {
+  if (switches::IsRunWebTestsSwitchPresent()) {
     raw_web_contents->GetMutableRendererPrefs()->use_custom_colors = false;
     raw_web_contents->GetRenderViewHost()->SyncRendererPrefs();
   }
@@ -287,7 +287,7 @@
                            bool* was_blocked) {
   WebContents* raw_new_contents = new_contents.get();
   CreateShell(std::move(new_contents), AdjustWindowSize(initial_rect.size()));
-  if (switches::IsRunLayoutTestSwitchPresent())
+  if (switches::IsRunWebTestsSwitchPresent())
     SecondaryTestWindowObserver::CreateForWebContents(raw_new_contents);
 }
 
@@ -372,7 +372,7 @@
                                  params.source_site_instance,
                                  gfx::Size());  // Use default size.
       target = new_window->web_contents();
-      if (switches::IsRunLayoutTestSwitchPresent())
+      if (switches::IsRunWebTestsSwitchPresent())
         SecondaryTestWindowObserver::CreateForWebContents(target);
       break;
     }
@@ -434,7 +434,7 @@
 #if defined(OS_ANDROID)
   PlatformToggleFullscreenModeForTab(web_contents, enter_fullscreen);
 #endif
-  if (!switches::IsRunLayoutTestSwitchPresent())
+  if (!switches::IsRunWebTestsSwitchPresent())
     return;
   if (is_fullscreen_ != enter_fullscreen) {
     is_fullscreen_ = enter_fullscreen;
@@ -487,7 +487,7 @@
 JavaScriptDialogManager* Shell::GetJavaScriptDialogManager(
     WebContents* source) {
   if (!dialog_manager_) {
-    dialog_manager_.reset(switches::IsRunLayoutTestSwitchPresent()
+    dialog_manager_.reset(switches::IsRunWebTestsSwitchPresent()
                               ? new LayoutTestJavaScriptDialogManager
                               : new ShellJavaScriptDialogManager);
   }
@@ -498,7 +498,7 @@
     RenderFrameHost* frame,
     const BluetoothChooser::EventHandler& event_handler) {
   BlinkTestController* blink_test_controller = BlinkTestController::Get();
-  if (blink_test_controller && switches::IsRunLayoutTestSwitchPresent())
+  if (blink_test_controller && switches::IsRunWebTestsSwitchPresent())
     return blink_test_controller->RunBluetoothChooser(frame, event_handler);
   return nullptr;
 }
@@ -508,13 +508,13 @@
                                    const base::string16& message,
                                    int32_t line_no,
                                    const base::string16& source_id) {
-  return switches::IsRunLayoutTestSwitchPresent();
+  return switches::IsRunWebTestsSwitchPresent();
 }
 
 void Shell::RendererUnresponsive(WebContents* source,
                                  RenderWidgetHost* render_widget_host) {
   BlinkTestController* blink_test_controller = BlinkTestController::Get();
-  if (blink_test_controller && switches::IsRunLayoutTestSwitchPresent())
+  if (blink_test_controller && switches::IsRunWebTestsSwitchPresent())
     blink_test_controller->RendererUnresponsive();
 }
 
@@ -529,9 +529,7 @@
     const GURL& resource_url) {
   bool allowed_by_test = false;
   BlinkTestController* blink_test_controller = BlinkTestController::Get();
-  if (blink_test_controller &&
-      base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kRunLayoutTest)) {
+  if (blink_test_controller && switches::IsRunWebTestsSwitchPresent()) {
     const base::DictionaryValue& test_flags =
         blink_test_controller->accumulated_layout_test_runtime_flags_changes();
     test_flags.GetBoolean("running_insecure_content_allowed", &allowed_by_test);
diff --git a/content/shell/browser/shell_devtools_manager_delegate.cc b/content/shell/browser/shell_devtools_manager_delegate.cc
index 07cb3e64..d0a3a9a 100644
--- a/content/shell/browser/shell_devtools_manager_delegate.cc
+++ b/content/shell/browser/shell_devtools_manager_delegate.cc
@@ -186,7 +186,7 @@
                                         url,
                                         nullptr,
                                         gfx::Size());
-  if (switches::IsRunLayoutTestSwitchPresent())
+  if (switches::IsRunWebTestsSwitchPresent())
     SecondaryTestWindowObserver::CreateForWebContents(shell->web_contents());
   return DevToolsAgentHost::GetOrCreateFor(shell->web_contents());
 }
diff --git a/content/shell/browser/shell_url_request_context_getter.cc b/content/shell/browser/shell_url_request_context_getter.cc
index 15ff5b7..4d2e631 100644
--- a/content/shell/browser/shell_url_request_context_getter.cc
+++ b/content/shell/browser/shell_url_request_context_getter.cc
@@ -188,7 +188,7 @@
     if (base::FeatureList::IsEnabled(network::features::kReporting)) {
       std::unique_ptr<net::ReportingPolicy> reporting_policy =
           std::make_unique<net::ReportingPolicy>();
-      if (command_line.HasSwitch(switches::kRunLayoutTest))
+      if (command_line.HasSwitch(switches::kRunWebTests))
         reporting_policy->delivery_interval =
             base::TimeDelta::FromMilliseconds(100);
       builder.set_reporting_policy(std::move(reporting_policy));
diff --git a/content/shell/browser/shell_web_contents_view_delegate_mac.mm b/content/shell/browser/shell_web_contents_view_delegate_mac.mm
index be81d60..a95cb94 100644
--- a/content/shell/browser/shell_web_contents_view_delegate_mac.mm
+++ b/content/shell/browser/shell_web_contents_view_delegate_mac.mm
@@ -96,7 +96,7 @@
 void ShellWebContentsViewDelegate::ShowContextMenu(
     RenderFrameHost* render_frame_host,
     const ContextMenuParams& params) {
-  if (switches::IsRunLayoutTestSwitchPresent())
+  if (switches::IsRunWebTestsSwitchPresent())
     return;
 
   params_ = params;
diff --git a/content/shell/browser/shell_web_contents_view_delegate_views.cc b/content/shell/browser/shell_web_contents_view_delegate_views.cc
index 11c9750..937639f 100644
--- a/content/shell/browser/shell_web_contents_view_delegate_views.cc
+++ b/content/shell/browser/shell_web_contents_view_delegate_views.cc
@@ -69,7 +69,7 @@
 void ShellWebContentsViewDelegate::ShowContextMenu(
     RenderFrameHost* render_frame_host,
     const ContextMenuParams& params) {
-  if (switches::IsRunLayoutTestSwitchPresent())
+  if (switches::IsRunWebTestsSwitchPresent())
     return;
 
   gfx::Point screen_point(params.x, params.y);
diff --git a/content/shell/common/layout_test/layout_test_switches.cc b/content/shell/common/layout_test/layout_test_switches.cc
index a8a287ca..8aa83ee 100644
--- a/content/shell/common/layout_test/layout_test_switches.cc
+++ b/content/shell/common/layout_test/layout_test_switches.cc
@@ -21,6 +21,7 @@
 #endif // defined(OS_ANDROID)
 
 // Check whether all system dependencies for running layout tests are met.
+// TODO(tkent): Rename this to "check-web-test-sys-deps".
 const char kCheckLayoutTestSysDeps[] = "check-layout-test-sys-deps";
 
 // When specified to "enable-leak-detection" command-line option,
@@ -51,7 +52,7 @@
 
 // Request the render trees of pages to be dumped as text once they have
 // finished loading.
-const char kRunLayoutTest[] = "run-layout-test";
+const char kRunWebTests[] = "run-web-tests";
 
 // This makes us disable some web-platform runtime features so that we test
 // content_shell as if it was a stable release. It is only followed when
diff --git a/content/shell/common/layout_test/layout_test_switches.h b/content/shell/common/layout_test/layout_test_switches.h
index d672d4c2..6fb6947 100644
--- a/content/shell/common/layout_test/layout_test_switches.h
+++ b/content/shell/common/layout_test/layout_test_switches.h
@@ -29,7 +29,7 @@
 extern const char kAlwaysUseComplexText[];
 extern const char kEnableLeakDetection[];
 extern const char kEncodeBinary[];
-extern const char kRunLayoutTest[];
+extern const char kRunWebTests[];
 extern const char kStableReleaseMode[];
 extern const char kEnableDisplayCompositorPixelDump[];
 
diff --git a/content/shell/common/shell_content_client.cc b/content/shell/common/shell_content_client.cc
index 9adc56d0..5042ed8 100644
--- a/content/shell/common/shell_content_client.cc
+++ b/content/shell/common/shell_content_client.cc
@@ -37,7 +37,7 @@
 }
 
 base::string16 ShellContentClient::GetLocalizedString(int message_id) const {
-  if (switches::IsRunLayoutTestSwitchPresent()) {
+  if (switches::IsRunWebTestsSwitchPresent()) {
     switch (message_id) {
       case IDS_FORM_OTHER_DATE_LABEL:
         return base::ASCIIToUTF16("<<OtherDateLabel>>");
@@ -61,7 +61,7 @@
 base::StringPiece ShellContentClient::GetDataResource(
     int resource_id,
     ui::ScaleFactor scale_factor) const {
-  if (switches::IsRunLayoutTestSwitchPresent()) {
+  if (switches::IsRunWebTestsSwitchPresent()) {
     switch (resource_id) {
       case IDR_BROKENIMAGE:
 #if defined(OS_MACOSX)
diff --git a/content/shell/common/shell_switches.cc b/content/shell/common/shell_switches.cc
index d196d3c..de87710 100644
--- a/content/shell/common/shell_switches.cc
+++ b/content/shell/common/shell_switches.cc
@@ -58,9 +58,9 @@
   return files;
 }
 
-bool IsRunLayoutTestSwitchPresent() {
+bool IsRunWebTestsSwitchPresent() {
   return base::CommandLine::ForCurrentProcess()->HasSwitch(
-      switches::kRunLayoutTest);
+      switches::kRunWebTests);
 }
 
 }  // namespace switches
diff --git a/content/shell/common/shell_switches.h b/content/shell/common/shell_switches.h
index a06d39e..0215d01 100644
--- a/content/shell/common/shell_switches.h
+++ b/content/shell/common/shell_switches.h
@@ -25,11 +25,11 @@
 // Returns list of extra font files to be made accessible to the renderer.
 std::vector<std::string> GetSideloadFontFiles();
 
-// Tells if content shell is running layout tests.
+// Tells if content shell is running web_tests.
 // TODO(lukasza): The function below somewhat violates the layering (by
 // enabling shell -> layout_tests dependency) but at least narrows the extent of
 // the dependency to a single switch...
-bool IsRunLayoutTestSwitchPresent();
+bool IsRunWebTestsSwitchPresent();
 
 }  // namespace switches
 
diff --git a/content/shell/tools/breakpad_integration_test.py b/content/shell/tools/breakpad_integration_test.py
index 9d24020..7b4307e 100755
--- a/content/shell/tools/breakpad_integration_test.py
+++ b/content/shell/tools/breakpad_integration_test.py
@@ -29,7 +29,7 @@
 
   print "# Run content_shell and make it crash."
   cmd = [options.binary,
-         '--run-layout-test',
+         '--run-web-tests',
          'chrome://crash',
          '--enable-crash-reporter',
          '--crash-dumps-dir=%s' % crash_dir]
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py
index 595cc4d..0b70571 100755
--- a/content/test/gpu/generate_buildbot_json.py
+++ b/content/test/gpu/generate_buildbot_json.py
@@ -2181,6 +2181,8 @@
       {
         'names': [
           'Linux FYI Ozone (Intel)',
+          # TODO(jdarpinian): Re-enable when http://crbug.com/841789 is fixed.
+          'Win10 FYI Exp Release (Intel HD 630)',
         ],
       },
     ],
@@ -2208,6 +2210,8 @@
       {
         'names': [
           'Linux FYI Ozone (Intel)',
+          # TODO(jdarpinian): Re-enable when http://crbug.com/841789 is fixed.
+          'Win10 FYI Exp Release (Intel HD 630)',
         ],
       },
     ],
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index 427aacd92..98a4fa64 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -308,6 +308,8 @@
     # Win / Intel
     self.Fail('conformance/rendering/rendering-stencil-large-viewport.html',
         ['win', 'intel', 'd3d11'], bug=782317)
+    self.Fail('conformance2/glsl3/short-circuiting-in-loop-condition.html',
+        ['win', 'intel'], bug=843369)
 
     # Seems to cause the harness to fail immediately afterward
     self.Skip('conformance2/textures/video/tex-2d-rgba16f-rgba-half_float.html',
diff --git a/device/BUILD.gn b/device/BUILD.gn
index a5d97242..e0df5c7 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -70,6 +70,8 @@
     "fido/fido_ble_connection_unittest.cc",
     "fido/fido_ble_device_unittest.cc",
     "fido/fido_ble_frames_unittest.cc",
+    "fido/fido_cable_device_unittest.cc",
+    "fido/fido_cable_discovery_unittest.cc",
     "fido/fido_discovery_unittest.cc",
     "fido/fido_hid_message_unittest.cc",
     "fido/fido_parsing_utils_unittest.cc",
@@ -283,6 +285,8 @@
       "bluetooth/bluetooth_low_energy_win_fake.h",
       "bluetooth/test/fake_bluetooth_adapter_winrt.cc",
       "bluetooth/test/fake_bluetooth_adapter_winrt.h",
+      "bluetooth/test/fake_device_information_winrt.cc",
+      "bluetooth/test/fake_device_information_winrt.h",
     ]
   }
 
diff --git a/device/bluetooth/bluetooth_adapter_winrt.cc b/device/bluetooth/bluetooth_adapter_winrt.cc
index 37ee2d69..3be2b94 100644
--- a/device/bluetooth/bluetooth_adapter_winrt.cc
+++ b/device/bluetooth/bluetooth_adapter_winrt.cc
@@ -33,6 +33,9 @@
 }  // namespace uwp
 using ABI::Windows::Devices::Bluetooth::IBluetoothAdapter;
 using ABI::Windows::Devices::Bluetooth::IBluetoothAdapterStatics;
+using ABI::Windows::Devices::Enumeration::DeviceInformation;
+using ABI::Windows::Devices::Enumeration::IDeviceInformation;
+using ABI::Windows::Devices::Enumeration::IDeviceInformationStatics;
 using ABI::Windows::Foundation::IAsyncOperation;
 using ABI::Windows::Foundation::IAsyncOperationCompletedHandler;
 using Microsoft::WRL::Callback;
@@ -305,6 +308,13 @@
       RuntimeClass_Windows_Devices_Bluetooth_BluetoothAdapter>(statics);
 }
 
+HRESULT BluetoothAdapterWinrt::GetDeviceInformationStaticsActivationFactory(
+    IDeviceInformationStatics** statics) const {
+  return base::win::GetActivationFactory<
+      IDeviceInformationStatics,
+      RuntimeClass_Windows_Devices_Enumeration_DeviceInformation>(statics);
+}
+
 void BluetoothAdapterWinrt::OnGetDefaultAdapter(
     base::ScopedClosureRunner on_init,
     ComPtr<IBluetoothAdapter> adapter) {
@@ -337,9 +347,51 @@
     return;
   }
 
-  // TODO(https://crbug.com/841261): Retrieve the name from the appropriate
-  // DeviceInformation.
-  name_ = base::win::ScopedHString(device_id).GetAsUTF8();
+  ComPtr<IDeviceInformationStatics> device_information_statics;
+  hr =
+      GetDeviceInformationStaticsActivationFactory(&device_information_statics);
+  if (FAILED(hr)) {
+    VLOG(2) << "GetDeviceInformationStaticsActivationFactory failed: "
+            << logging::SystemErrorCodeToString(hr);
+    return;
+  }
+
+  ComPtr<IAsyncOperation<DeviceInformation*>> create_from_id_op;
+  hr = device_information_statics->CreateFromIdAsync(device_id,
+                                                     &create_from_id_op);
+  if (FAILED(hr)) {
+    VLOG(2) << "CreateFromIdAsync failed: "
+            << logging::SystemErrorCodeToString(hr);
+    return;
+  }
+
+  hr = PostAsyncResults(
+      std::move(create_from_id_op), ui_task_runner_,
+      base::BindOnce(&BluetoothAdapterWinrt::OnCreateFromIdAsync,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(on_init)));
+  if (FAILED(hr)) {
+    VLOG(2) << "PostAsyncResults failed: "
+            << logging::SystemErrorCodeToString(hr);
+  }
+}
+
+void BluetoothAdapterWinrt::OnCreateFromIdAsync(
+    base::ScopedClosureRunner on_init,
+    ComPtr<IDeviceInformation> device_information) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  if (!device_information) {
+    VLOG(2) << "Getting Device Information failed.";
+    return;
+  }
+
+  HSTRING name;
+  HRESULT hr = device_information->get_Name(&name);
+  if (FAILED(hr)) {
+    VLOG(2) << "Getting Name failed: " << logging::SystemErrorCodeToString(hr);
+    return;
+  }
+
+  name_ = base::win::ScopedHString(name).GetAsUTF8();
 }
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_adapter_winrt.h b/device/bluetooth/bluetooth_adapter_winrt.h
index aaf0b07c..150d9640 100644
--- a/device/bluetooth/bluetooth_adapter_winrt.h
+++ b/device/bluetooth/bluetooth_adapter_winrt.h
@@ -6,6 +6,7 @@
 #define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_WINRT_H_
 
 #include <windows.devices.bluetooth.h>
+#include <windows.devices.enumeration.h>
 #include <wrl/client.h>
 
 #include <memory>
@@ -82,10 +83,13 @@
   void RemovePairingDelegateInternal(
       BluetoothDevice::PairingDelegate* pairing_delegate) override;
 
-  // This is declared virtual so that it can be overridden by tests.
+  // These are declared virtual so that they can be overridden by tests.
   virtual HRESULT GetBluetoothAdapterStaticsActivationFactory(
       ABI::Windows::Devices::Bluetooth::IBluetoothAdapterStatics** statics)
       const;
+  virtual HRESULT GetDeviceInformationStaticsActivationFactory(
+      ABI::Windows::Devices::Enumeration::IDeviceInformationStatics** statics)
+      const;
 
  private:
   void OnGetDefaultAdapter(
@@ -93,6 +97,12 @@
       Microsoft::WRL::ComPtr<
           ABI::Windows::Devices::Bluetooth::IBluetoothAdapter> adapter);
 
+  void OnCreateFromIdAsync(
+      base::ScopedClosureRunner on_init,
+      Microsoft::WRL::ComPtr<
+          ABI::Windows::Devices::Enumeration::IDeviceInformation>
+          device_information);
+
   bool is_initialized_ = false;
   bool is_present_ = false;
   std::string address_;
diff --git a/device/bluetooth/test/bluetooth_test_win.cc b/device/bluetooth/test/bluetooth_test_win.cc
index f21416d..6beb3e0 100644
--- a/device/bluetooth/test/bluetooth_test_win.cc
+++ b/device/bluetooth/test/bluetooth_test_win.cc
@@ -27,19 +27,24 @@
 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_win.h"
 #include "device/bluetooth/bluetooth_remote_gatt_service_win.h"
 #include "device/bluetooth/test/fake_bluetooth_adapter_winrt.h"
+#include "device/bluetooth/test/fake_device_information_winrt.h"
 
 namespace {
 
 using Microsoft::WRL::Make;
 using Microsoft::WRL::ComPtr;
-using ABI::Windows::Devices::Bluetooth::IBluetoothAdapterStatics;
 using ABI::Windows::Devices::Bluetooth::IBluetoothAdapter;
+using ABI::Windows::Devices::Bluetooth::IBluetoothAdapterStatics;
+using ABI::Windows::Devices::Enumeration::IDeviceInformation;
+using ABI::Windows::Devices::Enumeration::IDeviceInformationStatics;
 
 class TestBluetoothAdapterWinrt : public device::BluetoothAdapterWinrt {
  public:
   TestBluetoothAdapterWinrt(ComPtr<IBluetoothAdapter> adapter,
+                            ComPtr<IDeviceInformation> device_information,
                             InitCallback init_cb)
-      : adapter_(std::move(adapter)) {
+      : adapter_(std::move(adapter)),
+        device_information_(std::move(device_information)) {
     Init(std::move(init_cb));
   }
 
@@ -53,8 +58,17 @@
     return adapter_statics.CopyTo(statics);
   };
 
+  HRESULT
+  GetDeviceInformationStaticsActivationFactory(
+      IDeviceInformationStatics** statics) const override {
+    auto device_information_statics =
+        Make<device::FakeDeviceInformationStaticsWinrt>(device_information_);
+    return device_information_statics.CopyTo(statics);
+  };
+
  private:
   ComPtr<IBluetoothAdapter> adapter_;
+  ComPtr<IDeviceInformation> device_information_;
 };
 
 BLUETOOTH_ADDRESS CanonicalStringToBLUETOOTH_ADDRESS(
@@ -151,7 +165,7 @@
   if (UseNewBLEWinImplementation()) {
     base::RunLoop run_loop;
     adapter_ = base::MakeRefCounted<TestBluetoothAdapterWinrt>(
-        nullptr, run_loop.QuitClosure());
+        nullptr, nullptr, run_loop.QuitClosure());
     run_loop.Run();
     return;
   }
@@ -166,7 +180,8 @@
   if (UseNewBLEWinImplementation()) {
     base::RunLoop run_loop;
     adapter_ = base::MakeRefCounted<TestBluetoothAdapterWinrt>(
-        Make<FakeBluetoothAdapterWinrt>(kTestAdapterAddress, kTestAdapterName),
+        Make<FakeBluetoothAdapterWinrt>(kTestAdapterAddress),
+        Make<FakeDeviceInformationWinrt>(kTestAdapterName),
         run_loop.QuitClosure());
     run_loop.Run();
     return;
diff --git a/device/bluetooth/test/fake_bluetooth_adapter_winrt.cc b/device/bluetooth/test/fake_bluetooth_adapter_winrt.cc
index b0372877..48413782 100644
--- a/device/bluetooth/test/fake_bluetooth_adapter_winrt.cc
+++ b/device/bluetooth/test/fake_bluetooth_adapter_winrt.cc
@@ -9,11 +9,11 @@
 #include "base/bind.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "base/task_runner_util.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/win/async_operation.h"
-#include "base/win/scoped_hstring.h"
 #include "device/bluetooth/test/bluetooth_test.h"
 
 namespace device {
@@ -33,11 +33,10 @@
 
 }  // namespace
 
-FakeBluetoothAdapterWinrt::FakeBluetoothAdapterWinrt(std::string address,
-                                                     std::string device_id)
-    : address_(std::move(address)), device_id_(std::move(device_id)) {
+FakeBluetoothAdapterWinrt::FakeBluetoothAdapterWinrt(
+    base::StringPiece address) {
   const bool result = base::HexStringToUInt64(
-      base::StrCat(base::SplitStringPiece(address_, ":", base::TRIM_WHITESPACE,
+      base::StrCat(base::SplitStringPiece(address, ":", base::TRIM_WHITESPACE,
                                           base::SPLIT_WANT_ALL)),
       &raw_address_);
   DCHECK(result);
@@ -46,7 +45,8 @@
 FakeBluetoothAdapterWinrt::~FakeBluetoothAdapterWinrt() = default;
 
 HRESULT FakeBluetoothAdapterWinrt::get_DeviceId(HSTRING* value) {
-  *value = base::win::ScopedHString::Create(device_id_).release();
+  // The actual device id does not matter for testing, as long as this method
+  // returns a success code.
   return S_OK;
 }
 
diff --git a/device/bluetooth/test/fake_bluetooth_adapter_winrt.h b/device/bluetooth/test/fake_bluetooth_adapter_winrt.h
index 4b05cb6..4181a20a 100644
--- a/device/bluetooth/test/fake_bluetooth_adapter_winrt.h
+++ b/device/bluetooth/test/fake_bluetooth_adapter_winrt.h
@@ -12,9 +12,8 @@
 
 #include <stdint.h>
 
-#include <string>
-
 #include "base/macros.h"
+#include "base/strings/string_piece_forward.h"
 
 namespace device {
 
@@ -24,7 +23,7 @@
               Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
           ABI::Windows::Devices::Bluetooth::IBluetoothAdapter> {
  public:
-  FakeBluetoothAdapterWinrt(std::string address, std::string device_id);
+  explicit FakeBluetoothAdapterWinrt(base::StringPiece address);
   ~FakeBluetoothAdapterWinrt() override;
 
   // IBluetoothAdapter:
@@ -42,9 +41,7 @@
                 ABI::Windows::Devices::Radios::Radio*>** operation) override;
 
  private:
-  std::string address_;
   uint64_t raw_address_;
-  std::string device_id_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeBluetoothAdapterWinrt);
 };
@@ -55,7 +52,7 @@
               Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
           ABI::Windows::Devices::Bluetooth::IBluetoothAdapterStatics> {
  public:
-  FakeBluetoothAdapterStaticsWinrt(
+  explicit FakeBluetoothAdapterStaticsWinrt(
       Microsoft::WRL::ComPtr<
           ABI::Windows::Devices::Bluetooth::IBluetoothAdapter> default_adapter);
   ~FakeBluetoothAdapterStaticsWinrt() override;
diff --git a/device/bluetooth/test/fake_device_information_winrt.cc b/device/bluetooth/test/fake_device_information_winrt.cc
new file mode 100644
index 0000000..122a30f
--- /dev/null
+++ b/device/bluetooth/test/fake_device_information_winrt.cc
@@ -0,0 +1,158 @@
+// 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 "device/bluetooth/test/fake_device_information_winrt.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/strings/string_piece.h"
+#include "base/task_runner_util.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/win/async_operation.h"
+#include "base/win/scoped_hstring.h"
+
+namespace device {
+
+namespace {
+
+using ABI::Windows::Devices::Enumeration::DeviceClass;
+using ABI::Windows::Devices::Enumeration::DeviceInformation;
+using ABI::Windows::Devices::Enumeration::DeviceInformationCollection;
+using ABI::Windows::Devices::Enumeration::DeviceThumbnail;
+using ABI::Windows::Devices::Enumeration::IDeviceInformation;
+using ABI::Windows::Devices::Enumeration::IDeviceInformationUpdate;
+using ABI::Windows::Devices::Enumeration::IDeviceWatcher;
+using ABI::Windows::Devices::Enumeration::IEnclosureLocation;
+using ABI::Windows::Foundation::Collections::IIterable;
+using ABI::Windows::Foundation::Collections::IMapView;
+using ABI::Windows::Foundation::IAsyncOperation;
+using Microsoft::WRL::ComPtr;
+using Microsoft::WRL::Make;
+
+}  // namespace
+
+FakeDeviceInformationWinrt::FakeDeviceInformationWinrt(std::string name)
+    : name_(std::move(name)) {}
+
+FakeDeviceInformationWinrt::~FakeDeviceInformationWinrt() = default;
+
+HRESULT FakeDeviceInformationWinrt::get_Id(HSTRING* value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationWinrt::get_Name(HSTRING* value) {
+  *value = base::win::ScopedHString::Create(name_).release();
+  return S_OK;
+}
+
+HRESULT FakeDeviceInformationWinrt::get_IsEnabled(boolean* value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationWinrt::get_IsDefault(boolean* value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationWinrt::get_EnclosureLocation(
+    IEnclosureLocation** value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationWinrt::get_Properties(
+    IMapView<HSTRING, IInspectable*>** value) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationWinrt::Update(
+    IDeviceInformationUpdate* update_info) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationWinrt::GetThumbnailAsync(
+    IAsyncOperation<DeviceThumbnail*>** async_op) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationWinrt::GetGlyphThumbnailAsync(
+    IAsyncOperation<DeviceThumbnail*>** async_op) {
+  return E_NOTIMPL;
+}
+
+FakeDeviceInformationStaticsWinrt::FakeDeviceInformationStaticsWinrt(
+    ComPtr<IDeviceInformation> device_information)
+    : device_information_(std::move(device_information)) {}
+
+FakeDeviceInformationStaticsWinrt::~FakeDeviceInformationStaticsWinrt() =
+    default;
+
+HRESULT FakeDeviceInformationStaticsWinrt::CreateFromIdAsync(
+    HSTRING device_id,
+    IAsyncOperation<DeviceInformation*>** async_op) {
+  auto operation = Make<base::win::AsyncOperation<DeviceInformation*>>();
+  base::SequencedTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(operation->callback(), device_information_));
+  *async_op = operation.Detach();
+  return S_OK;
+}
+
+HRESULT
+FakeDeviceInformationStaticsWinrt::CreateFromIdAsyncAdditionalProperties(
+    HSTRING device_id,
+    IIterable<HSTRING>* additional_properties,
+    IAsyncOperation<DeviceInformation*>** async_op) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationStaticsWinrt::FindAllAsync(
+    IAsyncOperation<DeviceInformationCollection*>** async_op) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationStaticsWinrt::FindAllAsyncDeviceClass(
+    DeviceClass device_class,
+    IAsyncOperation<DeviceInformationCollection*>** async_op) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationStaticsWinrt::FindAllAsyncAqsFilter(
+    HSTRING aqs_filter,
+    IAsyncOperation<DeviceInformationCollection*>** async_op) {
+  return E_NOTIMPL;
+}
+
+HRESULT
+FakeDeviceInformationStaticsWinrt::FindAllAsyncAqsFilterAndAdditionalProperties(
+    HSTRING aqs_filter,
+    IIterable<HSTRING>* additional_properties,
+    IAsyncOperation<DeviceInformationCollection*>** async_op) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationStaticsWinrt::CreateWatcher(
+    IDeviceWatcher** watcher) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationStaticsWinrt::CreateWatcherDeviceClass(
+    DeviceClass device_class,
+    IDeviceWatcher** watcher) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationStaticsWinrt::CreateWatcherAqsFilter(
+    HSTRING aqs_filter,
+    IDeviceWatcher** watcher) {
+  return E_NOTIMPL;
+}
+
+HRESULT FakeDeviceInformationStaticsWinrt::
+    CreateWatcherAqsFilterAndAdditionalProperties(
+        HSTRING aqs_filter,
+        IIterable<HSTRING>* additional_properties,
+        IDeviceWatcher** watcher) {
+  return E_NOTIMPL;
+}
+
+}  // namespace device
diff --git a/device/bluetooth/test/fake_device_information_winrt.h b/device/bluetooth/test/fake_device_information_winrt.h
new file mode 100644
index 0000000..0be4d8d
--- /dev/null
+++ b/device/bluetooth/test/fake_device_information_winrt.h
@@ -0,0 +1,126 @@
+// 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 DEVICE_BLUETOOTH_TEST_FAKE_DEVICE_INFORMATION_WINRT_H_
+#define DEVICE_BLUETOOTH_TEST_FAKE_DEVICE_INFORMATION_WINRT_H_
+
+#include <windows.devices.enumeration.h>
+#include <wrl/client.h>
+#include <wrl/implements.h>
+
+#include <string>
+
+#include "base/macros.h"
+
+namespace device {
+
+class FakeDeviceInformationWinrt
+    : public Microsoft::WRL::RuntimeClass<
+          Microsoft::WRL::RuntimeClassFlags<
+              Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
+          ABI::Windows::Devices::Enumeration::IDeviceInformation> {
+ public:
+  explicit FakeDeviceInformationWinrt(std::string name);
+  ~FakeDeviceInformationWinrt() override;
+
+  // IDeviceInformation:
+  IFACEMETHODIMP get_Id(HSTRING* value) override;
+  IFACEMETHODIMP get_Name(HSTRING* value) override;
+  IFACEMETHODIMP get_IsEnabled(boolean* value) override;
+  IFACEMETHODIMP get_IsDefault(boolean* value) override;
+  IFACEMETHODIMP get_EnclosureLocation(
+      ABI::Windows::Devices::Enumeration::IEnclosureLocation** value) override;
+  IFACEMETHODIMP get_Properties(
+      ABI::Windows::Foundation::Collections::IMapView<HSTRING, IInspectable*>**
+          value) override;
+  IFACEMETHODIMP Update(
+      ABI::Windows::Devices::Enumeration::IDeviceInformationUpdate* update_info)
+      override;
+  IFACEMETHODIMP GetThumbnailAsync(
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Enumeration::DeviceThumbnail*>** async_op)
+      override;
+  IFACEMETHODIMP GetGlyphThumbnailAsync(
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Enumeration::DeviceThumbnail*>** async_op)
+      override;
+
+ private:
+  std::string name_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeDeviceInformationWinrt);
+};
+
+class FakeDeviceInformationStaticsWinrt
+    : public Microsoft::WRL::RuntimeClass<
+          Microsoft::WRL::RuntimeClassFlags<
+              Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
+          ABI::Windows::Devices::Enumeration::IDeviceInformationStatics> {
+ public:
+  explicit FakeDeviceInformationStaticsWinrt(
+      Microsoft::WRL::ComPtr<
+          ABI::Windows::Devices::Enumeration::IDeviceInformation>
+          device_information);
+  ~FakeDeviceInformationStaticsWinrt() override;
+
+  // IDeviceInformationStatics:
+  IFACEMETHODIMP CreateFromIdAsync(
+      HSTRING device_id,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Enumeration::DeviceInformation*>** async_op)
+      override;
+  IFACEMETHODIMP CreateFromIdAsyncAdditionalProperties(
+      HSTRING device_id,
+      ABI::Windows::Foundation::Collections::IIterable<HSTRING>*
+          additional_properties,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Enumeration::DeviceInformation*>** async_op)
+      override;
+  IFACEMETHODIMP FindAllAsync(
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Enumeration::DeviceInformationCollection*>**
+          async_op) override;
+  IFACEMETHODIMP FindAllAsyncDeviceClass(
+      ABI::Windows::Devices::Enumeration::DeviceClass device_class,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Enumeration::DeviceInformationCollection*>**
+          async_op) override;
+  IFACEMETHODIMP FindAllAsyncAqsFilter(
+      HSTRING aqs_filter,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Enumeration::DeviceInformationCollection*>**
+          async_op) override;
+  IFACEMETHODIMP
+  FindAllAsyncAqsFilterAndAdditionalProperties(
+      HSTRING aqs_filter,
+      ABI::Windows::Foundation::Collections::IIterable<HSTRING>*
+          additional_properties,
+      ABI::Windows::Foundation::IAsyncOperation<
+          ABI::Windows::Devices::Enumeration::DeviceInformationCollection*>**
+          async_op) override;
+  IFACEMETHODIMP CreateWatcher(
+      ABI::Windows::Devices::Enumeration::IDeviceWatcher** watcher) override;
+  IFACEMETHODIMP CreateWatcherDeviceClass(
+      ABI::Windows::Devices::Enumeration::DeviceClass device_class,
+      ABI::Windows::Devices::Enumeration::IDeviceWatcher** watcher) override;
+  IFACEMETHODIMP CreateWatcherAqsFilter(
+      HSTRING aqs_filter,
+      ABI::Windows::Devices::Enumeration::IDeviceWatcher** watcher) override;
+  IFACEMETHODIMP
+  CreateWatcherAqsFilterAndAdditionalProperties(
+      HSTRING aqs_filter,
+      ABI::Windows::Foundation::Collections::IIterable<HSTRING>*
+          additional_properties,
+      ABI::Windows::Devices::Enumeration::IDeviceWatcher** watcher) override;
+
+ private:
+  Microsoft::WRL::ComPtr<ABI::Windows::Devices::Enumeration::IDeviceInformation>
+      device_information_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeDeviceInformationStaticsWinrt);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_BLUETOOTH_TEST_FAKE_DEVICE_INFORMATION_WINRT_H_
diff --git a/device/fido/BUILD.gn b/device/fido/BUILD.gn
index def3a2b..aa264087 100644
--- a/device/fido/BUILD.gn
+++ b/device/fido/BUILD.gn
@@ -47,12 +47,18 @@
     "fido_ble_device.h",
     "fido_ble_discovery.cc",
     "fido_ble_discovery.h",
+    "fido_ble_discovery_base.cc",
+    "fido_ble_discovery_base.h",
     "fido_ble_frames.cc",
     "fido_ble_frames.h",
     "fido_ble_transaction.cc",
     "fido_ble_transaction.h",
     "fido_ble_uuids.cc",
     "fido_ble_uuids.h",
+    "fido_cable_device.cc",
+    "fido_cable_device.h",
+    "fido_cable_discovery.cc",
+    "fido_cable_discovery.h",
     "fido_constants.cc",
     "fido_constants.h",
     "fido_device.cc",
diff --git a/device/fido/fido_ble_device.cc b/device/fido/fido_ble_device.cc
index c4ee5cc..ae49580 100644
--- a/device/fido/fido_ble_device.cc
+++ b/device/fido/fido_ble_device.cc
@@ -84,6 +84,23 @@
   return weak_factory_.GetWeakPtr();
 }
 
+void FidoBleDevice::OnResponseFrame(FrameCallback callback,
+                                    base::Optional<FidoBleFrame> frame) {
+  // The request is done, time to reset |transaction_|.
+  ResetTransaction();
+
+  state_ = frame ? State::kReady : State::kDeviceError;
+  auto self = GetWeakPtr();
+  std::move(callback).Run(std::move(frame));
+  // Executing callbacks may free |this|. Check |self| first.
+  if (self)
+    Transition();
+}
+
+void FidoBleDevice::ResetTransaction() {
+  transaction_.reset();
+}
+
 void FidoBleDevice::Transition() {
   switch (state_) {
     case State::kInit:
@@ -165,19 +182,6 @@
                      std::move(callback)));
 }
 
-void FidoBleDevice::OnResponseFrame(FrameCallback callback,
-                                    base::Optional<FidoBleFrame> frame) {
-  // The request is done, time to reset |transaction_|.
-  transaction_.reset();
-
-  state_ = frame ? State::kReady : State::kDeviceError;
-  auto self = GetWeakPtr();
-  std::move(callback).Run(std::move(frame));
-  // Executing callbacks may free |this|. Check |self| first.
-  if (self)
-    Transition();
-}
-
 void FidoBleDevice::StartTimeout() {
   timer_.Start(FROM_HERE, kDeviceTimeout, this, &FidoBleDevice::OnTimeout);
 }
diff --git a/device/fido/fido_ble_device.h b/device/fido/fido_ble_device.h
index 419d823..58b1121 100644
--- a/device/fido/fido_ble_device.h
+++ b/device/fido/fido_ble_device.h
@@ -52,12 +52,15 @@
                       DeviceCallback callback) override;
   base::WeakPtr<FidoDevice> GetWeakPtr() override;
 
- private:
+  virtual void OnResponseFrame(FrameCallback callback,
+                               base::Optional<FidoBleFrame> frame);
   void Transition();
   void AddToPendingFrames(FidoBleDeviceCommand cmd,
                           std::vector<uint8_t> request,
                           DeviceCallback callback);
+  void ResetTransaction();
 
+ private:
   void OnConnectionStatus(bool success);
   void OnStatusMessage(std::vector<uint8_t> data);
 
@@ -66,8 +69,6 @@
 
   void SendPendingRequestFrame();
   void SendRequestFrame(FidoBleFrame frame, FrameCallback callback);
-  void OnResponseFrame(FrameCallback callback,
-                       base::Optional<FidoBleFrame> frame);
 
   void StartTimeout();
   void StopTimeout();
diff --git a/device/fido/fido_ble_discovery.cc b/device/fido/fido_ble_discovery.cc
index ef8b2c5..16de4ad 100644
--- a/device/fido/fido_ble_discovery.cc
+++ b/device/fido/fido_ble_discovery.cc
@@ -4,18 +4,12 @@
 
 #include "device/fido/fido_ble_discovery.h"
 
-#include <string>
 #include <utility>
 
 #include "base/bind.h"
-#include "base/location.h"
-#include "base/stl_util.h"
-#include "base/strings/string_piece.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "build/build_config.h"
-#include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "base/callback_helpers.h"
+#include "device/bluetooth/bluetooth_adapter.h"
 #include "device/bluetooth/bluetooth_common.h"
-#include "device/bluetooth/bluetooth_discovery_filter.h"
 #include "device/bluetooth/bluetooth_discovery_session.h"
 #include "device/bluetooth/bluetooth_uuid.h"
 #include "device/fido/fido_ble_device.h"
@@ -23,15 +17,9 @@
 
 namespace device {
 
-FidoBleDiscovery::FidoBleDiscovery()
-    : FidoDiscovery(FidoTransportProtocol::kBluetoothLowEnergy),
-      weak_factory_(this) {}
-FidoBleDiscovery::~FidoBleDiscovery() {
-  if (adapter_)
-    adapter_->RemoveObserver(this);
+FidoBleDiscovery::FidoBleDiscovery() : weak_factory_(this) {}
 
-  // Destroying |discovery_session_| will best-effort-stop discovering.
-}
+FidoBleDiscovery::~FidoBleDiscovery() = default;
 
 // static
 const BluetoothUUID& FidoBleDiscovery::FidoServiceUUID() {
@@ -39,29 +27,11 @@
   return service_uuid;
 }
 
-void FidoBleDiscovery::OnGetAdapter(scoped_refptr<BluetoothAdapter> adapter) {
-  DCHECK(!adapter_);
-  adapter_ = std::move(adapter);
-  DCHECK(adapter_);
-  VLOG(2) << "Got adapter " << adapter_->GetAddress();
-
-  adapter_->AddObserver(this);
-  if (adapter_->IsPowered()) {
-    OnSetPowered();
-  } else {
-    adapter_->SetPowered(
-        true,
-        base::Bind(&FidoBleDiscovery::OnSetPowered, weak_factory_.GetWeakPtr()),
-        base::Bind(&FidoBleDiscovery::OnSetPoweredError,
-                   weak_factory_.GetWeakPtr()));
-  }
-}
-
 void FidoBleDiscovery::OnSetPowered() {
-  DCHECK(adapter_);
-  VLOG(2) << "Adapter " << adapter_->GetAddress() << " is powered on.";
+  DCHECK(adapter());
+  VLOG(2) << "Adapter " << adapter()->GetAddress() << " is powered on.";
 
-  for (BluetoothDevice* device : adapter_->GetDevices()) {
+  for (BluetoothDevice* device : adapter()->GetDevices()) {
     if (base::ContainsKey(device->GetUUIDs(), FidoServiceUUID())) {
       VLOG(2) << "U2F BLE device: " << device->GetAddress();
       AddDevice(std::make_unique<FidoBleDevice>(device->GetAddress()));
@@ -72,49 +42,14 @@
       BluetoothTransport::BLUETOOTH_TRANSPORT_LE);
   filter->AddUUID(FidoServiceUUID());
 
-  adapter_->StartDiscoverySessionWithFilter(
+  adapter()->StartDiscoverySessionWithFilter(
       std::move(filter),
-      base::Bind(&FidoBleDiscovery::OnStartDiscoverySessionWithFilter,
-                 weak_factory_.GetWeakPtr()),
-      base::Bind(&FidoBleDiscovery::OnStartDiscoverySessionWithFilterError,
-                 weak_factory_.GetWeakPtr()));
-}
-
-void FidoBleDiscovery::OnSetPoweredError() {
-  DLOG(ERROR) << "Failed to power on the adapter.";
-  NotifyDiscoveryStarted(false);
-}
-
-void FidoBleDiscovery::OnStartDiscoverySessionWithFilter(
-    std::unique_ptr<BluetoothDiscoverySession> session) {
-  discovery_session_ = std::move(session);
-  DVLOG(2) << "Discovery session started.";
-  NotifyDiscoveryStarted(true);
-}
-
-void FidoBleDiscovery::OnStartDiscoverySessionWithFilterError() {
-  DLOG(ERROR) << "Discovery session not started.";
-  NotifyDiscoveryStarted(false);
-}
-
-void FidoBleDiscovery::StartInternal() {
-  auto& factory = BluetoothAdapterFactory::Get();
-  auto callback = base::BindRepeating(&FidoBleDiscovery::OnGetAdapter,
-                                      weak_factory_.GetWeakPtr());
-#if defined(OS_MACOSX)
-  // BluetoothAdapter may invoke the callback synchronously on Mac, but
-  // StartInternal() never wants to invoke to NotifyDiscoveryStarted()
-  // immediately, so ensure there is at least post-task at this bottleneck.
-  // See: https://crbug.com/823686.
-  callback = base::BindRepeating(
-      [](BluetoothAdapterFactory::AdapterCallback callback,
-         scoped_refptr<BluetoothAdapter> adapter) {
-        base::ThreadTaskRunnerHandle::Get()->PostTask(
-            FROM_HERE, base::BindRepeating(callback, adapter));
-      },
-      std::move(callback));
-#endif  // defined(OS_MACOSX)
-  factory.GetAdapter(std::move(callback));
+      base::AdaptCallbackForRepeating(
+          base::BindOnce(&FidoBleDiscovery::OnStartDiscoverySessionWithFilter,
+                         weak_factory_.GetWeakPtr())),
+      base::AdaptCallbackForRepeating(
+          base::BindOnce(&FidoBleDiscovery::OnStartDiscoverySessionError,
+                         weak_factory_.GetWeakPtr())));
 }
 
 void FidoBleDiscovery::DeviceAdded(BluetoothAdapter* adapter,
diff --git a/device/fido/fido_ble_discovery.h b/device/fido/fido_ble_discovery.h
index 6e560b9..abf6f27 100644
--- a/device/fido/fido_ble_discovery.h
+++ b/device/fido/fido_ble_discovery.h
@@ -9,20 +9,16 @@
 
 #include "base/component_export.h"
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
-#include "device/bluetooth/bluetooth_adapter.h"
-#include "device/fido/fido_discovery.h"
+#include "device/fido/fido_ble_discovery_base.h"
 
 namespace device {
 
 class BluetoothDevice;
-class BluetoothDiscoverySession;
 class BluetoothUUID;
 
 class COMPONENT_EXPORT(DEVICE_FIDO) FidoBleDiscovery
-    : public FidoDiscovery,
-      BluetoothAdapter::Observer {
+    : public FidoBleDiscoveryBase {
  public:
   FidoBleDiscovery();
   ~FidoBleDiscovery() override;
@@ -30,15 +26,8 @@
  private:
   static const BluetoothUUID& FidoServiceUUID();
 
-  void OnGetAdapter(scoped_refptr<BluetoothAdapter> adapter);
-  void OnSetPowered();
-  void OnSetPoweredError();
-  void OnStartDiscoverySessionWithFilter(
-      std::unique_ptr<BluetoothDiscoverySession>);
-  void OnStartDiscoverySessionWithFilterError();
-
-  // FidoDiscovery:
-  void StartInternal() override;
+  // FidoBleDiscoveryBase:
+  void OnSetPowered() override;
 
   // BluetoothAdapter::Observer:
   void DeviceAdded(BluetoothAdapter* adapter, BluetoothDevice* device) override;
@@ -47,9 +36,6 @@
   void DeviceRemoved(BluetoothAdapter* adapter,
                      BluetoothDevice* device) override;
 
-  scoped_refptr<BluetoothAdapter> adapter_;
-  std::unique_ptr<BluetoothDiscoverySession> discovery_session_;
-
   base::WeakPtrFactory<FidoBleDiscovery> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(FidoBleDiscovery);
diff --git a/device/fido/fido_ble_discovery_base.cc b/device/fido/fido_ble_discovery_base.cc
new file mode 100644
index 0000000..b118bc1
--- /dev/null
+++ b/device/fido/fido_ble_discovery_base.cc
@@ -0,0 +1,94 @@
+// 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 "device/fido/fido_ble_discovery_base.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "base/location.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
+#include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "device/bluetooth/bluetooth_common.h"
+#include "device/bluetooth/bluetooth_discovery_session.h"
+
+namespace device {
+
+FidoBleDiscoveryBase::FidoBleDiscoveryBase()
+    : FidoDiscovery(FidoTransportProtocol::kBluetoothLowEnergy),
+      weak_factory_(this) {}
+
+FidoBleDiscoveryBase::~FidoBleDiscoveryBase() {
+  if (adapter_)
+    adapter_->RemoveObserver(this);
+
+  // Destroying |discovery_session_| will best-effort-stop discovering.
+}
+
+void FidoBleDiscoveryBase::OnStartDiscoverySessionWithFilter(
+    std::unique_ptr<BluetoothDiscoverySession> session) {
+  SetDiscoverySession(std::move(session));
+  DVLOG(2) << "Discovery session started.";
+  NotifyDiscoveryStarted(true);
+}
+
+void FidoBleDiscoveryBase::OnSetPoweredError() {
+  DLOG(ERROR) << "Failed to power on the adapter.";
+  NotifyDiscoveryStarted(false);
+}
+
+void FidoBleDiscoveryBase::OnStartDiscoverySessionError() {
+  DLOG(ERROR) << "Discovery session not started.";
+  NotifyDiscoveryStarted(false);
+}
+
+void FidoBleDiscoveryBase::SetDiscoverySession(
+    std::unique_ptr<BluetoothDiscoverySession> discovery_session) {
+  discovery_session_ = std::move(discovery_session);
+}
+
+void FidoBleDiscoveryBase::OnGetAdapter(
+    scoped_refptr<BluetoothAdapter> adapter) {
+  DCHECK(!adapter_);
+  adapter_ = std::move(adapter);
+  DCHECK(adapter_);
+  VLOG(2) << "Got adapter " << adapter_->GetAddress();
+
+  adapter_->AddObserver(this);
+  if (adapter_->IsPowered()) {
+    OnSetPowered();
+  } else {
+    adapter_->SetPowered(
+        true,
+        base::AdaptCallbackForRepeating(base::BindOnce(
+            &FidoBleDiscoveryBase::OnSetPowered, weak_factory_.GetWeakPtr())),
+        base::AdaptCallbackForRepeating(
+            base::BindOnce(&FidoBleDiscoveryBase::OnSetPoweredError,
+                           weak_factory_.GetWeakPtr())));
+  }
+}
+
+void FidoBleDiscoveryBase::StartInternal() {
+  auto& factory = BluetoothAdapterFactory::Get();
+  auto callback = base::BindOnce(&FidoBleDiscoveryBase::OnGetAdapter,
+                                 weak_factory_.GetWeakPtr());
+#if defined(OS_MACOSX)
+  // BluetoothAdapter may invoke the callback synchronously on Mac, but
+  // StartInternal() never wants to invoke to NotifyDiscoveryStarted()
+  // immediately, so ensure there is at least post-task at this bottleneck.
+  // See: https://crbug.com/823686.
+  callback = base::BindOnce(
+      [](BluetoothAdapterFactory::AdapterCallback callback,
+         scoped_refptr<BluetoothAdapter> adapter) {
+        base::ThreadTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(std::move(callback), adapter));
+      },
+      base::AdaptCallbackForRepeating(std::move(callback)));
+#endif  // defined(OS_MACOSX)
+  factory.GetAdapter(base::AdaptCallbackForRepeating(std::move(callback)));
+}
+
+}  // namespace device
diff --git a/device/fido/fido_ble_discovery_base.h b/device/fido/fido_ble_discovery_base.h
new file mode 100644
index 0000000..dd4a0f14
--- /dev/null
+++ b/device/fido/fido_ble_discovery_base.h
@@ -0,0 +1,56 @@
+// 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 DEVICE_FIDO_FIDO_BLE_DISCOVERY_BASE_H_
+#define DEVICE_FIDO_FIDO_BLE_DISCOVERY_BASE_H_
+
+#include <memory>
+
+#include "base/component_export.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "device/bluetooth/bluetooth_adapter.h"
+#include "device/fido/fido_discovery.h"
+
+namespace device {
+
+class BluetoothDiscoverySession;
+
+class COMPONENT_EXPORT(DEVICE_FIDO) FidoBleDiscoveryBase
+    : public FidoDiscovery,
+      public BluetoothAdapter::Observer {
+ public:
+  FidoBleDiscoveryBase();
+  ~FidoBleDiscoveryBase() override;
+
+ protected:
+  virtual void OnSetPowered() = 0;
+  virtual void OnStartDiscoverySessionWithFilter(
+      std::unique_ptr<BluetoothDiscoverySession>);
+
+  void OnSetPoweredError();
+  void OnStartDiscoverySessionError();
+  void SetDiscoverySession(
+      std::unique_ptr<BluetoothDiscoverySession> discovery_session);
+
+  BluetoothAdapter* adapter() { return adapter_.get(); }
+
+ private:
+  void OnGetAdapter(scoped_refptr<BluetoothAdapter> adapter);
+
+  // FidoDiscovery:
+  void StartInternal() override;
+
+  scoped_refptr<BluetoothAdapter> adapter_;
+  std::unique_ptr<BluetoothDiscoverySession> discovery_session_;
+
+  base::WeakPtrFactory<FidoBleDiscoveryBase> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(FidoBleDiscoveryBase);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_FIDO_FIDO_BLE_DISCOVERY_BASE_H_
diff --git a/device/fido/fido_ble_uuids.cc b/device/fido/fido_ble_uuids.cc
index 8fe32d09..75c11182 100644
--- a/device/fido/fido_ble_uuids.cc
+++ b/device/fido/fido_ble_uuids.cc
@@ -14,5 +14,6 @@
 const char kFidoServiceRevisionUUID[] = "00002a28-0000-1000-8000-00805f9b34fb";
 const char kFidoServiceRevisionBitfieldUUID[] =
     "f1d0fff4-deaa-ecee-b42f-c9ba7ed623bb";
+const char kCableAdvertisementUUID[] = "0000fde2-0000-1000-8000-00805f9b34fb";
 
 }  // namespace device
diff --git a/device/fido/fido_ble_uuids.h b/device/fido/fido_ble_uuids.h
index 61c4a559..a2ead64 100644
--- a/device/fido/fido_ble_uuids.h
+++ b/device/fido/fido_ble_uuids.h
@@ -22,6 +22,9 @@
 COMPONENT_EXPORT(DEVICE_FIDO) extern const char kFidoServiceRevisionUUID[];
 COMPONENT_EXPORT(DEVICE_FIDO)
 extern const char kFidoServiceRevisionBitfieldUUID[];
+// TODO(hongjunchoi): Add URL to the specification once CaBLE protocol is
+// standardized.
+COMPONENT_EXPORT(DEVICE_FIDO) extern const char kCableAdvertisementUUID[];
 
 }  // namespace device
 
diff --git a/device/fido/fido_cable_device.cc b/device/fido/fido_cable_device.cc
new file mode 100644
index 0000000..02deea1
--- /dev/null
+++ b/device/fido/fido_cable_device.cc
@@ -0,0 +1,178 @@
+// 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 "device/fido/fido_cable_device.h"
+
+#include <utility>
+
+#include "base/command_line.h"
+#include "base/strings/string_piece.h"
+#include "device/fido/fido_ble_connection.h"
+#include "device/fido/fido_ble_frames.h"
+#include "device/fido/fido_constants.h"
+#include "device/fido/fido_parsing_utils.h"
+
+namespace device {
+
+namespace switches {
+constexpr char kEnableCableEncryption[] = "enable-cable-encryption";
+}  // namespace switches
+
+namespace {
+
+// Maximum size of EncryptionData::read_sequence_num or
+// EncryptionData::write_sequence_num allowed. If we encounter
+// counter larger than |kMaxCounter| FidoCableDevice should error out.
+constexpr size_t kMaxCounter = (1 << 24) - 1;
+
+base::StringPiece ConvertToStringPiece(const std::vector<uint8_t>& data) {
+  return base::StringPiece(reinterpret_cast<const char*>(data.data()),
+                           data.size());
+}
+
+// static
+bool IsEncryptionEnabled() {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  return command_line->HasSwitch(switches::kEnableCableEncryption);
+}
+
+base::Optional<std::vector<uint8_t>> ConstructEncryptionNonce(
+    base::span<const uint8_t> nonce,
+    bool is_sender_client,
+    uint32_t counter) {
+  if (counter > kMaxCounter)
+    return base::nullopt;
+
+  auto constructed_nonce = fido_parsing_utils::Materialize(nonce);
+  constructed_nonce.push_back(is_sender_client ? 0x00 : 0x01);
+  constructed_nonce.push_back(counter >> 16 & 0xFF);
+  constructed_nonce.push_back(counter >> 8 & 0xFF);
+  constructed_nonce.push_back(counter & 0xFF);
+  return constructed_nonce;
+}
+
+bool EncryptOutgoingMessage(
+    const FidoCableDevice::EncryptionData& encryption_data,
+    std::vector<uint8_t>* message_to_encrypt) {
+  const auto nonce = ConstructEncryptionNonce(
+      encryption_data.nonce, true /* is_sender_client */,
+      encryption_data.write_sequence_num);
+  if (!nonce)
+    return false;
+
+  DCHECK_EQ(nonce->size(), encryption_data.aes_key.NonceLength());
+  std::string ciphertext;
+  bool encryption_success = encryption_data.aes_key.Seal(
+      ConvertToStringPiece(*message_to_encrypt), ConvertToStringPiece(*nonce),
+      nullptr /* additional_data */, &ciphertext);
+  if (!encryption_success)
+    return false;
+
+  message_to_encrypt->assign(ciphertext.begin(), ciphertext.end());
+  return true;
+}
+
+bool DecryptIncomingMessage(
+    const FidoCableDevice::EncryptionData& encryption_data,
+    FidoBleFrame* incoming_frame) {
+  const auto nonce = ConstructEncryptionNonce(
+      encryption_data.nonce, false /* is_sender_client */,
+      encryption_data.read_sequence_num);
+  if (!nonce)
+    return false;
+
+  DCHECK_EQ(nonce->size(), encryption_data.aes_key.NonceLength());
+  std::string ciphertext;
+
+  bool decryption_success = encryption_data.aes_key.Open(
+      ConvertToStringPiece(incoming_frame->data()),
+      ConvertToStringPiece(*nonce), nullptr /* additional_data */, &ciphertext);
+  if (!decryption_success)
+    return false;
+
+  incoming_frame->data().assign(ciphertext.begin(), ciphertext.end());
+  return true;
+}
+
+}  // namespace
+
+// FidoCableDevice::EncryptionData ----------------------------------------
+
+FidoCableDevice::EncryptionData::EncryptionData(
+    std::string session_key,
+    const std::array<uint8_t, 8>& nonce)
+    : encryption_key(std::move(session_key)), nonce(nonce) {
+  DCHECK_EQ(encryption_key.size(), aes_key.KeyLength());
+  aes_key.Init(&encryption_key);
+}
+
+FidoCableDevice::EncryptionData::EncryptionData(EncryptionData&& data) =
+    default;
+
+FidoCableDevice::EncryptionData& FidoCableDevice::EncryptionData::operator=(
+    EncryptionData&& other) = default;
+
+FidoCableDevice::EncryptionData::~EncryptionData() = default;
+
+// FidoCableDevice::EncryptionData ----------------------------------------
+
+FidoCableDevice::FidoCableDevice(std::string address,
+                                 std::string session_key,
+                                 const std::array<uint8_t, 8>& nonce)
+    : FidoBleDevice(std::move(address)),
+      encryption_data_(std::move(session_key), nonce),
+      weak_factory_(this) {}
+
+FidoCableDevice::FidoCableDevice(std::unique_ptr<FidoBleConnection> connection,
+                                 std::string session_key,
+                                 const std::array<uint8_t, 8>& nonce)
+    : FidoBleDevice(std::move(connection)),
+      encryption_data_(std::move(session_key), nonce),
+      weak_factory_(this) {}
+
+FidoCableDevice::~FidoCableDevice() = default;
+
+void FidoCableDevice::DeviceTransact(std::vector<uint8_t> command,
+                                     DeviceCallback callback) {
+  if (IsEncryptionEnabled()) {
+    if (!EncryptOutgoingMessage(encryption_data_, &command)) {
+      state_ = State::kDeviceError;
+      return;
+    }
+
+    ++encryption_data_.write_sequence_num;
+  }
+
+  AddToPendingFrames(FidoBleDeviceCommand::kMsg, std::move(command),
+                     std::move(callback));
+}
+
+void FidoCableDevice::OnResponseFrame(FrameCallback callback,
+                                      base::Optional<FidoBleFrame> frame) {
+  // The request is done, time to reset |transaction_|.
+  ResetTransaction();
+  state_ = frame ? State::kReady : State::kDeviceError;
+
+  if (frame && IsEncryptionEnabled()) {
+    if (!DecryptIncomingMessage(encryption_data_, &frame.value())) {
+      state_ = State::kDeviceError;
+      frame = base::nullopt;
+    }
+
+    ++encryption_data_.read_sequence_num;
+  }
+
+  auto self = GetWeakPtr();
+  std::move(callback).Run(std::move(frame));
+
+  // Executing callbacks may free |this|. Check |self| first.
+  if (self)
+    Transition();
+}
+
+base::WeakPtr<FidoDevice> FidoCableDevice::GetWeakPtr() {
+  return weak_factory_.GetWeakPtr();
+}
+
+}  // namespace device
diff --git a/device/fido/fido_cable_device.h b/device/fido/fido_cable_device.h
new file mode 100644
index 0000000..e8c76fe0c
--- /dev/null
+++ b/device/fido/fido_cable_device.h
@@ -0,0 +1,78 @@
+// 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 DEVICE_FIDO_FIDO_CABLE_DEVICE_H_
+#define DEVICE_FIDO_FIDO_CABLE_DEVICE_H_
+
+#include <array>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/component_export.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
+#include "crypto/aead.h"
+#include "device/fido/fido_ble_device.h"
+
+namespace device {
+
+class FidoBleFrame;
+class FidoBleConnection;
+
+class COMPONENT_EXPORT(DEVICE_FIDO) FidoCableDevice : public FidoBleDevice {
+ public:
+  // Encapsulates state FidoCableDevice maintains to encrypt and decrypt
+  // data within FidoBleFrame.
+  struct COMPONENT_EXPORT(DEVICE_FIDO) EncryptionData {
+    EncryptionData() = delete;
+    EncryptionData(std::string session_key,
+                   const std::array<uint8_t, 8>& nonce);
+    EncryptionData(EncryptionData&& data);
+    EncryptionData& operator=(EncryptionData&& other);
+    ~EncryptionData();
+
+    std::string encryption_key;
+    std::array<uint8_t, 8> nonce;
+    crypto::Aead aes_key{crypto::Aead::AES_256_GCM};
+    uint32_t write_sequence_num = 0;
+    uint32_t read_sequence_num = 0;
+
+    DISALLOW_COPY_AND_ASSIGN(EncryptionData);
+  };
+
+  using FrameCallback = FidoBleTransaction::FrameCallback;
+
+  FidoCableDevice(std::string address,
+                  std::string session_key,
+                  const std::array<uint8_t, 8>& nonce);
+  // Constructor used for testing purposes.
+  FidoCableDevice(std::unique_ptr<FidoBleConnection> connection,
+                  std::string session_key,
+                  const std::array<uint8_t, 8>& nonce);
+  ~FidoCableDevice() override;
+
+  // FidoBleDevice:
+  void DeviceTransact(std::vector<uint8_t> command,
+                      DeviceCallback callback) override;
+  void OnResponseFrame(FrameCallback callback,
+                       base::Optional<FidoBleFrame> frame) override;
+  base::WeakPtr<FidoDevice> GetWeakPtr() override;
+
+ private:
+  FRIEND_TEST_ALL_PREFIXES(FidoCableDeviceTest,
+                           TestCableDeviceSendMultipleRequests);
+  FRIEND_TEST_ALL_PREFIXES(FidoCableDeviceTest,
+                           TestCableDeviceErrorOnMaxCounter);
+
+  EncryptionData encryption_data_;
+  base::WeakPtrFactory<FidoCableDevice> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(FidoCableDevice);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_FIDO_FIDO_CABLE_DEVICE_H_
diff --git a/device/fido/fido_cable_device_unittest.cc b/device/fido/fido_cable_device_unittest.cc
new file mode 100644
index 0000000..75ad4ac
--- /dev/null
+++ b/device/fido/fido_cable_device_unittest.cc
@@ -0,0 +1,360 @@
+// 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 "device/fido/fido_cable_device.h"
+
+#include <array>
+#include <limits>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/command_line.h"
+#include "base/optional.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "crypto/aead.h"
+#include "device/bluetooth/test/bluetooth_test.h"
+#include "device/fido/fido_parsing_utils.h"
+#include "device/fido/mock_fido_ble_connection.h"
+#include "device/fido/test_callback_receiver.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace device {
+
+namespace {
+
+using ::testing::_;
+using ::testing::Invoke;
+using ::testing::Test;
+using TestDeviceCallbackReceiver =
+    test::ValueCallbackReceiver<base::Optional<std::vector<uint8_t>>>;
+
+// Sufficiently large test control point length as we are not interested
+// in testing fragmentations of BLE messages. All Cable messages are encrypted
+// and decrypted per request frame, not fragment.
+constexpr auto kControlPointLength = std::numeric_limits<uint16_t>::max();
+// Counter value that is larger than FidoCableDevice::kMaxCounter.
+constexpr uint32_t kInvalidCounter = 1 << 24;
+constexpr char kTestSessionKey[] = "00000000000000000000000000000000";
+constexpr std::array<uint8_t, 8> kTestEncryptionNonce = {
+    {1, 1, 1, 1, 1, 1, 1, 1}};
+constexpr uint8_t kTestData[] = {'T', 'E', 'S', 'T'};
+
+std::vector<uint8_t> ConstructSerializedOutgoingFragment(
+    base::span<const uint8_t> data) {
+  FidoBleFrame response_frame(FidoBleDeviceCommand::kMsg,
+                              fido_parsing_utils::Materialize(data));
+  const auto response_fragment =
+      std::get<0>(response_frame.ToFragments(kControlPointLength));
+
+  std::vector<uint8_t> outgoing_message;
+  response_fragment.Serialize(&outgoing_message);
+  return outgoing_message;
+}
+
+class FakeCableAuthenticator {
+ public:
+  // Returns encrypted message of the ciphertext received from the client.
+  std::vector<uint8_t> ReplyWithSameMessage(base::span<const uint8_t> message) {
+    auto decrypted_message = DecryptMessage(message);
+    auto message_to_send = EncryptMessage(std::move(decrypted_message));
+    return std::vector<uint8_t>(message_to_send.begin(), message_to_send.end());
+  }
+
+  void SetSessionKey(const std::string& session_key) {
+    session_key_ = session_key;
+  }
+
+  void SetAuthenticatorCounter(uint32_t authenticator_counter) {
+    authenticator_counter_ = authenticator_counter;
+  }
+
+ private:
+  std::string EncryptMessage(std::string message) {
+    crypto::Aead aead(crypto::Aead::AES_256_GCM);
+    DCHECK_EQ(session_key_.size(), aead.KeyLength());
+    aead.Init(&session_key_);
+
+    auto encryption_nonce = fido_parsing_utils::Materialize(nonce_);
+    encryption_nonce.push_back(0x01);
+    encryption_nonce.push_back(authenticator_counter_ >> 16 & 0xFF);
+    encryption_nonce.push_back(authenticator_counter_ >> 8 & 0xFF);
+    encryption_nonce.push_back(authenticator_counter_ & 0xFF);
+    DCHECK(encryption_nonce.size() == aead.NonceLength());
+
+    std::string ciphertext;
+    aead.Seal(message,
+              base::StringPiece(
+                  reinterpret_cast<const char*>(encryption_nonce.data()),
+                  encryption_nonce.size()),
+              nullptr /* additional_data */, &ciphertext);
+    authenticator_counter_++;
+    return ciphertext;
+  }
+
+  std::string DecryptMessage(base::span<const uint8_t> message) {
+    crypto::Aead aead(crypto::Aead::AES_256_GCM);
+    DCHECK_EQ(session_key_.size(), aead.KeyLength());
+    aead.Init(&session_key_);
+
+    auto encryption_nonce = fido_parsing_utils::Materialize(nonce_);
+    encryption_nonce.push_back(0x00);
+    encryption_nonce.push_back(expected_client_counter_ >> 16 & 0xFF);
+    encryption_nonce.push_back(expected_client_counter_ >> 8 & 0xFF);
+    encryption_nonce.push_back(expected_client_counter_ & 0xFF);
+    DCHECK(encryption_nonce.size() == aead.NonceLength());
+
+    std::string ciphertext;
+    aead.Open(base::StringPiece(reinterpret_cast<const char*>(message.data()),
+                                message.size()),
+              base::StringPiece(
+                  reinterpret_cast<const char*>(encryption_nonce.data()),
+                  encryption_nonce.size()),
+              nullptr /* additional_data */, &ciphertext);
+    expected_client_counter_++;
+    return ciphertext;
+  }
+
+  std::array<uint8_t, 8> nonce_ = kTestEncryptionNonce;
+  std::string session_key_ = kTestSessionKey;
+  uint32_t expected_client_counter_ = 0;
+  uint32_t authenticator_counter_ = 0;
+};
+
+}  // namespace
+
+class FidoCableDeviceTest : public Test {
+ public:
+  FidoCableDeviceTest() {
+    auto connection = std::make_unique<MockFidoBleConnection>(
+        BluetoothTestBase::kTestDeviceAddress1);
+    connection_ = connection.get();
+    device_ = std::make_unique<FidoCableDevice>(
+        std::move(connection), kTestSessionKey, kTestEncryptionNonce);
+
+    connection_->connection_status_callback() =
+        device_->GetConnectionStatusCallbackForTesting();
+    connection_->read_callback() = device_->GetReadCallbackForTesting();
+  }
+
+  void ConnectWithLength(uint16_t length) {
+    EXPECT_CALL(*connection(), Connect()).WillOnce(Invoke([this] {
+      connection()->connection_status_callback().Run(true);
+    }));
+
+    EXPECT_CALL(*connection(), ReadControlPointLengthPtr(_))
+        .WillOnce(Invoke([length](auto* cb) { std::move(*cb).Run(length); }));
+
+    device()->Connect();
+  }
+
+  void SetUpEncryptionSwitch() {
+    base::CommandLine::ForCurrentProcess()->AppendSwitch(
+        "enable-cable-encryption");
+  }
+
+  FidoCableDevice* device() { return device_.get(); }
+  MockFidoBleConnection* connection() { return connection_; }
+  FakeCableAuthenticator* authenticator() { return &authenticator_; }
+
+ protected:
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
+
+ private:
+  FakeCableAuthenticator authenticator_;
+  MockFidoBleConnection* connection_;
+  std::unique_ptr<FidoCableDevice> device_;
+};
+
+TEST_F(FidoCableDeviceTest, TestCaBleDeviceSendData) {
+  SetUpEncryptionSwitch();
+  ConnectWithLength(kControlPointLength);
+
+  EXPECT_CALL(*connection(), WriteControlPointPtr(_, _))
+      .WillOnce(Invoke([this](const auto& data, auto* cb) {
+        base::SequencedTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(std::move(*cb), true));
+
+        const auto authenticator_reply = authenticator()->ReplyWithSameMessage(
+            base::make_span(data).subspan(3));
+        base::SequencedTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(connection()->read_callback(),
+                                      ConstructSerializedOutgoingFragment(
+                                          authenticator_reply)));
+      }));
+
+  TestDeviceCallbackReceiver callback_receiver;
+  device()->DeviceTransact(fido_parsing_utils::Materialize(kTestData),
+                           callback_receiver.callback());
+
+  callback_receiver.WaitForCallback();
+  const auto& value = callback_receiver.value();
+  ASSERT_TRUE(value);
+  EXPECT_THAT(*value, ::testing::ElementsAreArray(kTestData));
+}
+
+// Test that FidoCableDevice properly updates counters when sending/receiving
+// multiple requests.
+TEST_F(FidoCableDeviceTest, TestCableDeviceSendMultipleRequests) {
+  SetUpEncryptionSwitch();
+  ConnectWithLength(kControlPointLength);
+  EXPECT_CALL(*connection(), WriteControlPointPtr(_, _))
+      .Times(2)
+      .WillRepeatedly(Invoke([this](const auto& data, auto* cb) {
+        base::SequencedTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(std::move(*cb), true));
+
+        const auto authenticator_reply = authenticator()->ReplyWithSameMessage(
+            base::make_span(data).subspan(3));
+        base::SequencedTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(connection()->read_callback(),
+                                      ConstructSerializedOutgoingFragment(
+                                          authenticator_reply)));
+      }));
+
+  EXPECT_EQ(0u, device()->encryption_data_.write_sequence_num);
+  EXPECT_EQ(0u, device()->encryption_data_.read_sequence_num);
+
+  TestDeviceCallbackReceiver callback_receiver1;
+  device()->DeviceTransact(fido_parsing_utils::Materialize(kTestData),
+                           callback_receiver1.callback());
+  callback_receiver1.WaitForCallback();
+  const auto& value1 = callback_receiver1.value();
+  ASSERT_TRUE(value1);
+  EXPECT_THAT(*value1, ::testing::ElementsAreArray(kTestData));
+  EXPECT_EQ(1u, device()->encryption_data_.write_sequence_num);
+  EXPECT_EQ(1u, device()->encryption_data_.read_sequence_num);
+
+  constexpr uint8_t kTestData2[] = {'T', 'E', 'S', 'T', '2'};
+  TestDeviceCallbackReceiver callback_receiver2;
+  device()->DeviceTransact(fido_parsing_utils::Materialize(kTestData2),
+                           callback_receiver2.callback());
+  callback_receiver2.WaitForCallback();
+  const auto& value2 = callback_receiver2.value();
+  ASSERT_TRUE(value2);
+  EXPECT_THAT(*value2, ::testing::ElementsAreArray(kTestData2));
+  EXPECT_EQ(2u, device()->encryption_data_.write_sequence_num);
+  EXPECT_EQ(2u, device()->encryption_data_.read_sequence_num);
+}
+
+TEST_F(FidoCableDeviceTest, TestCableDeviceFailOnIncorrectSessionKey) {
+  constexpr char kIncorrectSessionKey[] = "11111111111111111111111111111111";
+  SetUpEncryptionSwitch();
+  ConnectWithLength(kControlPointLength);
+
+  EXPECT_CALL(*connection(), WriteControlPointPtr(_, _))
+      .WillOnce(Invoke([this, &kIncorrectSessionKey](const auto& data,
+                                                     auto* cb) {
+        base::SequencedTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(std::move(*cb), true));
+
+        authenticator()->SetSessionKey(kIncorrectSessionKey);
+        const auto authenticator_reply = authenticator()->ReplyWithSameMessage(
+            base::make_span(data).subspan(3));
+
+        base::SequencedTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(connection()->read_callback(),
+                                      ConstructSerializedOutgoingFragment(
+                                          authenticator_reply)));
+      }));
+
+  TestDeviceCallbackReceiver callback_receiver;
+  device()->DeviceTransact(fido_parsing_utils::Materialize(kTestData),
+                           callback_receiver.callback());
+
+  callback_receiver.WaitForCallback();
+  const auto& value = callback_receiver.value();
+  EXPECT_FALSE(value);
+}
+
+TEST_F(FidoCableDeviceTest, TestCableDeviceFailOnUnexpectedCounter) {
+  constexpr uint32_t kIncorrectAuthenticatorCounter = 1;
+  SetUpEncryptionSwitch();
+  ConnectWithLength(kControlPointLength);
+
+  EXPECT_CALL(*connection(), WriteControlPointPtr(_, _))
+      .WillOnce(Invoke([this, kIncorrectAuthenticatorCounter](const auto& data,
+                                                              auto* cb) {
+        base::SequencedTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(std::move(*cb), true));
+
+        authenticator()->SetAuthenticatorCounter(
+            kIncorrectAuthenticatorCounter);
+        const auto authenticator_reply = authenticator()->ReplyWithSameMessage(
+            base::make_span(data).subspan(3));
+
+        base::SequencedTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(connection()->read_callback(),
+                                      ConstructSerializedOutgoingFragment(
+                                          authenticator_reply)));
+      }));
+
+  TestDeviceCallbackReceiver callback_receiver;
+  device()->DeviceTransact(fido_parsing_utils::Materialize(kTestData),
+                           callback_receiver.callback());
+
+  callback_receiver.WaitForCallback();
+  const auto& value = callback_receiver.value();
+  EXPECT_FALSE(value);
+}
+
+// Test the unlikely event that the authenticator and client has sent/received
+// requests more than FidoCableDevice::kMaxCounter amount of times. As we are
+// only using 3 bytes to encapsulate counter during encryption, any counter
+// value that is above FidoCableDevice::kMaxCounter -- even though it may be
+// the expected counter value -- should return an error.
+TEST_F(FidoCableDeviceTest, TestCableDeviceErrorOnMaxCounter) {
+  ConnectWithLength(kControlPointLength);
+  SetUpEncryptionSwitch();
+
+  EXPECT_CALL(*connection(), WriteControlPointPtr(_, _))
+      .WillOnce(Invoke([this](const auto& data, auto* cb) {
+        base::SequencedTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(std::move(*cb), true));
+
+        authenticator()->SetAuthenticatorCounter(kInvalidCounter);
+        const auto authenticator_reply = authenticator()->ReplyWithSameMessage(
+            base::make_span(data).subspan(3));
+
+        base::SequencedTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(connection()->read_callback(),
+                                      ConstructSerializedOutgoingFragment(
+                                          authenticator_reply)));
+      }));
+
+  TestDeviceCallbackReceiver callback_receiver;
+  device()->encryption_data_.read_sequence_num = kInvalidCounter;
+  device()->DeviceTransact(fido_parsing_utils::Materialize(kTestData),
+                           callback_receiver.callback());
+
+  callback_receiver.WaitForCallback();
+  const auto& value = callback_receiver.value();
+  EXPECT_FALSE(value);
+}
+
+TEST_F(FidoCableDeviceTest, TestEncryptionDisabledWithoutCommandLineSwitch) {
+  ConnectWithLength(kControlPointLength);
+
+  EXPECT_CALL(*connection(), WriteControlPointPtr(_, _))
+      .WillOnce(Invoke([this](const auto& data, auto* cb) {
+        base::SequencedTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(std::move(*cb), true));
+
+        base::SequencedTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(connection()->read_callback(), data));
+      }));
+
+  TestDeviceCallbackReceiver callback_receiver;
+  device()->DeviceTransact(fido_parsing_utils::Materialize(kTestData),
+                           callback_receiver.callback());
+
+  callback_receiver.WaitForCallback();
+  const auto& value = callback_receiver.value();
+  ASSERT_TRUE(value);
+  EXPECT_THAT(*value, ::testing::ElementsAreArray(kTestData));
+}
+
+}  // namespace device
diff --git a/device/fido/fido_cable_discovery.cc b/device/fido/fido_cable_discovery.cc
new file mode 100644
index 0000000..f38da0c
--- /dev/null
+++ b/device/fido/fido_cable_discovery.cc
@@ -0,0 +1,224 @@
+// 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 "device/fido/fido_cable_discovery.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "build/build_config.h"
+#include "device/bluetooth/bluetooth_advertisement.h"
+#include "device/bluetooth/bluetooth_discovery_session.h"
+#include "device/bluetooth/bluetooth_uuid.h"
+#include "device/fido/fido_ble_uuids.h"
+#include "device/fido/fido_cable_device.h"
+#include "device/fido/fido_parsing_utils.h"
+
+namespace device {
+
+namespace {
+
+const BluetoothUUID& CableAdvertisementUUID() {
+  static const BluetoothUUID service_uuid(kCableAdvertisementUUID);
+  return service_uuid;
+}
+
+bool IsCableDevice(const BluetoothDevice* device) {
+  return base::ContainsKey(device->GetServiceData(), CableAdvertisementUUID());
+}
+
+// Construct advertisement data with different formats depending on client's
+// operating system. Ideally, we advertise EIDs as part of Service Data, but
+// this isn't available on all platforms. On Windows we use Manufacturer Data
+// instead, and on Mac our only option is to advertise an additional service
+// with the EID as its UUID.
+std::unique_ptr<BluetoothAdvertisement::Data> ConstructAdvertisementData(
+    base::StringPiece advertisement_uuid,
+    base::span<const uint8_t, FidoCableDiscovery::kEphemeralIdSize>
+        client_eid) {
+  auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
+      BluetoothAdvertisement::AdvertisementType::ADVERTISEMENT_TYPE_BROADCAST);
+
+#if defined(OS_MACOSX)
+  auto list = std::make_unique<BluetoothAdvertisement::UUIDList>();
+  list->emplace_back(advertisement_uuid);
+  list->emplace_back(std::string(client_eid.cbegin(), client_eid.cend()));
+  advertisement_data->set_service_uuids(std::move(list));
+
+#elif defined(OS_WIN)
+  constexpr uint16_t kFidoManufacturerId = 0xFFFD;
+  constexpr std::array<uint8_t, 2> kFidoManufacturerDataHeader = {0x51, 0xFE};
+
+  auto manufacturer_data =
+      std::make_unique<BluetoothAdvertisement::ManufacturerData>();
+  std::vector<uint8_t> manufacturer_data_value;
+  fido_parsing_utils::Append(&manufacturer_data_value,
+                             kFidoManufacturerDataHeader);
+  fido_parsing_utils::Append(&manufacturer_data_value, client_eid);
+  manufacturer_data->emplace(kFidoManufacturerId,
+                             std::move(manufacturer_data_value));
+  advertisement_data->set_manufacturer_data(std::move(manufacturer_data));
+
+#elif defined(OS_LINUX) || defined(OS_CHROMEOS)
+  auto service_data = std::make_unique<BluetoothAdvertisement::ServiceData>();
+  service_data->emplace(advertisement_uuid,
+                        fido_parsing_utils::Materialize(client_eid));
+  advertisement_data->set_service_data(std::move(service_data));
+#endif
+
+  return advertisement_data;
+}
+
+}  // namespace
+
+// FidoCableDiscovery::CableDiscoveryData -------------------------------------
+
+FidoCableDiscovery::CableDiscoveryData::CableDiscoveryData(
+    const EidArray& client_eid,
+    const EidArray& authenticator_eid,
+    const SessionKeyArray& session_key)
+    : client_eid(client_eid),
+      authenticator_eid(authenticator_eid),
+      session_key(session_key) {}
+
+FidoCableDiscovery::CableDiscoveryData::CableDiscoveryData(
+    const CableDiscoveryData& data) = default;
+
+FidoCableDiscovery::CableDiscoveryData& FidoCableDiscovery::CableDiscoveryData::
+operator=(const CableDiscoveryData& other) = default;
+
+FidoCableDiscovery::CableDiscoveryData::~CableDiscoveryData() = default;
+
+// FidoCableDiscovery ---------------------------------------------------------
+
+FidoCableDiscovery::FidoCableDiscovery(
+    std::vector<CableDiscoveryData> discovery_data)
+    : discovery_data_(std::move(discovery_data)), weak_factory_(this) {}
+
+// Destruction of FidoCableDiscovery will unregister |advertisements_| on
+// best-effort basis.
+FidoCableDiscovery::~FidoCableDiscovery() = default;
+
+void FidoCableDiscovery::DeviceAdded(BluetoothAdapter* adapter,
+                                     BluetoothDevice* device) {
+  if (!IsCableDevice(device))
+    return;
+
+  DVLOG(2) << "Discovered Cable device: " << device->GetAddress();
+  CableDeviceFound(adapter, device);
+}
+
+void FidoCableDiscovery::DeviceChanged(BluetoothAdapter* adapter,
+                                       BluetoothDevice* device) {
+  if (!IsCableDevice(device))
+    return;
+
+  DVLOG(2) << "Device changed for Cable device: " << device->GetAddress();
+  CableDeviceFound(adapter, device);
+}
+
+void FidoCableDiscovery::DeviceRemoved(BluetoothAdapter* adapter,
+                                       BluetoothDevice* device) {
+  if (IsCableDevice(device) && GetFoundCableDiscoveryData(device)) {
+    const auto& device_address = device->GetAddress();
+    VLOG(2) << "Cable device removed: " << device_address;
+    RemoveDevice(FidoBleDevice::GetId(device_address));
+  }
+}
+
+void FidoCableDiscovery::OnSetPowered() {
+  DCHECK(adapter());
+
+  adapter()->StartDiscoverySessionWithFilter(
+      std::make_unique<BluetoothDiscoveryFilter>(
+          BluetoothTransport::BLUETOOTH_TRANSPORT_LE),
+      base::AdaptCallbackForRepeating(
+          base::BindOnce(&FidoCableDiscovery::OnStartDiscoverySessionWithFilter,
+                         weak_factory_.GetWeakPtr())),
+      base::AdaptCallbackForRepeating(
+          base::BindOnce(&FidoCableDiscovery::OnStartDiscoverySessionError,
+                         weak_factory_.GetWeakPtr())));
+
+  for (const auto& data : discovery_data_) {
+    base::SequencedTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(&FidoCableDiscovery::StartAdvertisement,
+                                  weak_factory_.GetWeakPtr(), data.client_eid));
+  }
+}
+
+void FidoCableDiscovery::StartAdvertisement(const EidArray& client_eid) {
+  DCHECK(adapter());
+
+  adapter()->RegisterAdvertisement(
+      ConstructAdvertisementData(kCableAdvertisementUUID, client_eid),
+      base::AdaptCallbackForRepeating(
+          base::BindOnce(&FidoCableDiscovery::OnAdvertisementRegistered,
+                         weak_factory_.GetWeakPtr(), client_eid)),
+      base::AdaptCallbackForRepeating(
+          base::BindOnce(&FidoCableDiscovery::OnAdvertisementRegisterError,
+                         weak_factory_.GetWeakPtr())));
+}
+
+void FidoCableDiscovery::OnAdvertisementRegistered(
+    const EidArray& client_eid,
+    scoped_refptr<BluetoothAdvertisement> advertisement) {
+  DVLOG(2) << "Advertisement registered.";
+  advertisements_.emplace(client_eid, std::move(advertisement));
+}
+
+void FidoCableDiscovery::OnAdvertisementRegisterError(
+    BluetoothAdvertisement::ErrorCode error_code) {
+  DLOG(ERROR) << "Failed to register advertisement: " << error_code;
+  NotifyDiscoveryStarted(false);
+}
+
+void FidoCableDiscovery::CableDeviceFound(BluetoothAdapter* adapter,
+                                          BluetoothDevice* device) {
+  const auto* found_cable_device_data = GetFoundCableDiscoveryData(device);
+  if (!found_cable_device_data)
+    return;
+
+  DVLOG(2) << "Found new Cable device.";
+  // Nonce is embedded as first 8 bytes of client EID.
+  std::array<uint8_t, 8> nonce;
+  bool extract_success = fido_parsing_utils::ExtractArray(
+      found_cable_device_data->client_eid, 0, &nonce);
+  if (!extract_success)
+    return;
+
+  AddDevice(std::make_unique<FidoCableDevice>(
+      device->GetAddress(),
+      std::string(found_cable_device_data->session_key.begin(),
+                  found_cable_device_data->session_key.end()),
+      nonce));
+}
+
+const FidoCableDiscovery::CableDiscoveryData*
+FidoCableDiscovery::GetFoundCableDiscoveryData(
+    const BluetoothDevice* device) const {
+  const auto* service_data =
+      device->GetServiceDataForUUID(CableAdvertisementUUID());
+  DCHECK(service_data);
+
+  EidArray received_authenticator_eid;
+  bool extract_success = fido_parsing_utils::ExtractArray(
+      *service_data, 8, &received_authenticator_eid);
+  if (!extract_success)
+    return nullptr;
+
+  auto discovery_data_iterator = std::find_if(
+      discovery_data_.begin(), discovery_data_.end(),
+      [&received_authenticator_eid](const auto& data) {
+        return received_authenticator_eid == data.authenticator_eid;
+      });
+
+  return discovery_data_iterator != discovery_data_.end()
+             ? &(*discovery_data_iterator)
+             : nullptr;
+}
+
+}  // namespace device
diff --git a/device/fido/fido_cable_discovery.h b/device/fido/fido_cable_discovery.h
new file mode 100644
index 0000000..06768b4
--- /dev/null
+++ b/device/fido/fido_cable_discovery.h
@@ -0,0 +1,86 @@
+// 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 DEVICE_FIDO_FIDO_CABLE_DISCOVERY_H_
+#define DEVICE_FIDO_FIDO_CABLE_DISCOVERY_H_
+
+#include <stdint.h>
+
+#include <array>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/component_export.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "device/fido/fido_ble_discovery_base.h"
+
+namespace device {
+
+class BluetoothDevice;
+class BluetoothAdvertisement;
+
+class COMPONENT_EXPORT(DEVICE_FIDO) FidoCableDiscovery
+    : public FidoBleDiscoveryBase {
+ public:
+  static constexpr size_t kEphemeralIdSize = 16;
+  static constexpr size_t kSessionKeySize = 32;
+  using EidArray = std::array<uint8_t, kEphemeralIdSize>;
+  using SessionKeyArray = std::array<uint8_t, kSessionKeySize>;
+
+  // Encapsulates information required to discover Cable device per single
+  // credential. When multiple credentials are enrolled to a single account
+  // (i.e. more than one phone has been enrolled to an user account as a
+  // security key), then FidoCableDiscovery must advertise for all of the client
+  // EID received from the relying party.
+  struct COMPONENT_EXPORT(DEVICE_FIDO) CableDiscoveryData {
+    CableDiscoveryData(const EidArray& client_eid,
+                       const EidArray& authenticator_eid,
+                       const SessionKeyArray& session_key);
+    CableDiscoveryData(const CableDiscoveryData& data);
+    CableDiscoveryData& operator=(const CableDiscoveryData& other);
+    ~CableDiscoveryData();
+
+    EidArray client_eid;
+    EidArray authenticator_eid;
+    SessionKeyArray session_key;
+  };
+
+  FidoCableDiscovery(std::vector<CableDiscoveryData> discovery_data);
+  ~FidoCableDiscovery() override;
+
+ private:
+  // BluetoothAdapter::Observer:
+  void DeviceAdded(BluetoothAdapter* adapter, BluetoothDevice* device) override;
+  void DeviceChanged(BluetoothAdapter* adapter,
+                     BluetoothDevice* device) override;
+  void DeviceRemoved(BluetoothAdapter* adapter,
+                     BluetoothDevice* device) override;
+
+  // FidoBleDiscoveryBase:
+  void OnSetPowered() override;
+
+  void StartAdvertisement(const EidArray& client_eid);
+  void OnAdvertisementRegistered(
+      const EidArray& client_eid,
+      scoped_refptr<BluetoothAdvertisement> advertisement);
+  void OnAdvertisementRegisterError(
+      BluetoothAdvertisement::ErrorCode error_code);
+  void CableDeviceFound(BluetoothAdapter* adapter, BluetoothDevice* device);
+  const CableDiscoveryData* GetFoundCableDiscoveryData(
+      const BluetoothDevice* device) const;
+
+  std::vector<CableDiscoveryData> discovery_data_;
+  std::map<EidArray, scoped_refptr<BluetoothAdvertisement>> advertisements_;
+  base::WeakPtrFactory<FidoCableDiscovery> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(FidoCableDiscovery);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_FIDO_FIDO_CABLE_DISCOVERY_H_
diff --git a/device/fido/fido_cable_discovery_unittest.cc b/device/fido/fido_cable_discovery_unittest.cc
new file mode 100644
index 0000000..6029b2d
--- /dev/null
+++ b/device/fido/fido_cable_discovery_unittest.cc
@@ -0,0 +1,216 @@
+// 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 "device/fido/fido_cable_discovery.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/stl_util.h"
+#include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "device/bluetooth/test/bluetooth_test.h"
+#include "device/bluetooth/test/mock_bluetooth_adapter.h"
+#include "device/bluetooth/test/mock_bluetooth_advertisement.h"
+#include "device/fido/fido_ble_device.h"
+#include "device/fido/fido_ble_uuids.h"
+#include "device/fido/fido_parsing_utils.h"
+#include "device/fido/mock_fido_discovery_observer.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::NiceMock;
+
+namespace device {
+
+namespace {
+
+// Constants required for discovering and constructing a Cable device that
+// are given by the relying party via an extension.
+constexpr FidoCableDiscovery::EidArray kClientEid = {
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00}};
+
+constexpr FidoCableDiscovery::EidArray kAuthenticatorEid = {
+    {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+     0x01, 0x01, 0x01, 0x01}};
+
+constexpr FidoCableDiscovery::EidArray kInvalidAuthenticatorEid = {
+    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00}};
+
+constexpr FidoCableDiscovery::SessionKeyArray kTestSessionKey = {
+    {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
+
+// Below constants are used to construct MockBluetoothDevice for testing.
+constexpr char kTestBleDeviceAddress[] = "11:12:13:14:15:16";
+
+constexpr char kTestBleDeviceName[] = "test_cable_device";
+
+std::unique_ptr<MockBluetoothDevice> CreateTestBluetoothDevice() {
+  return std::make_unique<testing::NiceMock<MockBluetoothDevice>>(
+      nullptr /* adapter */, 0 /* bluetooth_class */, kTestBleDeviceName,
+      kTestBleDeviceAddress, true /* paired */, true /* connected */);
+}
+
+// Mock BLE adapter that abstracts out authenticator logic with the following
+// logic:
+//  - Responds to BluetoothAdapter::RegisterAdvertisement() by always invoking
+//    success callback.
+//  - Responds to BluetoothAdapter::StartDiscoverySessionWithFilter() by
+//    invoking BluetoothAdapter::Observer::DeviceAdded() on a test bluetooth
+//    device that includes service data containing authenticator EID.
+class CableMockAdapter : public MockBluetoothAdapter {
+ public:
+  MOCK_METHOD3(RegisterAdvertisement,
+               void(std::unique_ptr<BluetoothAdvertisement::Data>,
+                    const CreateAdvertisementCallback&,
+                    const AdvertisementErrorCallback&));
+
+  void AddNewTestBluetoothDevice(
+      base::span<const uint8_t, FidoCableDiscovery::kEphemeralIdSize>
+          authenticator_eid) {
+    auto mock_device = CreateTestBluetoothDevice();
+
+    std::vector<uint8_t> service_data(8);
+    fido_parsing_utils::Append(&service_data, authenticator_eid);
+    BluetoothDevice::ServiceDataMap service_data_map;
+    service_data_map.emplace(kCableAdvertisementUUID, std::move(service_data));
+
+    mock_device->UpdateAdvertisementData(
+        1 /* rssi */, BluetoothDevice::UUIDList(), std::move(service_data_map),
+        BluetoothDevice::ManufacturerDataMap(), nullptr /* tx_power*/);
+
+    auto* mock_device_ptr = mock_device.get();
+    AddMockDevice(std::move(mock_device));
+
+    for (auto& observer : GetObservers())
+      observer.DeviceAdded(this, mock_device_ptr);
+  }
+
+  void ExpectRegisterAdvertisementWithSuccessResponse(size_t num_called) {
+    EXPECT_CALL(*this, RegisterAdvertisement(_, _, _))
+        .Times(num_called)
+        .WillRepeatedly(::testing::WithArg<1>([](const auto& callback) {
+          callback.Run(base::MakeRefCounted<MockBluetoothAdvertisement>());
+        }));
+  }
+
+  void ExpectSuccessCallbackToSetPowered() {
+    EXPECT_CALL(*this, SetPowered(true, _, _))
+        .WillOnce(::testing::WithArg<1>(
+            [](const auto& callback) { callback.Run(); }));
+  }
+
+ protected:
+  ~CableMockAdapter() override = default;
+};
+
+}  // namespace
+
+class FidoCableDiscoveryTest : public ::testing::Test {
+ public:
+  std::unique_ptr<FidoCableDiscovery> CreateDiscovery() {
+    std::vector<FidoCableDiscovery::CableDiscoveryData> discovery_data;
+    discovery_data.emplace_back(kClientEid, kAuthenticatorEid, kTestSessionKey);
+    return std::make_unique<FidoCableDiscovery>(std::move(discovery_data));
+  }
+
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
+};
+
+// Tests regular successful discovery flow for Cable device.
+TEST_F(FidoCableDiscoveryTest, TestDiscoveryFindsNewDevice) {
+  auto cable_discovery = CreateDiscovery();
+  NiceMock<MockFidoDiscoveryObserver> mock_observer;
+  EXPECT_CALL(mock_observer, DeviceAdded(_, _));
+  cable_discovery->set_observer(&mock_observer);
+
+  auto mock_adapter =
+      base::MakeRefCounted<::testing::NiceMock<CableMockAdapter>>();
+  mock_adapter->ExpectSuccessCallbackToSetPowered();
+
+  EXPECT_CALL(*mock_adapter, StartDiscoverySessionWithFilterRaw(_, _, _))
+      .WillOnce(::testing::WithArg<1>([&mock_adapter](const auto& callback) {
+        mock_adapter->AddNewTestBluetoothDevice(kAuthenticatorEid);
+        callback.Run(nullptr);
+      }));
+  mock_adapter->ExpectRegisterAdvertisementWithSuccessResponse(1);
+
+  BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter);
+  cable_discovery->Start();
+  scoped_task_environment_.RunUntilIdle();
+}
+
+// Tests a scenario where upon broadcasting advertisement and scanning, client
+// discovers a device with an incorrect authenticator EID. Observer::AddDevice()
+// must not be called.
+TEST_F(FidoCableDiscoveryTest, TestDiscoveryFindsIncorrectDevice) {
+  auto mock_adapter =
+      base::MakeRefCounted<::testing::NiceMock<CableMockAdapter>>();
+  auto cable_discovery = CreateDiscovery();
+  NiceMock<MockFidoDiscoveryObserver> mock_observer;
+
+  EXPECT_CALL(mock_observer, DeviceAdded(_, _)).Times(0);
+  cable_discovery->set_observer(&mock_observer);
+  mock_adapter->ExpectSuccessCallbackToSetPowered();
+
+  EXPECT_CALL(*mock_adapter, StartDiscoverySessionWithFilterRaw(_, _, _))
+      .WillOnce(::testing::WithArg<1>([&mock_adapter](const auto& callback) {
+        mock_adapter->AddNewTestBluetoothDevice(kInvalidAuthenticatorEid);
+        callback.Run(nullptr);
+      }));
+  mock_adapter->ExpectRegisterAdvertisementWithSuccessResponse(1);
+
+  BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter);
+  cable_discovery->Start();
+  scoped_task_environment_.RunUntilIdle();
+}
+
+// Tests Cable discovery flow when multiple(2) sets of client/authenticator EIDs
+// are passed on from the relying party. We should expect 2 invocations of
+// BluetoothAdapter::RegisterAdvertisement().
+TEST_F(FidoCableDiscoveryTest, TestDiscoveryWithMultipleEids) {
+  constexpr FidoCableDiscovery::EidArray kSecondaryClientEid = {
+      {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff}};
+
+  constexpr FidoCableDiscovery::EidArray kSecondaryAuthenticatorEid = {
+      {0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
+       0xee, 0xee, 0xee, 0xee}};
+
+  constexpr FidoCableDiscovery::SessionKeyArray kSecondarySessionKey = {
+      {0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
+       0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd}};
+
+  std::vector<FidoCableDiscovery::CableDiscoveryData> discovery_data;
+  discovery_data.emplace_back(kClientEid, kAuthenticatorEid, kTestSessionKey);
+  discovery_data.emplace_back(kSecondaryClientEid, kSecondaryAuthenticatorEid,
+                              kSecondarySessionKey);
+  auto cable_discovery =
+      std::make_unique<FidoCableDiscovery>(std::move(discovery_data));
+
+  NiceMock<MockFidoDiscoveryObserver> mock_observer;
+  EXPECT_CALL(mock_observer, DeviceAdded(_, _));
+  cable_discovery->set_observer(&mock_observer);
+
+  auto mock_adapter =
+      base::MakeRefCounted<::testing::NiceMock<CableMockAdapter>>();
+  mock_adapter->ExpectSuccessCallbackToSetPowered();
+  mock_adapter->ExpectRegisterAdvertisementWithSuccessResponse(2);
+  EXPECT_CALL(*mock_adapter, StartDiscoverySessionWithFilterRaw(_, _, _))
+      .WillOnce(::testing::WithArg<1>([&mock_adapter](const auto& callback) {
+        mock_adapter->AddNewTestBluetoothDevice(kAuthenticatorEid);
+        callback.Run(nullptr);
+      }));
+
+  BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter);
+  cable_discovery->Start();
+  scoped_task_environment_.RunUntilIdle();
+}
+
+}  // namespace device
diff --git a/device/fido/fido_discovery.cc b/device/fido/fido_discovery.cc
index 8e941b65..b245490b 100644
--- a/device/fido/fido_discovery.cc
+++ b/device/fido/fido_discovery.cc
@@ -64,9 +64,10 @@
 void FidoDiscovery::Start() {
   DCHECK_EQ(state_, State::kIdle);
   state_ = State::kStarting;
+  // TODO(hongjunchoi): Fix so that NotifiyStarted() is never called
+  // synchronously after StartInternal().
+  // See: https://crbug.com/823686
   StartInternal();
-  // StartInternal should never synchronously call NotifyStarted().
-  DCHECK_EQ(state_, State::kStarting);
 }
 
 void FidoDiscovery::NotifyDiscoveryStarted(bool success) {
diff --git a/docs/accessibility/tests.md b/docs/accessibility/tests.md
index f618a72..25f10f80 100644
--- a/docs/accessibility/tests.md
+++ b/docs/accessibility/tests.md
@@ -39,7 +39,7 @@
 To run just one test by itself without the script:
 ```
 ninja -C out/release blink_tests
-out/release/content_shell --run-layout-test third_party/WebKit/LayoutTests/accessibility/name-calc-inputs.html
+out/release/content_shell --run-web-tests third_party/WebKit/LayoutTests/accessibility/name-calc-inputs.html
 ```
 
 ## DumpAccessibilityTree tests
diff --git a/docs/cipd.md b/docs/cipd.md
index 17eb176f..a82fe7c4 100644
--- a/docs/cipd.md
+++ b/docs/cipd.md
@@ -133,6 +133,7 @@
 ```
 # Assuming that the third-party dependency in question is at version 1.2.3
 # and this is the first chromium revision of that version.
+$ cipd auth-login  # One-time auth.
 $ cipd create --pkg-def cipd.yaml -tag version:1.2.3-cr0
 ```
 
@@ -197,6 +198,12 @@
 By default, [cria/project-chromium-cipd-owners][4] own all CIPD packages
 under `chromium/`. If you're adding a package, talk to one of them.
 
+To obtain write access to a new package, ask an owner to run:
+
+```
+$ cipd acl-edit chromium/third_party/sample_cipd_dep -owner user:email@address.com
+```
+
 ## Troubleshooting
 
  - **A file maintained by CIPD is missing, and gclient sync doesn't recreate it.**
diff --git a/docs/testing/layout_tests.md b/docs/testing/layout_tests.md
index 6d46f348..5b434a1 100644
--- a/docs/testing/layout_tests.md
+++ b/docs/testing/layout_tests.md
@@ -112,13 +112,13 @@
 content_shell executable to run specific tests by using (for Windows):
 
 ```bash
-out/Default/content_shell.exe --run-layout-test --no-sandbox full_test_source_path
+out/Default/content_shell.exe --run-web-tests --no-sandbox full_test_source_path
 ```
 
 as in:
 
 ```bash
-out/Default/content_shell.exe --run-layout-test --no-sandbox \
+out/Default/content_shell.exe --run-web-tests --no-sandbox \
     c:/chrome/src/third_party/WebKit/LayoutTests/fast/forms/001.html
 ```
 
@@ -341,7 +341,7 @@
       If you have no other information, set a breakpoint on page load.
 * If your test only works in full layout-test mode, or if you find it simpler to
   debug without all the overhead of an interactive session, start the
-  content_shell with the command-line flag `--run-layout-test`, followed by the
+  content_shell with the command-line flag `--run-web-tests`, followed by the
   URL (`file:` or `http:`) to your test. More information about running layout tests
   in content_shell can be found [here](./layout_tests_in_content_shell.md).
     * In VS, you can do this in the Debugging section of the content_shell
@@ -418,7 +418,7 @@
       --time-out-ms=6000000`
     * Option B) If you need to debug an http/tests/inspector test, start httpd
       as described above. Then, run content_shell:
-      `out/Default/content_shell --debug-devtools --remote-debugging-port=9222 --run-layout-test
+      `out/Default/content_shell --debug-devtools --remote-debugging-port=9222 --run-web-tests
       http://127.0.0.1:8000/path/to/test.html`
 * Open `http://localhost:9222` in a stable/beta/canary Chrome, click the single
   link to open the devtools with the test loaded.
diff --git a/docs/testing/layout_tests_in_content_shell.md b/docs/testing/layout_tests_in_content_shell.md
index 25ac0a7..8a94292 100644
--- a/docs/testing/layout_tests_in_content_shell.md
+++ b/docs/testing/layout_tests_in_content_shell.md
@@ -3,10 +3,10 @@
 ## Basic usage
 
 Layout tests can be run with `content_shell`. To just dump the render tree, use
-the `--run-layout-test` flag:
+the `--run-web-tests` flag:
 
 ```bash
-out/Default/content_shell --run-layout-test foo.html
+out/Default/content_shell --run-web-tests foo.html
 ```
 
 ### Compiling
diff --git a/extensions/common/permissions/permissions_data.cc b/extensions/common/permissions/permissions_data.cc
index 313ee3f..995ca60 100644
--- a/extensions/common/permissions/permissions_data.cc
+++ b/extensions/common/permissions/permissions_data.cc
@@ -58,7 +58,9 @@
 }  // namespace
 
 PermissionsData::PermissionsData(const Extension* extension)
-    : extension_id_(extension->id()), manifest_type_(extension->GetType()) {
+    : extension_id_(extension->id()),
+      manifest_type_(extension->GetType()),
+      location_(extension->location()) {
   const PermissionSet& required_permissions =
       PermissionsParser::GetRequiredPermissions(extension);
   active_permissions_unsafe_.reset(new PermissionSet(
@@ -96,14 +98,10 @@
   return extension_id == extension_misc::kProdHangoutsExtensionId;
 }
 
-// static
 bool PermissionsData::IsRestrictedUrl(const GURL& document_url,
-                                      const Extension* extension,
-                                      std::string* error) {
-  if (extension &&
-      CanExecuteScriptEverywhere(extension->id(), extension->location())) {
+                                      std::string* error) const {
+  if (CanExecuteScriptEverywhere(extension_id_, location_))
     return false;
-  }
 
   if (g_policy_delegate &&
       g_policy_delegate->IsRestrictedUrl(document_url, error)) {
@@ -114,8 +112,7 @@
   if (!URLPattern::IsValidSchemeForExtensions(document_url.scheme()) &&
       document_url.spec() != url::kAboutBlankURL) {
     if (error) {
-      if (extension->permissions_data()->active_permissions().HasAPIPermission(
-              APIPermission::kTab)) {
+      if (active_permissions().HasAPIPermission(APIPermission::kTab)) {
         *error = ErrorUtils::FormatErrorMessage(
             manifest_errors::kCannotAccessPageWithUrl, document_url.spec());
       } else {
@@ -137,8 +134,8 @@
     return true;
   }
 
-  if (extension && document_url.SchemeIs(kExtensionScheme) &&
-      document_url.host() != extension->id() && !allow_on_chrome_urls) {
+  if (document_url.SchemeIs(kExtensionScheme) &&
+      document_url.host() != extension_id_ && !allow_on_chrome_urls) {
     if (error)
       *error = manifest_errors::kCannotAccessExtensionUrl;
     return true;
@@ -462,7 +459,7 @@
     return PageAccess::kDenied;
   }
 
-  if (IsRestrictedUrl(document_url, extension, error))
+  if (IsRestrictedUrl(document_url, error))
     return PageAccess::kDenied;
 
   if (tab_url_patterns && tab_url_patterns->MatchesURL(document_url))
diff --git a/extensions/common/permissions/permissions_data.h b/extensions/common/permissions/permissions_data.h
index b8b7aaf7..5be5fd25 100644
--- a/extensions/common/permissions/permissions_data.h
+++ b/extensions/common/permissions/permissions_data.h
@@ -84,9 +84,7 @@
   // Returns true if the given |url| is restricted for the given |extension|,
   // as is commonly the case for chrome:// urls.
   // NOTE: You probably want to use CanAccessPage().
-  static bool IsRestrictedUrl(const GURL& document_url,
-                              const Extension* extension,
-                              std::string* error);
+  bool IsRestrictedUrl(const GURL& document_url, std::string* error) const;
 
   // Is this extension using the default scope for policy_blocked_hosts and
   // policy_allowed_hosts of the ExtensionSettings policy.
@@ -319,6 +317,9 @@
   // The associated extension's manifest type.
   Manifest::Type manifest_type_;
 
+  // The associated extension's location.
+  Manifest::Location location_;
+
   mutable base::Lock runtime_lock_;
 
   // The permission's which are currently active on the extension during
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 645bf69..33b9535d 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -3833,6 +3833,8 @@
 }
 
 - (CGFloat)overscrollHeaderHeight {
+  if (base::FeatureList::IsEnabled(kBrowserContainerFullscreen))
+    return self.headerHeight;
   return self.headerHeight + StatusBarHeight();
 }
 
diff --git a/ios/chrome/browser/ui/overscroll_actions/BUILD.gn b/ios/chrome/browser/ui/overscroll_actions/BUILD.gn
index 16fefba..c536959 100644
--- a/ios/chrome/browser/ui/overscroll_actions/BUILD.gn
+++ b/ios/chrome/browser/ui/overscroll_actions/BUILD.gn
@@ -24,6 +24,7 @@
     "//ios/chrome/app/strings:ios_strings_grit",
     "//ios/chrome/app/theme",
     "//ios/chrome/browser/ui",
+    "//ios/chrome/browser/ui:feature_flags",
     "//ios/chrome/browser/ui:notifications",
     "//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant",
     "//ios/chrome/browser/ui/fullscreen",
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm
index 28458dc..c40e982 100644
--- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm
+++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm
@@ -23,6 +23,7 @@
 #include "ios/chrome/browser/ui/rtl_geometry.h"
 #import "ios/chrome/browser/ui/toolbar/legacy/toolbar_controller_constants.h"
 #import "ios/chrome/browser/ui/tools_menu/public/tools_menu_constants.h"
+#include "ios/chrome/browser/ui/ui_feature_flags.h"
 #include "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/voice/voice_search_notification_names.h"
 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
@@ -368,7 +369,14 @@
   }
   CGFloat contentOffsetFromExpandedHeader =
       contentOffsetFromTheTop + self.initialHeaderInset;
-  if (contentOffsetFromExpandedHeader >= 0) {
+  CGFloat limit = 0;
+  CGFloat topMargin = 0;
+  if (!_webViewProxy &&
+      base::FeatureList::IsEnabled(kBrowserContainerFullscreen)) {
+    limit = -StatusBarHeight();
+    topMargin = StatusBarHeight();
+  }
+  if (contentOffsetFromExpandedHeader >= limit) {
     // Record initial content offset and dispatch delegate on state change.
     self.overscrollState = OverscrollState::NO_PULL_STARTED;
   } else {
@@ -382,7 +390,8 @@
       _initialHeaderHeight = [[self delegate] overscrollHeaderHeight];
       self.overscrollState = OverscrollState::STARTED_PULLING;
     }
-    [self updateWithVerticalOffset:-contentOffsetFromExpandedHeader];
+    [self updateWithVerticalOffset:-contentOffsetFromExpandedHeader
+                         topMargin:topMargin];
   }
 }
 
@@ -814,13 +823,16 @@
   }
 }
 
-- (void)updateWithVerticalOffset:(CGFloat)verticalOffset {
+- (void)updateWithVerticalOffset:(CGFloat)verticalOffset
+                       topMargin:(CGFloat)topMargin {
   self.overscrollActionView.backgroundView.alpha =
       1.0 -
-      Clamp(verticalOffset / (kHeaderMaxExpansionThreshold / 2.0), 0.0, 1.0);
+      Clamp((verticalOffset - topMargin) / (kHeaderMaxExpansionThreshold / 2.0),
+            0.0, 1.0);
   SetViewFrameHeight(self.overscrollActionView,
                      self.initialHeaderHeight + verticalOffset);
-  [self.overscrollActionView updateWithVerticalOffset:verticalOffset];
+  [self.overscrollActionView
+      updateWithVerticalOffset:verticalOffset - topMargin];
 }
 
 - (CGFloat)initialContentInset {
@@ -893,8 +905,9 @@
   if (_bounceState.yInset - _bounceState.headerInset < 0.5)
     _bounceState.yInset = _bounceState.headerInset;
   if (_performingScrollViewIndependentAnimation) {
-    [self updateWithVerticalOffset:_bounceState.yInset -
-                                   _bounceState.headerInset];
+    [self
+        updateWithVerticalOffset:_bounceState.yInset - _bounceState.headerInset
+                       topMargin:0];
   } else {
     const UIEdgeInsets insets = UIEdgeInsetsMake(_bounceState.yInset, 0, 0, 0);
     _forceStateUpdate = YES;
diff --git a/ios/chrome/browser/ui/tab_grid/grid/grid_layout.mm b/ios/chrome/browser/ui/tab_grid/grid/grid_layout.mm
index c889be4..4726666 100644
--- a/ios/chrome/browser/ui/tab_grid/grid/grid_layout.mm
+++ b/ios/chrome/browser/ui/tab_grid/grid/grid_layout.mm
@@ -77,6 +77,23 @@
 }
 
 - (UICollectionViewLayoutAttributes*)
+initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath*)itemIndexPath {
+  UICollectionViewLayoutAttributes* attributes =
+      [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
+  // TODO(crbug.com/820410) : Polish the animation, and put constants where they
+  // belong.
+  // Cells being inserted start faded out, scaled down, and drop downwards
+  // slightly.
+  attributes.alpha = 0.0;
+  CGAffineTransform transform =
+      CGAffineTransformScale(attributes.transform, /*sx=*/0.9, /*sy=*/0.9);
+  transform = CGAffineTransformTranslate(transform, /*tx=*/0,
+                                         /*ty=*/attributes.size.height * 0.1);
+  attributes.transform = transform;
+  return attributes;
+}
+
+- (UICollectionViewLayoutAttributes*)
 finalLayoutAttributesForDisappearingItemAtIndexPath:
     (NSIndexPath*)itemIndexPath {
   UICollectionViewLayoutAttributes* attributes =
diff --git a/ios/chrome/browser/ui/tab_grid/grid/grid_view_controller.mm b/ios/chrome/browser/ui/tab_grid/grid/grid_view_controller.mm
index 4275893..f9bfe11 100644
--- a/ios/chrome/browser/ui/tab_grid/grid/grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_grid/grid/grid_view_controller.mm
@@ -30,6 +30,9 @@
 @interface GridViewController ()<GridCellDelegate,
                                  UICollectionViewDataSource,
                                  UICollectionViewDelegate>
+// Bookkeeping based on |-viewDidAppear:| and |-viewDidDisappear:|.
+// If the view is not appeared, there is no need to update the collection view.
+@property(nonatomic, assign, getter=isViewAppeared) BOOL viewAppeared;
 // A collection view of items in a grid format.
 @property(nonatomic, weak) UICollectionView* collectionView;
 // The local model backing the collection view.
@@ -43,6 +46,8 @@
 // The gesture recognizer used for interactive item reordering.
 @property(nonatomic, strong)
     UILongPressGestureRecognizer* itemReorderRecognizer;
+// Animator to show or hide the empty state.
+@property(nonatomic, strong) UIViewPropertyAnimator* emptyStateAnimator;
 @end
 
 @implementation GridViewController
@@ -50,11 +55,14 @@
 @synthesize theme = _theme;
 @synthesize delegate = _delegate;
 @synthesize imageDataSource = _imageDataSource;
+@synthesize emptyStateView = _emptyStateView;
 // Private properties.
+@synthesize viewAppeared = _viewAppeared;
 @synthesize collectionView = _collectionView;
 @synthesize items = _items;
 @synthesize selectedItemID = _selectedItemID;
 @synthesize itemReorderRecognizer = _itemReorderRecognizer;
+@synthesize emptyStateAnimator = _emptyStateAnimator;
 
 - (instancetype)init {
   if (self = [super init]) {
@@ -72,7 +80,9 @@
       forCellWithReuseIdentifier:kCellIdentifier];
   collectionView.dataSource = self;
   collectionView.delegate = self;
-  collectionView.backgroundColor = UIColorFromRGB(kGridBackgroundColor);
+  collectionView.backgroundView = [[UIView alloc] init];
+  collectionView.backgroundView.backgroundColor =
+      UIColorFromRGB(kGridBackgroundColor);
   if (@available(iOS 11, *))
     collectionView.contentInsetAdjustmentBehavior =
         UIScrollViewContentInsetAdjustmentAlways;
@@ -93,7 +103,6 @@
 - (void)viewWillAppear:(BOOL)animated {
   [super viewWillAppear:animated];
   [self.collectionView reloadData];
-  self.emptyStateView.hidden = (self.items.count > 0);
   // Selection is invalid if there are no items.
   if (self.items.count == 0)
     return;
@@ -104,6 +113,16 @@
   [self.delegate gridViewController:self didChangeItemCount:self.items.count];
 }
 
+- (void)viewDidAppear:(BOOL)animated {
+  [super viewDidAppear:animated];
+  self.viewAppeared = YES;
+}
+
+- (void)viewDidDisappear:(BOOL)animated {
+  [super viewDidDisappear:animated];
+  self.viewAppeared = NO;
+}
+
 #pragma mark - Public
 
 - (UIScrollView*)gridView {
@@ -111,14 +130,17 @@
 }
 
 - (void)setEmptyStateView:(UIView*)emptyStateView {
-  self.collectionView.backgroundView = emptyStateView;
-  // The emptyStateView is hidden when there are items, and shown when the
-  // collectionView is empty.
-  self.collectionView.backgroundView.hidden = (self.items.count > 0);
-}
-
-- (UIView*)emptyStateView {
-  return self.collectionView.backgroundView;
+  if (_emptyStateView)
+    [_emptyStateView removeFromSuperview];
+  _emptyStateView = emptyStateView;
+  emptyStateView.translatesAutoresizingMaskIntoConstraints = NO;
+  [self.collectionView.backgroundView addSubview:emptyStateView];
+  [NSLayoutConstraint activateConstraints:@[
+    [self.collectionView.backgroundView.centerXAnchor
+        constraintEqualToAnchor:emptyStateView.centerXAnchor],
+    [self.collectionView.backgroundView.centerYAnchor
+        constraintEqualToAnchor:emptyStateView.centerYAnchor]
+  ]];
 }
 
 - (BOOL)isGridEmpty {
@@ -238,7 +260,7 @@
 
   self.items = [items mutableCopy];
   self.selectedItemID = selectedItemID;
-  if ([self isViewVisible]) {
+  if ([self isViewAppeared]) {
     [self.collectionView reloadData];
     [self.collectionView
         selectItemAtIndexPath:CreateIndexPath(self.selectedIndex)
@@ -259,14 +281,14 @@
     [self.items insertObject:item atIndex:index];
     self.selectedItemID = selectedItemID;
   };
-  if (![self isViewVisible]) {
+  if (![self isViewAppeared]) {
     performDataSourceUpdates();
     [self.delegate gridViewController:self didChangeItemCount:self.items.count];
     return;
   }
   auto performAllUpdates = ^{
     performDataSourceUpdates();
-    self.emptyStateView.hidden = YES;
+    [self animateEmptyStateOut];
     [self.collectionView insertItemsAtIndexPaths:@[ CreateIndexPath(index) ]];
   };
   auto completion = ^(BOOL finished) {
@@ -287,7 +309,7 @@
     [self.items removeObjectAtIndex:index];
     self.selectedItemID = selectedItemID;
   };
-  if (![self isViewVisible]) {
+  if (![self isViewAppeared]) {
     performDataSourceUpdates();
     [self.delegate gridViewController:self didChangeItemCount:self.items.count];
     return;
@@ -296,7 +318,7 @@
     performDataSourceUpdates();
     [self.collectionView deleteItemsAtIndexPaths:@[ CreateIndexPath(index) ]];
     if (self.items.count == 0) {
-      [self animateEmptyStateIntoView];
+      [self animateEmptyStateIn];
     }
   };
   auto completion = ^(BOOL finished) {
@@ -314,7 +336,7 @@
 
 - (void)selectItemWithID:(NSString*)selectedItemID {
   self.selectedItemID = selectedItemID;
-  if (![self isViewVisible])
+  if (![self isViewAppeared])
     return;
   [self.collectionView
       selectItemAtIndexPath:CreateIndexPath(self.selectedIndex)
@@ -328,11 +350,10 @@
          [self indexOfItemWithID:item.identifier] == NSNotFound);
   NSUInteger index = [self indexOfItemWithID:itemID];
   self.items[index] = item;
-  if (![self isViewVisible])
+  if (![self isViewAppeared])
     return;
   GridCell* cell = base::mac::ObjCCastStrict<GridCell>(
       [self.collectionView cellForItemAtIndexPath:CreateIndexPath(index)]);
-  // TODO(crbug.com/839892) : Cell is sometimes nil, but should not be.
   [self configureCell:cell withItem:item];
 }
 
@@ -349,7 +370,7 @@
   };
   // If the view isn't visible, there's no need for the collection view to
   // update.
-  if (![self isViewVisible]) {
+  if (![self isViewAppeared]) {
     performDataSourceUpdates();
     return;
   }
@@ -385,17 +406,12 @@
   return [self.items indexOfObjectPassingTest:selectedTest];
 }
 
-// If the view is not visible, there is no need to update the collection view.
-- (BOOL)isViewVisible {
-  return self.viewIfLoaded.window != nil;
-}
-
 // Configures |cell|'s title synchronously, and favicon and snapshot
 // asynchronously with information from |item|. Updates the |cell|'s theme to
 // this view controller's theme. This view controller becomes the delegate for
 // the cell.
 - (void)configureCell:(GridCell*)cell withItem:(GridItem*)item {
-  // TODO(crbug.com/839892) : Cell is sometimes nil. Add DCHECK(cell) here.
+  DCHECK(cell);
   DCHECK(item);
   cell.delegate = self;
   cell.theme = self.theme;
@@ -419,25 +435,34 @@
 }
 
 // Animates the empty state into view.
-- (void)animateEmptyStateIntoView {
+- (void)animateEmptyStateIn {
   // TODO(crbug.com/820410) : Polish the animation, and put constants where they
   // belong.
-  CGFloat scale = 0.8f;
-  CGAffineTransform originalTransform = self.emptyStateView.transform;
-  self.emptyStateView.transform =
-      CGAffineTransformScale(self.emptyStateView.transform, scale, scale);
-  self.emptyStateView.alpha = 0.0f;
-  self.emptyStateView.hidden = NO;
-  [UIView animateWithDuration:1.0f
-                        delay:0.0f
-       usingSpringWithDamping:1.0f
-        initialSpringVelocity:0.7f
-                      options:UIViewAnimationCurveEaseOut
-                   animations:^{
-                     self.emptyStateView.alpha = 1.0f;
-                     self.emptyStateView.transform = originalTransform;
-                   }
-                   completion:nil];
+  [self.emptyStateAnimator stopAnimation:YES];
+  self.emptyStateAnimator = [[UIViewPropertyAnimator alloc]
+      initWithDuration:1.0 - self.emptyStateView.alpha
+          dampingRatio:1.0
+            animations:^{
+              self.emptyStateView.alpha = 1.0;
+              self.emptyStateView.transform = CGAffineTransformIdentity;
+            }];
+  [self.emptyStateAnimator startAnimation];
+}
+
+// Animates the empty state out of view.
+- (void)animateEmptyStateOut {
+  // TODO(crbug.com/820410) : Polish the animation, and put constants where they
+  // belong.
+  [self.emptyStateAnimator stopAnimation:YES];
+  self.emptyStateAnimator = [[UIViewPropertyAnimator alloc]
+      initWithDuration:self.emptyStateView.alpha
+          dampingRatio:1.0
+            animations:^{
+              self.emptyStateView.alpha = 0.0;
+              self.emptyStateView.transform = CGAffineTransformScale(
+                  CGAffineTransformIdentity, /*sx=*/0.9, /*sy=*/0.9);
+            }];
+  [self.emptyStateAnimator startAnimation];
 }
 
 // Handle the long-press gesture used to reorder cells in the collection view.
diff --git a/ios/chrome/test/app/navigation_test_util.mm b/ios/chrome/test/app/navigation_test_util.mm
index 8ceba18..dc7feba8 100644
--- a/ios/chrome/test/app/navigation_test_util.mm
+++ b/ios/chrome/test/app/navigation_test_util.mm
@@ -5,15 +5,12 @@
 #include "ios/chrome/test/app/navigation_test_util.h"
 
 #import "ios/chrome/test/app/chrome_test_util.h"
-#import "ios/testing/wait_util.h"
 #import "ios/web/public/test/navigation_test_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
-using testing::WaitUntilConditionOrTimeout;
-
 namespace chrome_test_util {
 
 void LoadUrl(const GURL& url) {
@@ -25,9 +22,7 @@
 }
 
 bool WaitForPageToFinishLoading() {
-  return WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
-    return !IsLoading();
-  });
+  return web::test::WaitForPageToFinishLoading(GetCurrentWebState());
 }
 
 }  // namespace chrome_test_util
diff --git a/ios/web/public/test/navigation_test_util.h b/ios/web/public/test/navigation_test_util.h
index 099d758..2c62da2 100644
--- a/ios/web/public/test/navigation_test_util.h
+++ b/ios/web/public/test/navigation_test_util.h
@@ -12,7 +12,11 @@
 namespace test {
 
 // Loads |url| in |web_state| with transition of type ui::PAGE_TRANSITION_TYPED.
-void LoadUrl(web::WebState* web_state, const GURL& url);
+void LoadUrl(WebState* web_state, const GURL& url);
+
+// Returns true if the current page in the current WebState finishes loading
+// within a timeout.
+bool WaitForPageToFinishLoading(WebState* web_state) WARN_UNUSED_RESULT;
 
 }  // namespace test
 }  // namespace web
diff --git a/ios/web/public/test/navigation_test_util.mm b/ios/web/public/test/navigation_test_util.mm
index c546cec8..5642465 100644
--- a/ios/web/public/test/navigation_test_util.mm
+++ b/ios/web/public/test/navigation_test_util.mm
@@ -4,13 +4,15 @@
 
 #import "ios/web/public/test/navigation_test_util.h"
 
+#import "ios/testing/wait_util.h"
 #import "ios/web/public/navigation_manager.h"
+#import "ios/web/public/web_state/web_state.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
-using web::NavigationManager;
+using testing::WaitUntilConditionOrTimeout;
 
 namespace web {
 namespace test {
@@ -22,5 +24,11 @@
   navigation_manager->LoadURLWithParams(params);
 }
 
+bool WaitForPageToFinishLoading(WebState* web_state) {
+  return WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
+    return !web_state->IsLoading();
+  });
+}
+
 }  // namespace test
 }  // namespace web
diff --git a/ios/web/web_state/navigation_and_load_callbacks_inttest.mm b/ios/web/web_state/navigation_and_load_callbacks_inttest.mm
index 6453b23f..3f0475e8 100644
--- a/ios/web/web_state/navigation_and_load_callbacks_inttest.mm
+++ b/ios/web/web_state/navigation_and_load_callbacks_inttest.mm
@@ -202,7 +202,7 @@
   // TODO(crbug.com/676129): Reload does not create a pending item. Remove this
   // workaround once the bug is fixed. The slim navigation manager fixes this
   // bug.
-  if (web::GetWebClient()->IsSlimNavigationManagerEnabled() ||
+  if (GetWebClient()->IsSlimNavigationManagerEnabled() ||
       !ui::PageTransitionTypeIncludingQualifiersIs(
           ui::PageTransition::PAGE_TRANSITION_RELOAD,
           (*context)->GetPageTransition())) {
@@ -371,13 +371,13 @@
   // TODO(crbug.com/676129): Reload should not be renderer-initiated, but only
   // marked so because LegacyNavigationManager doesn't create a pending item.
   // WKBasedNavigationManager fixes this problem.
-  EXPECT_EQ(!web::GetWebClient()->IsSlimNavigationManagerEnabled(),
+  EXPECT_EQ(!GetWebClient()->IsSlimNavigationManagerEnabled(),
             (*context)->IsRendererInitiated());
   EXPECT_FALSE((*context)->GetResponseHeaders());
   // TODO(crbug.com/676129): Reload does not create a pending item. Check
   // pending item once the bug is fixed. The slim navigation manager fixes this
   // bug.
-  if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
+  if (GetWebClient()->IsSlimNavigationManagerEnabled()) {
     NavigationManager* navigation_manager = web_state->GetNavigationManager();
     NavigationItem* item = navigation_manager->GetPendingItem();
     EXPECT_EQ(url, item->GetURL());
@@ -411,7 +411,7 @@
   // TODO(crbug.com/676129): Reload should not be renderer-initiated, but only
   // marked so because LegacyNavigationManager doesn't create a pending item.
   // WKBasedNavigationManager fixes this problem.
-  EXPECT_EQ(!web::GetWebClient()->IsSlimNavigationManagerEnabled(),
+  EXPECT_EQ(!GetWebClient()->IsSlimNavigationManagerEnabled(),
             (*context)->IsRendererInitiated());
   if (is_web_page) {
     ASSERT_TRUE((*context)->GetResponseHeaders());
@@ -492,11 +492,10 @@
 using testing::StrictMock;
 using testing::_;
 using testing::WaitUntilConditionOrTimeout;
-using web::test::WaitForWebViewContainingText;
+using test::WaitForWebViewContainingText;
 
-// Test fixture for WebStateDelegate::ProvisionalNavigationStarted,
-// WebStateDelegate::DidFinishNavigation, WebStateDelegate::DidStartLoading and
-// WebStateDelegate::DidStopLoading integration tests.
+// Test fixture to test navigation and load callbacks from WebStateObserver and
+// WebStatePolicyDecider.
 class NavigationAndLoadCallbacksTest : public WebIntTest {
  public:
   NavigationAndLoadCallbacksTest() : scoped_observer_(&observer_) {}
@@ -533,14 +532,15 @@
 
  protected:
   TestNativeContentProvider* provider_;
-  std::unique_ptr<StrictMock<PolicyDeciderMock>> decider_;
   TestNativeContent* content_;
+  std::unique_ptr<StrictMock<PolicyDeciderMock>> decider_;
   StrictMock<WebStateObserverMock> observer_;
+  std::unique_ptr<net::test_server::EmbeddedTestServer> test_server_;
+
+ private:
   ScopedObserver<WebState, WebStateObserver> scoped_observer_;
   testing::InSequence callbacks_sequence_checker_;
 
-  std::unique_ptr<net::test_server::EmbeddedTestServer> test_server_;
-
   DISALLOW_COPY_AND_ASSIGN(NavigationAndLoadCallbacksTest);
 };
 
@@ -621,11 +621,8 @@
           VerifyErrorFinishedContext(web_state(), url, &context, &nav_id));
   EXPECT_CALL(observer_,
               PageLoaded(web_state(), PageLoadCompletionStatus::FAILURE));
-  // LoadUrl() expects sucessfull load and can not be used here.
-  web::test::LoadUrl(web_state(), url);
-  EXPECT_TRUE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
-    return !web_state()->IsLoading();
-  }));
+  test::LoadUrl(web_state(), url);
+  ASSERT_TRUE(test::WaitForPageToFinishLoading(web_state()));
 }
 
 // Tests web page reload navigation.
@@ -934,7 +931,8 @@
   EXPECT_CALL(observer_, DidStopLoading(web_state()));
   EXPECT_CALL(observer_,
               PageLoaded(web_state(), PageLoadCompletionStatus::SUCCESS));
-  navigation_manager()->Reload(ReloadType::NORMAL, false /*check_for_repost*/);
+  web_state()->GetNavigationManager()->Reload(ReloadType::NORMAL,
+                                              /*check_for_repost=*/false);
 }
 
 // Tests successful navigation to a new page with post HTTP method.
@@ -962,7 +960,7 @@
               PageLoaded(web_state(), PageLoadCompletionStatus::SUCCESS));
 
   // Load request using POST HTTP method.
-  web::NavigationManager::WebLoadParams params(url);
+  NavigationManager::WebLoadParams params(url);
   params.post_data = [@"foo" dataUsingEncoding:NSUTF8StringEncoding];
   params.extra_headers = @{@"Content-Type" : @"text/html"};
   ASSERT_TRUE(LoadWithParams(params));
@@ -1000,7 +998,7 @@
                                          /*renderer_initiated=*/true));
   EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true))
       .WillOnce(Return(true));
-  if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
+  if (GetWebClient()->IsSlimNavigationManagerEnabled()) {
     EXPECT_CALL(observer_, DidChangeBackForwardState(web_state()));
   }
   EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _))
@@ -1042,7 +1040,7 @@
   EXPECT_CALL(observer_, DidStartNavigation(web_state(), _));
   EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true))
       .WillOnce(Return(true));
-  if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
+  if (GetWebClient()->IsSlimNavigationManagerEnabled()) {
     EXPECT_CALL(observer_, DidChangeBackForwardState(web_state()));
   }
   EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _));
@@ -1057,7 +1055,7 @@
   NavigationContext* context = nullptr;
   int32_t nav_id = 0;
   EXPECT_CALL(observer_, DidStartLoading(web_state()));
-  if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
+  if (GetWebClient()->IsSlimNavigationManagerEnabled()) {
     // ShouldAllowRequest() not called because SlimNavigationManager catches
     // repost before calling policy decider.
   } else {
@@ -1066,7 +1064,7 @@
   }
 
   bool reload_is_renderer_initiated = false;
-  if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
+  if (!GetWebClient()->IsSlimNavigationManagerEnabled()) {
     // TODO(crbug.com/676129) LegacyNavigationManager doesn't create a pending
     // item on reload. This causes the navigation context to be incorrectly
     // marked renderer-initiated. Remove this workaround.
@@ -1122,7 +1120,7 @@
   EXPECT_CALL(observer_, DidStartNavigation(web_state(), _));
   EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true))
       .WillOnce(Return(true));
-  if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
+  if (GetWebClient()->IsSlimNavigationManagerEnabled()) {
     EXPECT_CALL(observer_, DidChangeBackForwardState(web_state()));
   }
   EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _));
@@ -1134,7 +1132,7 @@
       WaitForWebViewContainingText(web_state(), testing::kTestFormFieldValue));
 
   // Go Back.
-  if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
+  if (GetWebClient()->IsSlimNavigationManagerEnabled()) {
     EXPECT_CALL(observer_, DidChangeBackForwardState(web_state())).Times(2);
     EXPECT_CALL(*decider_, ShouldAllowRequest(_, _, /*from_main_frame=*/true))
         .WillOnce(Return(true));
@@ -1158,7 +1156,7 @@
   // Go forward.
   NavigationContext* context = nullptr;
   int32_t nav_id = 0;
-  if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
+  if (GetWebClient()->IsSlimNavigationManagerEnabled()) {
     EXPECT_CALL(observer_, DidChangeBackForwardState(web_state())).Times(2);
     // ShouldAllowRequest() not called on repost.
     EXPECT_CALL(observer_, DidStartLoading(web_state()));
@@ -1235,10 +1233,8 @@
           VerifyDownloadFinishedContext(web_state(), url, &context, &nav_id));
   EXPECT_CALL(observer_, DidStopLoading(web_state()));
 
-  web::test::LoadUrl(web_state(), url);
-  EXPECT_TRUE(WaitUntilConditionOrTimeout(testing::kWaitForDownloadTimeout, ^{
-    return !web_state()->IsLoading();
-  }));
+  test::LoadUrl(web_state(), url);
+  ASSERT_TRUE(test::WaitForPageToFinishLoading(web_state()));
 
   EXPECT_FALSE(web_state()->GetNavigationManager()->GetPendingItem());
 }
@@ -1264,20 +1260,17 @@
   EXPECT_CALL(observer_, DidStopLoading(web_state()));
   EXPECT_CALL(observer_,
               PageLoaded(web_state(), PageLoadCompletionStatus::FAILURE));
-  web::test::LoadUrl(web_state(), url);
+  test::LoadUrl(web_state(), url);
 
-  // Server does not stop responding until it's shut down. Let the server run
-  // to make web state finish the navigation.
-  EXPECT_FALSE(WaitUntilConditionOrTimeout(2.0, ^{
-    return !web_state()->IsLoading();
+  // Server will never stop responding. Wait until the navigation is committed.
+  EXPECT_FALSE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
+    return context && context->HasCommitted();
   }));
 
   // It this point the navigation should be finished. Shutdown the server and
   // wait until web state stop loading.
   ASSERT_TRUE(test_server_->ShutdownAndWaitUntilComplete());
-  EXPECT_TRUE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
-    return !web_state()->IsLoading();
-  }));
+  ASSERT_TRUE(test::WaitForPageToFinishLoading(web_state()));
 }
 
 // Tests rejecting the navigation from ShouldAllowRequest. The load should stop,
@@ -1287,10 +1280,8 @@
   EXPECT_CALL(*decider_, ShouldAllowRequest(_, _, /*from_main_frame=*/true))
       .WillOnce(Return(false));
   EXPECT_CALL(observer_, DidStopLoading(web_state()));
-  web::test::LoadUrl(web_state(), test_server_->GetURL("/echo"));
-  EXPECT_TRUE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
-    return !web_state()->IsLoading();
-  }));
+  test::LoadUrl(web_state(), test_server_->GetURL("/echo"));
+  ASSERT_TRUE(test::WaitForPageToFinishLoading(web_state()));
 }
 
 // Tests rejecting the navigation from ShouldAllowResponse. PageLoaded callback
@@ -1314,10 +1305,8 @@
   EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _))
       .WillOnce(VerifyResponseRejectedFinishedContext(web_state(), url,
                                                       &context, &nav_id));
-  web::test::LoadUrl(web_state(), test_server_->GetURL("/echo"));
-  EXPECT_TRUE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
-    return !web_state()->IsLoading();
-  }));
+  test::LoadUrl(web_state(), test_server_->GetURL("/echo"));
+  ASSERT_TRUE(test::WaitForPageToFinishLoading(web_state()));
 }
 
 // Tests stopping a navigation. Did FinishLoading and PageLoaded are never
@@ -1327,11 +1316,9 @@
   EXPECT_CALL(observer_, DidStopLoading(web_state()));
   EXPECT_CALL(*decider_, ShouldAllowRequest(_, _, /*from_main_frame=*/true))
       .WillOnce(Return(true));
-  web::test::LoadUrl(web_state(), test_server_->GetURL("/hung"));
+  test::LoadUrl(web_state(), test_server_->GetURL("/hung"));
   web_state()->Stop();
-  EXPECT_TRUE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
-    return !web_state()->IsLoading();
-  }));
+  ASSERT_TRUE(test::WaitForPageToFinishLoading(web_state()));
 }
 
 // Tests stopping a finished navigation. PageLoaded is never called.
@@ -1354,7 +1341,7 @@
                                              &context, &nav_id));
   EXPECT_CALL(observer_, DidStopLoading(web_state()));
 
-  web::test::LoadUrl(web_state(), url);
+  test::LoadUrl(web_state(), url);
 
   // Server will never stop responding. Wait until the navigation is committed.
   EXPECT_FALSE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
@@ -1363,15 +1350,13 @@
 
   // Stop the loading.
   web_state()->Stop();
-  EXPECT_TRUE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
-    return !web_state()->IsLoading();
-  }));
+  ASSERT_TRUE(test::WaitForPageToFinishLoading(web_state()));
 }
 
 // Tests that iframe navigation triggers DidChangeBackForwardState.
 TEST_F(NavigationAndLoadCallbacksTest, IframeNavigation) {
   // LegacyNavigationManager doesn't support iframe navigation history.
-  if (!web::GetWebClient()->IsSlimNavigationManagerEnabled())
+  if (!GetWebClient()->IsSlimNavigationManagerEnabled())
     return;
 
   GURL url = test_server_->GetURL("/iframe_host.html");
@@ -1393,10 +1378,8 @@
   EXPECT_CALL(observer_,
               PageLoaded(web_state(), PageLoadCompletionStatus::SUCCESS));
 
-  web::test::LoadUrl(web_state(), url);
-  EXPECT_TRUE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
-    return !web_state()->IsLoading();
-  }));
+  test::LoadUrl(web_state(), url);
+  ASSERT_TRUE(test::WaitForPageToFinishLoading(web_state()));
 
   // Trigger different-document load in iframe.
   EXPECT_CALL(*decider_, ShouldAllowRequest(_, _, /*from_main_frame=*/false))
@@ -1406,11 +1389,11 @@
   EXPECT_CALL(observer_, DidChangeBackForwardState(web_state()));
   test::TapWebViewElementWithIdInIframe(web_state(), "normal-link");
   EXPECT_TRUE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
-    return navigation_manager()->CanGoBack();
+    return web_state()->GetNavigationManager()->CanGoBack();
   }));
   id history_length = ExecuteJavaScript(@"history.length;");
   ASSERT_NSEQ(@2, history_length);
-  EXPECT_FALSE(navigation_manager()->CanGoForward());
+  EXPECT_FALSE(web_state()->GetNavigationManager()->CanGoForward());
 
   // Go back to top.
   EXPECT_CALL(observer_, DidChangeBackForwardState(web_state()))
@@ -1419,11 +1402,11 @@
       .WillOnce(Return(true));
   EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/false))
       .WillOnce(Return(true));
-  navigation_manager()->GoBack();
+  web_state()->GetNavigationManager()->GoBack();
   EXPECT_TRUE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
-    return navigation_manager()->CanGoForward();
+    return web_state()->GetNavigationManager()->CanGoForward();
   }));
-  EXPECT_FALSE(navigation_manager()->CanGoBack());
+  EXPECT_FALSE(web_state()->GetNavigationManager()->CanGoBack());
 
   // Trigger same-document load in iframe.
   EXPECT_CALL(*decider_, ShouldAllowRequest(_, _, /*from_main_frame=*/false))
@@ -1433,9 +1416,9 @@
       .Times(2);  // called once each for canGoBack and canGoForward
   test::TapWebViewElementWithIdInIframe(web_state(), "same-page-link");
   EXPECT_TRUE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
-    return navigation_manager()->CanGoBack();
+    return web_state()->GetNavigationManager()->CanGoBack();
   }));
-  EXPECT_FALSE(navigation_manager()->CanGoForward());
+  EXPECT_FALSE(web_state()->GetNavigationManager()->CanGoForward());
 }
 
 }  // namespace web
diff --git a/ios/web/webui/web_ui_mojo_inttest.mm b/ios/web/webui/web_ui_mojo_inttest.mm
index c70634660..30fbdf51 100644
--- a/ios/web/webui/web_ui_mojo_inttest.mm
+++ b/ios/web/webui/web_ui_mojo_inttest.mm
@@ -9,6 +9,7 @@
 #import "ios/testing/wait_util.h"
 #include "ios/web/grit/ios_web_resources.h"
 #import "ios/web/public/navigation_manager.h"
+#import "ios/web/public/test/navigation_test_util.h"
 #include "ios/web/public/web_state/web_state_interface_provider.h"
 #include "ios/web/public/web_ui_ios_data_source.h"
 #include "ios/web/public/webui/web_ui_ios_controller.h"
@@ -180,11 +181,12 @@
 // |TestUIHandler| successfully receives "ack" message from WebUI page.
 TEST_F(WebUIMojoTest, MessageExchange) {
   @autoreleasepool {
-    web_state()->GetView();  // WebState won't load URL without view.
-    GURL url(url::SchemeHostPort(kTestWebUIScheme, kTestWebUIURLHost, 0)
-                 .Serialize());
-    NavigationManager::WebLoadParams load_params(url);
-    web_state()->GetNavigationManager()->LoadURLWithParams(load_params);
+    url::SchemeHostPort tuple(kTestWebUIScheme, kTestWebUIURLHost, 0);
+    GURL url(tuple.Serialize());
+    test::LoadUrl(web_state(), url);
+    // LoadIfNecessary is needed because the view is not created (but needed)
+    // when loading the page. TODO(crbug.com/705819): Remove this call.
+    web_state()->GetNavigationManager()->LoadIfNecessary();
 
     // Wait until |TestUIHandler| receives "fin" message from WebUI page.
     bool fin_received = testing::WaitUntilConditionOrTimeout(kMessageTimeout, ^{
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn
index 470b293..c459b50 100644
--- a/ios/web_view/BUILD.gn
+++ b/ios/web_view/BUILD.gn
@@ -319,6 +319,7 @@
     "internal/autofill/cwv_autofill_controller_unittest.mm",
     "internal/autofill/cwv_autofill_profile_unittest.mm",
     "internal/autofill/cwv_autofill_suggestion_unittest.mm",
+    "internal/autofill/cwv_credit_card_unittest.mm",
     "internal/cwv_html_element_unittest.mm",
     "internal/cwv_preferences_unittest.mm",
     "internal/cwv_preview_element_info_unittest.mm",
diff --git a/ios/web_view/internal/autofill/cwv_credit_card_unittest.mm b/ios/web_view/internal/autofill/cwv_credit_card_unittest.mm
new file mode 100644
index 0000000..f4eee72
--- /dev/null
+++ b/ios/web_view/internal/autofill/cwv_credit_card_unittest.mm
@@ -0,0 +1,123 @@
+// 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.
+
+#import "ios/web_view/internal/autofill/cwv_credit_card_internal.h"
+
+#import <UIKit/UIKit.h>
+#include <string>
+
+#include "base/base_paths.h"
+#include "base/path_service.h"
+#include "base/strings/sys_string_conversions.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#import "testing/gtest_mac.h"
+#include "testing/platform_test.h"
+#include "ui/base/resource/resource_bundle.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace ios_web_view {
+
+namespace {
+NSString* const kGuid = @"12345";
+NSString* const kOrigin = @"www.chromium.org";
+NSString* const kLocale = @"en";
+NSString* const kCardHolderFullName = @"Homer Simpson";
+NSString* const kCardNumber = @"4408041234567893";
+NSString* const kNetworkName = @"Visa";
+NSString* const kExpirationMonth = @"08";
+NSString* const kExpirationYear = @"2038";
+}
+
+class CWVCreditCardTest : public PlatformTest {
+ protected:
+  CWVCreditCardTest() {
+    ui::ResourceBundle::InitSharedInstanceWithLocale(
+        base::SysNSStringToUTF8(kLocale), /*delegate=*/nullptr,
+        ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES);
+    ui::ResourceBundle& resource_bundle =
+        ui::ResourceBundle::GetSharedInstance();
+
+    // Don't load 100P resource since no @1x devices are supported.
+    if (ui::ResourceBundle::IsScaleFactorSupported(ui::SCALE_FACTOR_200P)) {
+      base::FilePath pak_file_200;
+      base::PathService::Get(base::DIR_MODULE, &pak_file_200);
+      pak_file_200 =
+          pak_file_200.Append(FILE_PATH_LITERAL("web_view_200_percent.pak"));
+      resource_bundle.AddDataPackFromPath(pak_file_200, ui::SCALE_FACTOR_200P);
+    }
+    if (ui::ResourceBundle::IsScaleFactorSupported(ui::SCALE_FACTOR_300P)) {
+      base::FilePath pak_file_300;
+      base::PathService::Get(base::DIR_MODULE, &pak_file_300);
+      pak_file_300 =
+          pak_file_300.Append(FILE_PATH_LITERAL("web_view_300_percent.pak"));
+      resource_bundle.AddDataPackFromPath(pak_file_300, ui::SCALE_FACTOR_300P);
+    }
+  }
+
+  ~CWVCreditCardTest() override { ui::ResourceBundle::CleanupSharedInstance(); }
+};
+
+// Tests CWVCreditCard initialization.
+TEST_F(CWVCreditCardTest, Initialization) {
+  autofill::CreditCard credit_card(base::SysNSStringToUTF8(kGuid),
+                                   base::SysNSStringToUTF8(kOrigin));
+  credit_card.SetInfo(autofill::CREDIT_CARD_NAME_FULL,
+                      base::SysNSStringToUTF16(kCardHolderFullName),
+                      base::SysNSStringToUTF8(kLocale));
+  credit_card.SetInfo(autofill::CREDIT_CARD_NUMBER,
+                      base::SysNSStringToUTF16(kCardNumber),
+                      base::SysNSStringToUTF8(kLocale));
+  credit_card.SetInfo(autofill::CREDIT_CARD_EXP_MONTH,
+                      base::SysNSStringToUTF16(kExpirationMonth),
+                      base::SysNSStringToUTF8(kLocale));
+  credit_card.SetInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR,
+                      base::SysNSStringToUTF16(kExpirationYear),
+                      base::SysNSStringToUTF8(kLocale));
+  CWVCreditCard* cwv_credit_card =
+      [[CWVCreditCard alloc] initWithCreditCard:credit_card];
+
+  EXPECT_NSEQ(kCardHolderFullName, cwv_credit_card.cardHolderFullName);
+  EXPECT_NSEQ(kCardNumber, cwv_credit_card.cardNumber);
+  EXPECT_NSEQ(kNetworkName, cwv_credit_card.networkName);
+  EXPECT_NSEQ(kExpirationMonth, cwv_credit_card.expirationMonth);
+  EXPECT_NSEQ(kExpirationYear, cwv_credit_card.expirationYear);
+  EXPECT_TRUE(cwv_credit_card.savedLocally);
+
+  // It is not sufficient to simply test for networkIcon != nil because
+  // ui::ResourceBundle will return a placeholder image at @1x scale if the
+  // underlying resource id is not found. Since no @1x devices are supported
+  // anymore, check to make sure the UIImage scale matches that of the UIScreen.
+  EXPECT_TRUE(cwv_credit_card.networkIcon.scale == UIScreen.mainScreen.scale);
+}
+
+// Tests CWVCreditCard updates properties.
+TEST_F(CWVCreditCardTest, ModifyProperties) {
+  autofill::CreditCard credit_card(base::SysNSStringToUTF8(kGuid),
+                                   base::SysNSStringToUTF8(kOrigin));
+  CWVCreditCard* cwv_credit_card =
+      [[CWVCreditCard alloc] initWithCreditCard:credit_card];
+  cwv_credit_card.cardHolderFullName = kCardHolderFullName;
+  cwv_credit_card.cardNumber = kCardNumber;
+  cwv_credit_card.expirationMonth = kExpirationMonth;
+  cwv_credit_card.expirationYear = kExpirationYear;
+
+  EXPECT_NSEQ(kCardHolderFullName, cwv_credit_card.cardHolderFullName);
+  EXPECT_NSEQ(kCardNumber, cwv_credit_card.cardNumber);
+  EXPECT_NSEQ(kNetworkName, cwv_credit_card.networkName);
+  EXPECT_NSEQ(kExpirationMonth, cwv_credit_card.expirationMonth);
+  EXPECT_NSEQ(kExpirationYear, cwv_credit_card.expirationYear);
+  EXPECT_TRUE(cwv_credit_card.savedLocally);
+
+  // It is not sufficient to simply test for networkIcon != nil because
+  // ui::ResourceBundle will return a placeholder image at @1x scale if the
+  // underlying resource id is not found. Since no @1x devices are supported
+  // anymore, check to make sure the UIImage scale matches that of the UIScreen.
+  EXPECT_TRUE(cwv_credit_card.networkIcon.scale == UIScreen.mainScreen.scale);
+}
+
+}  // namespace ios_web_view
diff --git a/mojo/public/cpp/bindings/associated_interface_ptr_info.h b/mojo/public/cpp/bindings/associated_interface_ptr_info.h
index 1f79662..cc3f627 100644
--- a/mojo/public/cpp/bindings/associated_interface_ptr_info.h
+++ b/mojo/public/cpp/bindings/associated_interface_ptr_info.h
@@ -45,7 +45,7 @@
 
   bool is_valid() const { return handle_.is_valid(); }
 
-  explicit operator bool() const { return handle_; }
+  explicit operator bool() const { return handle_.is_valid(); }
 
   ScopedInterfaceEndpointHandle PassHandle() {
     return std::move(handle_);
diff --git a/mojo/public/cpp/bindings/associated_interface_request.h b/mojo/public/cpp/bindings/associated_interface_request.h
index 12d2f3c..0926f3d 100644
--- a/mojo/public/cpp/bindings/associated_interface_request.h
+++ b/mojo/public/cpp/bindings/associated_interface_request.h
@@ -50,7 +50,7 @@
   // handle.
   bool is_pending() const { return handle_.is_valid(); }
 
-  explicit operator bool() const { return handle_; }
+  explicit operator bool() const { return handle_.is_valid(); }
 
   ScopedInterfaceEndpointHandle PassHandle() { return std::move(handle_); }
 
diff --git a/net/base/filename_util_unittest.cc b/net/base/filename_util_unittest.cc
index ec25e4c..b4747c4 100644
--- a/net/base/filename_util_unittest.cc
+++ b/net/base/filename_util_unittest.cc
@@ -231,6 +231,16 @@
     // %2f ('/') and %5c ('\\') are left alone by both GURL and
     // FileURLToFilePath.
     {L"C:\\foo%2f..%5cbar", "file:///C:\\foo%2f..%5cbar"},
+    // Other percent-encoded characters that are left alone when displaying a
+    // URL are also left alone in a file path.
+    // TODO(mgiuca): Keeping these escaped makes no sense in a file path. Fix
+    // this (https://crbug.com/585422).
+    {L"C:\\foo\\%F0%9F%94%92.txt",
+     "file:/c:/foo/%F0%9F%94%92.txt"},                          // Blacklisted.
+    {L"C:\\foo\\%E2%80%81.txt", "file:/c:/foo/%E2%80%81.txt"},  // Blacklisted.
+    {L"C:\\foo\\%0A.txt", "file:/c:/foo/%0A.txt"},              // Control char.
+    // Make sure that '+' isn't converted into ' '.
+    {L"C:\\foo\\romeo+juliet.txt", "file:/c:/foo/romeo+juliet.txt"},
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
     {L"/c:/foo/bar.txt", "file:/c:/foo/bar.txt"},
     {L"/c:/foo/bar.txt", "file:///c:/foo/bar.txt"},
@@ -248,13 +258,19 @@
     // %2f ('/') and %5c ('\\') are left alone by both GURL and
     // FileURLToFilePath.
     {L"/foo%2f..%5cbar", "file:///foo%2f..%5cbar"},
-//  We get these wrong because GURL turns back slashes into forward
-//  slashes.
-//  {L"/foo%5Cbar.txt", "file://foo\\bar.txt"},
-//  {L"/c|/foo%5Cbar.txt", "file:c|/foo\\bar.txt"},
-//  {L"/foo%5Cbar.txt", "file://foo\\bar.txt"},
-//  {L"/foo%5Cbar.txt", "file:////foo\\bar.txt"},
-//  {L"/foo%5Cbar.txt", "file://foo\\bar.txt"},
+    // Other percent-encoded characters that are left alone when displaying a
+    // URL are also left alone in a file path.
+    // TODO(mgiuca): Keeping these escaped makes no sense in a file path. Fix
+    // this (https://crbug.com/585422).
+    {L"/foo/%F0%9F%94%92.txt", "file:///foo/%F0%9F%94%92.txt"},  // Blacklisted.
+    {L"/foo/%E2%80%81.txt", "file:///foo/%E2%80%81.txt"},        // Blacklisted.
+    {L"/foo/%0A.txt", "file:///foo/%0A.txt"},  // Control char.
+    // Make sure that '+' isn't converted into ' '.
+    {L"/foo/romeo+juliet.txt", "file:///foo/romeo+juliet.txt"},
+    // Backslashes in a file URL are normalized as forward slashes.
+    {L"/bar.txt", "file://foo\\bar.txt"},
+    {L"/c|/foo/bar.txt", "file:c|/foo\\bar.txt"},
+    {L"/foo/bar.txt", "file:////foo\\bar.txt"},
 #endif
   };
   for (const auto& test_case : url_cases) {
@@ -262,15 +278,40 @@
     EXPECT_EQ(test_case.file, FilePathAsWString(output));
   }
 
-// Unfortunately, UTF8ToWide discards invalid UTF8 input.
-#ifdef BUG_878908_IS_FIXED
-  // Test that no conversion happens if the UTF-8 input is invalid, and that
-  // the input is preserved in UTF-8
-  const char invalid_utf8[] = "file:///d:/Blah/\xff.doc";
-  const wchar_t invalid_wide[] = L"D:\\Blah\\\xff.doc";
-  EXPECT_TRUE(FileURLToFilePath(GURL(std::string(invalid_utf8)), &output));
-  EXPECT_EQ(std::wstring(invalid_wide), output);
+  // Invalid UTF-8 tests can't be tested above because FilePathAsWString assumes
+  // the output is valid UTF-8.
+
+  // Invalid UTF-8 bytes in input.
+  {
+    const char invalid_utf8[] = "file:///d:/Blah/\x85\x99.doc";
+    EXPECT_TRUE(FileURLToFilePath(GURL(invalid_utf8), &output));
+#if defined(OS_WIN)
+    // On Windows, invalid UTF-8 bytes are interpreted using the default ANSI
+    // code page. This defaults to Windows-1252 (which we assume here).
+    const wchar_t expected_output[] = L"D:\\Blah\\\u2026\u2122.doc";
+    EXPECT_EQ(std::wstring(expected_output), output.value());
+#elif defined(OS_POSIX)
+    // No conversion should happen, and the invalid UTF-8 should be preserved.
+    const char expected_output[] = "/d:/Blah/\x85\x99.doc";
+    EXPECT_EQ(expected_output, output.value());
 #endif
+  }
+
+  // Invalid UTF-8 percent-encoded bytes in input.
+  {
+    const char invalid_utf8[] = "file:///d:/Blah/%85%99.doc";
+    EXPECT_TRUE(FileURLToFilePath(GURL(invalid_utf8), &output));
+#if defined(OS_WIN)
+    // On Windows, invalid UTF-8 bytes are interpreted using the default ANSI
+    // code page. This defaults to Windows-1252 (which we assume here).
+    const wchar_t expected_output[] = L"D:\\Blah\\\u2026\u2122.doc";
+    EXPECT_EQ(std::wstring(expected_output), output.value());
+#elif defined(OS_POSIX)
+    // No conversion should happen, and the invalid UTF-8 should be preserved.
+    const char expected_output[] = "/d:/Blah/\x85\x99.doc";
+    EXPECT_EQ(expected_output, output.value());
+#endif
+  }
 
   // Test that if a file URL is malformed, we get a failure
   EXPECT_FALSE(FileURLToFilePath(GURL("filefoobar"), &output));
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc
index 0dff0ec..619c3a1 100644
--- a/net/nqe/network_quality_estimator.cc
+++ b/net/nqe/network_quality_estimator.cc
@@ -1002,11 +1002,12 @@
 
   base::TimeDelta http_rtt = nqe::internal::InvalidRTT();
   base::TimeDelta transport_rtt = nqe::internal::InvalidRTT();
+  base::TimeDelta end_to_end_rtt = nqe::internal::InvalidRTT();
   int32_t downstream_throughput_kbps = nqe::internal::INVALID_RTT_THROUGHPUT;
 
   effective_connection_type_ =
       GetRecentEffectiveConnectionTypeAndNetworkQuality(
-          base::TimeTicks(), &http_rtt, &transport_rtt,
+          base::TimeTicks(), &http_rtt, &transport_rtt, &end_to_end_rtt,
           &downstream_throughput_kbps,
           &transport_rtt_observation_count_last_ect_computation_);
 
@@ -1027,6 +1028,10 @@
                         network_quality_.transport_rtt());
   }
 
+  if (end_to_end_rtt != nqe::internal::InvalidRTT()) {
+    UMA_HISTOGRAM_TIMES("NQE.EndToEndRTT.OnECTComputation", end_to_end_rtt);
+  }
+
   if (network_quality_.downstream_throughput_kbps() !=
       nqe::internal::INVALID_RTT_THROUGHPUT) {
     UMA_HISTOGRAM_COUNTS_1M("NQE.Kbps.OnECTComputation",
@@ -1064,11 +1069,13 @@
 
   base::TimeDelta http_rtt = nqe::internal::InvalidRTT();
   base::TimeDelta transport_rtt = nqe::internal::InvalidRTT();
+  base::TimeDelta end_to_end_rtt = nqe::internal::InvalidRTT();
+
   int32_t downstream_throughput_kbps = nqe::internal::INVALID_RTT_THROUGHPUT;
 
   return GetRecentEffectiveConnectionTypeAndNetworkQuality(
-      start_time, &http_rtt, &transport_rtt, &downstream_throughput_kbps,
-      nullptr);
+      start_time, &http_rtt, &transport_rtt, &end_to_end_rtt,
+      &downstream_throughput_kbps, nullptr);
 }
 
 EffectiveConnectionType
@@ -1076,20 +1083,20 @@
     const base::TimeTicks& start_time,
     base::TimeDelta* http_rtt,
     base::TimeDelta* transport_rtt,
+    base::TimeDelta* end_to_end_rtt,
     int32_t* downstream_throughput_kbps,
     size_t* transport_rtt_observation_count) const {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-    return GetRecentEffectiveConnectionTypeUsingMetrics(
-        start_time,
-        NetworkQualityEstimator::MetricUsage::
-            MUST_BE_USED /* http_rtt_metric */,
-        NetworkQualityEstimator::MetricUsage::
-            DO_NOT_USE /* transport_rtt_metric */,
-        NetworkQualityEstimator::MetricUsage::
-            USE_IF_AVAILABLE /* downstream_throughput_kbps_metric */,
-        http_rtt, transport_rtt, downstream_throughput_kbps,
-        transport_rtt_observation_count);
+  return GetRecentEffectiveConnectionTypeUsingMetrics(
+      start_time,
+      NetworkQualityEstimator::MetricUsage::MUST_BE_USED /* http_rtt_metric */,
+      NetworkQualityEstimator::MetricUsage::
+          DO_NOT_USE /* transport_rtt_metric */,
+      NetworkQualityEstimator::MetricUsage::
+          USE_IF_AVAILABLE /* downstream_throughput_kbps_metric */,
+      http_rtt, transport_rtt, end_to_end_rtt, downstream_throughput_kbps,
+      transport_rtt_observation_count);
 }
 
 EffectiveConnectionType
@@ -1100,12 +1107,14 @@
     NetworkQualityEstimator::MetricUsage downstream_throughput_kbps_metric,
     base::TimeDelta* http_rtt,
     base::TimeDelta* transport_rtt,
+    base::TimeDelta* end_to_end_rtt,
     int32_t* downstream_throughput_kbps,
     size_t* transport_rtt_observation_count) const {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   *http_rtt = nqe::internal::InvalidRTT();
   *transport_rtt = nqe::internal::InvalidRTT();
+  *end_to_end_rtt = nqe::internal::InvalidRTT();
   *downstream_throughput_kbps = nqe::internal::INVALID_RTT_THROUGHPUT;
 
   auto forced_ect =
@@ -1137,6 +1146,11 @@
     *transport_rtt = nqe::internal::InvalidRTT();
   }
 
+  if (!GetRecentRTT(nqe::internal::OBSERVATION_CATEGORY_END_TO_END, start_time,
+                    end_to_end_rtt, nullptr)) {
+    *end_to_end_rtt = nqe::internal::InvalidRTT();
+  }
+
   if (*http_rtt != nqe::internal::InvalidRTT() &&
       *transport_rtt != nqe::internal::InvalidRTT()) {
     // Use transport RTT to clamp the HTTP RTT between lower and upper bounds.
@@ -1296,6 +1310,7 @@
   switch (observation_category) {
     case nqe::internal::OBSERVATION_CATEGORY_HTTP:
     case nqe::internal::OBSERVATION_CATEGORY_TRANSPORT:
+    case nqe::internal::OBSERVATION_CATEGORY_END_TO_END:
       return base::TimeDelta::FromMilliseconds(
           rtt_ms_observations_[observation_category]
               .GetPercentile(start_time, current_network_id_.signal_strength,
@@ -1458,8 +1473,12 @@
       &rtt_ms_observations_[nqe::internal::OBSERVATION_CATEGORY_TRANSPORT]);
   ++new_rtt_observations_since_last_ect_computation_;
 
-  rtt_ms_observations_[observation.GetObservationCategory()].AddObservation(
-      observation);
+  std::vector<nqe::internal::ObservationCategory> observation_categories =
+      observation.GetObservationCategories();
+  for (nqe::internal::ObservationCategory observation_category :
+       observation_categories) {
+    rtt_ms_observations_[observation_category].AddObservation(observation);
+  }
 
   if (observation.source() == NETWORK_QUALITY_OBSERVATION_SOURCE_TCP ||
       observation.source() == NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC) {
@@ -1490,8 +1509,9 @@
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK_NE(nqe::internal::INVALID_RTT_THROUGHPUT, observation.value());
   DCHECK_GT(NETWORK_QUALITY_OBSERVATION_SOURCE_MAX, observation.source());
+  DCHECK_EQ(1u, observation.GetObservationCategories().size());
   DCHECK_EQ(nqe::internal::OBSERVATION_CATEGORY_HTTP,
-            observation.GetObservationCategory());
+            observation.GetObservationCategories().front());
 
   if (!ShouldAddObservation(observation))
     return;
diff --git a/net/nqe/network_quality_estimator.h b/net/nqe/network_quality_estimator.h
index e5124a6e..342462fc 100644
--- a/net/nqe/network_quality_estimator.h
+++ b/net/nqe/network_quality_estimator.h
@@ -269,6 +269,7 @@
       const base::TimeTicks& start_time,
       base::TimeDelta* http_rtt,
       base::TimeDelta* transport_rtt,
+      base::TimeDelta* end_to_end_rtt,
       int32_t* downstream_throughput_kbps,
       size_t* transport_rtt_observation_count) const;
 
@@ -461,6 +462,7 @@
       MetricUsage downstream_throughput_kbps_metric,
       base::TimeDelta* http_rtt,
       base::TimeDelta* transport_rtt,
+      base::TimeDelta* end_to_end_rtt,
       int32_t* downstream_throughput_kbps,
       size_t* transport_rtt_observation_count) const;
 
diff --git a/net/nqe/network_quality_estimator_test_util.cc b/net/nqe/network_quality_estimator_test_util.cc
index 276a9ae..f2e4545 100644
--- a/net/nqe/network_quality_estimator_test_util.cc
+++ b/net/nqe/network_quality_estimator_test_util.cc
@@ -135,6 +135,7 @@
     const base::TimeTicks& start_time,
     base::TimeDelta* http_rtt,
     base::TimeDelta* transport_rtt,
+    base::TimeDelta* end_to_end_rtt,
     int32_t* downstream_throughput_kbps,
     size_t* observations_count) const {
   if (recent_effective_connection_type_) {
@@ -147,8 +148,8 @@
   }
   return NetworkQualityEstimator::
       GetRecentEffectiveConnectionTypeAndNetworkQuality(
-          start_time, http_rtt, transport_rtt, downstream_throughput_kbps,
-          observations_count);
+          start_time, http_rtt, transport_rtt, end_to_end_rtt,
+          downstream_throughput_kbps, observations_count);
 }
 
 bool TestNetworkQualityEstimator::GetRecentRTT(
@@ -192,7 +193,8 @@
         return true;
       }
       break;
-
+    case nqe::internal::OBSERVATION_CATEGORY_END_TO_END:
+      break;
     case nqe::internal::OBSERVATION_CATEGORY_COUNT:
       NOTREACHED();
   }
diff --git a/net/nqe/network_quality_estimator_test_util.h b/net/nqe/network_quality_estimator_test_util.h
index a830e8f..2100a98 100644
--- a/net/nqe/network_quality_estimator_test_util.h
+++ b/net/nqe/network_quality_estimator_test_util.h
@@ -105,6 +105,7 @@
       const base::TimeTicks& start_time,
       base::TimeDelta* http_rtt,
       base::TimeDelta* transport_rtt,
+      base::TimeDelta* end_to_end_rtt,
       int32_t* downstream_throughput_kbps,
       size_t* observations_count) const override;
 
diff --git a/net/nqe/network_quality_estimator_unittest.cc b/net/nqe/network_quality_estimator_unittest.cc
index 6610f95..eaa6431 100644
--- a/net/nqe/network_quality_estimator_unittest.cc
+++ b/net/nqe/network_quality_estimator_unittest.cc
@@ -564,6 +564,7 @@
                                      NETWORK_QUALITY_OBSERVATION_SOURCE_TCP, 1);
   histogram_tester.ExpectBucketCount(
       "NQE.RTT.ObservationSource", NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC, 1);
+  histogram_tester.ExpectTotalCount("NQE.EndToEndRTT.OnECTComputation", 1);
   histogram_tester.ExpectTotalCount("NQE.RTT.ObservationSource", 2);
 }
 
@@ -1651,6 +1652,7 @@
 }
 
 TEST_F(NetworkQualityEstimatorTest, TestRttThroughputObservers) {
+  base::HistogramTester histogram_tester;
   TestRTTObserver rtt_observer;
   TestThroughputObserver throughput_observer;
 
@@ -1751,6 +1753,12 @@
   EXPECT_TRUE(
       estimator.GetRecentRTT(nqe::internal::OBSERVATION_CATEGORY_TRANSPORT,
                              base::TimeTicks(), &rtt, nullptr));
+
+  const std::vector<base::Bucket> end_to_end_rtt_samples =
+      histogram_tester.GetAllSamples("NQE.EndToEndRTT.OnECTComputation");
+  EXPECT_FALSE(end_to_end_rtt_samples.empty());
+  for (const auto& bucket : end_to_end_rtt_samples)
+    EXPECT_EQ(quic_rtt.InMilliseconds(), bucket.min);
 }
 
 TEST_F(NetworkQualityEstimatorTest, TestGlobalSocketWatcherThrottle) {
diff --git a/net/nqe/network_quality_observation.cc b/net/nqe/network_quality_observation.cc
index 35de19b..f568ddf9 100644
--- a/net/nqe/network_quality_observation.cc
+++ b/net/nqe/network_quality_observation.cc
@@ -36,24 +36,34 @@
 
 Observation::~Observation() = default;
 
-ObservationCategory Observation::GetObservationCategory() const {
+std::vector<ObservationCategory> Observation::GetObservationCategories() const {
+  std::vector<ObservationCategory> observation_categories;
   switch (source_) {
     case NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP:
     case NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE:
     case NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_HTTP_FROM_PLATFORM:
     case DEPRECATED_NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_EXTERNAL_ESTIMATE:
-      return ObservationCategory::OBSERVATION_CATEGORY_HTTP;
+      observation_categories.push_back(
+          ObservationCategory::OBSERVATION_CATEGORY_HTTP);
+      return observation_categories;
     case NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE:
     case NETWORK_QUALITY_OBSERVATION_SOURCE_DEFAULT_TRANSPORT_FROM_PLATFORM:
     case NETWORK_QUALITY_OBSERVATION_SOURCE_TCP:
+      observation_categories.push_back(
+          ObservationCategory::OBSERVATION_CATEGORY_TRANSPORT);
+      return observation_categories;
     case NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC:
-      return ObservationCategory::OBSERVATION_CATEGORY_TRANSPORT;
+      observation_categories.push_back(
+          ObservationCategory::OBSERVATION_CATEGORY_TRANSPORT);
+      observation_categories.push_back(
+          ObservationCategory::OBSERVATION_CATEGORY_END_TO_END);
+      return observation_categories;
     case NETWORK_QUALITY_OBSERVATION_SOURCE_MAX:
       NOTREACHED();
-      return ObservationCategory::OBSERVATION_CATEGORY_HTTP;
+      return observation_categories;
   }
   NOTREACHED();
-  return ObservationCategory::OBSERVATION_CATEGORY_HTTP;
+  return observation_categories;
 }
 
 }  // namespace internal
diff --git a/net/nqe/network_quality_observation.h b/net/nqe/network_quality_observation.h
index cbe7b56..31c8eac0 100644
--- a/net/nqe/network_quality_observation.h
+++ b/net/nqe/network_quality_observation.h
@@ -7,6 +7,8 @@
 
 #include <stdint.h>
 
+#include <vector>
+
 #include "base/optional.h"
 #include "base/time/time.h"
 #include "net/base/net_export.h"
@@ -56,8 +58,8 @@
   // A unique identifier for the remote host which was used for the measurement.
   base::Optional<IPHash> host() const { return host_; }
 
-  // Returns the observation category of this observation.
-  ObservationCategory GetObservationCategory() const;
+  // Returns the observation categories to which this observation belongs to.
+  std::vector<ObservationCategory> GetObservationCategories() const;
 
  private:
   int32_t value_;
diff --git a/net/nqe/network_quality_observation_source.h b/net/nqe/network_quality_observation_source.h
index c13a1e6..6cd6095 100644
--- a/net/nqe/network_quality_observation_source.h
+++ b/net/nqe/network_quality_observation_source.h
@@ -60,9 +60,20 @@
 // Different categories to which an observation source can belong to. Each
 // observation source belongs to exactly one category.
 enum ObservationCategory {
+  // HTTP RTT observations measure the RTT from this device taken at the
+  // HTTP layer. If a HTTP-layer proxy is in use, then the RTT observations
+  // would measure the RTT from this device to the proxy.
   OBSERVATION_CATEGORY_HTTP = 0,
+  // Transport RTT observations measure the RTT from this device taken at the
+  // transport layer. If a transport-layer proxy (e.g., TCP proxy) is in use,
+  // then the RTT observations would measure the RTT from this device to the
+  // proxy.
   OBSERVATION_CATEGORY_TRANSPORT = 1,
-  OBSERVATION_CATEGORY_COUNT = 2
+  // End to end RTT observations measure the RTT from this device to the remote
+  // web server. Currently, this only includes RTT observations taken from the
+  // QUIC connections.
+  OBSERVATION_CATEGORY_END_TO_END = 2,
+  OBSERVATION_CATEGORY_COUNT = 3
 };
 
 }  // namespace internal
diff --git a/sandbox/win/src/crosscall_client.h b/sandbox/win/src/crosscall_client.h
index c05e497..7bcfb3c 100644
--- a/sandbox/win/src/crosscall_client.h
+++ b/sandbox/win/src/crosscall_client.h
@@ -8,6 +8,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "base/compiler_specific.h"
 #include "sandbox/win/src/crosscall_params.h"
 #include "sandbox/win/src/sandbox.h"
 
@@ -150,7 +151,7 @@
   // We provide our not very optimized version of wcslen(), since we don't
   // want to risk having the linker use the version in the CRT since the CRT
   // might not be present when we do an early IPC call.
-  static size_t __cdecl StringLength(const wchar_t* wcs) {
+  static size_t CDECL StringLength(const wchar_t* wcs) {
     const wchar_t* eos = wcs;
     while (*eos++)
       ;
diff --git a/services/ui/ws2/BUILD.gn b/services/ui/ws2/BUILD.gn
index 61d4f2c1..a5db8e3 100644
--- a/services/ui/ws2/BUILD.gn
+++ b/services/ui/ws2/BUILD.gn
@@ -48,6 +48,7 @@
     "//services/ui/common:mus_common",
     "//services/ui/public/interfaces",
     "//ui/aura",
+    "//ui/wm",
   ]
 
   defines = [ "IS_WINDOW_SERVICE_IMPL" ]
diff --git a/services/ui/ws2/window_service_client.cc b/services/ui/ws2/window_service_client.cc
index 1b4dba9..04b98db 100644
--- a/services/ui/ws2/window_service_client.cc
+++ b/services/ui/ws2/window_service_client.cc
@@ -28,6 +28,7 @@
 #include "ui/compositor/layer_type.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
+#include "ui/wm/core/capture_controller.h"
 
 namespace ui {
 namespace ws2 {
@@ -430,6 +431,58 @@
   return true;
 }
 
+bool WindowServiceClient::SetCaptureImpl(const ClientWindowId& window_id) {
+  DVLOG(3) << "SetCapture window_id=" << window_id;
+  aura::Window* window = GetWindowByClientId(window_id);
+  if (!window) {
+    DVLOG(1) << "SetCapture failed (no window)";
+    return false;
+  }
+
+  if ((!IsClientCreatedWindow(window) && !IsClientRootWindow(window)) ||
+      !window->IsVisible() || !window->GetRootWindow()) {
+    DVLOG(1) << "SetCapture failed (access denied or invalid window)";
+    return false;
+  }
+
+  wm::CaptureController* capture_controller = wm::CaptureController::Get();
+  DCHECK(capture_controller);
+
+  if (capture_controller->GetCaptureWindow() == window)
+    return true;
+
+  capture_controller->SetCapture(window);
+  return capture_controller->GetCaptureWindow() == window;
+}
+
+bool WindowServiceClient::ReleaseCaptureImpl(const ClientWindowId& window_id) {
+  DVLOG(3) << "ReleaseCapture window_id=" << window_id;
+  aura::Window* window = GetWindowByClientId(window_id);
+  if (!window) {
+    DVLOG(1) << "ReleaseCapture failed (no window)";
+    return false;
+  }
+
+  if (!IsClientCreatedWindow(window) && !IsClientRootWindow(window)) {
+    DVLOG(1) << "ReleaseCapture failed (access denied)";
+    return false;
+  }
+
+  wm::CaptureController* capture_controller = wm::CaptureController::Get();
+  DCHECK(capture_controller);
+
+  if (!capture_controller->GetCaptureWindow())
+    return true;  // Capture window is already null.
+
+  if (capture_controller->GetCaptureWindow() != window) {
+    DVLOG(1) << "ReleaseCapture failed (supplied window does not have capture)";
+    return false;
+  }
+
+  capture_controller->ReleaseCapture(window);
+  return capture_controller->GetCaptureWindow() != window;
+}
+
 bool WindowServiceClient::AddWindowImpl(const ClientWindowId& parent_id,
                                         const ClientWindowId& child_id) {
   aura::Window* parent = GetWindowByClientId(parent_id);
@@ -751,12 +804,16 @@
       change_id, DeleteWindowImpl(MakeClientWindowId(transport_window_id)));
 }
 
-void WindowServiceClient::SetCapture(uint32_t change_id, Id window_id) {
-  NOTIMPLEMENTED();
+void WindowServiceClient::SetCapture(uint32_t change_id,
+                                     Id transport_window_id) {
+  window_tree_client_->OnChangeCompleted(
+      change_id, SetCaptureImpl(MakeClientWindowId(transport_window_id)));
 }
 
-void WindowServiceClient::ReleaseCapture(uint32_t change_id, Id window_id) {
-  NOTIMPLEMENTED();
+void WindowServiceClient::ReleaseCapture(uint32_t change_id,
+                                         Id transport_window_id) {
+  window_tree_client_->OnChangeCompleted(
+      change_id, ReleaseCaptureImpl(MakeClientWindowId(transport_window_id)));
 }
 
 void WindowServiceClient::StartPointerWatcher(bool want_moves) {
diff --git a/services/ui/ws2/window_service_client.h b/services/ui/ws2/window_service_client.h
index 2d4b268..015dfa4 100644
--- a/services/ui/ws2/window_service_client.h
+++ b/services/ui/ws2/window_service_client.h
@@ -186,6 +186,8 @@
       const ClientWindowId& client_window_id,
       const std::map<std::string, std::vector<uint8_t>>& properties);
   bool DeleteWindowImpl(const ClientWindowId& window_id);
+  bool SetCaptureImpl(const ClientWindowId& window_id);
+  bool ReleaseCaptureImpl(const ClientWindowId& window_id);
   bool AddWindowImpl(const ClientWindowId& parent_id,
                      const ClientWindowId& child_id);
   bool RemoveWindowFromParentImpl(const ClientWindowId& client_window_id);
@@ -225,8 +227,8 @@
       const base::flat_map<std::string, std::vector<uint8_t>>& properties)
       override;
   void DeleteWindow(uint32_t change_id, Id transport_window_id) override;
-  void SetCapture(uint32_t change_id, Id window_id) override;
-  void ReleaseCapture(uint32_t change_id, Id window_id) override;
+  void SetCapture(uint32_t change_id, Id transport_window_id) override;
+  void ReleaseCapture(uint32_t change_id, Id transport_window_id) override;
   void StartPointerWatcher(bool want_moves) override;
   void StopPointerWatcher() override;
   void SetWindowBounds(
diff --git a/services/ui/ws2/window_service_client_test_helper.cc b/services/ui/ws2/window_service_client_test_helper.cc
index 0b4ed09..f809bfa 100644
--- a/services/ui/ws2/window_service_client_test_helper.cc
+++ b/services/ui/ws2/window_service_client_test_helper.cc
@@ -43,6 +43,18 @@
       window_service_client_->MakeClientWindowId(transport_window_id));
 }
 
+bool WindowServiceClientTestHelper::SetCapture(aura::Window* window) {
+  return window_service_client_->SetCaptureImpl(
+      window_service_client_->MakeClientWindowId(
+          window_service_client_->TransportIdForWindow(window)));
+}
+
+bool WindowServiceClientTestHelper::ReleaseCapture(aura::Window* window) {
+  return window_service_client_->ReleaseCaptureImpl(
+      window_service_client_->MakeClientWindowId(
+          window_service_client_->TransportIdForWindow(window)));
+}
+
 void WindowServiceClientTestHelper::SetWindowBounds(aura::Window* window,
                                                     const gfx::Rect& bounds,
                                                     uint32_t change_id) {
diff --git a/services/ui/ws2/window_service_client_test_helper.h b/services/ui/ws2/window_service_client_test_helper.h
index b7f0790..9382cef 100644
--- a/services/ui/ws2/window_service_client_test_helper.h
+++ b/services/ui/ws2/window_service_client_test_helper.h
@@ -52,6 +52,8 @@
   aura::Window* NewTopLevelWindow(
       Id transport_window_id,
       base::flat_map<std::string, std::vector<uint8_t>> properties = {});
+  bool SetCapture(aura::Window* window);
+  bool ReleaseCapture(aura::Window* window);
   void SetWindowBounds(aura::Window* window,
                        const gfx::Rect& bounds,
                        uint32_t change_id = 1);
diff --git a/services/ui/ws2/window_service_client_unittest.cc b/services/ui/ws2/window_service_client_unittest.cc
index 084f2ef3..e1a42d8 100644
--- a/services/ui/ws2/window_service_client_unittest.cc
+++ b/services/ui/ws2/window_service_client_unittest.cc
@@ -502,6 +502,28 @@
   }
 }
 
+TEST(WindowServiceClientTest, Capture) {
+  WindowServiceTestHelper helper;
+  aura::Window* window = helper.helper()->NewWindow(1);
+
+  // Setting capture on |window| should fail as it's not visible.
+  EXPECT_FALSE(helper.helper()->SetCapture(window));
+
+  aura::Window* top_level = helper.helper()->NewTopLevelWindow(2);
+  ASSERT_TRUE(top_level);
+  EXPECT_FALSE(helper.helper()->SetCapture(top_level));
+  top_level->Show();
+  EXPECT_TRUE(helper.helper()->SetCapture(top_level));
+
+  EXPECT_FALSE(helper.helper()->ReleaseCapture(window));
+  EXPECT_TRUE(helper.helper()->ReleaseCapture(top_level));
+
+  top_level->AddChild(window);
+  window->Show();
+  EXPECT_TRUE(helper.helper()->SetCapture(window));
+  EXPECT_TRUE(helper.helper()->ReleaseCapture(window));
+}
+
 }  // namespace
 }  // namespace ws2
 }  // namespace ui
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index b8095a51..9e1dc2c2 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -13348,58 +13348,6 @@
           "--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": "8086:5912-24.20.100.6025",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 2
-        }
-      },
-      {
-        "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": "8086:5912-24.20.100.6025",
-              "os": "Windows-10",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 2
-        }
-      },
-      {
-        "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",
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json
index 9843e12..3e21384 100644
--- a/testing/buildbot/chromium.perf.json
+++ b/testing/buildbot/chromium.perf.json
@@ -1995,7 +1995,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_filters_cases",
@@ -2024,7 +2024,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -2055,7 +2055,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
@@ -2084,7 +2084,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -2175,7 +2175,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
@@ -2204,7 +2204,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -2235,7 +2235,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
@@ -2264,7 +2264,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -2295,7 +2295,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.image_decoding_cases",
@@ -2324,7 +2324,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -2475,7 +2475,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.maps",
@@ -2504,7 +2504,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -2715,7 +2715,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.top_25_smooth",
@@ -2744,7 +2744,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -2775,7 +2775,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_ad_cases",
@@ -2804,7 +2804,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -2835,7 +2835,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_animation_cases",
@@ -2864,7 +2864,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -2895,7 +2895,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_canvas_cases",
@@ -2924,7 +2924,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -2955,7 +2955,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_filters_cases",
@@ -2984,7 +2984,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -3015,7 +3015,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_image_decode_cases",
@@ -3044,7 +3044,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -3075,7 +3075,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_path_rendering_cases",
@@ -3104,7 +3104,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -3195,7 +3195,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_scrolling_cases",
@@ -3224,7 +3224,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -3255,7 +3255,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_texture_upload_cases",
@@ -3284,7 +3284,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -3315,7 +3315,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_ad_cases",
@@ -3344,7 +3344,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -3375,7 +3375,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_cases",
@@ -3404,7 +3404,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -6748,7 +6748,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_filters_cases",
@@ -6777,7 +6777,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -6808,7 +6808,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
@@ -6837,7 +6837,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -6928,7 +6928,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
@@ -6957,7 +6957,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -6988,7 +6988,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
@@ -7017,7 +7017,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -7048,7 +7048,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.image_decoding_cases",
@@ -7077,7 +7077,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -7228,7 +7228,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.maps",
@@ -7257,7 +7257,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -7468,7 +7468,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.top_25_smooth",
@@ -7497,7 +7497,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -7528,7 +7528,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_ad_cases",
@@ -7557,7 +7557,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -7588,7 +7588,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_animation_cases",
@@ -7617,7 +7617,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -7648,7 +7648,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_canvas_cases",
@@ -7677,7 +7677,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -7708,7 +7708,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_filters_cases",
@@ -7737,7 +7737,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -7768,7 +7768,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_image_decode_cases",
@@ -7797,7 +7797,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -7828,7 +7828,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_path_rendering_cases",
@@ -7857,7 +7857,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -7948,7 +7948,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_scrolling_cases",
@@ -7977,7 +7977,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -8008,7 +8008,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_texture_upload_cases",
@@ -8037,7 +8037,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -8068,7 +8068,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_ad_cases",
@@ -8097,7 +8097,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -8128,7 +8128,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_cases",
@@ -8157,7 +8157,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -10431,7 +10431,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -10461,7 +10461,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -10521,7 +10521,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -10551,7 +10551,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -10581,7 +10581,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -10671,7 +10671,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -10791,7 +10791,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -10821,7 +10821,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -10851,7 +10851,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -10881,7 +10881,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -10911,7 +10911,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -10941,7 +10941,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -10971,7 +10971,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -11031,7 +11031,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -11061,7 +11061,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -11091,7 +11091,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -11121,7 +11121,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -12715,7 +12715,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -12745,7 +12745,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -12805,7 +12805,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -12835,7 +12835,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -12865,7 +12865,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -12955,7 +12955,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -13075,7 +13075,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -13105,7 +13105,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -13135,7 +13135,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -13165,7 +13165,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -13195,7 +13195,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -13225,7 +13225,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -13255,7 +13255,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -13315,7 +13315,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -13345,7 +13345,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -13375,7 +13375,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -13405,7 +13405,7 @@
           "-v",
           "--upload-results",
           "--browser=android-webview",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk"
         ],
         "isolate_name": "telemetry_perf_webview_tests",
@@ -15987,7 +15987,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_filters_cases",
@@ -16016,7 +16016,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -16047,7 +16047,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
@@ -16076,7 +16076,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -16167,7 +16167,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
@@ -16196,7 +16196,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -16227,7 +16227,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
@@ -16256,7 +16256,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -16287,7 +16287,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.image_decoding_cases",
@@ -16316,7 +16316,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -16467,7 +16467,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.maps",
@@ -16496,7 +16496,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -16707,7 +16707,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.top_25_smooth",
@@ -16736,7 +16736,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -16767,7 +16767,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_ad_cases",
@@ -16796,7 +16796,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -16827,7 +16827,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_animation_cases",
@@ -16856,7 +16856,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -16887,7 +16887,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_canvas_cases",
@@ -16916,7 +16916,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -16947,7 +16947,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_filters_cases",
@@ -16976,7 +16976,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -17007,7 +17007,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_image_decode_cases",
@@ -17036,7 +17036,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -17067,7 +17067,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_path_rendering_cases",
@@ -17096,7 +17096,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -17187,7 +17187,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_scrolling_cases",
@@ -17216,7 +17216,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -17247,7 +17247,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_texture_upload_cases",
@@ -17276,7 +17276,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -17307,7 +17307,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_ad_cases",
@@ -17336,7 +17336,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -17367,7 +17367,7 @@
           "-v",
           "--upload-results",
           "--browser=android-chromium",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_cases",
@@ -17396,7 +17396,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -20816,7 +20816,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
@@ -20846,7 +20846,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -20878,7 +20878,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
@@ -20908,7 +20908,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -20940,7 +20940,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
@@ -20970,7 +20970,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21002,7 +21002,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.image_decoding_cases",
@@ -21032,7 +21032,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21064,7 +21064,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.key_desktop_move_cases",
@@ -21094,7 +21094,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21126,7 +21126,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.maps",
@@ -21156,7 +21156,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21188,7 +21188,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.top_25_smooth",
@@ -21218,7 +21218,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21250,7 +21250,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_ad_cases",
@@ -21280,7 +21280,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21312,7 +21312,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_animation_cases",
@@ -21342,7 +21342,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21374,7 +21374,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_canvas_cases",
@@ -21404,7 +21404,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21436,7 +21436,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_filters_cases",
@@ -21466,7 +21466,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21498,7 +21498,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_image_decode_cases",
@@ -21528,7 +21528,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21560,7 +21560,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_path_rendering_cases",
@@ -21590,7 +21590,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21622,7 +21622,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_scrolling_cases",
@@ -21652,7 +21652,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21684,7 +21684,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_texture_upload_cases",
@@ -21714,7 +21714,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21746,7 +21746,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_ad_cases",
@@ -21776,7 +21776,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -21808,7 +21808,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_cases",
@@ -21838,7 +21838,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -24858,7 +24858,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
@@ -24888,7 +24888,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -24920,7 +24920,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
@@ -24950,7 +24950,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -24982,7 +24982,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
@@ -25012,7 +25012,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25044,7 +25044,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.image_decoding_cases",
@@ -25074,7 +25074,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25106,7 +25106,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.key_desktop_move_cases",
@@ -25136,7 +25136,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25168,7 +25168,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.maps",
@@ -25198,7 +25198,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25230,7 +25230,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.top_25_smooth",
@@ -25260,7 +25260,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25292,7 +25292,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_ad_cases",
@@ -25322,7 +25322,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25354,7 +25354,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_animation_cases",
@@ -25384,7 +25384,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25416,7 +25416,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_canvas_cases",
@@ -25446,7 +25446,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25478,7 +25478,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_filters_cases",
@@ -25508,7 +25508,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25540,7 +25540,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_image_decode_cases",
@@ -25570,7 +25570,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25602,7 +25602,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_path_rendering_cases",
@@ -25632,7 +25632,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25664,7 +25664,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_scrolling_cases",
@@ -25694,7 +25694,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25726,7 +25726,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_texture_upload_cases",
@@ -25756,7 +25756,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25788,7 +25788,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_ad_cases",
@@ -25818,7 +25818,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -25850,7 +25850,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_cases",
@@ -25880,7 +25880,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -28884,7 +28884,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
@@ -28914,7 +28914,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -28946,7 +28946,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
@@ -28976,7 +28976,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29008,7 +29008,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
@@ -29038,7 +29038,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29070,7 +29070,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.image_decoding_cases",
@@ -29100,7 +29100,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29132,7 +29132,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.key_desktop_move_cases",
@@ -29162,7 +29162,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29194,7 +29194,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.maps",
@@ -29224,7 +29224,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29256,7 +29256,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.top_25_smooth",
@@ -29286,7 +29286,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29318,7 +29318,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_ad_cases",
@@ -29348,7 +29348,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29380,7 +29380,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_animation_cases",
@@ -29410,7 +29410,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29442,7 +29442,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_canvas_cases",
@@ -29472,7 +29472,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29504,7 +29504,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_filters_cases",
@@ -29534,7 +29534,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29566,7 +29566,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_image_decode_cases",
@@ -29596,7 +29596,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29628,7 +29628,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_path_rendering_cases",
@@ -29658,7 +29658,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29690,7 +29690,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_scrolling_cases",
@@ -29720,7 +29720,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29752,7 +29752,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_texture_upload_cases",
@@ -29782,7 +29782,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29814,7 +29814,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_ad_cases",
@@ -29844,7 +29844,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -29876,7 +29876,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_cases",
@@ -29906,7 +29906,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -32698,7 +32698,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_filters_cases",
@@ -32728,7 +32728,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -32760,7 +32760,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
@@ -32790,7 +32790,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -32822,7 +32822,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
@@ -32852,7 +32852,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -32884,7 +32884,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
@@ -32914,7 +32914,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -32946,7 +32946,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.image_decoding_cases",
@@ -32976,7 +32976,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33008,7 +33008,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.key_desktop_move_cases",
@@ -33038,7 +33038,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33070,7 +33070,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.maps",
@@ -33100,7 +33100,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33132,7 +33132,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.top_25_smooth",
@@ -33162,7 +33162,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33194,7 +33194,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_ad_cases",
@@ -33224,7 +33224,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33256,7 +33256,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_animation_cases",
@@ -33286,7 +33286,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33318,7 +33318,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_canvas_cases",
@@ -33348,7 +33348,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33380,7 +33380,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_filters_cases",
@@ -33410,7 +33410,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33442,7 +33442,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_image_decode_cases",
@@ -33472,7 +33472,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33504,7 +33504,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_path_rendering_cases",
@@ -33534,7 +33534,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33566,7 +33566,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_scrolling_cases",
@@ -33596,7 +33596,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33628,7 +33628,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_texture_upload_cases",
@@ -33658,7 +33658,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33690,7 +33690,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_ad_cases",
@@ -33720,7 +33720,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -33752,7 +33752,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_cases",
@@ -33782,7 +33782,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -36616,7 +36616,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_filters_cases",
@@ -36646,7 +36646,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -36678,7 +36678,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
@@ -36708,7 +36708,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -36740,7 +36740,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
@@ -36770,7 +36770,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -36802,7 +36802,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
@@ -36832,7 +36832,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -36864,7 +36864,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.image_decoding_cases",
@@ -36894,7 +36894,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -36926,7 +36926,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.key_desktop_move_cases",
@@ -36956,7 +36956,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -36988,7 +36988,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.maps",
@@ -37018,7 +37018,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -37050,7 +37050,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.top_25_smooth",
@@ -37080,7 +37080,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -37112,7 +37112,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_ad_cases",
@@ -37142,7 +37142,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -37174,7 +37174,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_animation_cases",
@@ -37204,7 +37204,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -37236,7 +37236,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_canvas_cases",
@@ -37266,7 +37266,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -37298,7 +37298,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_filters_cases",
@@ -37328,7 +37328,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -37360,7 +37360,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_image_decode_cases",
@@ -37390,7 +37390,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -37422,7 +37422,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_path_rendering_cases",
@@ -37452,7 +37452,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -37484,7 +37484,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_scrolling_cases",
@@ -37514,7 +37514,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -37546,7 +37546,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_texture_upload_cases",
@@ -37576,7 +37576,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -37608,7 +37608,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_ad_cases",
@@ -37638,7 +37638,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -37670,7 +37670,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_cases",
@@ -37700,7 +37700,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -40600,7 +40600,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_filters_cases",
@@ -40630,7 +40630,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -40662,7 +40662,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
@@ -40692,7 +40692,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -40724,7 +40724,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
@@ -40754,7 +40754,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -40786,7 +40786,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
@@ -40816,7 +40816,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -40848,7 +40848,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.image_decoding_cases",
@@ -40878,7 +40878,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -40910,7 +40910,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.key_desktop_move_cases",
@@ -40940,7 +40940,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -40972,7 +40972,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.maps",
@@ -41002,7 +41002,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -41034,7 +41034,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.top_25_smooth",
@@ -41064,7 +41064,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -41096,7 +41096,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_ad_cases",
@@ -41126,7 +41126,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -41158,7 +41158,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_animation_cases",
@@ -41188,7 +41188,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -41220,7 +41220,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_canvas_cases",
@@ -41250,7 +41250,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -41282,7 +41282,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_filters_cases",
@@ -41312,7 +41312,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -41344,7 +41344,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_image_decode_cases",
@@ -41374,7 +41374,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -41406,7 +41406,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_path_rendering_cases",
@@ -41436,7 +41436,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -41468,7 +41468,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_scrolling_cases",
@@ -41498,7 +41498,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -41530,7 +41530,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_texture_upload_cases",
@@ -41560,7 +41560,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -41592,7 +41592,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_ad_cases",
@@ -41622,7 +41622,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -41654,7 +41654,7 @@
           "-v",
           "--upload-results",
           "--browser=release_x64",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_cases",
@@ -41684,7 +41684,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -44563,7 +44563,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_filters_cases",
@@ -44593,7 +44593,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -44625,7 +44625,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
@@ -44655,7 +44655,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -44687,7 +44687,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
@@ -44717,7 +44717,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -44749,7 +44749,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
@@ -44779,7 +44779,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -44811,7 +44811,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.image_decoding_cases",
@@ -44841,7 +44841,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -44873,7 +44873,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.key_desktop_move_cases",
@@ -44903,7 +44903,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -44935,7 +44935,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.maps",
@@ -44965,7 +44965,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -44997,7 +44997,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.top_25_smooth",
@@ -45027,7 +45027,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -45059,7 +45059,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_ad_cases",
@@ -45089,7 +45089,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -45121,7 +45121,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_animation_cases",
@@ -45151,7 +45151,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -45183,7 +45183,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_canvas_cases",
@@ -45213,7 +45213,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -45245,7 +45245,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_filters_cases",
@@ -45275,7 +45275,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -45307,7 +45307,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_image_decode_cases",
@@ -45337,7 +45337,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -45369,7 +45369,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_path_rendering_cases",
@@ -45399,7 +45399,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -45431,7 +45431,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_scrolling_cases",
@@ -45461,7 +45461,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -45493,7 +45493,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_texture_upload_cases",
@@ -45523,7 +45523,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -45555,7 +45555,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_ad_cases",
@@ -45585,7 +45585,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
@@ -45617,7 +45617,7 @@
           "-v",
           "--upload-results",
           "--browser=release",
-          "--output-format=chartjson"
+          "--output-format=histograms"
         ],
         "isolate_name": "telemetry_perf_tests",
         "name": "smoothness.tough_webgl_cases",
@@ -45647,7 +45647,7 @@
           "-v",
           "--upload-results",
           "--browser=reference",
-          "--output-format=chartjson",
+          "--output-format=histograms",
           "--max-failures=5",
           "--output-trace-tag=_ref"
         ],
diff --git a/testing/scripts/run_performance_tests.py b/testing/scripts/run_performance_tests.py
index 6e05ce389..50e620c8 100755
--- a/testing/scripts/run_performance_tests.py
+++ b/testing/scripts/run_performance_tests.py
@@ -78,6 +78,25 @@
     'system_health.memory_desktop',
     'system_health.memory_mobile',
     'system_health.webview_startup',
+    'smoothness.gpu_rasterization.tough_filters_cases',
+    'smoothness.gpu_rasterization.tough_path_rendering_cases',
+    'smoothness.gpu_rasterization.tough_scrolling_cases',
+    'smoothness.gpu_rasterization_and_decoding.image_decoding_cases',
+    'smoothness.image_decoding_cases',
+    'smoothness.key_desktop_move_cases',
+    'smoothness.maps',
+    'smoothness.oop_rasterization.top_25_smooth',
+    'smoothness.top_25_smooth',
+    'smoothness.tough_ad_cases',
+    'smoothness.tough_animation_cases',
+    'smoothness.tough_canvas_cases',
+    'smoothness.tough_filters_cases',
+    'smoothness.tough_image_decode_cases',
+    'smoothness.tough_path_rendering_cases',
+    'smoothness.tough_scrolling_cases',
+    'smoothness.tough_texture_upload_cases',
+    'smoothness.tough_webgl_ad_cases',
+    'smoothness.tough_webgl_cases',
 ]
 
 def get_sharding_map_path(args):
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 6367ef2d..09b80d4 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -137,7 +137,6 @@
 crbug.com/591099 css2.1/t100801-c544-valgn-03-d-agi.html [ Failure ]
 crbug.com/591099 css2.1/t1202-counter-04-b.html [ Failure ]
 crbug.com/591099 css2.1/t1202-counters-04-b.html [ Failure ]
-crbug.com/591099 css2.1/t1205-c564-list-img-00-b-g.html [ Failure ]
 crbug.com/591099 css3/filters/composited-layer-child-bounds-after-composited-to-sw-shadow-change.html [ Failure ]
 crbug.com/591099 css3/filters/effect-brightness-clamping.html [ Failure ]
 crbug.com/591099 css3/filters/effect-brightness.html [ Failure ]
@@ -147,7 +146,6 @@
 crbug.com/591099 css3/flexbox/bug669714.html [ Failure ]
 crbug.com/591099 css3/flexbox/flex-flow-margins-auto-size.html [ Failure ]
 crbug.com/591099 css3/flexbox/flex-item-contains-strict.html [ Failure ]
-crbug.com/591099 css3/flexbox/flexbox-baseline.html [ Failure ]
 crbug.com/591099 css3/flexbox/flexbox-with-multi-column-property.html [ Failure ]
 crbug.com/591099 css3/flexbox/intrinsic-width-orthogonal-writing-mode.html [ Failure ]
 crbug.com/591099 css3/flexbox/line-wrapping.html [ Failure ]
@@ -271,7 +269,6 @@
 crbug.com/591099 external/wpt/css/css-scroll-anchoring/clipped-scrollers-skipped.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-scroll-anchoring/opt-out.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-scroll-anchoring/position-change-heuristic.html [ Failure ]
-crbug.com/714962 external/wpt/css/css-scroll-anchoring/start-edge-in-block-layout-direction.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-scroll-anchoring/wrapped-text.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-box/shape-outside-box-002.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-box/shape-outside-box-003.html [ Failure ]
@@ -510,9 +507,7 @@
 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/baseline-inline-non-replaced-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/block-flow-direction-vrl-009.xht [ Pass ]
-crbug.com/591099 external/wpt/css/css-writing-modes/block-flow-direction-vrl-026.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/clearance-calculations-vrl-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/clearance-calculations-vrl-004.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/clearance-calculations-vrl-006.xht [ Failure ]
@@ -521,18 +516,16 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-006.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-008.xht [ Failure ]
 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-002.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 ]
-crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-010.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-002.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-012.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/inline-block-alignment-006.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/line-box-direction-vlr-018.xht [ Crash ]
 crbug.com/591099 external/wpt/css/css-writing-modes/line-box-direction-vrl-009.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/margin-collapse-vrl-010.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/mongolian-orientation-002.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/nested-orthogonal-001.html [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/ortho-htb-alongside-vrl-floats-002.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/ortho-htb-alongside-vrl-floats-010.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/ortho-htb-alongside-vrl-floats-006.xht [ Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/ortho-htb-alongside-vrl-floats-014.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001a.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001c.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001e.html [ Failure ]
@@ -549,22 +542,8 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001v.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001w.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001x.html [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/percent-padding-vrl-006.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vlr-001.xht [ Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-007.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-008.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-009.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-011.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-012.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-019.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-020.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-021.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-023.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-htb-in-vrl-024.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-003.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-004.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-007.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-008.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/sizing-orthog-prct-htb-in-vrl-008.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/sizing-orthog-vrl-in-htb-013.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 ]
@@ -771,6 +750,7 @@
 crbug.com/591099 external/wpt/pointerevents/pointerevent_click_during_capture-manual.html [ Crash Timeout ]
 crbug.com/591099 external/wpt/pointerevents/pointerevent_pointerleave_pen-manual.html [ Failure ]
 crbug.com/591099 external/wpt/pointerevents/pointerevent_touch-action-span-test_touch-manual.html [ Failure ]
+crbug.com/591099 external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html [ Crash ]
 crbug.com/591099 external/wpt/quirks/line-height-calculation.html [ Failure ]
 crbug.com/591099 external/wpt/quirks/table-cell-width-calculation.html [ Pass ]
 crbug.com/591099 external/wpt/requestidlecallback/basic.html [ Pass ]
@@ -832,7 +812,6 @@
 crbug.com/591099 fast/backgrounds/background-leakage-transforms.html [ Failure ]
 crbug.com/591099 fast/backgrounds/quirks-mode-line-box-backgrounds.html [ Failure ]
 crbug.com/591099 fast/backgrounds/selection-background-color-of-image-list-style.html [ Failure ]
-crbug.com/591099 fast/backgrounds/selection-background-color-of-list-style.html [ Failure ]
 crbug.com/591099 fast/backgrounds/size/backgroundSize16.html [ Failure ]
 crbug.com/591099 fast/backgrounds/size/contain-and-cover.html [ Failure ]
 crbug.com/591099 fast/block/basic/quirk-percent-height-table-cell.html [ Failure ]
@@ -886,7 +865,6 @@
 crbug.com/591099 fast/css-grid-layout/grid-columns-rows-get-set-multiple.html [ Pass Timeout ]
 crbug.com/591099 fast/css-grid-layout/grid-columns-rows-get-set.html [ Pass Timeout ]
 crbug.com/591099 fast/css-grid-layout/grid-item-column-row-get-set.html [ Pass Timeout ]
-crbug.com/591099 fast/css-grid-layout/grid-self-baseline-01.html [ Failure ]
 crbug.com/591099 fast/css-grid-layout/grid-self-baseline-02-b.html [ Failure ]
 crbug.com/591099 fast/css-grid-layout/grid-self-baseline-02.html [ Failure ]
 crbug.com/591099 fast/css-grid-layout/grid-self-baseline-03.html [ Failure ]
@@ -938,8 +916,6 @@
 crbug.com/714962 fast/css/first-letter-before-hit-test.html [ Failure ]
 crbug.com/714962 fast/css/first-letter-hit-test.html [ Failure ]
 crbug.com/714962 fast/css/first-letter-hover-hit-test.html [ Failure ]
-crbug.com/714962 fast/css/first-line-change-color-direct.html [ Failure ]
-crbug.com/714962 fast/css/first-line-change-color.html [ Failure ]
 crbug.com/714962 fast/css/first-line-hover-001.html [ Failure ]
 crbug.com/591099 fast/css/first-line-text-decoration-inherited-from-parent.html [ Failure ]
 crbug.com/591099 fast/css/first-line-text-decoration.html [ Failure ]
@@ -981,7 +957,6 @@
 crbug.com/591099 fast/deprecated-flexbox/relpos-flex-item-with-percent-height-abspos-descendant.html [ Failure ]
 crbug.com/591099 fast/deprecated-flexbox/repaint-scrollbar.html [ Failure ]
 crbug.com/591099 fast/doctypes/001.html [ Failure ]
-crbug.com/591099 fast/doctypes/002.html [ Failure ]
 crbug.com/591099 fast/doctypes/003.html [ Failure ]
 crbug.com/591099 fast/doctypes/004.html [ Failure ]
 crbug.com/714962 fast/dom/Element/client-rect-list-argument.html [ Failure ]
@@ -1049,7 +1024,6 @@
 crbug.com/591099 fast/forms/textarea/textarea-align.html [ Failure ]
 crbug.com/591099 fast/forms/textarea/textarea-metrics.html [ Pass Timeout ]
 crbug.com/591099 fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer.html [ Pass Timeout ]
-crbug.com/591099 fast/forms/validation-bubble-appearance-rtl-ui.html [ Failure ]
 crbug.com/591099 fast/frames/iframe-with-frameborder.html [ Failure ]
 crbug.com/591099 fast/gradients/list-item-gradient.html [ Failure ]
 crbug.com/591099 fast/gradients/unprefixed-list-item-gradient.html [ Failure ]
@@ -1061,10 +1035,6 @@
 crbug.com/714962 fast/inline/continuation-outlines-with-layers-2.html [ Failure ]
 crbug.com/591099 fast/inline/continuation-outlines-with-layers.html [ Failure ]
 crbug.com/591099 fast/inline/continuation-outlines.html [ Failure ]
-crbug.com/591099 fast/inline/inline-box-background-long-image.html [ Failure ]
-crbug.com/591099 fast/inline/inline-box-background-repeat-x.html [ Failure ]
-crbug.com/591099 fast/inline/inline-box-background-repeat-y.html [ Failure ]
-crbug.com/591099 fast/inline/inline-box-background.html [ Failure ]
 crbug.com/591099 fast/inline/inline-focus-ring-under-absolute-enclosing-relative-div.html [ Failure ]
 crbug.com/591099 fast/inline/inline-offsetLeft-relpos.html [ Failure ]
 crbug.com/591099 fast/inline/inline-with-empty-inline-children.html [ Failure ]
@@ -1083,6 +1053,7 @@
 crbug.com/591099 fast/lists/003.html [ Failure ]
 crbug.com/591099 fast/lists/004.html [ Failure ]
 crbug.com/591099 fast/lists/007-vertical.html [ Failure ]
+crbug.com/591099 fast/lists/009-vertical.html [ Failure ]
 crbug.com/591099 fast/lists/calc-width-with-space.html [ Failure ]
 crbug.com/591099 fast/lists/drag-into-marker.html [ Failure ]
 crbug.com/591099 fast/lists/inline-before-content-after-list-marker.html [ Failure ]
@@ -1108,15 +1079,9 @@
 crbug.com/824918 fast/multicol/vertical-lr/caret-range-anonymous-block.html [ Failure ]
 crbug.com/824918 fast/multicol/vertical-rl/caret-range-anonymous-block-rtl.html [ Failure ]
 crbug.com/824918 fast/multicol/vertical-rl/caret-range-anonymous-block.html [ Failure ]
-crbug.com/824918 fast/multicol/vertical-rl/column-break-with-balancing.html [ Failure ]
-crbug.com/824918 fast/multicol/vertical-rl/column-count-with-rules.html [ Failure ]
-crbug.com/824918 fast/multicol/vertical-rl/float-avoidance.html [ Failure ]
 crbug.com/824918 fast/multicol/vertical-rl/float-big-line.html [ Failure ]
 crbug.com/824918 fast/multicol/vertical-rl/float-break.html [ Failure ]
-crbug.com/824918 fast/multicol/vertical-rl/float-content-break.html [ Failure ]
-crbug.com/824918 fast/multicol/vertical-rl/float-edge.html [ Failure ]
 crbug.com/824918 fast/multicol/vertical-rl/float-paginate.html [ Failure ]
-crbug.com/824918 fast/multicol/vertical-rl/unsplittable-inline-block.html [ Failure ]
 crbug.com/591099 fast/overflow/image-selection-highlight.html [ Failure ]
 crbug.com/714962 fast/overflow/line-clamp-hides-trailing-anchor.html [ Failure ]
 crbug.com/591099 fast/overflow/line-clamp.html [ Failure ]
@@ -1257,6 +1222,7 @@
 crbug.com/591099 fast/table/border-collapsing/004-vertical.html [ Failure ]
 crbug.com/591099 fast/table/border-collapsing/border-collapsing-head-foot-vertical.html [ Failure ]
 crbug.com/591099 fast/table/border-collapsing/composited-cell-collapsed-border.html [ Failure ]
+crbug.com/591099 fast/table/click-near-anonymous-table.html [ Crash ]
 crbug.com/591099 fast/table/column-in-inline.html [ Failure ]
 crbug.com/591099 fast/table/dynamic-descendant-percentage-height.html [ Failure ]
 crbug.com/591099 fast/table/empty-table-percent-height.html [ Failure ]
@@ -1266,13 +1232,11 @@
 crbug.com/714962 fast/table/hittest-tablecell-right-edge.html [ Failure ]
 crbug.com/714962 fast/table/hittest-tablecell-with-borders-bottom-edge.html [ Failure ]
 crbug.com/714962 fast/table/hittest-tablecell-with-borders-right-edge.html [ Failure ]
-crbug.com/591099 fast/table/inline-table-margin-baseline.html [ Failure ]
 crbug.com/591099 fast/table/large-shrink-wrapped-width.html [ Failure ]
 crbug.com/591099 fast/table/percent-height-overflow-auto-content-in-cell.html [ Failure ]
 crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure Pass ]
 crbug.com/591099 fast/table/percent-height-replaced-content-in-cell.html [ Failure ]
 crbug.com/591099 fast/table/percent-widths-stretch-vertical.html [ Failure ]
-crbug.com/591099 fast/table/split-table-section-before-anonymous-block-2.html [ Failure ]
 crbug.com/591099 fast/table/table-display-types-vertical.html [ Failure ]
 crbug.com/591099 fast/table/unbreakable-images-quirk.html [ Failure ]
 crbug.com/591099 fast/table/vertical-align-baseline-readjust.html [ Failure ]
@@ -1383,8 +1347,6 @@
 crbug.com/591099 fast/text/place-rtl-ellipsis-in-inline-blocks.html [ Failure ]
 crbug.com/714962 fast/text/selection/flexbox-selection-nested.html [ Failure Pass ]
 crbug.com/591099 fast/text/selection/flexbox-selection.html [ Failure ]
-crbug.com/591099 fast/text/selection/justified-selection-at-edge.html [ Failure ]
-crbug.com/591099 fast/text/selection/khmer-selection.html [ Failure ]
 crbug.com/714962 fast/text/selection/pre-wrap-overflow-selection.html [ Failure ]
 crbug.com/591099 fast/text/selection/selection-hard-linebreak.html [ Failure ]
 crbug.com/591099 fast/text/selection/selection-rect-rounding.html [ Failure Pass ]
@@ -1417,7 +1379,6 @@
 crbug.com/591099 fast/writing-mode/percentage-margins-absolute-replaced.html [ Failure ]
 crbug.com/591099 fast/writing-mode/percentage-margins-absolute.html [ Failure ]
 crbug.com/591099 fast/writing-mode/table-percent-width-quirk.html [ Failure ]
-crbug.com/591099 fast/writing-mode/table-vertical-child-width.html [ Failure ]
 crbug.com/591099 fast/writing-mode/text-combine-compress.html [ Failure ]
 crbug.com/591099 fast/writing-mode/text-combine-justify.html [ Failure ]
 crbug.com/591099 fast/writing-mode/text-combine-line-break.html [ Failure ]
@@ -1676,7 +1637,6 @@
 crbug.com/591099 paint/invalidation/scroll/fixed-with-border-under-composited-absolute-scrolled.html [ Crash ]
 crbug.com/591099 paint/invalidation/scroll/invalidate-after-composited-scroll-of-window.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/line-in-scrolled-clipped-block.html [ Failure ]
-crbug.com/591099 paint/invalidation/scroll/overflow-scroll-delete.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/invalidation-rect-includes-newline-for-rtl.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-lr.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-rl.html [ Failure ]
@@ -1832,7 +1792,6 @@
 crbug.com/591099 tables/mozilla/bugs/bug12008.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug1271.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug131020-2.html [ Failure ]
-crbug.com/591099 tables/mozilla/bugs/bug131020.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug133948.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug137388-2.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug137388-3.html [ Failure ]
@@ -1852,7 +1811,6 @@
 crbug.com/591099 tables/mozilla/bugs/bug55527.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug55694.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug57828-2.html [ Failure ]
-crbug.com/591099 tables/mozilla/bugs/bug57828.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug5798.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug58402-1.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug641-2.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 26151a58..fe547b1 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -336,6 +336,7 @@
 crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/020.html [ Failure ]
 crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/026.html [ Failure ]
 crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/028.html [ Failure ]
+crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/float-in-float-hit-testing.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/assert-when-moving-float.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/assert-when-moving-float-2.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/clear-intruding-floats-when-moving-to-inline-parent-3.html [ Failure Crash Pass ]
@@ -343,7 +344,6 @@
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-at-start-of-clean-lines-that-are-subsequently-dirtied-vertical-rl.html [ Failure ]
 crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/float/floats-and-text-indent.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-at-start-of-clean-lines-that-are-subsequently-dirtied.html [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/float-in-float-hit-testing.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-in-float-painting.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-inserted-into-clean-line.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-list-changed-before-layout-crash.html [ Crash Pass ]
@@ -386,6 +386,8 @@
 crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/margin-collapse/block-inside-inline/012.html [ Failure ]
 crbug.com/635619 [ Mac ] virtual/layout_ng/fast/block/margin-collapse/block-inside-inline/015.html [ Failure ]
 
+
+
 crbug.com/836300 fast/css3-text/css3-text-decoration/text-decoration-skip-ink-links.html [ Pass Failure ]
 
 # ====== LayoutNG ======
@@ -399,16 +401,10 @@
 ### Crash site: PaintController.cpp
 crbug.com/714962 virtual/layout_ng/fast/inline//continuation-outlines-with-layers-2.html [ Crash Failure ]
 
-# Needs rebase line for LayoutInline 0x0
-crbug.com/714962 virtual/layout_ng/fast/inline/002.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/inline/long-wrapped-line.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/inline/percentage-margins.html [ Failure ]
-
 crbug.com/835810 [ Win7 ] http/tests/devtools/startup/dom-storage-open.js [ Pass Timeout ]
 
 ### Image/text failures
 #crbug.com/714962 virtual/layout_ng/fast/inline/001.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/inline/br-text-decoration.html [ Crash Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/continuation-outlines-with-layers-2.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/drawStyledEmptyInlinesWithWS.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/emptyInlinesWithinLists.html [ Failure ]
@@ -416,22 +412,18 @@
 crbug.com/714962 virtual/layout_ng/fast/inline/inline-box-background-repeat-x.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/inline-box-background-repeat-y.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/inline-box-background.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/inline/inline-continuation-borders.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/inline-focus-ring.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/inline-offsetLeft-continuation.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/justify-emphasis-inline-box.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/outline-offset.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/inline/positionedLifetime.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/inline/bpm-inline-ancestors.html [ Failure ]
-
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/inline/br-text-decoration.html [ Failure ]
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/inline/drawStyledEmptyInlines.html [ Failure ]
 ### Image/text failures also on LayoutNG
 crbug.com/714962 virtual/layout_ng/fast/inline/absolute-positioned-inline-in-centred-block.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/continuation-outlines-with-layers.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/continuation-outlines.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/inline/drawStyledEmptyInlines.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/inline-borders-with-bidi-override.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/inline-focus-ring-under-absolute-enclosing-relative-div.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/inline/left-right-center-inline-alignment-in-ltr-and-rtl-blocks.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/nested-text-descendants.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/inline/outline-continuations.html [ Failure ]
@@ -465,24 +457,17 @@
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/border-radius-clipping-vertical-lr.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/border-styles-vertical-lr.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/border-styles-vertical-rl.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/writing-mode/border-vertical-lr.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/writing-mode/borders.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/writing-mode/box-shadow-horizontal-tb-tile-edge.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/box-shadow-vertical-lr.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/box-shadow-vertical-rl.html [ Failure ]
 crbug.com/714962 [ Mac ] virtual/layout_ng/fast/writing-mode/broken-ideograph-small-caps.html [ Failure ]
 crbug.com/714962 [ Mac ] virtual/layout_ng/fast/writing-mode/broken-ideographic-font.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/writing-mode/english-lr-text.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/english-rl-text.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/writing-mode/fallback-orientation.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/fieldsets.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/flipped-blocks-hit-test-line-edges.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/flipped-blocks-inline-map-local-to-container.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-lr-selection.html [ Failure ]
 crbug.com/714962 [ Mac Win ] virtual/layout_ng/fast/writing-mode/japanese-lr-text.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-rl-selection.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-rl-text-with-broken-font.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-rl-text.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-ruby-vertical-lr.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/japanese-ruby-vertical-rl.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/logical-height-after-clear.html [ Failure ]
@@ -492,23 +477,22 @@
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/percentage-height-orthogonal-writing-modes.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/percentage-margins-absolute-replaced.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/percentage-margins-absolute.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/writing-mode/table-hit-test.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/table-percent-width-quirk.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/writing-mode/table-vertical-child-width.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/text-combine-compress.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/text-combine-justify.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/text-combine-line-break.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/text-combine-various-fonts.html [ Failure ]
-crbug.com/714962 virtual/layout_ng/fast/writing-mode/text-orientation-basic.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/vertical-align-table-baseline.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/vertical-baseline-alignment.html [ Failure ]
 crbug.com/714962 [ Mac ] virtual/layout_ng/fast/writing-mode/vertical-font-fallback.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/vertical-lr-replaced-selection.html [ Failure ]
 crbug.com/714962 virtual/layout_ng/fast/writing-mode/vertical-rl-replaced-selection.html [ Failure ]
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/writing-mode/border-vertical-lr.html [ Failure ]
+crbug.com/714962 [ Mac Win ] virtual/layout_ng/fast/writing-mode/english-lr-text.html [ Failure ]
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/writing-mode/japanese-rl-text.html [ Failure ]
+crbug.com/714962 [ Mac ] virtual/layout_ng/fast/writing-mode/text-orientation-basic.html [ Failure ]
 
 # Crashes/asserts due to inline item reuse.
-crbug.com/636993 virtual/layout_ng/fast/block/float/add-float-back-to-anonymous-block-previous.html [ Crash ]
-crbug.com/636993 virtual/layout_ng/fast/inline/inline-empty-block-continuation-remove.html [ Crash Timeout ]
 crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/remove-block-from-content-after-spanner.html [ Failure Crash Timeout ]
 crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/remove-block-from-content-before-spanner.html [ Failure Crash Timeout ]
 crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/remove-block-from-content-between-spanners.html [ Failure Crash Timeout ]
diff --git a/third_party/WebKit/LayoutTests/editing/assert_selection.js b/third_party/WebKit/LayoutTests/editing/assert_selection.js
index ba687d6..7482c93 100644
--- a/third_party/WebKit/LayoutTests/editing/assert_selection.js
+++ b/third_party/WebKit/LayoutTests/editing/assert_selection.js
@@ -681,6 +681,14 @@
  * @param {!HTMLElement} element
  * @return {number}
  */
+function computeRight(element) {
+  return this.computeLeft(element) + element.offsetWidth;
+}
+
+/**
+ * @param {!HTMLElement} element
+ * @return {number}
+ */
 function computeTop(element) {
   let top = kIFrameBorderSize + element.ownerDocument.offsetTop;
   for (let runner = element; runner; runner = runner.offsetParent)
@@ -689,6 +697,14 @@
 }
 
 /**
+ * @param {!HTMLElement} element
+ * @return {number}
+ */
+function computeBottom(element) {
+  return this.computeTop(element) + element.offsetHeight;
+}
+
+/**
  * @this {!Selection}
  * @param {string} html
  * @param {string=} opt_text
@@ -735,7 +751,9 @@
     this.selection_.document.offsetTop = this.iframe_.offsetTop;
     this.selection_.setClipboardData = setClipboardData;
     this.selection_.computeLeft = computeLeft;
+    this.selection_.computeRight = computeRight;
     this.selection_.computeTop = computeTop;
+    this.selection_.computeBottom = computeBottom;
     this.load(sampleText);
   }
 
diff --git a/third_party/WebKit/LayoutTests/editing/selection/mouse/drag_selects_bidi_image.html b/third_party/WebKit/LayoutTests/editing/selection/mouse/drag_selects_bidi_image.html
new file mode 100644
index 0000000..2c11cb2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/editing/selection/mouse/drag_selects_bidi_image.html
@@ -0,0 +1,223 @@
+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../assert_selection.js"></script>
+<script>
+function mouseMoveTo(selection, id, side) {
+  const element = selection.document.getElementById(id);
+  const x = side == 'left' ? selection.computeLeft(element) + 1
+                           : selection.computeRight(element) - 1;
+  const y = selection.computeTop(element) + element.offsetHeight / 2;
+  eventSender.mouseMoveTo(x, y);
+}
+
+function startDrag(selection, id, side) {
+  mouseMoveTo(selection, id, side);
+  eventSender.mouseDown();
+}
+
+function endDrag(selection, id, side) {
+  mouseMoveTo(selection, id, side);
+  eventSender.mouseUp();
+}
+
+selection_test(
+  [
+    '<div dir="ltr" id="container" style="width: 200px">',
+    '\u05D0\u05D0',
+    '<img id="image" style="width: 20px; height: 20px">',
+    '\u05D0\u05D0',
+    '</div>'
+  ],
+  selection => {
+    assert_not_equals(
+        window.eventSender, undefined,
+        'This test requires eventSender to simulate mouse operations');
+
+    startDrag(selection, 'container', 'right');
+    endDrag(selection, 'image', 'right');
+  },
+  [
+    '<div dir="ltr" id="container" style="width: 200px">',
+    '^\u05D0\u05D0',
+    '|<img id="image" style="width: 20px; height: 20px">',
+    '\u05D0\u05D0',
+    '</div>'
+  ].join(''),
+  'Create forward selection extended to image in RTL bidi run in LTR paragraph');
+
+selection_test(
+  [
+    '<div dir="ltr" id="container" style="width: 200px">',
+    '\u05D0\u05D0',
+    '<img id="image" style="width: 20px; height: 20px">',
+    '\u05D0\u05D0',
+    '</div>'
+  ],
+  selection => {
+    assert_not_equals(
+        window.eventSender, undefined,
+        'This test requires eventSender to simulate mouse operations');
+
+    startDrag(selection, 'container', 'right');
+    endDrag(selection, 'image', 'left');
+  },
+  [
+    '<div dir="ltr" id="container" style="width: 200px">',
+    '^\u05D0\u05D0',
+    '<img id="image" style="width: 20px; height: 20px">|',
+    '\u05D0\u05D0',
+    '</div>'
+  ].join(''),
+  'Create forward selection extended beyond image in RTL bidi run in LTR paragraph');
+
+selection_test(
+  [
+    '<div dir="ltr" id="container" style="width: 200px">',
+    '\u05D0\u05D0',
+    '<img id="image" style="width: 20px; height: 20px">',
+    '\u05D0\u05D0',
+    '</div>'
+  ],
+  selection => {
+    assert_not_equals(
+        window.eventSender, undefined,
+        'This test requires eventSender to simulate mouse operations');
+
+    startDrag(selection, 'container', 'left');
+    endDrag(selection, 'image', 'left');
+  },
+  [
+    '<div dir="ltr" id="container" style="width: 200px">',
+    '\u05D0\u05D0',
+    '<img id="image" style="width: 20px; height: 20px">|',
+    '\u05D0\u05D0^',
+    '</div>'
+  ].join(''),
+  'Create backward selection extended to image in RTL bidi run in LTR paragraph');
+
+selection_test(
+  [
+    '<div dir="ltr" id="container" style="width: 200px">',
+    '\u05D0\u05D0',
+    '<img id="image" style="width: 20px; height: 20px">',
+    '\u05D0\u05D0',
+    '</div>'
+  ],
+  selection => {
+    assert_not_equals(
+        window.eventSender, undefined,
+        'This test requires eventSender to simulate mouse operations');
+
+    startDrag(selection, 'container', 'left');
+    endDrag(selection, 'image', 'right');
+  },
+  [
+    '<div dir="ltr" id="container" style="width: 200px">',
+    '\u05D0\u05D0',
+    '|<img id="image" style="width: 20px; height: 20px">',
+    '\u05D0\u05D0^',
+    '</div>'
+  ].join(''),
+  'Create backward selection extended beyond image in RTL bidi run in LTR paragraph');
+
+selection_test(
+  [
+    '<div dir="rtl" id="container" style="width: 200px">',
+    'XX',
+    '<img id="image" style="width: 20px; height: 20px">',
+    'XX',
+    '</div>'
+  ],
+  selection => {
+    assert_not_equals(
+        window.eventSender, undefined,
+        'This test requires eventSender to simulate mouse operations');
+
+    startDrag(selection, 'container', 'left');
+    endDrag(selection, 'image', 'left');
+  },
+  [
+    '<div dir="rtl" id="container" style="width: 200px">',
+    '^XX',
+    '|<img id="image" style="width: 20px; height: 20px">',
+    'XX',
+    '</div>'
+  ].join(''),
+  'Create forward selection extended to image in LTR bidi run in RTL paragraph');
+
+selection_test(
+  [
+    '<div dir="rtl" id="container" style="width: 200px">',
+    'XX',
+    '<img id="image" style="width: 20px; height: 20px">',
+    'XX',
+    '</div>'
+  ],
+  selection => {
+    assert_not_equals(
+        window.eventSender, undefined,
+        'This test requires eventSender to simulate mouse operations');
+
+    startDrag(selection, 'container', 'left');
+    endDrag(selection, 'image', 'right');
+  },
+  [
+    '<div dir="rtl" id="container" style="width: 200px">',
+    '^XX',
+    '<img id="image" style="width: 20px; height: 20px">|',
+    'XX',
+    '</div>'
+  ].join(''),
+  'Create forward selection extended beyond image in LTR bidi run in RTL paragraph');
+
+selection_test(
+  [
+    '<div dir="rtl" id="container" style="width: 200px">',
+    'XX',
+    '<img id="image" style="width: 20px; height: 20px">',
+    'XX',
+    '</div>'
+  ],
+  selection => {
+    assert_not_equals(
+        window.eventSender, undefined,
+        'This test requires eventSender to simulate mouse operations');
+
+    startDrag(selection, 'container', 'right');
+    endDrag(selection, 'image', 'right');
+  },
+  [
+    '<div dir="rtl" id="container" style="width: 200px">',
+    'XX',
+    '<img id="image" style="width: 20px; height: 20px">|',
+    'XX^',
+    '</div>'
+  ].join(''),
+  'Create backward selection extended to image in LTR bidi run in RTL paragraph');
+
+selection_test(
+  [
+    '<div dir="rtl" id="container" style="width: 200px">',
+    'XX',
+    '<img id="image" style="width: 20px; height: 20px">',
+    'XX',
+    '</div>'
+  ],
+  selection => {
+    assert_not_equals(
+        window.eventSender, undefined,
+        'This test requires eventSender to simulate mouse operations');
+
+    startDrag(selection, 'container', 'right');
+    endDrag(selection, 'image', 'left');
+  },
+  [
+    '<div dir="rtl" id="container" style="width: 200px">',
+    'XX',
+    '|<img id="image" style="width: 20px; height: 20px">',
+    'XX^',
+    '</div>'
+  ].join(''),
+  'Create backward selection extended beyond image in LTR bidi run in RTL paragraph');
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import.html b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import.html
index d6e0fe59..9ca6f3c8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import.html
@@ -52,4 +52,25 @@
       .then(e => assert_equals(e.data, 'TypeError'));
 }, 'importScripts() on module worker should throw an exception.');
 
+promise_test(() => {
+  const scriptURL = 'resources/non-existent-worker.js';
+  const worker = new Worker(scriptURL, { type: 'module' });
+  return new Promise(resolve => worker.onerror = resolve);
+}, 'Worker construction for non-existent script should throw an exception.');
+
+promise_test(() => {
+  const scriptURL = 'resources/static-import-non-existent-script-worker.js';
+  const worker = new Worker(scriptURL, { type: 'module' });
+  return new Promise(resolve => worker.onerror = resolve);
+}, 'Static import for non-existent script should throw an exception.');
+
+promise_test(() => {
+  const script_url = './non-existent-worker.js';
+  const worker = new Worker('resources/dynamic-import-given-url-worker.js',
+                            { type: 'module' });
+  worker.postMessage(script_url);
+  return new Promise(resolve => worker.onmessage = resolve)
+      .then(msg_event => assert_equals(msg_event.data, 'ERROR'));
+}, 'Dynamic import for non-existent script should throw an exception.');
+
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/dynamic-import-given-url-worker.js b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/dynamic-import-given-url-worker.js
index 888f604..444badd 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/dynamic-import-given-url-worker.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/dynamic-import-given-url-worker.js
@@ -1,4 +1,4 @@
 // Dynamically import the script URL sent by postMessage().
 self.addEventListener('message', e => {
-  import(e.data);
+  import(e.data).catch(error_event => postMessage('ERROR'));
 });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/static-import-non-existent-script-worker.js b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/static-import-non-existent-script-worker.js
new file mode 100644
index 0000000..16f70e9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/static-import-non-existent-script-worker.js
@@ -0,0 +1 @@
+import './non-existent-script.js';
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t1205-c564-list-img-00-b-g-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t1205-c564-list-img-00-b-g-expected.png
new file mode 100644
index 0000000..3da0a7a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t1205-c564-list-img-00-b-g-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t1205-c564-list-img-00-b-g-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t1205-c564-list-img-00-b-g-expected.txt
new file mode 100644
index 0000000..332e749
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css2.1/t1205-c564-list-img-00-b-g-expected.txt
@@ -0,0 +1,43 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x210
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x210
+    LayoutNGBlockFlow {BODY} at (8,16) size 784x178 [color=#000080]
+      LayoutNGBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 234x19
+          text run at (0,0) width 234: "Each bullet should look as described."
+      LayoutNGBlockFlow {UL} at (0,36) size 784x66
+        LayoutNGListItem {LI} at (40,0) size 744x22
+          LayoutNGListMarker (anonymous) at (-24,0) size 17x22
+            LayoutImage (anonymous) at (0,0) size 17x17
+          LayoutText {#text} at (0,2) size 85x19
+            text run at (0,2) width 85: "purple square"
+        LayoutNGListItem {LI} at (40,22) size 744x22
+          LayoutNGListMarker (anonymous) at (-24,0) size 17x22
+            LayoutImage (anonymous) at (0,0) size 17x17
+          LayoutText {#text} at (0,2) size 85x19
+            text run at (0,2) width 85: "purple square"
+        LayoutNGListItem {LI} at (40,44) size 744x22
+          LayoutNGListMarker (anonymous) at (-24,0) size 17x22
+            LayoutImage (anonymous) at (0,0) size 17x17
+          LayoutText {#text} at (0,2) size 85x19
+            text run at (0,2) width 85: "purple square"
+      LayoutNGBlockFlow {UL} at (0,118) size 784x60
+        LayoutNGListItem {LI} at (40,0) size 744x20
+          LayoutNGListMarker (anonymous) at (-18,0) size 10x20
+            LayoutText (anonymous) at (0,0) size 10x19
+              text run at (0,0) width 10: "\x{2022} "
+          LayoutText {#text} at (0,0) size 25x19
+            text run at (0,0) width 25: "disc"
+        LayoutNGListItem {LI} at (40,20) size 744x20
+          LayoutNGListMarker (anonymous) at (-18,0) size 10x20
+            LayoutText (anonymous) at (0,0) size 10x19
+              text run at (0,0) width 10: "\x{2022} "
+          LayoutText {#text} at (0,0) size 25x19
+            text run at (0,0) width 25: "disc"
+        LayoutNGListItem {LI} at (40,40) size 744x20
+          LayoutNGListMarker (anonymous) at (-18,0) size 10x20
+            LayoutText (anonymous) at (0,0) size 10x19
+              text run at (0,0) width 10: "\x{2022} "
+          LayoutText {#text} at (0,0) size 25x19
+            text run at (0,0) width 25: "disc"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css3/flexbox/flexbox-baseline-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css3/flexbox/flexbox-baseline-expected.png
new file mode 100644
index 0000000..b257d881
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/css3/flexbox/flexbox-baseline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/backgrounds/selection-background-color-of-list-style-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/backgrounds/selection-background-color-of-list-style-expected.png
new file mode 100644
index 0000000..b8384d9e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/backgrounds/selection-background-color-of-list-style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/backgrounds/selection-background-color-of-list-style-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/backgrounds/selection-background-color-of-list-style-expected.txt
new file mode 100644
index 0000000..c369d78
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/backgrounds/selection-background-color-of-list-style-expected.txt
@@ -0,0 +1,37 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x156
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x156
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x132
+      LayoutNGBlockFlow {DIV} at (0,0) size 784x132
+        LayoutNGBlockFlow (anonymous) at (0,0) size 784x20
+          LayoutText {#text} at (0,0) size 472x19
+            text run at (0,0) width 472: "Test passes if backgrounds of list style in ul and ol are each red and yellow."
+        LayoutNGBlockFlow {UL} at (0,36) size 784x40
+          LayoutNGListItem {LI} at (40,0) size 744x20
+            LayoutNGListMarker (anonymous) at (-18,0) size 10x20
+              LayoutText (anonymous) at (0,0) size 10x19
+                text run at (0,0) width 10: "\x{2022} "
+            LayoutText {#text} at (0,0) size 27x19
+              text run at (0,0) width 27: "One"
+          LayoutNGListItem {LI} at (40,20) size 744x20
+            LayoutNGListMarker (anonymous) at (-18,0) size 10x20
+              LayoutText (anonymous) at (0,0) size 10x19
+                text run at (0,0) width 10: "\x{2022} "
+            LayoutText {#text} at (0,0) size 29x19
+              text run at (0,0) width 29: "Two"
+        LayoutNGBlockFlow {OL} at (0,92) size 784x40
+          LayoutNGListItem {LI} at (40,0) size 744x20
+            LayoutNGListMarker (anonymous) at (-16,0) size 16x20
+              LayoutText (anonymous) at (0,0) size 16x19
+                text run at (0,0) width 16: "1. "
+            LayoutText {#text} at (0,0) size 27x19
+              text run at (0,0) width 27: "One"
+          LayoutNGListItem {LI} at (40,20) size 744x20
+            LayoutNGListMarker (anonymous) at (-16,0) size 16x20
+              LayoutText (anonymous) at (0,0) size 16x19
+                text run at (0,0) width 16: "2. "
+            LayoutText {#text} at (0,0) size 29x19
+              text run at (0,0) width 29: "Two"
+selection start: position 84 of child 0 {#text} of child 0 {DIV} of body
+selection end:   position 3 of child 0 {#text} of child 3 {LI} of child 3 {OL} of child 0 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/doctypes/002-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/doctypes/002-expected.png
index c3a11f1f..a33bf68a7 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/doctypes/002-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/doctypes/002-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/validation-bubble-appearance-rtl-ui-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/validation-bubble-appearance-rtl-ui-expected.png
index d3dd9cfc..4b87079 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/validation-bubble-appearance-rtl-ui-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/validation-bubble-appearance-rtl-ui-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-box-background-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-box-background-expected.png
new file mode 100644
index 0000000..93cf1c47
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-box-background-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-box-background-long-image-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-box-background-long-image-expected.png
new file mode 100644
index 0000000..3c79dfd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-box-background-long-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-box-background-repeat-x-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-box-background-repeat-x-expected.png
new file mode 100644
index 0000000..a1b31ca2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-box-background-repeat-x-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-box-background-repeat-y-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-box-background-repeat-y-expected.png
new file mode 100644
index 0000000..5b20447
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/inline/inline-box-background-repeat-y-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/split-table-section-before-anonymous-block-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/split-table-section-before-anonymous-block-2-expected.png
index 65173ee..8a47830 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/split-table-section-before-anonymous-block-2-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/split-table-section-before-anonymous-block-2-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/justified-selection-at-edge-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/justified-selection-at-edge-expected.png
index 6468a16..f72da77 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/justified-selection-at-edge-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/justified-selection-at-edge-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/khmer-selection-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/khmer-selection-expected.png
new file mode 100644
index 0000000..e90eab2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/text/selection/khmer-selection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/overflow-scroll-delete-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/overflow-scroll-delete-expected.png
new file mode 100644
index 0000000..d7f95745
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/overflow-scroll-delete-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/overflow-scroll-delete-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/overflow-scroll-delete-expected.txt
new file mode 100644
index 0000000..04e1315d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/scroll/overflow-scroll-delete-expected.txt
@@ -0,0 +1,84 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 136, 43, 17],
+          "reason": "chunk appeared"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 136, 39, 17],
+          "reason": "chunk disappeared"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "subtree"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug131020-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug131020-expected.png
new file mode 100644
index 0000000..a5c6c50
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug131020-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug57828-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug57828-expected.png
new file mode 100644
index 0000000..eb0a525
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug57828-expected.png
Binary files differ
diff --git a/third_party/blink/perf_tests/layout/resources/character_fallback_chars.js b/third_party/blink/perf_tests/layout/resources/character_fallback_chars.js
index 1d9628ce..f0e0bb8 100644
--- a/third_party/blink/perf_tests/layout/resources/character_fallback_chars.js
+++ b/third_party/blink/perf_tests/layout/resources/character_fallback_chars.js
@@ -1,8 +1,8 @@
 // This list of supported unicode characters was extracted from the Linux
-// content_shell font configuration, when in --run-layout-test mode in
-// Linux. It spans the list of 36 default configured fonts for running layout
-// tests and is intended as a good approximation of the coverage of installed
-// fonts on a regular system.
+// content_shell font configuration, when in --run-web-tests mode in Linux. It
+// spans the list of 36 default configured fonts for running layout tests and is
+// intended as a good approximation of the coverage of installed fonts on a
+// regular system.
 
 charsSupportedByNFonts = [];
 
diff --git a/third_party/blink/renderer/bindings/scripts/code_generator.py b/third_party/blink/renderer/bindings/scripts/code_generator.py
index df063fa..f66c4767 100644
--- a/third_party/blink/renderer/bindings/scripts/code_generator.py
+++ b/third_party/blink/renderer/bindings/scripts/code_generator.py
@@ -64,6 +64,7 @@
         return code
     return generate_indented_conditional(code, secure_context_test)
 
+
 # [OriginTrialEnabled]
 def origin_trial_enabled_if(code, origin_trial_feature_name, execution_context=None):
     if not origin_trial_feature_name:
@@ -82,6 +83,7 @@
     function = v8_utilities.runtime_enabled_function(name)
     return generate_indented_conditional(code, function)
 
+
 def initialize_jinja_env(cache_dir):
     jinja_env = jinja2.Environment(
         loader=jinja2.FileSystemLoader(TEMPLATES_DIR),
@@ -176,6 +178,11 @@
         # This should be implemented in subclasses.
         raise NotImplementedError()
 
+    def normalize_this_header_path(self, header_path):
+        match = re.search('(third_party/blink/.*)$', header_path)
+        assert match, 'Unkown style of path to output: ' + header_path
+        return match.group(1)
+
 
 def main(argv):
     # If file itself executed, cache templates
diff --git a/third_party/blink/renderer/bindings/scripts/code_generator_v8.py b/third_party/blink/renderer/bindings/scripts/code_generator_v8.py
index 5b343669..455a76e 100644
--- a/third_party/blink/renderer/bindings/scripts/code_generator_v8.py
+++ b/third_party/blink/renderer/bindings/scripts/code_generator_v8.py
@@ -217,7 +217,7 @@
         template_context['header_includes'].update(
             interface_info.get('additional_header_includes', []))
         header_path, cpp_path = self.output_paths(interface_name)
-        template_context['this_include_header_path'] = posixpath.basename(header_path)
+        template_context['this_include_header_path'] = self.normalize_this_header_path(header_path)
         header_template = self.jinja_env.get_template(header_template_filename)
         cpp_template = self.jinja_env.get_template(cpp_template_filename)
         header_text, cpp_text = self.render_templates(
@@ -244,7 +244,7 @@
             template_context['header_includes'].add(self.info_provider.include_path_for_export)
             template_context['exported'] = self.info_provider.specifier_for_export
         header_path, cpp_path = self.output_paths(dictionary_name)
-        template_context['this_include_header_path'] = posixpath.basename(header_path)
+        template_context['this_include_header_path'] = self.normalize_this_header_path(header_path)
         header_text, cpp_text = self.render_templates(
             include_paths, header_template, cpp_template, template_context)
         return (
@@ -283,7 +283,7 @@
         template_context['header_includes'].update(
             interface_info.get('additional_header_includes', []))
         header_path, cpp_path = self.output_paths(definition_name, interface_info)
-        template_context['this_include_header_path'] = posixpath.basename(header_path)
+        template_context['this_include_header_path'] = self.normalize_this_header_path(header_path)
         header_text, cpp_text = self.render_templates(
             include_paths, header_template, cpp_template, template_context)
         return (
@@ -314,15 +314,14 @@
         union_type = union_type.resolve_typedefs(self.typedefs)
         header_template = self.jinja_env.get_template('union_container.h.tmpl')
         cpp_template = self.jinja_env.get_template('union_container.cpp.tmpl')
-        template_context = v8_union.container_context(
-            union_type, self.info_provider)
+        template_context = v8_union.container_context(union_type, self.info_provider)
         template_context['header_includes'].append(
             self.info_provider.include_path_for_export)
         template_context['exported'] = self.info_provider.specifier_for_export
         snake_base_name = to_snake_case(shorten_union_name(union_type))
-        template_context['this_include_header_path'] = snake_base_name + '.h'
         header_path = posixpath.join(self.output_dir, '%s.h' % snake_base_name)
         cpp_path = posixpath.join(self.output_dir, '%s.cc' % snake_base_name)
+        template_context['this_include_header_path'] = self.normalize_this_header_path(header_path)
         header_text, cpp_text = self.render_templates(
             [], header_template, cpp_template, template_context)
         return (
@@ -381,12 +380,12 @@
                 template_context['header_includes'].append(
                     self.info_provider.include_path_for_union_types(argument.idl_type))
 
-        template_context['code_generator'] = MODULE_PYNAME
-        header_text, cpp_text = self.render_templates(
-            [], header_template, cpp_template, template_context)
         snake_base_name = to_snake_case('V8%s' % callback_function.name)
         header_path = posixpath.join(self.output_dir, '%s.h' % snake_base_name)
         cpp_path = posixpath.join(self.output_dir, '%s.cc' % snake_base_name)
+        template_context['this_include_header_path'] = self.normalize_this_header_path(header_path)
+        header_text, cpp_text = self.render_templates(
+            [], header_template, cpp_template, template_context)
         return (
             (header_path, header_text),
             (cpp_path, cpp_text),
diff --git a/third_party/blink/renderer/bindings/scripts/code_generator_web_agent_api.py b/third_party/blink/renderer/bindings/scripts/code_generator_web_agent_api.py
index e78dc755..cad68172 100644
--- a/third_party/blink/renderer/bindings/scripts/code_generator_web_agent_api.py
+++ b/third_party/blink/renderer/bindings/scripts/code_generator_web_agent_api.py
@@ -23,7 +23,7 @@
 import posixpath
 import sys
 
-from code_generator import CodeGeneratorBase, render_template
+from code_generator import CodeGeneratorBase, render_template, normalize_and_sort_includes
 # TODO(dglazkov): Move TypedefResolver to code_generator.py
 from code_generator_v8 import TypedefResolver
 
@@ -33,7 +33,7 @@
 
 MODULE_PYNAME = os.path.splitext(os.path.basename(__file__))[0] + '.py'
 
-STRING_INCLUDE_PATH = 'platform/wtf/text/wtf_string.h'
+STRING_INCLUDE_PATH = 'third_party/blink/renderer/platform/wtf/text/wtf_string.h'
 WEB_AGENT_API_IDL_ATTRIBUTE = 'WebAgentAPI'
 
 
@@ -84,7 +84,7 @@
         return idl_definition.idl_type.base_type
 
     def base_class_includes(self):
-        return set(['platform/heap/handle.h'])
+        return set(['third_party/blink/renderer/platform/heap/handle.h'])
 
 
 class MethodOverloadSplitter(object):
@@ -235,6 +235,10 @@
         }
 
     def build(self):
+        if 'cpp_includes' in self.result:
+            self.result['cpp_includes'] = set(normalize_and_sort_includes(self.result['cpp_includes']))
+        if 'header_includes' in self.result:
+            self.result['header_includes'] = set(normalize_and_sort_includes(self.result['header_includes']))
         return self.result
 
 
diff --git a/third_party/blink/renderer/bindings/scripts/code_generator_web_agent_api_test.py b/third_party/blink/renderer/bindings/scripts/code_generator_web_agent_api_test.py
index 9588191..09516f5 100644
--- a/third_party/blink/renderer/bindings/scripts/code_generator_web_agent_api_test.py
+++ b/third_party/blink/renderer/bindings/scripts/code_generator_web_agent_api_test.py
@@ -272,7 +272,7 @@
         builder.set_inheritance(None)
         self.assertEqual({
             'code_generator': 'test',
-            'header_includes': set(['platform/heap/handle.h']),
+            'header_includes': set(['third_party/blink/renderer/platform/heap/handle.h']),
         }, builder.build())
 
     def test_add_attribute(self):
diff --git a/third_party/blink/renderer/bindings/scripts/v8_callback_function.py b/third_party/blink/renderer/bindings/scripts/v8_callback_function.py
index 687f183..53b556f1 100644
--- a/third_party/blink/renderer/bindings/scripts/v8_callback_function.py
+++ b/third_party/blink/renderer/bindings/scripts/v8_callback_function.py
@@ -7,7 +7,6 @@
 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
 """
 
-from utilities import to_snake_case
 from v8_globals import includes
 
 CALLBACK_FUNCTION_H_INCLUDES = frozenset([
@@ -45,7 +44,6 @@
         'header_includes': sorted(CALLBACK_FUNCTION_H_INCLUDES),
         'idl_type': idl_type_str,
         'return_cpp_type': idl_type.cpp_type,
-        'this_include_header_path': to_snake_case('V8%s' % callback_function.name) + '.h',
     }
 
     if idl_type_str != 'void':
diff --git a/third_party/blink/renderer/bindings/tests/results/DEPS b/third_party/blink/renderer/bindings/tests/results/DEPS
index 369708d4..423281fe 100644
--- a/third_party/blink/renderer/bindings/tests/results/DEPS
+++ b/third_party/blink/renderer/bindings/tests/results/DEPS
@@ -1,7 +1,3 @@
 include_rules = [
-    # Allow paths relative to blink/renderder until fixing IDL compiler.
-    "!bindings",
-    "!core",
-    "!modules",
-    "!platform",
+    "+third_party/blink/renderer/bindings/tests/results",
 ]
diff --git a/third_party/blink/renderer/bindings/tests/results/core/array_buffer_or_array_buffer_view_or_dictionary.cc b/third_party/blink/renderer/bindings/tests/results/core/array_buffer_or_array_buffer_view_or_dictionary.cc
index d1c542f..b5c325b 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/array_buffer_or_array_buffer_view_or_dictionary.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/array_buffer_or_array_buffer_view_or_dictionary.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "array_buffer_or_array_buffer_view_or_dictionary.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/array_buffer_or_array_buffer_view_or_dictionary.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/boolean_or_element_sequence.cc b/third_party/blink/renderer/bindings/tests/results/core/boolean_or_element_sequence.cc
index 046c1ea9..6b773ac4 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/boolean_or_element_sequence.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/boolean_or_element_sequence.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "boolean_or_element_sequence.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/boolean_or_element_sequence.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/boolean_or_string_or_unrestricted_double.cc b/third_party/blink/renderer/bindings/tests/results/core/boolean_or_string_or_unrestricted_double.cc
index c0071a72..7624348ae6 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/boolean_or_string_or_unrestricted_double.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/boolean_or_string_or_unrestricted_double.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "boolean_or_string_or_unrestricted_double.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/boolean_or_string_or_unrestricted_double.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/boolean_or_test_callback_interface.cc b/third_party/blink/renderer/bindings/tests/results/core/boolean_or_test_callback_interface.cc
index 687168e..378d257f 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/boolean_or_test_callback_interface.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/boolean_or_test_callback_interface.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "boolean_or_test_callback_interface.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/boolean_or_test_callback_interface.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/byte_string_or_node_list.cc b/third_party/blink/renderer/bindings/tests/results/core/byte_string_or_node_list.cc
index cfe12930..e040223 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/byte_string_or_node_list.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/byte_string_or_node_list.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "byte_string_or_node_list.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/byte_string_or_node_list.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/byte_string_sequence_sequence_or_byte_string_byte_string_record.cc b/third_party/blink/renderer/bindings/tests/results/core/byte_string_sequence_sequence_or_byte_string_byte_string_record.cc
index 9090bb6a..3e59aca6 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/byte_string_sequence_sequence_or_byte_string_byte_string_record.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/byte_string_sequence_sequence_or_byte_string_byte_string_record.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "byte_string_sequence_sequence_or_byte_string_byte_string_record.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/byte_string_sequence_sequence_or_byte_string_byte_string_record.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/double_or_double_or_null_sequence.cc b/third_party/blink/renderer/bindings/tests/results/core/double_or_double_or_null_sequence.cc
index 70f2274..245f5bd3 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/double_or_double_or_null_sequence.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/double_or_double_or_null_sequence.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "double_or_double_or_null_sequence.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/double_or_double_or_null_sequence.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/double_or_double_sequence.cc b/third_party/blink/renderer/bindings/tests/results/core/double_or_double_sequence.cc
index ec754e8..b599d0e 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/double_or_double_sequence.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/double_or_double_sequence.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "double_or_double_sequence.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/double_or_double_sequence.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/double_or_long_or_boolean_sequence.cc b/third_party/blink/renderer/bindings/tests/results/core/double_or_long_or_boolean_sequence.cc
index 92ed53a..947d904 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/double_or_long_or_boolean_sequence.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/double_or_long_or_boolean_sequence.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "double_or_long_or_boolean_sequence.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/double_or_long_or_boolean_sequence.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/long_or_boolean.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/double_or_string.cc b/third_party/blink/renderer/bindings/tests/results/core/double_or_string.cc
index 7d8da5f..1e15db1 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/double_or_string.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/double_or_string.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "double_or_string.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/double_or_string.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/double_or_string_or_double_or_string_sequence.cc b/third_party/blink/renderer/bindings/tests/results/core/double_or_string_or_double_or_string_sequence.cc
index ab9b56a..d2baa4b4 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/double_or_string_or_double_or_string_sequence.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/double_or_string_or_double_or_string_sequence.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "double_or_string_or_double_or_string_sequence.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/double_or_string_or_double_or_string_sequence.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/double_or_string.h"
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/element_sequence_or_byte_string_double_or_string_record.cc b/third_party/blink/renderer/bindings/tests/results/core/element_sequence_or_byte_string_double_or_string_record.cc
index e75a5a5..082fe5c 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/element_sequence_or_byte_string_double_or_string_record.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/element_sequence_or_byte_string_double_or_string_record.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "element_sequence_or_byte_string_double_or_string_record.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/element_sequence_or_byte_string_double_or_string_record.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/double_or_string.h"
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/float_or_boolean.cc b/third_party/blink/renderer/bindings/tests/results/core/float_or_boolean.cc
index 44bfb97..30986b2f 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/float_or_boolean.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/float_or_boolean.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "float_or_boolean.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/float_or_boolean.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/long_or_boolean.cc b/third_party/blink/renderer/bindings/tests/results/core/long_or_boolean.cc
index b4a2a625..e736d4c 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/long_or_boolean.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/long_or_boolean.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "long_or_boolean.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/long_or_boolean.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/long_or_test_dictionary.cc b/third_party/blink/renderer/bindings/tests/results/core/long_or_test_dictionary.cc
index cb936070..57ad4db 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/long_or_test_dictionary.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/long_or_test_dictionary.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "long_or_test_dictionary.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/long_or_test_dictionary.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/long_sequence_or_event.cc b/third_party/blink/renderer/bindings/tests/results/core/long_sequence_or_event.cc
index 2407664..a8fb0f3 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/long_sequence_or_event.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/long_sequence_or_event.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "long_sequence_or_event.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/long_sequence_or_event.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/nested_union_type.cc b/third_party/blink/renderer/bindings/tests/results/core/nested_union_type.cc
index ead8168..b6d40d49 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/nested_union_type.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/nested_union_type.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "nested_union_type.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/nested_union_type.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/byte_string_or_node_list.h"
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/node_or_node_list.cc b/third_party/blink/renderer/bindings/tests/results/core/node_or_node_list.cc
index 08e99728..623c662 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/node_or_node_list.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/node_or_node_list.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "node_or_node_list.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/node_or_node_list.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_node.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/string_or_array_buffer_or_array_buffer_view.cc b/third_party/blink/renderer/bindings/tests/results/core/string_or_array_buffer_or_array_buffer_view.cc
index 30023f6..8b5e0177 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/string_or_array_buffer_or_array_buffer_view.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/string_or_array_buffer_or_array_buffer_view.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "string_or_array_buffer_or_array_buffer_view.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/string_or_array_buffer_or_array_buffer_view.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/string_or_double.cc b/third_party/blink/renderer/bindings/tests/results/core/string_or_double.cc
index c3b85de9..e52b7c7 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/string_or_double.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/string_or_double.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "string_or_double.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/string_or_double.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/string_or_string_sequence.cc b/third_party/blink/renderer/bindings/tests/results/core/string_or_string_sequence.cc
index dd5b31ef..4609b6a 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/string_or_string_sequence.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/string_or_string_sequence.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "string_or_string_sequence.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/string_or_string_sequence.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.cc b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.cc
index 2e929c5..4cda41a 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "test_dictionary.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h"
 
 #include "third_party/blink/renderer/bindings/tests/idls/core/test_interface_garbage_collected.h"
 #include "third_party/blink/renderer/bindings/tests/idls/core/test_interface_implementation.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary_derived.cc b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary_derived.cc
index ec7fc3f..ec382a0d 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary_derived.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary_derived.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "test_dictionary_derived.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/test_dictionary_derived.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_double.cc b/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_double.cc
index 480a944..c73fe99 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_double.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_double.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "test_enum_or_double.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/test_enum_or_double.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_or_null_sequence.cc b/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_or_null_sequence.cc
index 83b1166..0af8df7 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_or_null_sequence.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_or_null_sequence.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "test_enum_or_test_enum_or_null_sequence.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_or_null_sequence.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_sequence.cc b/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_sequence.cc
index fe8e279..3f55733 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_sequence.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_sequence.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "test_enum_or_test_enum_sequence.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/test_enum_or_test_enum_sequence.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_interface_2_or_uint8_array.cc b/third_party/blink/renderer/bindings/tests/results/core/test_interface_2_or_uint8_array.cc
index db3edcb2..02e18fa9d 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_interface_2_or_uint8_array.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_interface_2_or_uint8_array.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "test_interface_2_or_uint8_array.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/test_interface_2_or_uint8_array.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_test_interface_2.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_interface_3.cc b/third_party/blink/renderer/bindings/tests/results/core/test_interface_3.cc
index 37f9711..50275b2d 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_interface_3.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_interface_3.cc
@@ -12,8 +12,8 @@
 #include "web/api/test_interface_3.h"
 
 // TODO(dglazkov): Properly sort the includes.
-#include "bindings/tests/idls/core/test_interface_3.h"
-#include "platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/bindings/tests/idls/core/test_interface_3.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
 namespace web {
 
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_interface_3.h b/third_party/blink/renderer/bindings/tests/results/core/test_interface_3.h
index 2717afa..6005c9d5 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_interface_3.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_interface_3.h
@@ -12,7 +12,7 @@
 #ifndef WEB_API_TEST_INTERFACE_3_H
 #define WEB_API_TEST_INTERFACE_3_H
 
-#include "platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/handle.h"
 
 namespace blink {
 class TestInterface3;
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_interface_event_init.cc b/third_party/blink/renderer/bindings/tests/results/core/test_interface_event_init.cc
index bfbc84f..c5927f7 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_interface_event_init.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_interface_event_init.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "test_interface_event_init.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/test_interface_event_init.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_interface_garbage_collected_or_string.cc b/third_party/blink/renderer/bindings/tests/results/core/test_interface_garbage_collected_or_string.cc
index 9ed44a09..0d9c3ed8 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_interface_garbage_collected_or_string.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_interface_garbage_collected_or_string.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "test_interface_garbage_collected_or_string.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/test_interface_garbage_collected_or_string.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_long.cc b/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_long.cc
index 18ee334..1a097fe 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_long.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_long.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "test_interface_or_long.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/test_interface_or_long.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_test_interface_empty.cc b/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_test_interface_empty.cc
index 39b028c..e42b82db 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_test_interface_empty.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_interface_or_test_interface_empty.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "test_interface_or_test_interface_empty.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/test_interface_or_test_interface_empty.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_test_interface.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_permissive_dictionary.cc b/third_party/blink/renderer/bindings/tests/results/core/test_permissive_dictionary.cc
index c6e1e952..339d400 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_permissive_dictionary.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_permissive_dictionary.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "test_permissive_dictionary.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/test_permissive_dictionary.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/bindings/tests/results/core/unrestricted_double_or_string.cc b/third_party/blink/renderer/bindings/tests/results/core/unrestricted_double_or_string.cc
index a482328..7252f9b 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/unrestricted_double_or_string.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/unrestricted_double_or_string.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "unrestricted_double_or_string.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/unrestricted_double_or_string.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/unsigned_long_long_or_boolean_or_test_callback_interface.cc b/third_party/blink/renderer/bindings/tests/results/core/unsigned_long_long_or_boolean_or_test_callback_interface.cc
index 2502346..0874fd50 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/unsigned_long_long_or_boolean_or_test_callback_interface.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/unsigned_long_long_or_boolean_or_test_callback_interface.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "unsigned_long_long_or_boolean_or_test_callback_interface.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/unsigned_long_long_or_boolean_or_test_callback_interface.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_optional_any_arg.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_optional_any_arg.cc
index 30d3e2b..474fb827 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_optional_any_arg.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_optional_any_arg.cc
@@ -9,7 +9,7 @@
 
 // clang-format off
 
-#include "v8_any_callback_function_optional_any_arg.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_any_callback_function_optional_any_arg.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer.cc
index 894aa85..1208a9c 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_array_buffer.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer_view.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer_view.cc
index 9941006..2c2ed7f 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer_view.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer_view.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_array_buffer_view.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_array_buffer_view.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_data_view.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_data_view.cc
index dfc5b856..5112354 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_data_view.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_data_view.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_data_view.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_data_view.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_long_callback_function.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_long_callback_function.cc
index 0045ae8c..e5fb07ef 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_long_callback_function.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_long_callback_function.cc
@@ -9,7 +9,7 @@
 
 // clang-format off
 
-#include "v8_long_callback_function.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_long_callback_function.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_string_sequence_callback_function_long_sequence_arg.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_string_sequence_callback_function_long_sequence_arg.cc
index 86f672b..ecfb95f 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_string_sequence_callback_function_long_sequence_arg.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_string_sequence_callback_function_long_sequence_arg.cc
@@ -9,7 +9,7 @@
 
 // clang-format off
 
-#include "v8_string_sequence_callback_function_long_sequence_arg.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_string_sequence_callback_function_long_sequence_arg.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_svg_test_interface.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_svg_test_interface.cc
index 81e1fba9..5f63a2e 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_svg_test_interface.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_svg_test_interface.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_svg_test_interface.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_svg_test_interface.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_attribute_getters.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_attribute_getters.cc
index c1194324..a97c7816 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_attribute_getters.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_attribute_getters.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_attribute_getters.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_attribute_getters.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_functions.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_functions.cc
index 2167965b..e4e29a5e 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_functions.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_functions.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_callback_functions.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_functions.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_interface.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_interface.cc
index 9d6a6d3..b60b22c 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_interface.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_interface.cc
@@ -9,7 +9,7 @@
 
 // clang-format off
 
-#include "v8_test_callback_interface.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_callback_interface.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_constants.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_constants.cc
index 4c3d00a..01fbd01 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_constants.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_constants.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_constants.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_constants.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc
index 0473218..c32bbf22 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_dictionary.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary_derived.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary_derived.cc
index bfbf2949..dbd3238 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary_derived.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary_derived.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_dictionary_derived.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary_derived.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed.cc
index d513623..c88f005 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_integer_indexed.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_global.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_global.cc
index 4d6c424..b60ebc1 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_global.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_global.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_integer_indexed_global.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_global.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_primary_global.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_primary_global.cc
index 315b6d2..296d5ef3 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_primary_global.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_primary_global.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_integer_indexed_primary_global.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_integer_indexed_primary_global.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface.cc
index 44c9f0a..7e9e045 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_2.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_2.cc
index 2eb956b..873c728c 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_2.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_2.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_2.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_2.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_3.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_3.cc
index b4426da..068a3fb4 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_3.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_3.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_3.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_3.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.cc
index 8bc83366..b38bb7c 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_check_security.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/binding_security.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_conditional_secure_context.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_conditional_secure_context.cc
index 3e6be14a..9fe851c1 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_conditional_secure_context.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_conditional_secure_context.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_conditional_secure_context.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_conditional_secure_context.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor.cc
index 0e85192..e9df2924 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_constructor.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_2.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_2.cc
index 4081a004..18d0aac8 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_2.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_2.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_constructor_2.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_2.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_3.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_3.cc
index 1e3a31d..13c7931b 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_3.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_3.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_constructor_3.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_3.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_4.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_4.cc
index 2ad8693..54391b8 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_4.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_4.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_constructor_4.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_constructor_4.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_custom_constructor.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_custom_constructor.cc
index 2f0a03024..54ae07a 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_custom_constructor.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_custom_constructor.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_custom_constructor.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_custom_constructor.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_document.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_document.cc
index 7867c577..935d605 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_document.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_document.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_document.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_document.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_empty.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_empty.cc
index dc10fe4..89eac88 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_empty.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_empty.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_empty.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_empty.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init.cc
index 86723654..9ac60360 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_event_init.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init_constructor.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init_constructor.cc
index acd06da..2d6686be 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init_constructor.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init_constructor.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_event_init_constructor.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_init_constructor.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_target.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_target.cc
index 5b4ae04..2b993621 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_target.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_target.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_event_target.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_event_target.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_garbage_collected.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_garbage_collected.cc
index 9585566..2e25076 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_garbage_collected.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_garbage_collected.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_garbage_collected.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_garbage_collected.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor.cc
index dbbb456..803e7fd2 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_named_constructor.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor_2.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor_2.cc
index 752b7cc..6da0562 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor_2.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor_2.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_named_constructor_2.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_named_constructor_2.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_node.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_node.cc
index 8095967..7d7b8d9 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_node.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_node.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_node.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_node.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_origin_trial_enabled.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_origin_trial_enabled.cc
index 2dc0a00f..a3687bda 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_origin_trial_enabled.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_origin_trial_enabled.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_origin_trial_enabled.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_origin_trial_enabled.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_secure_context.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_secure_context.cc
index 7e6d95f..990b3cf 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_secure_context.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_secure_context.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_secure_context.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_secure_context.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_legacy_callback_interface.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_legacy_callback_interface.cc
index 2229022..25d8556 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_legacy_callback_interface.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_legacy_callback_interface.cc
@@ -9,7 +9,7 @@
 
 // clang-format off
 
-#include "v8_test_legacy_callback_interface.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_legacy_callback_interface.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_node.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_node.cc
index 390c921a..024ffcb54 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_node.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_node.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_node.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_node.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_object.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_object.cc
index 445cd4cd..7854ddd 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_object.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_object.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_object.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_object.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/binding_security.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_permissive_dictionary.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_permissive_dictionary.cc
index f9eecca..914c2fa 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_permissive_dictionary.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_permissive_dictionary.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_permissive_dictionary.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_permissive_dictionary.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations.cc
index 15a0a3b..606efac 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_special_operations.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations_not_enumerable.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations_not_enumerable.cc
index 3034632..a81d132 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations_not_enumerable.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations_not_enumerable.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_special_operations_not_enumerable.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_special_operations_not_enumerable.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_typedefs.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_typedefs.cc
index 0b6a637..5b98f81abe9 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_typedefs.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_typedefs.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_typedefs.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_typedefs.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_variadic_constructor_arguments.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_variadic_constructor_arguments.cc
index bb0193bb..de2f3af 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_variadic_constructor_arguments.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_variadic_constructor_arguments.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_variadic_constructor_arguments.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_test_variadic_constructor_arguments.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_uint8_clamped_array.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_uint8_clamped_array.cc
index d41543f..13d4b51 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_uint8_clamped_array.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_uint8_clamped_array.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_uint8_clamped_array.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_uint8_clamped_array.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function.cc
index 5576bd62..1e8a1586 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function.cc
@@ -9,7 +9,7 @@
 
 // clang-format off
 
-#include "v8_void_callback_function.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_dictionary_arg.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_dictionary_arg.cc
index cd960cf..b3f766c 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_dictionary_arg.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_dictionary_arg.cc
@@ -9,7 +9,7 @@
 
 // clang-format off
 
-#include "v8_void_callback_function_dictionary_arg.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_dictionary_arg.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_enum_arg.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_enum_arg.cc
index f24e31f..4ed195b 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_enum_arg.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_enum_arg.cc
@@ -9,7 +9,7 @@
 
 // clang-format off
 
-#include "v8_void_callback_function_enum_arg.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_enum_arg.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_interface_arg.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_interface_arg.cc
index 83f5579d..bf037db 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_interface_arg.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_interface_arg.cc
@@ -9,7 +9,7 @@
 
 // clang-format off
 
-#include "v8_void_callback_function_interface_arg.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_interface_arg.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_test_interface_sequence_arg.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_test_interface_sequence_arg.cc
index 1eae20c..770407b 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_test_interface_sequence_arg.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_test_interface_sequence_arg.cc
@@ -9,7 +9,7 @@
 
 // clang-format off
 
-#include "v8_void_callback_function_test_interface_sequence_arg.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_test_interface_sequence_arg.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_typedef.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_typedef.cc
index d6ddce4..a2983bd 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_typedef.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_typedef.cc
@@ -9,7 +9,7 @@
 
 // clang-format off
 
-#include "v8_void_callback_function_typedef.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/v8_void_callback_function_typedef.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/core/xml_http_request_or_string.cc b/third_party/blink/renderer/bindings/tests/results/core/xml_http_request_or_string.cc
index c2d09da..992cd4b 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/xml_http_request_or_string.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/xml_http_request_or_string.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "xml_http_request_or_string.h"
+#include "third_party/blink/renderer/bindings/tests/results/core/xml_http_request_or_string.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/boolean_or_string.cc b/third_party/blink/renderer/bindings/tests/results/modules/boolean_or_string.cc
index a02393c1..4ffcd76 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/boolean_or_string.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/boolean_or_string.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "boolean_or_string.h"
+#include "third_party/blink/renderer/bindings/tests/results/modules/boolean_or_string.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_inherited_legacy_unenumerable_named_properties.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_inherited_legacy_unenumerable_named_properties.cc
index 823432a..4434ed14 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_inherited_legacy_unenumerable_named_properties.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_inherited_legacy_unenumerable_named_properties.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_inherited_legacy_unenumerable_named_properties.h"
+#include "third_party/blink/renderer/bindings/tests/results/modules/v8_test_inherited_legacy_unenumerable_named_properties.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_2_partial.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_2_partial.cc
index 9b4ec490..02a797a 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_2_partial.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_2_partial.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_2_partial.h"
+#include "third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_2_partial.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_5.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_5.cc
index 70158b0c..d119526 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_5.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_5.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_5.h"
+#include "third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_5.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_partial.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_partial.cc
index fb24f208..70224b2 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_partial.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_partial.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_interface_partial.h"
+#include "third_party/blink/renderer/bindings/tests/results/modules/v8_test_interface_partial.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_not_enumerable_named_getter.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_not_enumerable_named_getter.cc
index e28c8118..0929469 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_not_enumerable_named_getter.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_not_enumerable_named_getter.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_not_enumerable_named_getter.h"
+#include "third_party/blink/renderer/bindings/tests/results/modules/v8_test_not_enumerable_named_getter.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_sub_object.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_sub_object.cc
index d58ca5e..100fe9d 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_test_sub_object.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_test_sub_object.cc
@@ -8,7 +8,7 @@
 // DO NOT MODIFY!
 
 // clang-format off
-#include "v8_test_sub_object.h"
+#include "third_party/blink/renderer/bindings/tests/results/modules/v8_test_sub_object.h"
 
 #include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
diff --git a/third_party/blink/renderer/bindings/tests/results/modules/v8_void_callback_function_modules.cc b/third_party/blink/renderer/bindings/tests/results/modules/v8_void_callback_function_modules.cc
index a885534..d3a9135 100644
--- a/third_party/blink/renderer/bindings/tests/results/modules/v8_void_callback_function_modules.cc
+++ b/third_party/blink/renderer/bindings/tests/results/modules/v8_void_callback_function_modules.cc
@@ -9,7 +9,7 @@
 
 // clang-format off
 
-#include "v8_void_callback_function_modules.h"
+#include "third_party/blink/renderer/bindings/tests/results/modules/v8_void_callback_function_modules.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
 #include "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h"
diff --git a/third_party/blink/renderer/build/mac/prefix.h b/third_party/blink/renderer/build/mac/prefix.h
index 7dfa038..d162131 100644
--- a/third_party/blink/renderer/build/mac/prefix.h
+++ b/third_party/blink/renderer/build/mac/prefix.h
@@ -23,6 +23,12 @@
  * build without this header, although we rarely test that.
  */
 
+#ifdef THIRD_PARTY_BLINK_RENDERER_BUILD_MAC_PREFIX_H_
+#error You shouldn't include the precompiled header file more than once.
+#endif
+
+#define THIRD_PARTY_BLINK_RENDERER_BUILD_MAC_PREFIX_H_
+
 #include <pthread.h>
 #include <sys/types.h>
 #include <fcntl.h>
diff --git a/third_party/blink/renderer/build/win/precompile.h b/third_party/blink/renderer/build/win/precompile.h
index e2b1b8d..fde39b8 100644
--- a/third_party/blink/renderer/build/win/precompile.h
+++ b/third_party/blink/renderer/build/win/precompile.h
@@ -2,10 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(WinPrecompile_h_)
+#ifdef THIRD_PARTY_BLINK_RENDERER_BUILD_WIN_PRECOMPILE_H_
 #error You shouldn't include the precompiled header file more than once.
 #endif
-#define WinPrecompile_h_
+
+#define THIRD_PARTY_BLINK_RENDERER_BUILD_WIN_PRECOMPILE_H_
 
 // Precompiled header for Blink when built on Windows using
 // GYP-generated project files.  Not used by other build
diff --git a/third_party/blink/renderer/core/css/cssom/element_computed_style_map.h b/third_party/blink/renderer/core/css/cssom/element_computed_style_map.h
index 5d46e17f..ead38f8 100644
--- a/third_party/blink/renderer/core/css/cssom/element_computed_style_map.h
+++ b/third_party/blink/renderer/core/css/cssom/element_computed_style_map.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/renderer/core/css/css_computed_style_declaration.h"
 #include "third_party/blink/renderer/core/css/cssom/computed_style_property_map.h"
+#include "third_party/blink/renderer/core/dom/element.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/core/css/remote_font_face_source.cc b/third_party/blink/renderer/core/css/remote_font_face_source.cc
index f8b690f..d2ee4ac 100644
--- a/third_party/blink/renderer/core/css/remote_font_face_source.cc
+++ b/third_party/blink/renderer/core/css/remote_font_face_source.cc
@@ -259,7 +259,7 @@
     if (font->IsLowPriorityLoadingAllowedForRemoteFont()) {
       font_selector_->GetExecutionContext()->AddConsoleMessage(
           ConsoleMessage::Create(
-              kOtherMessageSource, kInfoMessageLevel,
+              kInterventionMessageSource, kInfoMessageLevel,
               "Slow network is detected. See "
               "https://www.chromestatus.com/feature/5636954674692096 for more "
               "details. Fallback font will be used while loading: " +
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder.cc b/third_party/blink/renderer/core/editing/finder/text_finder.cc
index 356a45d..097c3215 100644
--- a/third_party/blink/renderer/core/editing/finder/text_finder.cc
+++ b/third_party/blink/renderer/core/editing/finder/text_finder.cc
@@ -664,16 +664,6 @@
     find_matches_cache_.swap(filtered_matches);
   }
 
-  // Invalidate the rects in child frames. Will be updated later during
-  // traversal.
-  if (!find_match_rects_are_valid_) {
-    for (WebFrame* child = OwnerFrame().FirstChild(); child;
-         child = child->NextSibling()) {
-      ToWebLocalFrameImpl(child)
-          ->EnsureTextFinder()
-          .find_match_rects_are_valid_ = false;
-    }
-  }
   find_match_rects_are_valid_ = true;
 }
 
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder.h b/third_party/blink/renderer/core/editing/finder/text_finder.h
index c00661b..e25cb53 100644
--- a/third_party/blink/renderer/core/editing/finder/text_finder.h
+++ b/third_party/blink/renderer/core/editing/finder/text_finder.h
@@ -149,8 +149,7 @@
   int SelectFindMatch(unsigned index, WebRect* selection_rect);
 
   // Compute and cache the rects for FindMatches if required.
-  // Rects are automatically invalidated in case of content size changes,
-  // propagating the invalidation to child frames.
+  // Rects are automatically invalidated in case of content size changes.
   void UpdateFindMatchRects();
 
   // Sets the markers within a range as active or inactive. Returns true if at
diff --git a/third_party/blink/renderer/core/editing/inline_box_position.cc b/third_party/blink/renderer/core/editing/inline_box_position.cc
index b7a9aaf9..edf6704 100644
--- a/third_party/blink/renderer/core/editing/inline_box_position.cc
+++ b/third_party/blink/renderer/core/editing/inline_box_position.cc
@@ -484,8 +484,12 @@
   const int caret_offset = position.ComputeEditingOffset();
 
   if (layout_object.IsText()) {
+    // TODO(yoichio): Consider |ToLayoutText(layout_object)->TextStartOffset()|
+    // for first-letter tested with LocalCaretRectTest::FloatFirstLetter.
+    const int round_offset =
+        std::min(caret_offset, layout_object.CaretMaxOffset());
     return ComputeInlineBoxPositionForTextNode(
-        &ToLayoutText(layout_object), caret_offset, adjusted.Affinity());
+        &ToLayoutText(layout_object), round_offset, adjusted.Affinity());
   }
 
   DCHECK(layout_object.IsAtomicInlineLevel());
diff --git a/third_party/blink/renderer/core/editing/layout_selection.cc b/third_party/blink/renderer/core/editing/layout_selection.cc
index 84892c4..f6ce09a 100644
--- a/third_party/blink/renderer/core/editing/layout_selection.cc
+++ b/third_party/blink/renderer/core/editing/layout_selection.cc
@@ -679,15 +679,21 @@
   return physical_line_box.BaseDirection() == shape_result->Direction();
 }
 
+// FrameSelection holds selection offsets in layout block flow at
+// LayoutSelection::Commit() if selection starts/ends within Text that
+// each LayoutObject::SelectionState indicates.
+// These offset can be out of |text_fragment| because SelectionState is of each
+// LayoutText and not of each NGPhysicalTextFragment for it.
 LayoutSelectionStatus LayoutSelection::ComputeSelectionStatus(
     const NGPaintFragment& fragment) const {
   const NGPhysicalTextFragment& text_fragment =
       ToNGPhysicalTextFragmentOrDie(fragment.PhysicalFragment());
-  // FrameSelection holds selection offsets in layout block flow at
-  // LayoutSelection::Commit() if selection starts/ends within Text that
-  // each LayoutObject::SelectionState indicates.
-  // These offset can out of |text_fragment| because SelectionState is of each
-  // LayoutText and not |text_fragment|.
+  // For BR, WBR, no selection painting.
+  if (fragment.GetNode() && !fragment.GetNode()->IsTextNode())
+    return {0, 0, SelectLineBreak::kNotSelected};
+  if (text_fragment.IsLineBreak())
+    return {0, 0, SelectLineBreak::kNotSelected};
+
   switch (text_fragment.GetLayoutObject()->GetSelectionState()) {
     case SelectionState::kStart: {
       DCHECK(SelectionStart().has_value());
diff --git a/third_party/blink/renderer/core/editing/layout_selection_test.cc b/third_party/blink/renderer/core/editing/layout_selection_test.cc
index b11f28d9..3b96075 100644
--- a/third_party/blink/renderer/core/editing/layout_selection_test.cc
+++ b/third_party/blink/renderer/core/editing/layout_selection_test.cc
@@ -911,4 +911,18 @@
   EXPECT_EQ(SelectLineBreak::kNotSelected,
             ComputeLayoutSelectionStatus(*bar).line_break);
 }
+
+TEST_F(NGLayoutSelectionTest, BRStatus) {
+  const SelectionInDOMTree& selection =
+      SetSelectionTextToBody("<div>foo<!--^--><br><!--|-->bar</div>");
+  Selection().SetSelectionAndEndTyping(selection);
+  Selection().CommitAppearanceIfNeeded();
+  LayoutObject* const layout_br =
+      GetDocument().QuerySelector("br")->GetLayoutObject();
+  CHECK(layout_br->IsBR());
+  EXPECT_EQ(
+      LayoutSelectionStatus(0u, 0u, SelectLineBreak::kNotSelected),
+      Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(layout_br)));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/editing/local_caret_rect_test.cc b/third_party/blink/renderer/core/editing/local_caret_rect_test.cc
index afaf615..8e43d94 100644
--- a/third_party/blink/renderer/core/editing/local_caret_rect_test.cc
+++ b/third_party/blink/renderer/core/editing/local_caret_rect_test.cc
@@ -679,9 +679,7 @@
                            LayoutRect(LayoutNGEnabled() ? 10 : 20, 0, 1, 10)),
             LocalCaretRectOfPosition(PositionWithAffinity(
                 Position(foo, 2), TextAffinity::kDownstream)));
-  EXPECT_EQ(LocalCaretRect(remaining_text, LayoutNGEnabled()
-                                               ? LayoutRect(20, 0, 1, 10)
-                                               : LayoutRect()),
+  EXPECT_EQ(LocalCaretRect(remaining_text, LayoutRect(20, 0, 1, 10)),
             LocalCaretRectOfPosition(PositionWithAffinity(
                 Position(foo, 3), TextAffinity::kDownstream)));
 }
@@ -904,6 +902,17 @@
   EXPECT_EQ(LayoutRect(299, 10, 1, 10), visible_position_rect);
 };
 
+// crbug.com/834686
+TEST_P(ParameterizedLocalCaretRectTest, AfterTrimedLineBreak) {
+  LoadAhem();
+  InsertStyleElement("body { font: 10px/10px Ahem; width: 300px }");
+  const Position& caret = SetCaretTextToBody("<div>foo\n|</div>");
+  LayoutRect position_rect, visible_position_rect;
+  std::tie(position_rect, visible_position_rect) = GetLayoutRects(caret);
+  EXPECT_EQ(LayoutRect(30, 0, 1, 10), position_rect);
+  EXPECT_EQ(LayoutRect(30, 0, 1, 10), visible_position_rect);
+};
+
 TEST_P(ParameterizedLocalCaretRectTest,
        UnicodeBidiPlaintextWithDifferentBlockDirection) {
   LoadAhem();
diff --git a/third_party/blink/renderer/core/editing/rendered_position_test.cc b/third_party/blink/renderer/core/editing/rendered_position_test.cc
index 152949d8..f9661d1 100644
--- a/third_party/blink/renderer/core/editing/rendered_position_test.cc
+++ b/third_party/blink/renderer/core/editing/rendered_position_test.cc
@@ -272,4 +272,27 @@
             FloatPoint(8.0f, 28.0f));
 }
 
+// crbug.com/834686
+TEST_P(RenderedPositionTest, RangeBeginAtBlockEnd) {
+  const SelectionInDOMTree& selection = SetSelectionTextToBody(
+      "<div style='font: 10px/10px Ahem;'>"
+      "<div>foo\n^</div><div>ba|r</div></div>");
+  Selection().SetSelection(
+      selection,
+      SetSelectionOptions::Builder().SetShouldShowHandle(true).Build());
+  Element* target = GetDocument().QuerySelector("div");
+  target->focus();
+  UpdateAllLifecyclePhases();
+  const CompositedSelection& composited_selection =
+      RenderedPosition::ComputeCompositedSelection(Selection());
+  EXPECT_EQ(composited_selection.start.edge_top_in_layer,
+            FloatPoint(38.0f, 8.0f));
+  EXPECT_EQ(composited_selection.start.edge_bottom_in_layer,
+            FloatPoint(38.0f, 18.0f));
+  EXPECT_EQ(composited_selection.end.edge_top_in_layer,
+            FloatPoint(28.0f, 18.0f));
+  EXPECT_EQ(composited_selection.end.edge_bottom_in_layer,
+            FloatPoint(28.0f, 28.0f));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/editing/selection_modifier_character.cc b/third_party/blink/renderer/core/editing/selection_modifier_character.cc
index afa02f57..79ac1a6 100644
--- a/third_party/blink/renderer/core/editing/selection_modifier_character.cc
+++ b/third_party/blink/renderer/core/editing/selection_modifier_character.cc
@@ -271,6 +271,60 @@
   }
 }
 
+// TODO(xiaochengh): Stop passing return value by non-const reference parameters
+template <typename Traversal>
+bool FindForwardBoxInPossiblyBidiContext(const InlineBox*& box,
+                                         int& offset,
+                                         TextDirection primary_direction) {
+  // TODO(xiaochengh): Make |level| and |forward_box| const, and use additional
+  // variables for their changed values.
+  unsigned char level = box->BidiLevel();
+  const InlineBox* forward_box = Traversal::ForwardLeafChildOf(*box);
+
+  if (box->Direction() == primary_direction) {
+    if (!forward_box) {
+      InlineBox* logical_start = nullptr;
+      if (Traversal::LogicalStartBoxOf(primary_direction, *box,
+                                       logical_start)) {
+        box = logical_start;
+        offset = Traversal::CaretMinOffsetOf(primary_direction, *box);
+      }
+      return true;
+    }
+    if (forward_box->BidiLevel() >= level)
+      return true;
+
+    level = forward_box->BidiLevel();
+    const InlineBox* const backward_box =
+        Traversal::FindBackwardBidiRun(*box, level);
+    if (backward_box && backward_box->BidiLevel() == level)
+      return true;
+
+    box = forward_box;
+    offset = Traversal::CaretEndOffsetOf(*box);
+    return box->Direction() == primary_direction;
+  }
+
+  while (forward_box && !forward_box->GetLineLayoutItem().GetNode())
+    forward_box = Traversal::ForwardLeafChildOf(*forward_box);
+
+  if (forward_box) {
+    box = forward_box;
+    offset = Traversal::CaretEndOffsetOf(*box);
+    if (box->BidiLevel() > level) {
+      forward_box = Traversal::FindForwardBidiRun(*forward_box, level);
+      if (!forward_box || forward_box->BidiLevel() < level)
+        return false;
+    }
+    return true;
+  }
+  // Trailing edge of a secondary run. Set to the leading edge of
+  // the entire run.
+  box = LeadingBoxOfEntireSecondaryRun<Traversal>(box);
+  offset = Traversal::CaretMinOffsetOf(primary_direction, *box);
+  return true;
+}
+
 template <typename Strategy, typename Traversal>
 static PositionTemplate<Strategy> TraverseInternalAlgorithm(
     const VisiblePositionTemplate<Strategy>& visible_position) {
@@ -353,55 +407,10 @@
       }
 
       DCHECK_EQ(offset, Traversal::CaretStartOffsetOf(*box));
-
-      unsigned char level = box->BidiLevel();
-      const InlineBox* forward_box = Traversal::ForwardLeafChildOf(*box);
-
-      if (box->Direction() == primary_direction) {
-        if (!forward_box) {
-          InlineBox* logical_start = nullptr;
-          if (Traversal::LogicalStartBoxOf(primary_direction, *box,
-                                           logical_start)) {
-            box = logical_start;
-            offset = Traversal::CaretMinOffsetOf(primary_direction, *box);
-          }
-          break;
-        }
-        if (forward_box->BidiLevel() >= level)
-          break;
-
-        level = forward_box->BidiLevel();
-
-        const InlineBox* const backward_box =
-            Traversal::FindBackwardBidiRun(*box, level);
-        if (backward_box && backward_box->BidiLevel() == level)
-          break;
-
-        box = forward_box;
-        offset = Traversal::CaretEndOffsetOf(*box);
-        if (box->Direction() == primary_direction)
-          break;
-        continue;
-      }
-
-      while (forward_box && !forward_box->GetLineLayoutItem().GetNode())
-        forward_box = Traversal::ForwardLeafChildOf(*forward_box);
-
-      if (forward_box) {
-        box = forward_box;
-        offset = Traversal::CaretEndOffsetOf(*box);
-        if (box->BidiLevel() > level) {
-          forward_box = Traversal::FindForwardBidiRun(*forward_box, level);
-          if (!forward_box || forward_box->BidiLevel() < level)
-            continue;
-        }
+      const bool should_break = FindForwardBoxInPossiblyBidiContext<Traversal>(
+          box, offset, primary_direction);
+      if (should_break)
         break;
-      }
-      // Trailing edge of a secondary run. Set to the leading edge of
-      // the entire run.
-      box = LeadingBoxOfEntireSecondaryRun<Traversal>(box);
-      offset = Traversal::CaretMinOffsetOf(primary_direction, *box);
-      break;
     }
 
     p = PositionTemplate<Strategy>::EditingPositionOf(
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.h b/third_party/blink/renderer/core/html/forms/html_input_element.h
index 06effcc..eae585d 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.h
@@ -394,8 +394,6 @@
 
   void SetListAttributeTargetObserver(ListAttributeTargetObserver*);
   void ResetListAttributeTargetObserver();
-  void ParseMaxLengthAttribute(const AtomicString&);
-  void ParseMinLengthAttribute(const AtomicString&);
 
   // Returns null if this isn't associated with any radio button group.
   RadioButtonGroupScope* GetRadioButtonGroupScope() const;
diff --git a/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
index f208e2e..55bc8228 100644
--- a/third_party/blink/renderer/core/inspector/browser_protocol.pdl
+++ b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -3283,6 +3283,8 @@
       NameNotResolved
       InternetDisconnected
       AddressUnreachable
+      BlockedByClient
+      BlockedByResponse
 
   # UTC time in seconds, counted from January 1, 1970.
   type TimeSinceEpoch extends number
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow_line.cc b/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
index 8516d62..9d80ecff 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
+++ b/third_party/blink/renderer/core/layout/layout_block_flow_line.cc
@@ -38,6 +38,7 @@
 #include "third_party/blink/renderer/core/layout/line/word_measurement.h"
 #include "third_party/blink/renderer/core/layout/svg/line/svg_root_inline_box.h"
 #include "third_party/blink/renderer/core/layout/vertical_position_cache.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
 #include "third_party/blink/renderer/platform/text/bidi_resolver.h"
 #include "third_party/blink/renderer/platform/text/character.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -2654,6 +2655,8 @@
   DCHECK(ChildrenInline());
   if (RootInlineBox* first_root_box = FirstRootBox())
     first_root_box->SetShouldDoFullPaintInvalidationRecursively();
+  else if (NGPaintFragment* paint_fragment = PaintFragment())
+    paint_fragment->SetShouldDoFullPaintInvalidationForFirstLine();
 }
 
 bool LayoutBlockFlow::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() const {
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index cf12019..6fd5e66 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -66,10 +66,12 @@
 #include "third_party/blink/renderer/core/page/scrolling/root_scroller_util.h"
 #include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
 #include "third_party/blink/renderer/core/page/scrolling/snap_coordinator.h"
+#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
 #include "third_party/blink/renderer/core/paint/background_image_geometry.h"
 #include "third_party/blink/renderer/core/paint/box_paint_invalidator.h"
 #include "third_party/blink/renderer/core/paint/box_painter.h"
 #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
 #include "third_party/blink/renderer/core/paint/paint_layer.h"
 #include "third_party/blink/renderer/core/style/shadow_list.h"
 #include "third_party/blink/renderer/platform/geometry/double_rect.h"
@@ -5494,6 +5496,20 @@
                      point.Y());
 }
 
+LayoutPoint LayoutBox::FlipForWritingModeForChildForPaint(
+    const LayoutBox* child,
+    const LayoutPoint& point) const {
+  // Do nothing unless in FlippedBlocks(). Fast path optimization
+  if (!Style()->IsFlippedBlocksWritingMode())
+    return point;
+  // If child will be painted by LayoutNG, and will use fragment.Offset(),
+  // flip is not needed.
+  if (!AdjustPaintOffsetScope::WillUseLegacyLocation(child))
+    return point;
+
+  return FlipForWritingModeForChild(child, point);
+}
+
 LayoutBox* LayoutBox::LocationContainer() const {
   // Location of a non-root SVG object derived from LayoutBox should not be
   // affected by writing-mode of the containing box (SVGRoot).
@@ -6050,4 +6066,19 @@
   return overflow_ && overflow_->HasSubpixelVisualEffectOutsets() ? 1 : 0;
 }
 
+TextDirection LayoutBox::ResolvedDirection() const {
+  if (IsInline() && IsAtomicInlineLevel()) {
+    const auto fragments = NGPaintFragment::InlineFragmentsFor(this);
+    if (fragments.IsInLayoutNGInlineFormattingContext()) {
+      DCHECK(*fragments.begin()) << this;
+      const NGPaintFragment* fragment = *fragments.begin();
+      return fragment->PhysicalFragment().ResolvedDirection();
+    }
+
+    if (InlineBoxWrapper())
+      return InlineBoxWrapper()->Direction();
+  }
+  return Style()->Direction();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h
index 82f72ae..c3348c5 100644
--- a/third_party/blink/renderer/core/layout/layout_box.h
+++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -1154,6 +1154,12 @@
 
   LayoutPoint FlipForWritingModeForChild(const LayoutBox* child,
                                          const LayoutPoint&) const;
+
+  // NG: Like FlipForWritingModeForChild, except that it will not flip
+  // if LayoutBox will be painted by NG using fragment.Offset.
+  LayoutPoint FlipForWritingModeForChildForPaint(const LayoutBox* child,
+                                                 const LayoutPoint&) const;
+
   WARN_UNUSED_RESULT LayoutUnit FlipForWritingMode(LayoutUnit position) const {
     // The offset is in the block direction (y for horizontal writing modes, x
     // for vertical writing modes).
@@ -1526,6 +1532,11 @@
 
   LayoutRect LocalVisualRectIgnoringVisibility() const override;
 
+  // For atomic inlines, returns its resolved direction in text flow. Not to be
+  // confused with the CSS property 'direction'.
+  // Returns the CSS 'direction' property value when it is not atomic inline.
+  TextDirection ResolvedDirection() const;
+
  private:
   void UpdateShapeOutsideInfoAfterStyleChange(const ComputedStyle&,
                                               const ComputedStyle* old_style);
diff --git a/third_party/blink/renderer/core/layout/layout_replaced.cc b/third_party/blink/renderer/core/layout/layout_replaced.cc
index 8ffe6c3..c7fb8a94 100644
--- a/third_party/blink/renderer/core/layout/layout_replaced.cc
+++ b/third_party/blink/renderer/core/layout/layout_replaced.cc
@@ -961,9 +961,12 @@
         CaretMaxOffset());  // coordinates are below
 
   if (GetNode()) {
-    if (line_direction_position <= LogicalLeft() + (LogicalWidth() / 2))
-      return CreatePositionWithAffinity(0);
-    return CreatePositionWithAffinity(1);
+    const bool is_at_left_side =
+        line_direction_position <= LogicalLeft() + (LogicalWidth() / 2);
+    const bool is_at_start = is_at_left_side == IsLtr(ResolvedDirection());
+    // TODO(crbug.com/827923): Stop creating positions using int offsets on
+    // non-text nodes.
+    return CreatePositionWithAffinity(is_at_start ? 0 : 1);
   }
 
   return LayoutBox::PositionForPoint(point);
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc
index e1be2128..fcb193c6 100644
--- a/third_party/blink/renderer/core/layout/layout_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -659,20 +659,15 @@
           should_affinity_be_downstream);
     }
 
-    if (!prev_box || prev_box->BidiLevel() < box->BidiLevel()) {
-      // e.g. left of D in aDC12BAb
-      const InlineBox& rightmost_box =
-          InlineBoxTraversal::FindRightBoundaryOfEntireBidiRunIgnoringLineBreak(
-              *box, box->BidiLevel());
-      return CreatePositionWithAffinityForBox(
-          &rightmost_box,
-          box->IsLeftToRightDirection() ? rightmost_box.CaretMaxOffset()
-                                        : rightmost_box.CaretMinOffset(),
-          should_affinity_be_downstream);
-    }
-
-    return CreatePositionWithAffinityForBox(box, box->CaretRightmostOffset(),
-                                            should_affinity_be_downstream);
+    // e.g. left of D in aDC12BAb
+    const InlineBox& rightmost_box =
+        InlineBoxTraversal::FindRightBoundaryOfEntireBidiRunIgnoringLineBreak(
+            *box, box->BidiLevel());
+    return CreatePositionWithAffinityForBox(
+        &rightmost_box,
+        box->IsLeftToRightDirection() ? rightmost_box.CaretMaxOffset()
+                                      : rightmost_box.CaretMinOffset(),
+        should_affinity_be_downstream);
   }
 
   // offset is on the right edge
@@ -693,19 +688,14 @@
                                             should_affinity_be_downstream);
   }
 
-  if (!next_box || next_box->BidiLevel() < box->BidiLevel()) {
-    // e.g. right of A in aDC12BAb
-    const InlineBox& leftmost_box =
-        InlineBoxTraversal::FindLeftBoundaryOfEntireBidiRunIgnoringLineBreak(
-            *box, box->BidiLevel());
-    return CreatePositionWithAffinityForBox(&leftmost_box,
-                                            box->IsLeftToRightDirection()
-                                                ? leftmost_box.CaretMinOffset()
-                                                : leftmost_box.CaretMaxOffset(),
-                                            should_affinity_be_downstream);
-  }
-
-  return CreatePositionWithAffinityForBox(box, box->CaretLeftmostOffset(),
+  // e.g. right of A in aDC12BAb
+  const InlineBox& leftmost_box =
+      InlineBoxTraversal::FindLeftBoundaryOfEntireBidiRunIgnoringLineBreak(
+          *box, box->BidiLevel());
+  return CreatePositionWithAffinityForBox(&leftmost_box,
+                                          box->IsLeftToRightDirection()
+                                              ? leftmost_box.CaretMinOffset()
+                                              : leftmost_box.CaretMaxOffset(),
                                           should_affinity_be_downstream);
 }
 
@@ -1958,6 +1948,26 @@
   if (!cb)
     return LayoutRect();
 
+  const FrameSelection& frame_selection = GetFrame()->Selection();
+  const auto fragments = NGPaintFragment::InlineFragmentsFor(this);
+  if (fragments.IsInLayoutNGInlineFormattingContext()) {
+    LayoutRect rect;
+    for (const NGPaintFragment* fragment : fragments) {
+      const LayoutSelectionStatus status =
+          frame_selection.ComputeLayoutSelectionStatus(*fragment);
+      if (status.start == status.end)
+        continue;
+      // TODO(yoichio): We should consider linebreak selection. See
+      // ng_text_fragment_painter.cc::PaintSelection.
+      NGPhysicalOffsetRect fragment_rect =
+          ToNGPhysicalTextFragment(fragment->PhysicalFragment())
+              .LocalRect(status.start, status.end);
+      fragment_rect.offset += fragment->InlineOffsetToContainerBox();
+      rect.Unite(fragment_rect.ToLayoutRect());
+    }
+    return rect;
+  }
+
   // Now calculate startPos and endPos for painting selection.
   // We include a selection while endPos > 0
   unsigned start_pos, end_pos;
@@ -1966,7 +1976,6 @@
     start_pos = 0;
     end_pos = TextLength();
   } else {
-    const FrameSelection& frame_selection = GetFrame()->Selection();
     if (GetSelectionState() == SelectionState::kStart) {
       // TODO(yoichio): value_or is used to prevent use uininitialized value
       // on release. It should be value() after LayoutSelection brushup.
@@ -1982,12 +1991,8 @@
     }
   }
 
-  // TODO(yoichio): The following DCHECK should pass, but fails 14 tests.
-  // DCHECK_LE(start_pos, end_pos);
+  DCHECK_LE(start_pos, end_pos);
   LayoutRect rect;
-  if (start_pos >= end_pos)
-    return rect;
-
   for (InlineTextBox* box : TextBoxes()) {
     rect.Unite(box->LocalSelectionRect(start_pos, end_pos));
     rect.Unite(LayoutRect(EllipsisRectForBox(box, start_pos, end_pos)));
diff --git a/third_party/blink/renderer/core/layout/layout_text_test.cc b/third_party/blink/renderer/core/layout/layout_text_test.cc
index 6fe0006..fa02d5c8 100644
--- a/third_party/blink/renderer/core/layout/layout_text_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_test.cc
@@ -6,6 +6,9 @@
 
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/editing/frame_selection.h"
+#include "third_party/blink/renderer/core/editing/selection_template.h"
+#include "third_party/blink/renderer/core/editing/testing/selection_sample.h"
 #include "third_party/blink/renderer/core/layout/line/inline_text_box.h"
 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -33,6 +36,35 @@
   }
 
   LayoutText* GetBasicText() { return GetLayoutTextById("target"); }
+
+  void SetSelectionAndUpdateLayoutSelection(const std::string& selection_text) {
+    const SelectionInDOMTree selection =
+        SelectionSample::SetSelectionText(GetDocument().body(), selection_text);
+    UpdateAllLifecyclePhases();
+    Selection().SetSelectionAndEndTyping(selection);
+    Selection().CommitAppearanceIfNeeded();
+  }
+
+  const LayoutText* FindFirstLayoutText() {
+    for (const Node& node :
+         NodeTraversal::DescendantsOf(*GetDocument().body())) {
+      if (node.GetLayoutObject() && node.GetLayoutObject()->IsText())
+        return ToLayoutTextOrDie(node.GetLayoutObject());
+    }
+    NOTREACHED();
+    return nullptr;
+  }
+
+  LayoutRect GetSelectionRectFor(const std::string& selection_text) {
+    std::stringstream stream;
+    stream << "<div style='font: 10px/10px Ahem;'>" << selection_text
+           << "</div>";
+    SetSelectionAndUpdateLayoutSelection(stream.str());
+    const Node* target = GetDocument().getElementById("target");
+    const LayoutObject* layout_object =
+        target ? target->GetLayoutObject() : FindFirstLayoutText();
+    return layout_object->LocalSelectionRect();
+  }
 };
 
 const char kTacoText[] = "Los Compadres Taco Truck";
@@ -579,4 +611,28 @@
   EXPECT_EQ(0, layout_wbr->CaretMaxOffset());
 }
 
+TEST_P(ParameterizedLayoutTextTest, LocalSelectionRect) {
+  LoadAhem();
+  // TODO(yoichio): Fix LayoutNG incompatibility.
+  EXPECT_EQ(LayoutRect(10, 0, 50, 10), GetSelectionRectFor("f^oo ba|r"));
+  EXPECT_EQ(
+      LayoutNGEnabled() ? LayoutRect(0, 0, 30, 20) : LayoutRect(0, 0, 40, 20),
+      GetSelectionRectFor("<div style='width: 2em'>f^oo ba|r</div>"));
+  EXPECT_EQ(
+      LayoutNGEnabled() ? LayoutRect(0, 0, 0, 0) : LayoutRect(30, 0, 10, 10),
+      GetSelectionRectFor("foo^<br id='target'>|bar"));
+  EXPECT_EQ(LayoutRect(30, 0, 10, 10), GetSelectionRectFor("foo^ |bar"));
+  EXPECT_EQ(LayoutRect(0, 0, 0, 0), GetSelectionRectFor("^ |foo"));
+  EXPECT_EQ(LayoutRect(0, 0, 0, 0),
+            GetSelectionRectFor("fo^o<wbr id='target'>ba|r"));
+  EXPECT_EQ(
+      LayoutRect(0, 0, 10, 10),
+      GetSelectionRectFor("<style>:first-letter { float: right}</style>^fo|o"));
+  // Since we don't paint trimed white spaces on LayoutNG,  we don't need fix
+  // this case.
+  EXPECT_EQ(
+      LayoutNGEnabled() ? LayoutRect(0, 0, 0, 0) : LayoutRect(30, 0, 10, 10),
+      GetSelectionRectFor("foo^ |"));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
index 8888f016..728be74 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
@@ -237,7 +237,8 @@
                                         accumulated_offset, action);
   }
 
-  LayoutPoint adjusted_location = accumulated_offset + Base::Location();
+  LayoutPoint adjusted_location =
+      accumulated_offset + PaintFragment()->Offset().ToLayoutPoint();
   if (!RootScrollerUtil::IsEffective(*this)) {
     // Check if we need to do anything at all.
     // If we have clipping, then we can't have any spillout.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
index 1318b8f..73513ed 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -126,6 +126,8 @@
 // handles such cases.
 void CopyFragmentDataToLayoutBoxForInlineChildren(
     const NGPhysicalContainerFragment& container,
+    LayoutUnit initial_container_width,
+    bool initial_container_is_flipped,
     NGPhysicalOffset offset = {}) {
   for (const auto& child : container.Children()) {
     if (child->IsContainer()) {
@@ -136,7 +138,13 @@
       LayoutObject* layout_object = child->GetLayoutObject();
       if (layout_object && layout_object->IsBox()) {
         LayoutBox& layout_box = ToLayoutBox(*layout_object);
-        layout_box.SetLocation(child_offset.ToLayoutPoint());
+        NGPhysicalOffset maybe_flipped_offset = child_offset;
+        if (initial_container_is_flipped) {
+          maybe_flipped_offset.left = initial_container_width -
+                                      child->Size().width -
+                                      maybe_flipped_offset.left;
+        }
+        layout_box.SetLocation(maybe_flipped_offset.ToLayoutPoint());
       }
 
       // The Location() of inline LayoutObject is relative to the
@@ -145,7 +153,8 @@
       // to its descendants in this case.
       if (!child->IsBlockLayoutRoot()) {
         CopyFragmentDataToLayoutBoxForInlineChildren(
-            ToNGPhysicalContainerFragment(*child), child_offset);
+            ToNGPhysicalContainerFragment(*child), initial_container_width,
+            initial_container_is_flipped, child_offset);
       }
     }
   }
@@ -204,8 +213,12 @@
     DCHECK(layout_result->PhysicalFragment());
 
     if (block_flow && first_child && first_child.IsInline()) {
-        CopyFragmentDataToLayoutBoxForInlineChildren(
-            ToNGPhysicalBoxFragment(*layout_result->PhysicalFragment()));
+      NGBoxStrut scrollbars = GetScrollbarSizes();
+      CopyFragmentDataToLayoutBoxForInlineChildren(
+          ToNGPhysicalBoxFragment(*layout_result->PhysicalFragment()),
+          layout_result->PhysicalFragment()->Size().width -
+              scrollbars.block_start,
+          Style().IsFlippedBlocksWritingMode());
 
       block_flow->SetPaintFragment(layout_result->PhysicalFragment());
     }
diff --git a/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.cc b/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.cc
index 8a1ccf9..aa4b69e 100644
--- a/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.cc
+++ b/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
 
+#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
 #include "third_party/blink/renderer/core/layout/layout_table_section.h"
 
 namespace blink {
@@ -58,4 +59,17 @@
   return false;
 }
 
+bool AdjustPaintOffsetScope::WillUseLegacyLocation(const LayoutBox* child) {
+  if (child->HasSelfPaintingLayer())
+    return true;
+  if (child->IsLayoutNGMixin()) {
+    NGPaintFragment* paint_fragment = ToLayoutBlockFlow(child)->PaintFragment();
+    if (!paint_fragment)
+      return true;
+    if (!paint_fragment->PhysicalFragment().IsPlacedByLayoutNG())
+      return true;
+    return false;
+  }
+  return true;
+}
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h b/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h
index 117d920..23e0154 100644
--- a/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h
+++ b/third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h
@@ -34,28 +34,10 @@
     if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled() &&
         AdjustPaintOffset(box))
       return;
-    // This code is poorly understood, this is teams current understanding.
-    //
-    // adjusted_paint_offset should be the flipped block physical frament
-    // offset from Layer() (flipped if flippedBlock, physical otherwise)
-    if (UNLIKELY(box.HasFlippedBlocksWritingMode() ||
-                 box.HasSelfPaintingLayer())) {
-      // Two separate problems result in thesame solution:
-      // A) box.HasSelfPaintingLayer()
+    if (UNLIKELY(box.HasSelfPaintingLayer())) {
       //   There is no containing block here, we are painting from origin.
       //   paint_offset is 0,0
       //   box.Location is offset from Layer()
-      //   => adjusted__paint_offset = box offset from Layer()
-      // C) box.HasFlippedBlocksWritingMode()
-      //   paint_offset is containing box offset from Layer() in flipped blocks
-      //   box.Location is box offset from containing box in flipped blocks
-      //   => adjusted_paint_offset = box offset from Layer()
-      //
-      // fragment.Offset() is in physical coordinate, not a flipped physical
-      // coordinate, but BlockPainter::PaintChild() has already incorporated
-      // flipping and assume child painters accumulate flipped offset.
-      // NGBlockNode::CopyFragmentDataToLayoutBox() already computed flipped
-      // fragment.Offset() and stored to LayoutBox, so use it.
       adjusted_paint_offset_ = paint_offset + box.Location();
     } else {
       adjusted_paint_offset_ = paint_offset + fragment.Offset().ToLayoutPoint();
@@ -74,6 +56,9 @@
 
   LayoutPoint AdjustedPaintOffset() const { return adjusted_paint_offset_; }
 
+  // True if child will use LayoutObject::Location to compute adjusted_offset.
+  static bool WillUseLegacyLocation(const LayoutBox* child);
+
  private:
   // Returns true if paint info and offset has been adjusted.
   bool AdjustPaintOffset(const LayoutBox&);
diff --git a/third_party/blink/renderer/core/paint/block_painter.cc b/third_party/blink/renderer/core/paint/block_painter.cc
index b81d48aa..cd5fa156 100644
--- a/third_party/blink/renderer/core/paint/block_painter.cc
+++ b/third_party/blink/renderer/core/paint/block_painter.cc
@@ -113,7 +113,7 @@
                               const PaintInfo& paint_info,
                               const LayoutPoint& paint_offset) {
   LayoutPoint child_point =
-      layout_block_.FlipForWritingModeForChild(&child, paint_offset);
+      layout_block_.FlipForWritingModeForChildForPaint(&child, paint_offset);
   if (!child.HasSelfPaintingLayer() && !child.IsFloating() &&
       !child.IsColumnSpanAll())
     child.Paint(paint_info, child_point);
@@ -134,7 +134,7 @@
     const PaintInfo& paint_info,
     const LayoutPoint& paint_offset) {
   LayoutPoint child_point =
-      layout_block_.FlipForWritingModeForChild(&child, paint_offset);
+      layout_block_.FlipForWritingModeForChildForPaint(&child, paint_offset);
   if (!child.HasSelfPaintingLayer() && !child.IsFloating())
     ObjectPainter(child).PaintAllPhasesAtomically(paint_info, child_point);
 }
@@ -159,7 +159,7 @@
     child_point =
         LineLayoutAPIShim::LayoutObjectFrom(inline_box.GetLineLayoutItem())
             ->ContainingBlock()
-            ->FlipForWritingModeForChild(
+            ->FlipForWritingModeForChildForPaint(
                 ToLayoutBox(LineLayoutAPIShim::LayoutObjectFrom(
                     inline_box.GetLineLayoutItem())),
                 child_point);
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.cc b/third_party/blink/renderer/core/paint/box_painter_base.cc
index 76057ec..75f212f 100644
--- a/third_party/blink/renderer/core/paint/box_painter_base.cc
+++ b/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -269,47 +269,6 @@
   return is_non_associative;
 }
 
-FloatRoundedRect BoxPainterBase::BackgroundRoundedRectAdjustedForBleedAvoidance(
-    const LayoutRect& border_rect,
-    bool flow_box_has_multiple_fragments,
-    const LayoutSize& flow_box_size,
-    bool include_logical_left_edge,
-    bool include_logical_right_edge,
-    FloatRoundedRect background_rounded_rect) const {
-  // Inset the background rect by a "safe" amount: 1/2 border-width for opaque
-  // border styles, 1/6 border-width for double borders.
-
-  // TODO(fmalita): we should be able to fold these parameters into
-  // BoxBorderInfo or BoxDecorationData and avoid calling getBorderEdgeInfo
-  // redundantly here.
-  BorderEdge edges[4];
-  style_.GetBorderEdgeInfo(edges, include_logical_left_edge,
-                           include_logical_right_edge);
-
-  // Use the most conservative inset to avoid mixed-style corner issues.
-  float fractional_inset = 1.0f / 2;
-  for (auto& edge : edges) {
-    if (edge.BorderStyle() == EBorderStyle::kDouble) {
-      fractional_inset = 1.0f / 6;
-      break;
-    }
-  }
-
-  FloatRectOutsets insets(
-      -fractional_inset * edges[static_cast<unsigned>(BoxSide::kTop)].Width(),
-      -fractional_inset * edges[static_cast<unsigned>(BoxSide::kRight)].Width(),
-      -fractional_inset *
-          edges[static_cast<unsigned>(BoxSide::kBottom)].Width(),
-      -fractional_inset * edges[static_cast<unsigned>(BoxSide::kLeft)].Width());
-
-  FloatRect inset_rect(background_rounded_rect.Rect());
-  inset_rect.Expand(insets);
-  FloatRoundedRect::Radii inset_radii(background_rounded_rect.GetRadii());
-  inset_radii.Shrink(-insets.Top(), -insets.Bottom(), -insets.Left(),
-                     -insets.Right());
-  return FloatRoundedRect(inset_rect, inset_radii);
-}
-
 BoxPainterBase::FillLayerInfo::FillLayerInfo(
     const Document& doc,
     const ComputedStyle& style,
@@ -449,16 +408,94 @@
 
   return true;
 }
+// Inset the background rect by a "safe" amount: 1/2 border-width for opaque
+// border styles, 1/6 border-width for double borders.
+FloatRoundedRect BackgroundRoundedRectAdjustedForBleedAvoidance(
+    const ComputedStyle& style,
+    const LayoutRect& border_rect,
+    bool flow_box_has_multiple_fragments,
+    bool include_logical_left_edge,
+    bool include_logical_right_edge,
+    FloatRoundedRect background_rounded_rect) {
+  // TODO(fmalita): we should be able to fold these parameters into
+  // BoxBorderInfo or BoxDecorationData and avoid calling getBorderEdgeInfo
+  // redundantly here.
+  BorderEdge edges[4];
+  style.GetBorderEdgeInfo(edges, include_logical_left_edge,
+                          include_logical_right_edge);
 
-}  // anonymous namespace
+  // Use the most conservative inset to avoid mixed-style corner issues.
+  float fractional_inset = 1.0f / 2;
+  for (auto& edge : edges) {
+    if (edge.BorderStyle() == EBorderStyle::kDouble) {
+      fractional_inset = 1.0f / 6;
+      break;
+    }
+  }
 
-void BoxPainterBase::PaintFillLayerBackground(
-    GraphicsContext& context,
-    const FillLayerInfo& info,
-    Image* image,
-    SkBlendMode composite_op,
-    const BackgroundImageGeometry& geometry,
-    LayoutRect scrolled_paint_rect) {
+  FloatRectOutsets insets(
+      -fractional_inset * edges[static_cast<unsigned>(BoxSide::kTop)].Width(),
+      -fractional_inset * edges[static_cast<unsigned>(BoxSide::kRight)].Width(),
+      -fractional_inset *
+          edges[static_cast<unsigned>(BoxSide::kBottom)].Width(),
+      -fractional_inset * edges[static_cast<unsigned>(BoxSide::kLeft)].Width());
+
+  FloatRect inset_rect(background_rounded_rect.Rect());
+  inset_rect.Expand(insets);
+  FloatRoundedRect::Radii inset_radii(background_rounded_rect.GetRadii());
+  inset_radii.Shrink(-insets.Top(), -insets.Bottom(), -insets.Left(),
+                     -insets.Right());
+  return FloatRoundedRect(inset_rect, inset_radii);
+}
+
+FloatRoundedRect RoundedBorderRectForClip(
+    const ComputedStyle& style,
+    const BoxPainterBase::FillLayerInfo& info,
+    const FillLayer& bg_layer,
+    const LayoutRect& rect,
+    bool flow_box_has_multiple_fragments,
+    const LayoutSize& flow_box_size,
+    BackgroundBleedAvoidance bleed_avoidance,
+    LayoutRectOutsets border_padding_insets) {
+  if (!info.is_rounded_fill)
+    return FloatRoundedRect();
+
+  FloatRoundedRect border = style.GetRoundedBorderFor(
+      rect, info.include_left_edge, info.include_right_edge);
+  if (flow_box_has_multiple_fragments) {
+    FloatRoundedRect segment_border = style.GetRoundedBorderFor(
+        LayoutRect(LayoutPoint(), LayoutSize(FlooredIntSize(flow_box_size))),
+        info.include_left_edge, info.include_right_edge);
+    border.SetRadii(segment_border.GetRadii());
+  }
+
+  if (info.is_border_fill &&
+      bleed_avoidance == kBackgroundBleedShrinkBackground) {
+    border = BackgroundRoundedRectAdjustedForBleedAvoidance(
+        style, rect, flow_box_has_multiple_fragments, info.include_left_edge,
+        info.include_right_edge, border);
+  }
+
+  // Clip to the padding or content boxes as necessary.
+  if (bg_layer.Clip() == EFillBox::kContent) {
+    border = style.GetRoundedInnerBorderFor(
+        LayoutRect(border.Rect()), border_padding_insets,
+        info.include_left_edge, info.include_right_edge);
+  } else if (bg_layer.Clip() == EFillBox::kPadding) {
+    border = style.GetRoundedInnerBorderFor(LayoutRect(border.Rect()),
+                                            info.include_left_edge,
+                                            info.include_right_edge);
+  }
+  return border;
+}
+
+void PaintFillLayerBackground(GraphicsContext& context,
+                              const BoxPainterBase::FillLayerInfo& info,
+                              Node* node,
+                              Image* image,
+                              SkBlendMode composite_op,
+                              const BackgroundImageGeometry& geometry,
+                              LayoutRect scrolled_paint_rect) {
   // Paint the color first underneath all images, culled if background image
   // occludes it.
   // TODO(trchen): In the !bgLayer.hasRepeatXY() case, we could improve the
@@ -475,7 +512,7 @@
   if (info.should_paint_image && !geometry.DestRect().IsEmpty() && image) {
     TRACE_EVENT1(
         TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data",
-        InspectorPaintImageEvent::Data(node_, *info.image, image->Rect(),
+        InspectorPaintImageEvent::Data(node, *info.image, image->Rect(),
                                        FloatRect(scrolled_paint_rect)));
     context.DrawTiledImage(image, FloatRect(geometry.DestRect()),
                            FloatPoint(geometry.Phase()),
@@ -484,41 +521,22 @@
   }
 }
 
+LayoutRectOutsets AdjustOutsetsForEdgeInclusion(
+    const LayoutRectOutsets outsets,
+    const BoxPainterBase::FillLayerInfo& info) {
+  LayoutRectOutsets adjusted = outsets;
+  if (!info.include_right_edge)
+    adjusted.SetRight(LayoutUnit());
+  if (!info.include_left_edge)
+    adjusted.SetLeft(LayoutUnit());
+  return adjusted;
+}
+
+}  // anonymous namespace
+
 LayoutRectOutsets BoxPainterBase::BorderOutsets(
     const FillLayerInfo& info) const {
-  LayoutRectOutsets borders = border_;
-  if (!info.include_right_edge)
-    borders.SetRight(LayoutUnit());
-  if (!info.include_left_edge)
-    borders.SetLeft(LayoutUnit());
-  return borders;
-}
-
-LayoutRectOutsets BoxPainterBase::PaddingOutsets(
-    const FillLayerInfo& info) const {
-  LayoutRectOutsets paddings = padding_;
-  if (!info.include_right_edge)
-    paddings.SetRight(LayoutUnit());
-  if (!info.include_left_edge)
-    paddings.SetLeft(LayoutUnit());
-  return paddings;
-}
-
-FloatRoundedRect BoxPainterBase::GetBackgroundRoundedRect(
-    const LayoutRect& border_rect,
-    bool flow_box_has_multiple_fragments,
-    const LayoutSize& flow_box_size,
-    bool include_logical_left_edge,
-    bool include_logical_right_edge) const {
-  FloatRoundedRect border = style_.GetRoundedBorderFor(
-      border_rect, include_logical_left_edge, include_logical_right_edge);
-  if (flow_box_has_multiple_fragments) {
-    FloatRoundedRect segment_border = style_.GetRoundedBorderFor(
-        LayoutRect(LayoutPoint(), LayoutSize(FlooredIntSize(flow_box_size))),
-        include_logical_left_edge, include_logical_right_edge);
-    border.SetRadii(segment_border.GetRadii());
-  }
-  return border;
+  return AdjustOutsetsForEdgeInclusion(border_, info);
 }
 
 void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
@@ -568,8 +586,8 @@
 
   LayoutRectOutsets border_padding_insets = -(border_ + padding_);
   FloatRoundedRect border_rect = RoundedBorderRectForClip(
-      info, bg_layer, rect, flow_box_has_multiple_fragments, flow_box_size,
-      bleed_avoidance, border_padding_insets);
+      style_, info, bg_layer, rect, flow_box_has_multiple_fragments,
+      flow_box_size, bleed_avoidance, border_padding_insets);
 
   // Fast path for drawing simple color backgrounds.
   if (PaintFastBottomLayer(display_item_, node_, paint_info, info, rect,
@@ -598,9 +616,9 @@
 
       // Clip to the padding or content boxes as necessary.
       LayoutRect clip_rect = scrolled_paint_rect;
-      clip_rect.Contract(BorderOutsets(info));
+      clip_rect.Contract(AdjustOutsetsForEdgeInclusion(border_, info));
       if (bg_layer.Clip() == EFillBox::kContent)
-        clip_rect.Contract(PaddingOutsets(info));
+        clip_rect.Contract(AdjustOutsetsForEdgeInclusion(padding_, info));
       background_clip_state_saver.Save();
       // TODO(chrishtr): this should be pixel-snapped.
       context.Clip(FloatRect(clip_rect));
@@ -614,8 +632,8 @@
       break;
   }
 
-  PaintFillLayerBackground(context, info, image.get(), composite_op, geometry,
-                           scrolled_paint_rect);
+  PaintFillLayerBackground(context, info, node_, image.get(), composite_op,
+                           geometry, scrolled_paint_rect);
 }
 
 void BoxPainterBase::PaintFillLayerTextFillBox(
@@ -639,7 +657,7 @@
   context.Clip(mask_rect);
   context.BeginLayer(1, composite_op);
 
-  PaintFillLayerBackground(context, info, image, SkBlendMode::kSrcOver,
+  PaintFillLayerBackground(context, info, node_, image, SkBlendMode::kSrcOver,
                            geometry, scrolled_paint_rect);
 
   // Create the text mask layer and draw the text into the mask. We do this by
@@ -654,41 +672,6 @@
   context.EndLayer();  // Background layer.
 }
 
-FloatRoundedRect BoxPainterBase::RoundedBorderRectForClip(
-    const BoxPainterBase::FillLayerInfo& info,
-    const FillLayer& bg_layer,
-    const LayoutRect& rect,
-    bool flow_box_has_multiple_fragments,
-    const LayoutSize& flow_box_size,
-    BackgroundBleedAvoidance bleed_avoidance,
-    LayoutRectOutsets border_padding_insets) const {
-  if (!info.is_rounded_fill)
-    return FloatRoundedRect();
-
-  FloatRoundedRect border = GetBackgroundRoundedRect(
-      rect, flow_box_has_multiple_fragments, flow_box_size,
-      info.include_left_edge, info.include_right_edge);
-
-  if (info.is_border_fill &&
-      bleed_avoidance == kBackgroundBleedShrinkBackground) {
-    border = BackgroundRoundedRectAdjustedForBleedAvoidance(
-        rect, flow_box_has_multiple_fragments, flow_box_size,
-        info.include_left_edge, info.include_right_edge, border);
-  }
-
-  // Clip to the padding or content boxes as necessary.
-  if (bg_layer.Clip() == EFillBox::kContent) {
-    border = style_.GetRoundedInnerBorderFor(
-        LayoutRect(border.Rect()), border_padding_insets,
-        info.include_left_edge, info.include_right_edge);
-  } else if (bg_layer.Clip() == EFillBox::kPadding) {
-    border = style_.GetRoundedInnerBorderFor(LayoutRect(border.Rect()),
-                                             info.include_left_edge,
-                                             info.include_right_edge);
-  }
-  return border;
-}
-
 void BoxPainterBase::PaintBorder(const ImageResourceObserver& obj,
                                  const Document& document,
                                  Node* node,
@@ -733,7 +716,6 @@
     // prevent a flash of unmasked content.
     if (mask_box_image)
       all_mask_images_loaded &= mask_box_image->IsLoaded();
-
     all_mask_images_loaded &= mask_layers.ImagesAreLoaded();
 
     paint_info.context.BeginLayer(1, SkBlendMode::kDstIn);
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.h b/third_party/blink/renderer/core/paint/box_painter_base.h
index 681cea4..ff298a8 100644
--- a/third_party/blink/renderer/core/paint/box_painter_base.h
+++ b/third_party/blink/renderer/core/paint/box_painter_base.h
@@ -143,31 +143,7 @@
   };
 
  protected:
-  FloatRoundedRect BackgroundRoundedRectAdjustedForBleedAvoidance(
-      const LayoutRect& border_rect,
-      bool flow_box_has_multiple_fragments,
-      const LayoutSize& flow_box_size,
-      bool include_logical_left_edge,
-      bool include_logical_right_edge,
-      FloatRoundedRect background_rounded_rect) const;
-  FloatRoundedRect RoundedBorderRectForClip(
-      const FillLayerInfo&,
-      const FillLayer&,
-      const LayoutRect&,
-      bool flow_box_has_multiple_fragments,
-      const LayoutSize& flow_box_size,
-      BackgroundBleedAvoidance,
-      LayoutRectOutsets border_padding_insets) const;
-
-  void PaintFillLayerBackground(GraphicsContext&,
-                                const FillLayerInfo&,
-                                Image*,
-                                SkBlendMode,
-                                const BackgroundImageGeometry&,
-                                LayoutRect scrolled_paint_rect);
   LayoutRectOutsets BorderOutsets(const FillLayerInfo&) const;
-  LayoutRectOutsets PaddingOutsets(const FillLayerInfo&) const;
-
   void PaintFillLayerTextFillBox(GraphicsContext&,
                                  const FillLayerInfo&,
                                  Image*,
@@ -186,13 +162,6 @@
   virtual FillLayerInfo GetFillLayerInfo(const Color&,
                                          const FillLayer&,
                                          BackgroundBleedAvoidance) const = 0;
-  FloatRoundedRect GetBackgroundRoundedRect(
-      const LayoutRect& border_rect,
-      bool flow_box_has_multiple_fragments,
-      const LayoutSize& flow_box_size,
-      bool include_logical_left_edge,
-      bool include_logical_right_edge) const;
-
   static void PaintInsetBoxShadow(const PaintInfo&,
                                   const FloatRoundedRect&,
                                   const ComputedStyle&,
@@ -204,8 +173,8 @@
   Member<const Document> document_;
   const ComputedStyle& style_;
   Member<Node> node_;
-  LayoutRectOutsets border_;
-  LayoutRectOutsets padding_;
+  const LayoutRectOutsets border_;
+  const LayoutRectOutsets padding_;
   const PaintLayer* paint_layer_;
 };
 
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
index 3a2083ea..baa2ae9 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -466,27 +466,31 @@
     const PaintInfo& paint_info,
     const LayoutPoint& paint_offset,
     const LayoutPoint& legacy_paint_offset) {
-  LayoutObject* layout_object = fragment.GetLayoutObject();
-  DCHECK(layout_object);
-  if (layout_object->IsLayoutNGMixin() &&
-      ToLayoutBlockFlow(layout_object)->PaintFragment()) {
+  LayoutObject* child_layout_object = fragment.GetLayoutObject();
+  DCHECK(child_layout_object);
+  if (child_layout_object->IsLayoutNGMixin() &&
+      ToLayoutBlockFlow(child_layout_object)->PaintFragment()) {
     // This object will use NGBoxFragmentPainter. NGBoxFragmentPainter expects
     // |paint_offset| relative to the parent, even when in inline context.
-    layout_object->Paint(paint_info, paint_offset);
+    LayoutPoint child_point =
+        FlipForWritingModeForChild(fragment, paint_offset);
+    child_layout_object->Paint(paint_info, child_point);
     return;
   }
 
   // When in inline context, pre-NG painters expect |paint_offset| of their
   // block container.
-  if (layout_object->IsAtomicInlineLevel()) {
+  if (child_layout_object->IsAtomicInlineLevel()) {
     // Pre-NG painters also expect callers to use |PaintAllPhasesAtomically()|
     // for atomic inlines.
-    ObjectPainter(*layout_object)
-        .PaintAllPhasesAtomically(paint_info, legacy_paint_offset);
+    LayoutPoint child_point =
+        FlipForWritingModeForChild(fragment, legacy_paint_offset);
+    ObjectPainter(*child_layout_object)
+        .PaintAllPhasesAtomically(paint_info, child_point);
     return;
   }
 
-  layout_object->Paint(paint_info, paint_offset);
+  child_layout_object->Paint(paint_info, paint_offset);
 }
 
 void NGBoxFragmentPainter::PaintAllPhasesAtomically(
@@ -940,6 +944,37 @@
   return !location_in_container.Intersects(style.GetRoundedBorderFor(rect));
 }
 
+LayoutPoint NGBoxFragmentPainter::FlipForWritingModeForChild(
+    const NGPhysicalFragment& child_fragment,
+    const LayoutPoint& offset) {
+  if (!PhysicalFragment().Style().IsFlippedBlocksWritingMode())
+    return offset;
+
+  LayoutPoint flipped_offset;
+  LayoutObject* child_layout_object = child_fragment.GetLayoutObject();
+  if (!AdjustPaintOffsetScope::WillUseLegacyLocation(
+          ToLayoutBox(child_layout_object)))
+    return offset;
+  LayoutObject* container_layout_object = box_fragment_.GetLayoutObject();
+  DCHECK(child_layout_object->IsBox());
+  if (container_layout_object->IsLayoutBlock()) {
+    flipped_offset = ToLayoutBlock(container_layout_object)
+                         ->FlipForWritingModeForChild(
+                             ToLayoutBox(child_layout_object), offset);
+  } else if (container_layout_object->IsInline()) {
+    // Reimplementation of LayoutBox::FlipForWritingModeForChild because
+    // LayoutInline cannot be an argument to FlipForWritingModeForChild
+    NGPhysicalSize container_size = PhysicalFragment().Size();
+    LayoutSize child_size = ToLayoutBox(child_layout_object)->Size();
+    LayoutPoint child_location = ToLayoutBox(child_layout_object)->Location();
+    flipped_offset =
+        LayoutPoint(offset.X() + container_size.width - child_size.Width() -
+                        (2 * child_location.X()),
+                    offset.Y());
+  }
+  return flipped_offset;
+}
+
 const NGPhysicalBoxFragment& NGBoxFragmentPainter::PhysicalFragment() const {
   return static_cast<const NGPhysicalBoxFragment&>(
       box_fragment_.PhysicalFragment());
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
index 623e5ee..1669ea0 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
+++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
@@ -122,6 +122,9 @@
                            const LayoutPoint& accumulated_offset);
   bool HitTestClippedOutByBorder(const HitTestLocation&,
                                  const LayoutPoint& border_box_location) const;
+  LayoutPoint FlipForWritingModeForChild(
+      const NGPhysicalFragment& child_fragment,
+      const LayoutPoint& offset);
 
   const NGPhysicalBoxFragment& PhysicalFragment() const;
 
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
index 85b5c447..6bf7c0b 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -226,4 +226,28 @@
   return nullptr;
 }
 
+NGPaintFragment* NGPaintFragment::FirstLineBox() const {
+  for (auto& child : children_) {
+    if (child->PhysicalFragment().IsLineBox())
+      return child.get();
+  }
+  return nullptr;
+}
+
+void NGPaintFragment::SetShouldDoFullPaintInvalidationRecursively() {
+  if (LayoutObject* layout_object = GetLayoutObject())
+    layout_object->SetShouldDoFullPaintInvalidation();
+
+  for (auto& child : children_)
+    child->SetShouldDoFullPaintInvalidationRecursively();
+}
+
+void NGPaintFragment::SetShouldDoFullPaintInvalidationForFirstLine() {
+  DCHECK(PhysicalFragment().IsBox() && GetLayoutObject() &&
+         GetLayoutObject()->IsLayoutBlockFlow());
+
+  if (NGPaintFragment* line_box = FirstLineBox())
+    line_box->SetShouldDoFullPaintInvalidationRecursively();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
index ef75474..9ced4349 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
@@ -50,6 +50,9 @@
     return children_;
   }
 
+  // Returns the first line box for a block-level container.
+  NGPaintFragment* FirstLineBox() const;
+
   // Returns the container line box for inline fragments.
   const NGPaintFragment* ContainerLineBox() const;
 
@@ -80,6 +83,14 @@
 
   LayoutRect PartialInvalidationRect() const override;
 
+  // Set ShouldDoFullPaintInvalidation flag in the corresponding LayoutObject
+  // recursively.
+  void SetShouldDoFullPaintInvalidationRecursively();
+
+  // Set ShouldDoFullPaintInvalidation flag to all objects in the first line of
+  // this block-level fragment.
+  void SetShouldDoFullPaintInvalidationForFirstLine();
+
   // Paint all descendant inline box fragments that belong to the specified
   // LayoutObject.
   void PaintInlineBoxForDescendants(const PaintInfo&,
diff --git a/third_party/blink/renderer/core/paint/table_painter.cc b/third_party/blink/renderer/core/paint/table_painter.cc
index 1b8b0ab8..a920976 100644
--- a/third_party/blink/renderer/core/paint/table_painter.cc
+++ b/third_party/blink/renderer/core/paint/table_painter.cc
@@ -38,8 +38,9 @@
          child = child->NextSibling()) {
       if (child->IsBox() && !ToLayoutBox(child)->HasSelfPaintingLayer() &&
           (child->IsTableSection() || child->IsTableCaption())) {
-        LayoutPoint child_point = layout_table_.FlipForWritingModeForChild(
-            ToLayoutBox(child), paint_offset);
+        LayoutPoint child_point =
+            layout_table_.FlipForWritingModeForChildForPaint(ToLayoutBox(child),
+                                                             paint_offset);
         child->Paint(paint_info_for_descendants, child_point);
       }
     }
@@ -101,7 +102,7 @@
   for (LayoutTableSection* section = layout_table_.BottomSection(); section;
        section = layout_table_.SectionAbove(section)) {
     LayoutPoint child_point =
-        layout_table_.FlipForWritingModeForChild(section, paint_offset);
+        layout_table_.FlipForWritingModeForChildForPaint(section, paint_offset);
     TableSectionPainter(*section).PaintCollapsedBorders(paint_info,
                                                         child_point);
   }
diff --git a/third_party/blink/renderer/core/paint/table_row_painter.cc b/third_party/blink/renderer/core/paint/table_row_painter.cc
index 15320fd9..e30a6be 100644
--- a/third_party/blink/renderer/core/paint/table_row_painter.cc
+++ b/third_party/blink/renderer/core/paint/table_row_painter.cc
@@ -126,8 +126,9 @@
   // doesn't need to flip in section's blocks direction. A row doesn't have
   // flipped blocks direction.
   if (!layout_table_row_.HasSelfPaintingLayer()) {
-    cell_point = layout_table_row_.Section()->FlipForWritingModeForChild(
-        &cell, cell_point);
+    cell_point =
+        layout_table_row_.Section()->FlipForWritingModeForChildForPaint(
+            &cell, cell_point);
   }
   TableCellPainter(cell).PaintContainerBackgroundBehindCell(
       paint_info, cell_point, layout_table_row_);
@@ -157,7 +158,7 @@
        c > dirtied_columns.Start(); c--) {
     if (const auto* cell = section->OriginatingCellAt(row, c - 1)) {
       LayoutPoint cell_point =
-          section->FlipForWritingModeForChild(cell, paint_offset);
+          section->FlipForWritingModeForChildForPaint(cell, paint_offset);
       CollapsedBorderPainter(*cell).PaintCollapsedBorders(paint_info,
                                                           cell_point);
     }
diff --git a/third_party/blink/renderer/core/paint/table_section_painter.cc b/third_party/blink/renderer/core/paint/table_section_painter.cc
index b3165a56..d6f03ff 100644
--- a/third_party/blink/renderer/core/paint/table_section_painter.cc
+++ b/third_party/blink/renderer/core/paint/table_section_painter.cc
@@ -443,7 +443,8 @@
     const PaintInfo& paint_info_for_cells,
     const LayoutPoint& paint_offset) {
   LayoutPoint cell_point =
-      layout_table_section_.FlipForWritingModeForChild(&cell, paint_offset);
+      layout_table_section_.FlipForWritingModeForChildForPaint(&cell,
+                                                               paint_offset);
 
   // We need to handle painting a stack of backgrounds. This stack (from bottom
   // to top) consists of the column group, column, row group, row, and then the
@@ -483,7 +484,8 @@
                                     const LayoutPoint& paint_offset) {
   if (!cell.HasSelfPaintingLayer() && !cell.Row()->HasSelfPaintingLayer()) {
     LayoutPoint cell_point =
-        layout_table_section_.FlipForWritingModeForChild(&cell, paint_offset);
+        layout_table_section_.FlipForWritingModeForChildForPaint(&cell,
+                                                                 paint_offset);
     cell.Paint(paint_info_for_cells, cell_point);
   }
 }
diff --git a/third_party/blink/renderer/core/precompile_core.h b/third_party/blink/renderer/core/precompile_core.h
index 17d062b..1cf10f3 100644
--- a/third_party/blink/renderer/core/precompile_core.h
+++ b/third_party/blink/renderer/core/precompile_core.h
@@ -2,15 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(PrecompileCore_h_)
+#ifdef THIRD_PARTY_BLINK_RENDERER_CORE_PRECOMPILE_CORE_H_
 #error You shouldn't include the precompiled header file more than once.
 #endif
-#define PrecompileCore_h_
+
+#define THIRD_PARTY_BLINK_RENDERER_CORE_PRECOMPILE_CORE_H_
 
 #if defined(_MSC_VER)
-#include "build/win/precompile.h"
+#include "third_party/blink/renderer/build/win/precompile.h"
 #elif defined(__APPLE__)
-#include "build/mac/prefix.h"
+#include "third_party/blink/renderer/build/mac/prefix.h"
 #else
 #error implement
 #endif
@@ -18,8 +19,8 @@
 // In Blink a lot of operations center around dom and Document, or around
 // layout/rendering and LayoutObject. Those two headers are in turn pulling
 // in large parts of Blink's other headers which means that every compilation
-// unit is compiling large parts of Blink. By precompiling Document.h
-// and LayoutObject.h we only have to compile those parts once rather
+// unit is compiling large parts of Blink. By precompiling document.h
+// and layout_object.h we only have to compile those parts once rather
 // than 1500 times. It can make a large difference in compilation
 // times (3-4 times faster).
 #include "third_party/blink/renderer/core/dom/document.h"
diff --git a/third_party/blink/renderer/core/script/script_runner_test.cc b/third_party/blink/renderer/core/script/script_runner_test.cc
index 1c349fd2..aa14d4a 100644
--- a/third_party/blink/renderer/core/script/script_runner_test.cc
+++ b/third_party/blink/renderer/core/script/script_runner_test.cc
@@ -87,20 +87,22 @@
   static MockScriptLoader* CreateInOrder() {
     auto* loader = new MockScriptLoader();
     loader->SetAsyncExecTypeForTesting(ScriptRunner::kInOrder);
+    MockPendingScript* pending_script = MockPendingScript::Create();
+    loader->mock_pending_script_ = pending_script;
     return loader;
   }
   static MockScriptLoader* CreateAsync() {
     auto* loader = new MockScriptLoader();
     loader->SetAsyncExecTypeForTesting(ScriptRunner::kAsync);
-    loader->mock_pending_script_if_script_is_async_ =
-        MockPendingScript::Create();
+    MockPendingScript* pending_script = MockPendingScript::Create();
+    loader->mock_pending_script_ = pending_script;
+    loader->mock_pending_script_if_script_is_async_ = pending_script;
     return loader;
   }
 
   ~MockScriptLoader() override {}
 
   MOCK_METHOD0(Execute, void());
-  MOCK_CONST_METHOD0(IsReady, bool());
 
   void Trace(blink::Visitor*) override;
 
@@ -108,18 +110,21 @@
     return mock_pending_script_if_script_is_async_.Get();
   }
   MockPendingScript* GetMockPendingScript() {
-    return mock_pending_script_if_script_is_async_.Get();
+    return mock_pending_script_.Get();
   }
+  bool IsReady() const { return mock_pending_script_->IsReady(); }
 
  private:
   explicit MockScriptLoader()
       : ScriptLoader(MockScriptElementBase::Create(), false, false, false) {}
 
+  Member<MockPendingScript> mock_pending_script_;
   Member<MockPendingScript> mock_pending_script_if_script_is_async_;
 };
 
 void MockScriptLoader::Trace(blink::Visitor* visitor) {
   ScriptLoader::Trace(visitor);
+  visitor->Trace(mock_pending_script_);
   visitor->Trace(mock_pending_script_if_script_is_async_);
 }
 
@@ -163,7 +168,8 @@
   script_runner_->QueueScriptForExecution(script_loader,
                                           ScriptRunner::kInOrder);
 
-  EXPECT_CALL(*script_loader, IsReady()).WillOnce(Return(true));
+  EXPECT_CALL(*script_loader->GetMockPendingScript(), IsReady())
+      .WillOnce(Return(true));
   EXPECT_CALL(*script_loader, Execute());
 
   script_runner_->NotifyScriptReady(script_loader, ScriptRunner::kInOrder);
@@ -196,7 +202,7 @@
   bool is_ready[] = {false, false, false};
 
   for (size_t i = 0; i < script_loaders.size(); ++i) {
-    EXPECT_CALL(*script_loaders[i], IsReady())
+    EXPECT_CALL(*script_loaders[i]->GetMockPendingScript(), IsReady())
         .WillRepeatedly(Invoke([&is_ready, i] { return is_ready[i]; }));
   }
 
@@ -227,15 +233,20 @@
   script_runner_->QueueScriptForExecution(script_loader4, ScriptRunner::kAsync);
   script_runner_->QueueScriptForExecution(script_loader5, ScriptRunner::kAsync);
 
-  EXPECT_CALL(*script_loader1, IsReady()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*script_loader2, IsReady()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*script_loader1->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader2->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(false));
   script_runner_->NotifyScriptReady(script_loader1, ScriptRunner::kInOrder);
 
-  EXPECT_CALL(*script_loader2, IsReady()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*script_loader3, IsReady()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*script_loader2->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader3->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(false));
   script_runner_->NotifyScriptReady(script_loader2, ScriptRunner::kInOrder);
 
-  EXPECT_CALL(*script_loader3, IsReady()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader3->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
   script_runner_->NotifyScriptReady(script_loader3, ScriptRunner::kInOrder);
 
   script_runner_->NotifyScriptReady(script_loader4, ScriptRunner::kAsync);
@@ -308,9 +319,12 @@
   auto* script_loader2 = MockScriptLoader::CreateInOrder();
   auto* script_loader3 = MockScriptLoader::CreateInOrder();
 
-  EXPECT_CALL(*script_loader1, IsReady()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*script_loader2, IsReady()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*script_loader3, IsReady()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader1->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader2->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader3->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
 
   script_runner_->QueueScriptForExecution(script_loader1,
                                           ScriptRunner::kInOrder);
@@ -359,7 +373,8 @@
 
   for (int i = 0; i < 20; i++) {
     script_loaders[i] = MockScriptLoader::CreateAsync();
-    EXPECT_CALL(*script_loaders[i], IsReady()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*script_loaders[i]->GetMockPendingScript(), IsReady())
+        .WillRepeatedly(Return(true));
 
     script_runner_->QueueScriptForExecution(script_loaders[i],
                                             ScriptRunner::kAsync);
@@ -413,18 +428,25 @@
     order_.push_back(3);
   }));
 
-  EXPECT_CALL(*script_loader2, IsReady()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*script_loader3, IsReady()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader2->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader3->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
 
-  EXPECT_CALL(*script_loader1, IsReady()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*script_loader2, IsReady()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*script_loader1->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader2->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(false));
   script_runner_->NotifyScriptReady(script_loader1, ScriptRunner::kInOrder);
 
-  EXPECT_CALL(*script_loader2, IsReady()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*script_loader3, IsReady()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*script_loader2->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader3->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(false));
   script_runner_->NotifyScriptReady(script_loader2, ScriptRunner::kInOrder);
 
-  EXPECT_CALL(*script_loader3, IsReady()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader3->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
   script_runner_->NotifyScriptReady(script_loader3, ScriptRunner::kInOrder);
 
   platform_->RunSingleTask();
@@ -472,8 +494,10 @@
   auto* script_loader1 = MockScriptLoader::CreateInOrder();
   auto* script_loader2 = MockScriptLoader::CreateInOrder();
 
-  EXPECT_CALL(*script_loader1, IsReady()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*script_loader2, IsReady()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader1->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader2->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
 
   script_runner_->QueueScriptForExecution(script_loader1,
                                           ScriptRunner::kInOrder);
@@ -502,8 +526,10 @@
   Persistent<MockScriptLoader> script_loader1 = MockScriptLoader::CreateAsync();
   Persistent<MockScriptLoader> script_loader2 = MockScriptLoader::CreateAsync();
 
-  EXPECT_CALL(*script_loader1, IsReady()).WillRepeatedly(Return(true));
-  EXPECT_CALL(*script_loader2, IsReady()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader1->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader2->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
 
   script_runner_->QueueScriptForExecution(script_loader1, ScriptRunner::kAsync);
   script_runner_->QueueScriptForExecution(script_loader2, ScriptRunner::kAsync);
@@ -525,19 +551,22 @@
 
 TEST_F(ScriptRunnerTest, TryStreamWhenEnqueingScript) {
   auto* script_loader1 = MockScriptLoader::CreateAsync();
-  EXPECT_CALL(*script_loader1, IsReady()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader1->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
   script_runner_->QueueScriptForExecution(script_loader1, ScriptRunner::kAsync);
 }
 
 TEST_F(ScriptRunnerTest, DontExecuteWhileStreaming) {
   auto* script_loader = MockScriptLoader::CreateAsync();
-  EXPECT_CALL(*script_loader, IsReady()).WillRepeatedly(Return(false));
+  EXPECT_CALL(*script_loader->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(false));
 
   // Enqueue script.
   script_runner_->QueueScriptForExecution(script_loader, ScriptRunner::kAsync);
 
   // Simulate script load and mark the pending script as streaming ready.
-  EXPECT_CALL(*script_loader, IsReady()).WillRepeatedly(Return(true));
+  EXPECT_CALL(*script_loader->GetMockPendingScript(), IsReady())
+      .WillRepeatedly(Return(true));
   script_loader->GetMockPendingScript()->PrepareForStreaming();
   script_runner_->NotifyScriptReady(script_loader, ScriptRunner::kAsync);
 
diff --git a/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc b/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc
index 249ebf2..8c1c6e4 100644
--- a/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc
+++ b/third_party/blink/renderer/core/workers/parent_execution_context_task_runners.cc
@@ -26,11 +26,13 @@
 ParentExecutionContextTaskRunners::ParentExecutionContextTaskRunners(
     ExecutionContext* context)
     : ContextLifecycleObserver(context) {
-  // For now we only support very limited task types.
-  for (auto type : {TaskType::kInternalDefault, TaskType::kInternalLoading,
-                    TaskType::kNetworking, TaskType::kPostedMessage,
-                    TaskType::kUnthrottled, TaskType::kInternalTest,
-                    TaskType::kInternalInspector, TaskType::kInternalWorker}) {
+  // For now we only support very limited task types. Sort in the TaskType enum
+  // value order.
+  for (auto type : {TaskType::kNetworking, TaskType::kPostedMessage,
+                    TaskType::kInternalDefault, TaskType::kInternalLoading,
+                    TaskType::kInternalTest, TaskType::kInternalMedia,
+                    TaskType::kInternalInspector, TaskType::kInternalWorker,
+                    TaskType::kUnthrottled}) {
     auto task_runner =
         context ? context->GetTaskRunner(type)
                 : Platform::Current()->CurrentThread()->GetTaskRunner();
diff --git a/third_party/blink/renderer/core/workers/worker_module_tree_client.cc b/third_party/blink/renderer/core/workers/worker_module_tree_client.cc
index daaac9d6..ceab4de8 100644
--- a/third_party/blink/renderer/core/workers/worker_module_tree_client.cc
+++ b/third_party/blink/renderer/core/workers/worker_module_tree_client.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/workers/worker_module_tree_client.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/core/events/error_event.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/script/module_script.h"
 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
@@ -20,24 +21,29 @@
 // https://html.spec.whatwg.org/multipage/workers.html#worker-processing-model
 void WorkerModuleTreeClient::NotifyModuleTreeLoadFinished(
     ModuleScript* module_script) {
+  auto* execution_context =
+      ExecutionContext::From(modulator_->GetScriptState());
+
   if (!module_script) {
-    // Step 11: ... "If the algorithm asynchronously completes with null, queue
-    // a task to fire an event named error at worker, and abort these steps."
-    // ...
-    // TODO(nhiroki): Throw an ErrorEvent at the Worker object on the owner
-    // Document.
+    // Step 13: "If the algorithm asynchronously completes with null, queue
+    // a task to fire an event named error at worker, and return."
+    // This ErrorEvent object is just used for passing error information to a
+    // worker object on the parent context thread and not dispatched directly.
+    execution_context->ExceptionThrown(
+        ErrorEvent::Create("Failed to load a module script.",
+                           SourceLocation::Capture(), nullptr /* world */));
     return;
   }
 
-  // Step 11: ... "Otherwise, continue the rest of these steps after the
-  // algorithm's asynchronous completion, with script being the asynchronous
-  // completion value." ...
+  // Step 13: "Otherwise, continue the rest of these steps after the algorithm's
+  // asynchronous completion, with script being the asynchronous completion
+  // value."
 
   ScriptValue error = modulator_->ExecuteModule(
       module_script, Modulator::CaptureEvalErrorFlag::kReport);
-  WorkerGlobalScope* global_scope =
-      ToWorkerGlobalScope(ExecutionContext::From(modulator_->GetScriptState()));
-  global_scope->ReportingProxy().DidEvaluateModuleScript(error.IsEmpty());
+  ToWorkerGlobalScope(execution_context)
+      ->ReportingProxy()
+      .DidEvaluateModuleScript(error.IsEmpty());
 }
 
 void WorkerModuleTreeClient::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_main_run.py b/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_main_run.py
index 725c344..500f52c 100644
--- a/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_main_run.py
+++ b/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/fuzz_main_run.py
@@ -158,8 +158,8 @@
                                        args.output_dir)
 
         if args.content_shell_dir:
-            print '{} --run-layout-test {}'.format(args.content_shell_dir,
-                                                   test_file_path)
+            print '{} --run-web-tests {}'.format(args.content_shell_dir,
+                                                 test_file_path)
 
 
 if __name__ == '__main__':
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index 677ae79..be2e936 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -566,7 +566,7 @@
   }
 
   peer_handler_ = Platform::Current()->CreateRTCPeerConnectionHandler(
-      this, document->GetTaskRunner(TaskType::kUnthrottled));
+      this, document->GetTaskRunner(TaskType::kInternalMedia));
   if (!peer_handler_) {
     closed_ = true;
     stopped_ = true;
@@ -1058,7 +1058,7 @@
   // destruction as well as the resolver's destruction.
   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
       ExecutionContext::From(script_state)
-          ->GetTaskRunner(blink::TaskType::kUnthrottled);
+          ->GetTaskRunner(blink::TaskType::kInternalMedia);
   if (!expires) {
     certificate_generator->GenerateCertificate(
         key_params.value(), std::move(certificate_observer), task_runner);
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_object_proxy.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_object_proxy.cc
index ab8a269..04ee72e6 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_object_proxy.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_object_proxy.cc
@@ -42,7 +42,7 @@
     return;
 
   PostCrossThreadTask(
-      *GetParentExecutionContextTaskRunners()->Get(TaskType::kUnthrottled),
+      *GetParentExecutionContextTaskRunners()->Get(TaskType::kInternalMedia),
       FROM_HERE,
       CrossThreadBind(
           &AudioWorkletMessagingProxy::SynchronizeWorkletProcessorInfoList,
diff --git a/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc b/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc
index f7c7bd3..c81bf9e 100644
--- a/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/default_audio_destination_node.cc
@@ -95,8 +95,9 @@
     // This task runner is only used to fire the audio render callback, so it
     // MUST not be throttled to avoid potential audio glitch.
     destination_->StartWithWorkletTaskRunner(
-        audio_worklet->GetMessagingProxy()->GetBackingWorkerThread()
-                     ->GetTaskRunner(TaskType::kUnthrottled));
+        audio_worklet->GetMessagingProxy()
+            ->GetBackingWorkerThread()
+            ->GetTaskRunner(TaskType::kInternalMedia));
   } else {
     destination_->Start();
   }
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index 8cf9d90..07c561b 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -4881,10 +4881,6 @@
         adjusted_source_image_rect.Height(), format, type, bytes);
   } else {
     GLint upload_height = adjusted_source_image_rect.Height();
-    if (unpack_image_height) {
-      // GL_UNPACK_IMAGE_HEIGHT overrides the passed-in height.
-      upload_height = unpack_image_height;
-    }
     if (function_id == kTexImage3D) {
       ContextGL()->TexImage3D(target, level, internalformat,
                               adjusted_source_image_rect.Width(), upload_height,
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc
index e902bb28..5f1ed7b 100644
--- a/third_party/blink/renderer/platform/heap/heap_test.cc
+++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -2371,6 +2371,8 @@
 }
 
 // This test often fails on Android (https://crbug.com/843032).
+// We run out of memory on Android devices because ReserveCapacityForSize
+// actually allocates a much larger backing than specified (in this case 400MB).
 #if defined(OS_ANDROID)
 #define MAYBE_LargeHashMap DISABLED_LargeHashMap
 #else
@@ -2378,7 +2380,11 @@
 #endif
 TEST(HeapTest, MAYBE_LargeHashMap) {
   ClearOutOldGarbage();
-  size_t size = (1 << 27) / sizeof(Member<IntWrapper>);
+
+  // Try to allocate a HashTable larger than kMaxHeapObjectSize
+  // (crbug.com/597953).
+  size_t size = kMaxHeapObjectSize /
+                sizeof(HeapHashMap<int, Member<IntWrapper>>::ValueType);
   Persistent<HeapHashMap<int, Member<IntWrapper>>> map =
       new HeapHashMap<int, Member<IntWrapper>>();
   map->ReserveCapacityForSize(size);
@@ -2388,7 +2394,9 @@
 TEST(HeapTest, LargeVector) {
   ClearOutOldGarbage();
 
-  size_t size = (1 << 27) / sizeof(int);
+  // Try to allocate a HeapVectors larger than kMaxHeapObjectSize
+  // (crbug.com/597953).
+  size_t size = kMaxHeapObjectSize / sizeof(int);
   Persistent<HeapVector<int>> vector = new HeapVector<int>(size);
   EXPECT_LE(size, vector->capacity());
 }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
index edebcf2..82317ffc 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc
@@ -654,22 +654,8 @@
     return;
 
   while (!pending_requests_.empty()) {
-    // TODO(yhirano): Consider using a unified value.
-    const auto num_requests =
-        frame_scheduler_throttling_state_ ==
-                FrameScheduler::ThrottlingState::kNotThrottled
-            ? running_throttlable_requests_.size()
-            : running_requests_.size();
-
-    const bool has_enough_running_requets =
-        num_requests >= GetOutstandingLimit();
-
     if (IsThrottablePriority(pending_requests_.begin()->priority) &&
-        has_enough_running_requets) {
-      break;
-    }
-    if (IsThrottablePriority(pending_requests_.begin()->priority) &&
-        has_enough_running_requets) {
+        running_throttlable_requests_.size() >= GetOutstandingLimit()) {
       break;
     }
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
index d34cbb0d..01defed 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -55,6 +55,16 @@
 
 namespace blink {
 
+namespace {
+
+bool IsThrottlableRequestContext(WebURLRequest::RequestContext context) {
+  return context != WebURLRequest::kRequestContextEventSource &&
+         context != WebURLRequest::kRequestContextFetch &&
+         context != WebURLRequest::kRequestContextXMLHttpRequest;
+}
+
+}  // namespace
+
 ResourceLoader* ResourceLoader::Create(ResourceFetcher* fetcher,
                                        ResourceLoadScheduler* scheduler,
                                        Resource* resource,
@@ -100,11 +110,10 @@
   DCHECK_EQ(ResourceLoadScheduler::kInvalidClientId, scheduler_client_id_);
   auto throttle_option = ResourceLoadScheduler::ThrottleOption::kCanBeThrottled;
 
-  // Synchronous requests should not work with a throttling. Also, tentatively
-  // disables throttling for fetch requests that could keep on holding an active
-  // connection until data is read by JavaScript.
+  // Synchronous requests should not work with a throttling. Also, disables
+  // throttling for the case that can be used for aka long-polling requests.
   if (resource_->Options().synchronous_policy == kRequestSynchronously ||
-      request.GetRequestContext() == WebURLRequest::kRequestContextFetch) {
+      !IsThrottlableRequestContext(request.GetRequestContext())) {
     throttle_option = ResourceLoadScheduler::ThrottleOption::kCanNotBeThrottled;
   }
 
diff --git a/third_party/blink/renderer/platform/precompile_platform.h b/third_party/blink/renderer/platform/precompile_platform.h
index 432604e..bbd15745 100644
--- a/third_party/blink/renderer/platform/precompile_platform.h
+++ b/third_party/blink/renderer/platform/precompile_platform.h
@@ -2,20 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#if defined(PrecompilePlatform_h_)
+#ifdef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PRECOMPILE_PLATFORM_H_
 #error You shouldn't include the precompiled header file more than once.
 #endif
 
-#define PrecompilePlatform_h_
+#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PRECOMPILE_PLATFORM_H_
 
 #if defined(_MSC_VER)
-#include "build/win/precompile.h"
+#include "third_party/blink/renderer/build/win/precompile.h"
 #elif defined(__APPLE__)
-#include "build/mac/prefix.h"
+#include "third_party/blink/renderer/build/mac/prefix.h"
 #else
 #error implement
 #endif
 
-// Include Oilpan's Handle.h by default, as it is included by a significant
+// Include Oilpan's handle.h by default, as it is included by a significant
 // portion of platform/ source files.
 #include "third_party/blink/renderer/platform/heap/handle.h"
diff --git a/third_party/blink/tools/blinkpy/common/pretty_diff.py b/third_party/blink/tools/blinkpy/common/pretty_diff.py
index d06f414b..d6ce2ad 100644
--- a/third_party/blink/tools/blinkpy/common/pretty_diff.py
+++ b/third_party/blink/tools/blinkpy/common/pretty_diff.py
@@ -385,7 +385,7 @@
 
     def prettify(self):
         result_html = ('<tr><td class=hunkheader>@@<td class=hunkheader>@@'
-                       '<td class=hunkheader>{}</tr>\n').format(self._context)
+                       '<td class=hunkheader>{}</tr>\n').format(cgi.escape(self._context))
         old_lineno = self._old_start
         new_lineno = self._new_start
         for i, line in enumerate(self._lines):
diff --git a/third_party/blink/tools/blinkpy/common/pretty_diff_unittest.py b/third_party/blink/tools/blinkpy/common/pretty_diff_unittest.py
index 3aae9fd..7b728fa7 100644
--- a/third_party/blink/tools/blinkpy/common/pretty_diff_unittest.py
+++ b/third_party/blink/tools/blinkpy/common/pretty_diff_unittest.py
@@ -176,6 +176,11 @@
         self.assertEquals(self._annotate(['+', '+abc', ' de'], 0, 0, 2),
                           [[(0, 0)], [(0, 2)], None])
 
+    def test_prettify_header_context_escape(self):
+        hunk = DiffHunk(2, 2, '<h3>Constructing form data set</h3>', [])
+        self.assertNotIn('<h3>', hunk.prettify())
+        self.assertIn('&lt;h3&gt;', hunk.prettify())
+
 
 class TestBinaryHunk(unittest.TestCase):
 
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/base.py b/third_party/blink/tools/blinkpy/web_tests/port/base.py
index dde2669a..372f478d 100644
--- a/third_party/blink/tools/blinkpy/web_tests/port/base.py
+++ b/third_party/blink/tools/blinkpy/web_tests/port/base.py
@@ -250,7 +250,7 @@
             #
             fingerprint = 'Nxvaj3+bY3oVrTc+Jp7m3E3sB1n3lXtnMDCyBsqEXiY='
             flags += [
-                '--run-layout-test',
+                '--run-web-tests',
                 '--ignore-certificate-errors-spki-list=' + fingerprint,
                 '--user-data-dir']
         return flags
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/mock_drt_unittest.py b/third_party/blink/tools/blinkpy/web_tests/port/mock_drt_unittest.py
index 72fb420..4103cae 100644
--- a/third_party/blink/tools/blinkpy/web_tests/port/mock_drt_unittest.py
+++ b/third_party/blink/tools/blinkpy/web_tests/port/mock_drt_unittest.py
@@ -126,7 +126,7 @@
         drt_input, drt_output = self.make_input_output(
             port, test_name, pixel_tests, expected_checksum, drt_output, drt_input=None, expected_text=expected_text)
 
-        args = ['--run-layout-test', '--platform', port_name, '-']
+        args = ['--run-web-tests', '--platform', port_name, '-']
         stdin = io.BytesIO(drt_input)
         stdout = io.BytesIO()
         stderr = io.BytesIO()
@@ -146,7 +146,7 @@
         stdin = io.BytesIO()
         stdout = io.BytesIO()
         stderr = io.BytesIO()
-        res = mock_drt.main(['--run-layout-test', '--platform', 'test', '-'],
+        res = mock_drt.main(['--run-web-tests', '--platform', 'test', '-'],
                             host, stdin, stdout, stderr)
         self.assertEqual(res, 0)
         self.assertEqual(stdout.getvalue(), '#READY\n')
diff --git a/third_party/blink/tools/run_blink_httpd.py b/third_party/blink/tools/run_blink_httpd.py
index 3c80d4f..6594caa 100755
--- a/third_party/blink/tools/run_blink_httpd.py
+++ b/third_party/blink/tools/run_blink_httpd.py
@@ -40,7 +40,7 @@
 
 After starting the server, you can also run individual layout tests
 via content_shell, e.g.
-    $ out/Release/content_shell --run-layout-test \
+    $ out/Release/content_shell --run-web-tests \
     http://127.0.0.1:8000/security/cross-frame-access-get.html
 
 Note that some tests will only work if "127.0.0.1" for the host part of the
diff --git a/third_party/crashpad/crashpad/compat/linux/sys/ptrace.h b/third_party/crashpad/crashpad/compat/linux/sys/ptrace.h
index 73861576..e5c95c7 100644
--- a/third_party/crashpad/crashpad/compat/linux/sys/ptrace.h
+++ b/third_party/crashpad/crashpad/compat/linux/sys/ptrace.h
@@ -34,7 +34,7 @@
 #endif  // !PTRACE_GET_THREAD_AREA && !PT_GET_THREAD_AREA && defined(__GLIBC__)
 
 // https://sourceware.org/bugzilla/show_bug.cgi?id=22433
-#if !defined(PTRACE_GETVFPREGS) && \
+#if !defined(PTRACE_GETVFPREGS) && !defined(PT_GETVFPREGS) && \
     defined(__GLIBC__) && (defined(__arm__) || defined(__arm64__))
 static constexpr __ptrace_request PTRACE_GETVFPREGS =
     static_cast<__ptrace_request>(27);
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium
index 687e8cf..507ca26 100644
--- a/third_party/libvpx/README.chromium
+++ b/third_party/libvpx/README.chromium
@@ -5,9 +5,9 @@
 License File: source/libvpx/LICENSE
 Security Critical: yes
 
-Date: Friday May 04 2018
+Date: Tuesday May 15 2018
 Branch: master
-Commit: 28801f91c4c030da55d483840691582440f8f8f4
+Commit: d99abe9a9ad78b765386d0ee62559de184ba581e
 
 Description:
 Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx/libvpx_srcs.gni b/third_party/libvpx/libvpx_srcs.gni
index a59ffeb9..24e6a89 100644
--- a/third_party/libvpx/libvpx_srcs.gni
+++ b/third_party/libvpx/libvpx_srcs.gni
@@ -1632,6 +1632,7 @@
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/subpel_variance_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/subtract_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/sum_neon.h",
+  "//third_party/libvpx/source/libvpx/vpx_dsp/arm/sum_squares_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/transpose_neon.h",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/variance_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve8_neon.h",
@@ -2128,6 +2129,7 @@
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/sad_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/subpel_variance_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/subtract_neon.c",
+  "//third_party/libvpx/source/libvpx/vpx_dsp/arm/sum_squares_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/variance_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_scaled_convolve8_neon.c",
@@ -2467,6 +2469,7 @@
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/subpel_variance_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/subtract_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/sum_neon.h",
+  "//third_party/libvpx/source/libvpx/vpx_dsp/arm/sum_squares_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/transpose_neon.h",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/variance_neon.c",
   "//third_party/libvpx/source/libvpx/vpx_dsp/arm/vpx_convolve8_neon.c",
diff --git a/third_party/libvpx/source/config/ios/arm-neon/vpx_config.asm b/third_party/libvpx/source/config/ios/arm-neon/vpx_config.asm
index d459dae..aeaea99 100644
--- a/third_party/libvpx/source/config/ios/arm-neon/vpx_config.asm
+++ b/third_party/libvpx/source/config/ios/arm-neon/vpx_config.asm
@@ -78,6 +78,7 @@
 .set CONFIG_MULTI_RES_ENCODING ,  1
 .set CONFIG_TEMPORAL_DENOISING ,  1
 .set CONFIG_VP9_TEMPORAL_DENOISING ,  1
+.set CONFIG_CONSISTENT_RECODE ,  0
 .set CONFIG_COEFFICIENT_RANGE_CHECKING ,  0
 .set CONFIG_VP9_HIGHBITDEPTH ,  0
 .set CONFIG_BETTER_HW_COMPATIBILITY ,  0
diff --git a/third_party/libvpx/source/config/ios/arm-neon/vpx_config.h b/third_party/libvpx/source/config/ios/arm-neon/vpx_config.h
index b80461bd..365206f 100644
--- a/third_party/libvpx/source/config/ios/arm-neon/vpx_config.h
+++ b/third_party/libvpx/source/config/ios/arm-neon/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 0
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/ios/arm-neon/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/ios/arm-neon/vpx_dsp_rtcd.h
index cc0b382..0056935 100644
--- a/third_party/libvpx/source/config/ios/arm-neon/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/ios/arm-neon/vpx_dsp_rtcd.h
@@ -2210,7 +2210,8 @@
 #define vpx_subtract_block vpx_subtract_block_neon
 
 uint64_t vpx_sum_squares_2d_i16_c(const int16_t* src, int stride, int size);
-#define vpx_sum_squares_2d_i16 vpx_sum_squares_2d_i16_c
+uint64_t vpx_sum_squares_2d_i16_neon(const int16_t* src, int stride, int size);
+#define vpx_sum_squares_2d_i16 vpx_sum_squares_2d_i16_neon
 
 void vpx_tm_predictor_16x16_c(uint8_t* dst,
                               ptrdiff_t y_stride,
diff --git a/third_party/libvpx/source/config/ios/arm64/vpx_config.asm b/third_party/libvpx/source/config/ios/arm64/vpx_config.asm
index 63979ef..296266de 100644
--- a/third_party/libvpx/source/config/ios/arm64/vpx_config.asm
+++ b/third_party/libvpx/source/config/ios/arm64/vpx_config.asm
@@ -78,6 +78,7 @@
 .set CONFIG_MULTI_RES_ENCODING ,  1
 .set CONFIG_TEMPORAL_DENOISING ,  1
 .set CONFIG_VP9_TEMPORAL_DENOISING ,  1
+.set CONFIG_CONSISTENT_RECODE ,  0
 .set CONFIG_COEFFICIENT_RANGE_CHECKING ,  0
 .set CONFIG_VP9_HIGHBITDEPTH ,  0
 .set CONFIG_BETTER_HW_COMPATIBILITY ,  0
diff --git a/third_party/libvpx/source/config/ios/arm64/vpx_config.h b/third_party/libvpx/source/config/ios/arm64/vpx_config.h
index 1ab268c..13e7637 100644
--- a/third_party/libvpx/source/config/ios/arm64/vpx_config.h
+++ b/third_party/libvpx/source/config/ios/arm64/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 0
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/ios/arm64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/ios/arm64/vpx_dsp_rtcd.h
index cc0b382..0056935 100644
--- a/third_party/libvpx/source/config/ios/arm64/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/ios/arm64/vpx_dsp_rtcd.h
@@ -2210,7 +2210,8 @@
 #define vpx_subtract_block vpx_subtract_block_neon
 
 uint64_t vpx_sum_squares_2d_i16_c(const int16_t* src, int stride, int size);
-#define vpx_sum_squares_2d_i16 vpx_sum_squares_2d_i16_c
+uint64_t vpx_sum_squares_2d_i16_neon(const int16_t* src, int stride, int size);
+#define vpx_sum_squares_2d_i16 vpx_sum_squares_2d_i16_neon
 
 void vpx_tm_predictor_16x16_c(uint8_t* dst,
                               ptrdiff_t y_stride,
diff --git a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.asm b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.asm
index ccf2d701..e6fa07b 100644
--- a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.asm
+++ b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.asm
@@ -75,6 +75,7 @@
 .equ CONFIG_MULTI_RES_ENCODING ,  1
 .equ CONFIG_TEMPORAL_DENOISING ,  1
 .equ CONFIG_VP9_TEMPORAL_DENOISING ,  1
+.equ CONFIG_CONSISTENT_RECODE ,  0
 .equ CONFIG_COEFFICIENT_RANGE_CHECKING ,  0
 .equ CONFIG_VP9_HIGHBITDEPTH ,  0
 .equ CONFIG_BETTER_HW_COMPATIBILITY ,  0
diff --git a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.h b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.h
index 9cb0939..5b8efae 100644
--- a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.h
+++ b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 0
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_dsp_rtcd.h
index c518d2b..3308094 100644
--- a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vpx_dsp_rtcd.h
@@ -2891,7 +2891,10 @@
                                        ptrdiff_t pred_stride);
 
 uint64_t vpx_sum_squares_2d_i16_c(const int16_t* src, int stride, int size);
-#define vpx_sum_squares_2d_i16 vpx_sum_squares_2d_i16_c
+uint64_t vpx_sum_squares_2d_i16_neon(const int16_t* src, int stride, int size);
+RTCD_EXTERN uint64_t (*vpx_sum_squares_2d_i16)(const int16_t* src,
+                                               int stride,
+                                               int size);
 
 void vpx_tm_predictor_16x16_c(uint8_t* dst,
                               ptrdiff_t y_stride,
@@ -3694,6 +3697,9 @@
   vpx_subtract_block = vpx_subtract_block_c;
   if (flags & HAS_NEON)
     vpx_subtract_block = vpx_subtract_block_neon;
+  vpx_sum_squares_2d_i16 = vpx_sum_squares_2d_i16_c;
+  if (flags & HAS_NEON)
+    vpx_sum_squares_2d_i16 = vpx_sum_squares_2d_i16_neon;
   vpx_tm_predictor_16x16 = vpx_tm_predictor_16x16_c;
   if (flags & HAS_NEON)
     vpx_tm_predictor_16x16 = vpx_tm_predictor_16x16_neon;
diff --git a/third_party/libvpx/source/config/linux/arm-neon/vpx_config.asm b/third_party/libvpx/source/config/linux/arm-neon/vpx_config.asm
index 87cfb6a..1137b0f 100644
--- a/third_party/libvpx/source/config/linux/arm-neon/vpx_config.asm
+++ b/third_party/libvpx/source/config/linux/arm-neon/vpx_config.asm
@@ -75,6 +75,7 @@
 .equ CONFIG_MULTI_RES_ENCODING ,  1
 .equ CONFIG_TEMPORAL_DENOISING ,  1
 .equ CONFIG_VP9_TEMPORAL_DENOISING ,  1
+.equ CONFIG_CONSISTENT_RECODE ,  0
 .equ CONFIG_COEFFICIENT_RANGE_CHECKING ,  0
 .equ CONFIG_VP9_HIGHBITDEPTH ,  0
 .equ CONFIG_BETTER_HW_COMPATIBILITY ,  0
diff --git a/third_party/libvpx/source/config/linux/arm-neon/vpx_config.h b/third_party/libvpx/source/config/linux/arm-neon/vpx_config.h
index b80461bd..365206f 100644
--- a/third_party/libvpx/source/config/linux/arm-neon/vpx_config.h
+++ b/third_party/libvpx/source/config/linux/arm-neon/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 0
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/linux/arm-neon/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/arm-neon/vpx_dsp_rtcd.h
index cc0b382..0056935 100644
--- a/third_party/libvpx/source/config/linux/arm-neon/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/linux/arm-neon/vpx_dsp_rtcd.h
@@ -2210,7 +2210,8 @@
 #define vpx_subtract_block vpx_subtract_block_neon
 
 uint64_t vpx_sum_squares_2d_i16_c(const int16_t* src, int stride, int size);
-#define vpx_sum_squares_2d_i16 vpx_sum_squares_2d_i16_c
+uint64_t vpx_sum_squares_2d_i16_neon(const int16_t* src, int stride, int size);
+#define vpx_sum_squares_2d_i16 vpx_sum_squares_2d_i16_neon
 
 void vpx_tm_predictor_16x16_c(uint8_t* dst,
                               ptrdiff_t y_stride,
diff --git a/third_party/libvpx/source/config/linux/arm/vpx_config.asm b/third_party/libvpx/source/config/linux/arm/vpx_config.asm
index 6cc4a69..51d4f390 100644
--- a/third_party/libvpx/source/config/linux/arm/vpx_config.asm
+++ b/third_party/libvpx/source/config/linux/arm/vpx_config.asm
@@ -75,6 +75,7 @@
 .equ CONFIG_MULTI_RES_ENCODING ,  1
 .equ CONFIG_TEMPORAL_DENOISING ,  1
 .equ CONFIG_VP9_TEMPORAL_DENOISING ,  1
+.equ CONFIG_CONSISTENT_RECODE ,  0
 .equ CONFIG_COEFFICIENT_RANGE_CHECKING ,  0
 .equ CONFIG_VP9_HIGHBITDEPTH ,  0
 .equ CONFIG_BETTER_HW_COMPATIBILITY ,  0
diff --git a/third_party/libvpx/source/config/linux/arm/vpx_config.h b/third_party/libvpx/source/config/linux/arm/vpx_config.h
index 826ac8d1..fc57694 100644
--- a/third_party/libvpx/source/config/linux/arm/vpx_config.h
+++ b/third_party/libvpx/source/config/linux/arm/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 0
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/linux/arm64/vpx_config.asm b/third_party/libvpx/source/config/linux/arm64/vpx_config.asm
index c5284f8..54efd55c5 100644
--- a/third_party/libvpx/source/config/linux/arm64/vpx_config.asm
+++ b/third_party/libvpx/source/config/linux/arm64/vpx_config.asm
@@ -75,6 +75,7 @@
 .equ CONFIG_MULTI_RES_ENCODING ,  1
 .equ CONFIG_TEMPORAL_DENOISING ,  1
 .equ CONFIG_VP9_TEMPORAL_DENOISING ,  1
+.equ CONFIG_CONSISTENT_RECODE ,  0
 .equ CONFIG_COEFFICIENT_RANGE_CHECKING ,  0
 .equ CONFIG_VP9_HIGHBITDEPTH ,  0
 .equ CONFIG_BETTER_HW_COMPATIBILITY ,  0
diff --git a/third_party/libvpx/source/config/linux/arm64/vpx_config.h b/third_party/libvpx/source/config/linux/arm64/vpx_config.h
index 1ab268c..13e7637 100644
--- a/third_party/libvpx/source/config/linux/arm64/vpx_config.h
+++ b/third_party/libvpx/source/config/linux/arm64/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 0
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/linux/arm64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/arm64/vpx_dsp_rtcd.h
index cc0b382..0056935 100644
--- a/third_party/libvpx/source/config/linux/arm64/vpx_dsp_rtcd.h
+++ b/third_party/libvpx/source/config/linux/arm64/vpx_dsp_rtcd.h
@@ -2210,7 +2210,8 @@
 #define vpx_subtract_block vpx_subtract_block_neon
 
 uint64_t vpx_sum_squares_2d_i16_c(const int16_t* src, int stride, int size);
-#define vpx_sum_squares_2d_i16 vpx_sum_squares_2d_i16_c
+uint64_t vpx_sum_squares_2d_i16_neon(const int16_t* src, int stride, int size);
+#define vpx_sum_squares_2d_i16 vpx_sum_squares_2d_i16_neon
 
 void vpx_tm_predictor_16x16_c(uint8_t* dst,
                               ptrdiff_t y_stride,
diff --git a/third_party/libvpx/source/config/linux/generic/vpx_config.asm b/third_party/libvpx/source/config/linux/generic/vpx_config.asm
index fc694fb..650636a 100644
--- a/third_party/libvpx/source/config/linux/generic/vpx_config.asm
+++ b/third_party/libvpx/source/config/linux/generic/vpx_config.asm
@@ -75,6 +75,7 @@
 .equ CONFIG_MULTI_RES_ENCODING ,  1
 .equ CONFIG_TEMPORAL_DENOISING ,  1
 .equ CONFIG_VP9_TEMPORAL_DENOISING ,  1
+.equ CONFIG_CONSISTENT_RECODE ,  0
 .equ CONFIG_COEFFICIENT_RANGE_CHECKING ,  0
 .equ CONFIG_VP9_HIGHBITDEPTH ,  1
 .equ CONFIG_BETTER_HW_COMPATIBILITY ,  0
diff --git a/third_party/libvpx/source/config/linux/generic/vpx_config.h b/third_party/libvpx/source/config/linux/generic/vpx_config.h
index cc20ff9e..df5f6f8 100644
--- a/third_party/libvpx/source/config/linux/generic/vpx_config.h
+++ b/third_party/libvpx/source/config/linux/generic/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 1
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/linux/ia32/vpx_config.asm b/third_party/libvpx/source/config/linux/ia32/vpx_config.asm
index b1c79dd..6aa13d7 100644
--- a/third_party/libvpx/source/config/linux/ia32/vpx_config.asm
+++ b/third_party/libvpx/source/config/linux/ia32/vpx_config.asm
@@ -72,6 +72,7 @@
 %define CONFIG_MULTI_RES_ENCODING 1
 %define CONFIG_TEMPORAL_DENOISING 1
 %define CONFIG_VP9_TEMPORAL_DENOISING 1
+%define CONFIG_CONSISTENT_RECODE 0
 %define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 %define CONFIG_VP9_HIGHBITDEPTH 1
 %define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/linux/ia32/vpx_config.h b/third_party/libvpx/source/config/linux/ia32/vpx_config.h
index dbd8c1d3..7749f38 100644
--- a/third_party/libvpx/source/config/linux/ia32/vpx_config.h
+++ b/third_party/libvpx/source/config/linux/ia32/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 1
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/linux/mips64el/vpx_config.h b/third_party/libvpx/source/config/linux/mips64el/vpx_config.h
index d876f25b..98374b1 100644
--- a/third_party/libvpx/source/config/linux/mips64el/vpx_config.h
+++ b/third_party/libvpx/source/config/linux/mips64el/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 0
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/linux/mipsel/vpx_config.h b/third_party/libvpx/source/config/linux/mipsel/vpx_config.h
index 967e544..1a8a71b 100644
--- a/third_party/libvpx/source/config/linux/mipsel/vpx_config.h
+++ b/third_party/libvpx/source/config/linux/mipsel/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 0
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/linux/x64/vpx_config.asm b/third_party/libvpx/source/config/linux/x64/vpx_config.asm
index 84f986d3f..ffaf2d9 100644
--- a/third_party/libvpx/source/config/linux/x64/vpx_config.asm
+++ b/third_party/libvpx/source/config/linux/x64/vpx_config.asm
@@ -72,6 +72,7 @@
 %define CONFIG_MULTI_RES_ENCODING 1
 %define CONFIG_TEMPORAL_DENOISING 1
 %define CONFIG_VP9_TEMPORAL_DENOISING 1
+%define CONFIG_CONSISTENT_RECODE 0
 %define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 %define CONFIG_VP9_HIGHBITDEPTH 1
 %define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/linux/x64/vpx_config.h b/third_party/libvpx/source/config/linux/x64/vpx_config.h
index aedc476..c6e9e82 100644
--- a/third_party/libvpx/source/config/linux/x64/vpx_config.h
+++ b/third_party/libvpx/source/config/linux/x64/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 1
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/mac/ia32/vpx_config.asm b/third_party/libvpx/source/config/mac/ia32/vpx_config.asm
index b1c79dd..6aa13d7 100644
--- a/third_party/libvpx/source/config/mac/ia32/vpx_config.asm
+++ b/third_party/libvpx/source/config/mac/ia32/vpx_config.asm
@@ -72,6 +72,7 @@
 %define CONFIG_MULTI_RES_ENCODING 1
 %define CONFIG_TEMPORAL_DENOISING 1
 %define CONFIG_VP9_TEMPORAL_DENOISING 1
+%define CONFIG_CONSISTENT_RECODE 0
 %define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 %define CONFIG_VP9_HIGHBITDEPTH 1
 %define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/mac/ia32/vpx_config.h b/third_party/libvpx/source/config/mac/ia32/vpx_config.h
index dbd8c1d3..7749f38 100644
--- a/third_party/libvpx/source/config/mac/ia32/vpx_config.h
+++ b/third_party/libvpx/source/config/mac/ia32/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 1
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/mac/x64/vpx_config.asm b/third_party/libvpx/source/config/mac/x64/vpx_config.asm
index 84f986d3f..ffaf2d9 100644
--- a/third_party/libvpx/source/config/mac/x64/vpx_config.asm
+++ b/third_party/libvpx/source/config/mac/x64/vpx_config.asm
@@ -72,6 +72,7 @@
 %define CONFIG_MULTI_RES_ENCODING 1
 %define CONFIG_TEMPORAL_DENOISING 1
 %define CONFIG_VP9_TEMPORAL_DENOISING 1
+%define CONFIG_CONSISTENT_RECODE 0
 %define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 %define CONFIG_VP9_HIGHBITDEPTH 1
 %define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/mac/x64/vpx_config.h b/third_party/libvpx/source/config/mac/x64/vpx_config.h
index aedc476..c6e9e82 100644
--- a/third_party/libvpx/source/config/mac/x64/vpx_config.h
+++ b/third_party/libvpx/source/config/mac/x64/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 1
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/nacl/vpx_config.h b/third_party/libvpx/source/config/nacl/vpx_config.h
index cc20ff9e..df5f6f8 100644
--- a/third_party/libvpx/source/config/nacl/vpx_config.h
+++ b/third_party/libvpx/source/config/nacl/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 1
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h
index 7b05621..49c88455 100644
--- a/third_party/libvpx/source/config/vpx_version.h
+++ b/third_party/libvpx/source/config/vpx_version.h
@@ -2,7 +2,7 @@
 #define VERSION_MAJOR  1
 #define VERSION_MINOR  7
 #define VERSION_PATCH  0
-#define VERSION_EXTRA  "317-g28801f91c"
+#define VERSION_EXTRA  "377-gd99abe9a9"
 #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH))
-#define VERSION_STRING_NOSP "v1.7.0-317-g28801f91c"
-#define VERSION_STRING      " v1.7.0-317-g28801f91c"
+#define VERSION_STRING_NOSP "v1.7.0-377-gd99abe9a9"
+#define VERSION_STRING      " v1.7.0-377-gd99abe9a9"
diff --git a/third_party/libvpx/source/config/win/ia32/vpx_config.asm b/third_party/libvpx/source/config/win/ia32/vpx_config.asm
index 0592279..4e7f686 100644
--- a/third_party/libvpx/source/config/win/ia32/vpx_config.asm
+++ b/third_party/libvpx/source/config/win/ia32/vpx_config.asm
@@ -72,6 +72,7 @@
 %define CONFIG_MULTI_RES_ENCODING 1
 %define CONFIG_TEMPORAL_DENOISING 1
 %define CONFIG_VP9_TEMPORAL_DENOISING 1
+%define CONFIG_CONSISTENT_RECODE 0
 %define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 %define CONFIG_VP9_HIGHBITDEPTH 1
 %define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/win/ia32/vpx_config.h b/third_party/libvpx/source/config/win/ia32/vpx_config.h
index 0725ed3..2cf19145 100644
--- a/third_party/libvpx/source/config/win/ia32/vpx_config.h
+++ b/third_party/libvpx/source/config/win/ia32/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 1
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/win/x64/vpx_config.asm b/third_party/libvpx/source/config/win/x64/vpx_config.asm
index c17b1e3..ef886a3 100644
--- a/third_party/libvpx/source/config/win/x64/vpx_config.asm
+++ b/third_party/libvpx/source/config/win/x64/vpx_config.asm
@@ -72,6 +72,7 @@
 %define CONFIG_MULTI_RES_ENCODING 1
 %define CONFIG_TEMPORAL_DENOISING 1
 %define CONFIG_VP9_TEMPORAL_DENOISING 1
+%define CONFIG_CONSISTENT_RECODE 0
 %define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 %define CONFIG_VP9_HIGHBITDEPTH 1
 %define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/libvpx/source/config/win/x64/vpx_config.h b/third_party/libvpx/source/config/win/x64/vpx_config.h
index f0fbf89..6d53949 100644
--- a/third_party/libvpx/source/config/win/x64/vpx_config.h
+++ b/third_party/libvpx/source/config/win/x64/vpx_config.h
@@ -84,6 +84,7 @@
 #define CONFIG_MULTI_RES_ENCODING 1
 #define CONFIG_TEMPORAL_DENOISING 1
 #define CONFIG_VP9_TEMPORAL_DENOISING 1
+#define CONFIG_CONSISTENT_RECODE 0
 #define CONFIG_COEFFICIENT_RANGE_CHECKING 0
 #define CONFIG_VP9_HIGHBITDEPTH 1
 #define CONFIG_BETTER_HW_COMPATIBILITY 0
diff --git a/third_party/metrics_proto/README.chromium b/third_party/metrics_proto/README.chromium
index 97fa047f..beda783 100644
--- a/third_party/metrics_proto/README.chromium
+++ b/third_party/metrics_proto/README.chromium
@@ -1,8 +1,8 @@
 Name: Metrics Protos
 Short Name: metrics_proto
 URL: This is the canonical public repository
-Version: 192562418
-Date: 2018/04/12 UTC
+Version: 196311805
+Date: 2018/05/11 UTC
 License: BSD
 Security Critical: Yes
 
diff --git a/third_party/metrics_proto/system_profile.proto b/third_party/metrics_proto/system_profile.proto
index 81d0092..8bbfb922 100644
--- a/third_party/metrics_proto/system_profile.proto
+++ b/third_party/metrics_proto/system_profile.proto
@@ -15,7 +15,7 @@
 
 // Stores information about the user's brower and system configuration.
 // The system configuration fields are recorded once per client session.
-// Next tag: 27
+// Next tag: 28
 message SystemProfileProto {
   // The time when the client was compiled/linked, in seconds since the epoch.
   optional int64 build_timestamp = 1;
@@ -83,7 +83,8 @@
     // - Android
     // - Windows NT
     // - Linux (includes ChromeOS)
-    // - iPhone OS
+    // - iOS (iOS versions >= 9)
+    // - iPhone OS (iOS versions <= 8)
     // - Mac OS X
     optional string name = 1;
 
@@ -102,7 +103,7 @@
   optional OS os = 5;
 
   // Information on the user's hardware.
-  // Next tag: 18
+  // Next tag: 19
   message Hardware {
     // The CPU architecture (x86, PowerPC, x86_64, ...)
     optional string cpu_architecture = 1;
@@ -122,16 +123,23 @@
     // to that, device hardware class was incorrectly recorded in
     // cpu_architecture field.
     //
-    // For Chrome OS, the device hardware class ID is a unique string associated
-    // with each Chrome OS device product revision generally assigned at
-    // hardware qualification time. The hardware class effectively identifies
-    // the configured system components such as CPU, WiFi adapter, etc.
+    // For Chrome OS, prior to M68, this field had the value that is
+    // currently in |full_hardware_class| field. In M68+, this contains the
+    // board name only. E.G. "CELES", "VEYRON_MINNIE".
+
+    optional string hardware_class = 4;
+
+    // This field is only sent on Chrome OS. The full hardware class is a unique
+    // string associated with each Chrome OS device product revision generally
+    // assigned at hardware qualification time. The hardware class effectively
+    // identifies the configured system components such as CPU, WiFi adapter,
+    // etc.
     //
     // An example of such a hardware class is "IEC MARIO PONY 6101".  An
     // internal database associates this hardware class with the qualified
     // device specifications including OEM information, schematics, hardware
     // qualification reports, test device tags, etc.
-    optional string hardware_class = 4;
+    optional string full_hardware_class = 18;
 
     // The number of physical screens.
     optional int32 screen_count = 5;
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 588d136..a6c34b87 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -27,7 +27,7 @@
 # Do NOT CHANGE this if you don't know what you're doing -- see
 # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md
 # Reverting problematic clang rolls is safe, though.
-CLANG_REVISION = '331747'
+CLANG_REVISION = '332335'
 
 use_head_revision = bool(os.environ.get('LLVM_FORCE_HEAD_REVISION', '0')
                          in ('1', 'YES'))
diff --git a/tools/clang/translation_unit/TranslationUnitGenerator.cpp b/tools/clang/translation_unit/TranslationUnitGenerator.cpp
index ca5579b..be61238 100644
--- a/tools/clang/translation_unit/TranslationUnitGenerator.cpp
+++ b/tools/clang/translation_unit/TranslationUnitGenerator.cpp
@@ -60,11 +60,8 @@
                           const clang::FileEntry* file,
                           llvm::StringRef search_path,
                           llvm::StringRef relative_path,
-                          const clang::Module* imported
-#if defined(LLVM_FORCE_HEAD_REVISION)
-                          ,
+                          const clang::Module* imported,
                           clang::SrcMgr::CharacteristicKind /*file_type*/
-#endif
                           ) override;
   void EndOfMainFile() override;
 
@@ -148,11 +145,8 @@
     const clang::FileEntry* file,
     llvm::StringRef search_path,
     llvm::StringRef relative_path,
-    const clang::Module* imported
-#if defined(LLVM_FORCE_HEAD_REVISION)
-    ,
+    const clang::Module* imported,
     clang::SrcMgr::CharacteristicKind /*file_type*/
-#endif
     ) {
   if (!file)
     return;
diff --git a/tools/gn/ninja_action_target_writer_unittest.cc b/tools/gn/ninja_action_target_writer_unittest.cc
index 445a31a..1b2ddc8 100644
--- a/tools/gn/ninja_action_target_writer_unittest.cc
+++ b/tools/gn/ninja_action_target_writer_unittest.cc
@@ -409,77 +409,3 @@
       "build obj/foo/bar.stamp: stamp input1.out\n";
   EXPECT_EQ(expected_linux, out.str());
 }
-
-TEST(NinjaActionTargetWriter, NoTransitiveHardDeps) {
-  Err err;
-  TestWithScope setup;
-
-  setup.build_settings()->set_python_path(
-      base::FilePath(FILE_PATH_LITERAL("/usr/bin/python")));
-
-  Target dep(setup.settings(), Label(SourceDir("//foo/"), "dep"));
-  dep.set_output_type(Target::ACTION);
-  dep.visibility().SetPublic();
-  dep.SetToolchain(setup.toolchain());
-  ASSERT_TRUE(dep.OnResolved(&err));
-
-  Target foo(setup.settings(), Label(SourceDir("//foo/"), "foo"));
-  foo.set_output_type(Target::ACTION);
-  foo.visibility().SetPublic();
-  foo.sources().push_back(SourceFile("//foo/input1.txt"));
-  foo.action_values().set_script(SourceFile("//foo/script.py"));
-  foo.private_deps().push_back(LabelTargetPair(&dep));
-  foo.SetToolchain(setup.toolchain());
-  foo.action_values().outputs() =
-      SubstitutionList::MakeForTest("//out/Debug/foo.out");
-  ASSERT_TRUE(foo.OnResolved(&err));
-
-  {
-    std::ostringstream out;
-    NinjaActionTargetWriter writer(&foo, out);
-    writer.Run();
-
-    const char expected_linux[] =
-        "rule __foo_foo___rule\n"
-        // These come from the args.
-        "  command = /usr/bin/python ../../foo/script.py\n"
-        "  description = ACTION //foo:foo()\n"
-        "  restat = 1\n"
-        "\n"
-        "build foo.out: __foo_foo___rule | ../../foo/script.py"
-        " ../../foo/input1.txt obj/foo/dep.stamp\n"
-        "\n"
-        "build obj/foo/foo.stamp: stamp foo.out\n";
-    EXPECT_EQ(expected_linux, out.str());
-  }
-
-  Target bar(setup.settings(), Label(SourceDir("//bar/"), "bar"));
-  bar.set_output_type(Target::ACTION);
-  bar.sources().push_back(SourceFile("//bar/input1.txt"));
-  bar.action_values().set_script(SourceFile("//bar/script.py"));
-  bar.private_deps().push_back(LabelTargetPair(&foo));
-  bar.SetToolchain(setup.toolchain());
-  bar.action_values().outputs() =
-      SubstitutionList::MakeForTest("//out/Debug/bar.out");
-  ASSERT_TRUE(bar.OnResolved(&err)) << err.message();
-
-  {
-    std::ostringstream out;
-    NinjaActionTargetWriter writer(&bar, out);
-    writer.Run();
-
-    const char expected_linux[] =
-        "rule __bar_bar___rule\n"
-        // These come from the args.
-        "  command = /usr/bin/python ../../bar/script.py\n"
-        "  description = ACTION //bar:bar()\n"
-        "  restat = 1\n"
-        "\n"
-        // Do not have obj/foo/dep.stamp as dependency.
-        "build bar.out: __bar_bar___rule | ../../bar/script.py"
-        " ../../bar/input1.txt obj/foo/foo.stamp\n"
-        "\n"
-        "build obj/bar/bar.stamp: stamp bar.out\n";
-    EXPECT_EQ(expected_linux, out.str());
-  }
-}
diff --git a/tools/gn/ninja_target_writer_unittest.cc b/tools/gn/ninja_target_writer_unittest.cc
index 2bcbc8986..68a59c81 100644
--- a/tools/gn/ninja_target_writer_unittest.cc
+++ b/tools/gn/ninja_target_writer_unittest.cc
@@ -5,7 +5,6 @@
 #include <sstream>
 
 #include "testing/gtest/include/gtest/gtest.h"
-#include "tools/gn/ninja_action_target_writer.h"
 #include "tools/gn/ninja_target_writer.h"
 #include "tools/gn/target.h"
 #include "tools/gn/test_with_scope.h"
@@ -95,23 +94,6 @@
     EXPECT_EQ("obj/foo/base.stamp", dep[0].value());
   }
 
-  {
-    std::ostringstream stream;
-    NinjaActionTargetWriter writer(&action, stream);
-    writer.Run();
-    EXPECT_EQ(
-        "rule __foo_action___rule\n"
-        "  command =  ../../foo/script.py\n"
-        "  description = ACTION //foo:action()\n"
-        "  restat = 1\n"
-        "\n"
-        "build: __foo_action___rule | ../../foo/script.py"
-        " ../../foo/action_source.txt ./target\n"
-        "\n"
-        "build obj/foo/action.stamp: stamp\n",
-        stream.str());
-  }
-
   // Input deps for action which should depend on the base since its a hard dep
   // that is a (indirect) dependency, as well as the the action source.
   {
@@ -122,10 +104,9 @@
 
     ASSERT_EQ(1u, dep.size());
     EXPECT_EQ("obj/foo/action.inputdeps.stamp", dep[0].value());
-    EXPECT_EQ(
-        "build obj/foo/action.inputdeps.stamp: stamp ../../foo/script.py "
-        "../../foo/action_source.txt\n",
-        stream.str());
+    EXPECT_EQ("build obj/foo/action.inputdeps.stamp: stamp ../../foo/script.py "
+                  "../../foo/action_source.txt obj/foo/base.stamp\n",
+              stream.str());
   }
 }
 
diff --git a/tools/gn/target.cc b/tools/gn/target.cc
index e6013e43..15df27f5 100644
--- a/tools/gn/target.cc
+++ b/tools/gn/target.cc
@@ -372,13 +372,7 @@
 
   PullRecursiveBundleData();
   PullDependentTargetLibs();
-
-  if (!hard_dep()) {
-    // If this target is not hard_dep type, we need to pull hard dependency from
-    // dependent target, because it may not transitive for compiling tasks.
-    PullRecursiveHardDeps();
-  }
-
+  PullRecursiveHardDeps();
   if (!ResolvePrecompiledHeaders(err))
     return false;
 
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 0608200..d1453d5 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -115,10 +115,10 @@
       'CrWinAsan(dll)': 'asan_clang_shared_v8_heap_x86_full_symbols_release',
       'CrWinAsanCov': 'asan_clang_edge_fuzzer_static_v8_heap_x86_full_symbols_release',
 
-      'CrWinClangLLD': 'clang_tot_official_static_no_lld_x86',
-      'CrWinClangLLD64': 'clang_tot_shared_release_no_lld_dcheck',
-      'CrWinClngLLD64dbg': 'clang_tot_full_symbols_shared_debug_no_lld',
-      'CrWinClngLLDdbg': 'clang_tot_full_symbols_shared_debug_no_lld_x86',
+      'CrWinClangLLD': 'clang_tot_official_static_use_lld_x86',
+      'CrWinClangLLD64': 'clang_tot_shared_release_use_lld_dcheck',
+      'CrWinClngLLD64dbg': 'clang_tot_full_symbols_shared_debug_use_lld',
+      'CrWinClngLLDdbg': 'clang_tot_full_symbols_shared_debug_use_lld_x86',
       'linux-win_cross-rel': 'clang_tot_win_release_cross',
       'ToTAndroid': 'android_clang_tot_release_minimal_symbols',
       'ToTAndroid64': 'android_clang_tot_release_arm64',
@@ -1119,24 +1119,24 @@
       'clang_tot', 'shared', 'debug',
     ],
 
-    'clang_tot_full_symbols_shared_debug_no_lld': [
-      'clang_tot', 'full_symbols', 'shared', 'debug', 'no_lld',
+    'clang_tot_full_symbols_shared_debug_use_lld': [
+      'clang_tot', 'full_symbols', 'shared', 'debug', 'use_lld',
     ],
 
-    'clang_tot_full_symbols_shared_debug_no_lld_x86': [
-      'clang_tot', 'full_symbols', 'shared', 'debug', 'no_lld', 'x86',
+    'clang_tot_full_symbols_shared_debug_use_lld_x86': [
+      'clang_tot', 'full_symbols', 'shared', 'debug', 'use_lld', 'x86',
     ],
 
     'clang_tot_shared_debug_x86': [
       'clang_tot', 'shared', 'debug', 'x86',
     ],
 
-    'clang_tot_shared_release_no_lld_dcheck': [
-      'clang_tot', 'minimal_symbols', 'shared', 'release', 'no_lld', 'dcheck_always_on',
+    'clang_tot_shared_release_use_lld_dcheck': [
+      'clang_tot', 'minimal_symbols', 'shared', 'release', 'use_lld', 'dcheck_always_on',
     ],
 
-    'clang_tot_official_static_no_lld_x86': [
-      'clang_tot', 'minimal_symbols', 'official', 'static', 'release', 'no_lld', 'x86',
+    'clang_tot_official_static_use_lld_x86': [
+      'clang_tot', 'minimal_symbols', 'official', 'static', 'release', 'use_lld', 'x86',
     ],
 
     'clang_tot_minimal_symbols_shared_release': [
@@ -2087,10 +2087,6 @@
       'gn_args': 'use_lld=true',
     },
 
-    'no_lld': {
-      'gn_args': 'use_lld=false',
-    },
-
     'use_vaapi': {
       'gn_args': 'use_vaapi=true',
     },
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 929b5f5d..243a49e 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -58053,6 +58053,15 @@
   </summary>
 </histogram>
 
+<histogram name="NQE.EndToEndRTT.OnECTComputation" units="ms">
+  <owner>tbansal@chromium.org</owner>
+  <summary>
+    Rough estimate of the computed end-to-end round trip time. Recorded by the
+    network quality estimator every time the effective connection type is
+    computed.
+  </summary>
+</histogram>
+
 <histogram name="NQE.EstimateAvailable.MainFrame" enum="Boolean">
   <owner>tbansal@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
diff --git a/tools/perf/contrib/cluster_telemetry/local_trace_measurement.py b/tools/perf/contrib/cluster_telemetry/local_trace_measurement.py
index 5e17667..dca8243 100644
--- a/tools/perf/contrib/cluster_telemetry/local_trace_measurement.py
+++ b/tools/perf/contrib/cluster_telemetry/local_trace_measurement.py
@@ -26,6 +26,8 @@
   def Measure(self, platform, results):
     """Collect all possible metrics and add them to results."""
     # Extract the file name without the "file:/" prefix.
+    assert results.current_page.name.startswith("file:/"), \
+        "current page path should start with file:/"
     filename = results.current_page.name[len("file:/"):]
 
     metrics = self._tbm_options.GetTimelineBasedMetrics()
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py
index c4fc495..c16b950 100755
--- a/tools/perf/core/perf_data_generator.py
+++ b/tools/perf/core/perf_data_generator.py
@@ -449,6 +449,25 @@
     'system_health.memory_desktop',
     'system_health.memory_mobile',
     'system_health.webview_startup',
+    'smoothness.gpu_rasterization.tough_filters_cases',
+    'smoothness.gpu_rasterization.tough_path_rendering_cases',
+    'smoothness.gpu_rasterization.tough_scrolling_cases',
+    'smoothness.gpu_rasterization_and_decoding.image_decoding_cases',
+    'smoothness.image_decoding_cases',
+    'smoothness.key_desktop_move_cases',
+    'smoothness.maps',
+    'smoothness.oop_rasterization.top_25_smooth',
+    'smoothness.top_25_smooth',
+    'smoothness.tough_ad_cases',
+    'smoothness.tough_animation_cases',
+    'smoothness.tough_canvas_cases',
+    'smoothness.tough_filters_cases',
+    'smoothness.tough_image_decode_cases',
+    'smoothness.tough_path_rendering_cases',
+    'smoothness.tough_scrolling_cases',
+    'smoothness.tough_texture_upload_cases',
+    'smoothness.tough_webgl_ad_cases',
+    'smoothness.tough_webgl_cases',
 ]
 
 
diff --git a/tools/real_world_impact/real_world_impact.py b/tools/real_world_impact/real_world_impact.py
index 4d0b1663..0724909 100755
--- a/tools/real_world_impact/real_world_impact.py
+++ b/tools/real_world_impact/real_world_impact.py
@@ -278,7 +278,7 @@
 
   with open(os.devnull, "w") as fnull:
     p = subprocess.Popen([content_shell,
-                          "--run-layout-test",
+                          "--run-web-tests",
                           additional_content_shell_flags,
                           # The single quote is not a typo, it's a separator!
                           html_path + "'--pixel-test"
@@ -551,4 +551,4 @@
 
 
 if __name__ == '__main__':
-  sys.exit(main(sys.argv))
\ No newline at end of file
+  sys.exit(main(sys.argv))
diff --git a/ui/app_list/views/suggestion_chip_view.cc b/ui/app_list/views/suggestion_chip_view.cc
index 0b4e5205..25d0d2e9 100644
--- a/ui/app_list/views/suggestion_chip_view.cc
+++ b/ui/app_list/views/suggestion_chip_view.cc
@@ -5,6 +5,8 @@
 #include "ui/app_list/views/suggestion_chip_view.h"
 
 #include "ui/gfx/canvas.h"
+#include "ui/views/background.h"
+#include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/box_layout.h"
 
@@ -12,42 +14,92 @@
 
 namespace {
 
-// Appearance.
-constexpr SkColor kBackgroundColor = SkColorSetA(SK_ColorBLACK, 0x1F);
-constexpr int kCornerRadiusDip = 12;
-constexpr int kPaddingHorizontalDip = 8;
-constexpr int kPaddingVerticalDip = 4;
+// Colors.
+constexpr SkColor kBackgroundColor = SK_ColorWHITE;
+constexpr SkColor kStrokeColor = SkColorSetRGB(0xDA, 0xDC, 0xE0);  // G Grey 300
+constexpr SkColor kTextColor = SkColorSetRGB(0x3C, 0x40, 0x43);    // G Grey 800
 
-// Typography.
-constexpr SkColor kTextColor = SkColorSetA(SK_ColorBLACK, 0xDE);
+// Dimensions.
+constexpr int kIconMarginDip = 8;
+constexpr int kIconSizeDip = 20;
+constexpr int kPaddingDip = 16;
+constexpr int kPreferredHeightDip = 32;
+constexpr int kStrokeWidthDip = 1;
 
 }  // namespace
 
-SuggestionChipView::SuggestionChipView(const base::string16& text,
+// Params ----------------------------------------------------------------------
+
+SuggestionChipView::Params::Params() = default;
+
+SuggestionChipView::Params::~Params() = default;
+
+// SuggestionChipView ----------------------------------------------------------
+
+SuggestionChipView::SuggestionChipView(const Params& params,
                                        SuggestionChipListener* listener)
-    : text_view_(new views::Label(text)), listener_(listener) {
-  InitLayout();
+    : icon_view_(new views::ImageView()),
+      text_view_(new views::Label()),
+      listener_(listener) {
+  InitLayout(params);
 }
 
-void SuggestionChipView::InitLayout() {
-  SetLayoutManager(std::make_unique<views::BoxLayout>(
-      views::BoxLayout::Orientation::kHorizontal,
-      gfx::Insets(kPaddingVerticalDip, kPaddingHorizontalDip)));
+SuggestionChipView::~SuggestionChipView() = default;
 
-  // TODO(dmblack): Add optional icon.
+gfx::Size SuggestionChipView::CalculatePreferredSize() const {
+  return gfx::Size(views::View::CalculatePreferredSize().width(),
+                   kPreferredHeightDip);
+}
 
-  // Text view.
+void SuggestionChipView::InitLayout(const Params& params) {
+  // Layout padding differs depending on icon visibility.
+  const int padding_left_dip = params.icon ? kIconMarginDip : kPaddingDip;
+
+  views::BoxLayout* layout_manager =
+      SetLayoutManager(std::make_unique<views::BoxLayout>(
+          views::BoxLayout::Orientation::kHorizontal,
+          gfx::Insets(0, padding_left_dip, 0, kPaddingDip), kIconMarginDip));
+
+  layout_manager->set_cross_axis_alignment(
+      views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_CENTER);
+
+  // Icon.
+  icon_view_->SetImageSize(gfx::Size(kIconSizeDip, kIconSizeDip));
+  icon_view_->SetPreferredSize(gfx::Size(kIconSizeDip, kIconSizeDip));
+
+  if (params.icon)
+    icon_view_->SetImage(params.icon.value());
+  else
+    icon_view_->SetVisible(false);
+
+  AddChildView(icon_view_);
+
+  // Text.
   text_view_->SetAutoColorReadabilityEnabled(false);
   text_view_->SetEnabledColor(kTextColor);
   text_view_->SetFontList(text_view_->font_list().DeriveWithSizeDelta(2));
+  text_view_->SetText(params.text);
   AddChildView(text_view_);
 }
 
 void SuggestionChipView::OnPaintBackground(gfx::Canvas* canvas) {
   cc::PaintFlags flags;
   flags.setAntiAlias(true);
+
+  gfx::Rect bounds = GetContentsBounds();
+
+  // Background.
   flags.setColor(kBackgroundColor);
-  canvas->DrawRoundRect(GetContentsBounds(), kCornerRadiusDip, flags);
+  canvas->DrawRoundRect(bounds, height() / 2, flags);
+
+  // Stroke should be drawn within our contents bounds.
+  bounds.Inset(gfx::Insets(kStrokeWidthDip));
+
+  // Stroke.
+  flags.setColor(kStrokeColor);
+  flags.setStrokeWidth(kStrokeWidthDip);
+  flags.setStyle(cc::PaintFlags::Style::kStroke_Style);
+  canvas->DrawRoundRect(bounds, height() / 2, flags);
 }
 
 void SuggestionChipView::OnGestureEvent(ui::GestureEvent* event) {
diff --git a/ui/app_list/views/suggestion_chip_view.h b/ui/app_list/views/suggestion_chip_view.h
index 758f3fd..7e7762c 100644
--- a/ui/app_list/views/suggestion_chip_view.h
+++ b/ui/app_list/views/suggestion_chip_view.h
@@ -6,10 +6,12 @@
 #define UI_APP_LIST_VIEWS_SUGGESTION_CHIP_VIEW_H_
 
 #include "base/macros.h"
+#include "base/optional.h"
 #include "ui/app_list/app_list_export.h"
 #include "ui/views/view.h"
 
 namespace views {
+class ImageView;
 class Label;
 }  // namespace views
 
@@ -30,11 +32,23 @@
 // View representing a suggestion chip.
 class APP_LIST_EXPORT SuggestionChipView : public views::View {
  public:
-  SuggestionChipView(const base::string16& text,
+  // Initialization parameters.
+  struct Params {
+    Params();
+    ~Params();
+
+    // Display text.
+    base::string16 text;
+    // Optional icon.
+    base::Optional<gfx::ImageSkia*> icon;
+  };
+
+  SuggestionChipView(const Params& params,
                      SuggestionChipListener* listener = nullptr);
-  ~SuggestionChipView() override = default;
+  ~SuggestionChipView() override;
 
   // views::View:
+  gfx::Size CalculatePreferredSize() const override;
   void OnGestureEvent(ui::GestureEvent* event) override;
   bool OnMousePressed(const ui::MouseEvent& event) override;
   void OnPaintBackground(gfx::Canvas* canvas) override;
@@ -42,8 +56,9 @@
   const base::string16& GetText() const;
 
  private:
-  void InitLayout();
+  void InitLayout(const Params& params);
 
+  views::ImageView* icon_view_;  // Owned by view hierarchy.
   views::Label* text_view_;  // Owned by view hierarchy.
   SuggestionChipListener* listener_;
 
diff --git a/ui/arc/notification/arc_notification_manager.cc b/ui/arc/notification/arc_notification_manager.cc
index d7a5d2c5..b84fc36 100644
--- a/ui/arc/notification/arc_notification_manager.cc
+++ b/ui/arc/notification/arc_notification_manager.cc
@@ -8,9 +8,10 @@
 #include <utility>
 
 // TODO(https://crbug.com/768439): Remove nogncheck when moved to ash.
-#include "ash/login_status.h"                // nogncheck
-#include "ash/session/session_controller.h"  // nogncheck
-#include "ash/shell.h"                       // nogncheck
+#include "ash/login_status.h"                             // nogncheck
+#include "ash/session/session_controller.h"               // nogncheck
+#include "ash/shell.h"                                    // nogncheck
+#include "ash/system/message_center/notification_tray.h"  // nogncheck
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/arc/mojo_channel.h"
@@ -175,6 +176,11 @@
                           weak_ptr_factory_.GetWeakPtr(), std::move(data)));
 }
 
+void ArcNotificationManager::OpenMessageCenter() {
+  ash::Shell::Get()->GetNotificationTray()->ShowMessageCenter(
+      false /* show_by_click */);
+}
+
 void ArcNotificationManager::OnNotificationRemoved(const std::string& key) {
   auto it = items_.find(key);
   if (it == items_.end()) {
diff --git a/ui/arc/notification/arc_notification_manager.h b/ui/arc/notification/arc_notification_manager.h
index 6158f3c..5845cb1 100644
--- a/ui/arc/notification/arc_notification_manager.h
+++ b/ui/arc/notification/arc_notification_manager.h
@@ -55,6 +55,7 @@
   void OnNotificationPosted(mojom::ArcNotificationDataPtr data) override;
   void OnNotificationUpdated(mojom::ArcNotificationDataPtr data) override;
   void OnNotificationRemoved(const std::string& key) override;
+  void OpenMessageCenter() override;
 
   // Methods called from ArcNotificationItem:
   void SendNotificationRemovedFromChrome(const std::string& key);
diff --git a/ui/aura/mus/window_port_mus.cc b/ui/aura/mus/window_port_mus.cc
index eae2c63a..e09b18b6 100644
--- a/ui/aura/mus/window_port_mus.cc
+++ b/ui/aura/mus/window_port_mus.cc
@@ -428,8 +428,10 @@
 
 void WindowPortMus::UpdateLocalSurfaceIdFromEmbeddedClient(
     const viz::LocalSurfaceId& embedded_client_local_surface_id) {
-  local_surface_id_ = parent_local_surface_id_allocator_.UpdateFromChild(
+  parent_local_surface_id_allocator_.UpdateFromChild(
       embedded_client_local_surface_id);
+  local_surface_id_ =
+      parent_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
 }
 
 const viz::LocalSurfaceId& WindowPortMus::GetLocalSurfaceId() {
diff --git a/ui/chromeos/resources/default_100_percent/assistant/ic_placeholder_grey300_20dp.png b/ui/chromeos/resources/default_100_percent/assistant/ic_placeholder_grey300_20dp.png
new file mode 100644
index 0000000..a8e220d4
--- /dev/null
+++ b/ui/chromeos/resources/default_100_percent/assistant/ic_placeholder_grey300_20dp.png
Binary files differ
diff --git a/ui/chromeos/resources/default_200_percent/assistant/ic_placeholder_grey300_20dp.png b/ui/chromeos/resources/default_200_percent/assistant/ic_placeholder_grey300_20dp.png
new file mode 100644
index 0000000..ebdff28
--- /dev/null
+++ b/ui/chromeos/resources/default_200_percent/assistant/ic_placeholder_grey300_20dp.png
Binary files differ
diff --git a/ui/chromeos/resources/ui_chromeos_resources.grd b/ui/chromeos/resources/ui_chromeos_resources.grd
index be8aaee94..a0a8029 100644
--- a/ui/chromeos/resources/ui_chromeos_resources.grd
+++ b/ui/chromeos/resources/ui_chromeos_resources.grd
@@ -14,6 +14,9 @@
       <!-- Badge for Chrome Apps if Arc is enabled. -->
       <structure type="chrome_scaled_image" name="IDR_ARC_DUAL_ICON_BADGE" file="arc/dual-icon-badge.png" />
 
+      <!-- Assistant. -->
+      <structure type="chrome_scaled_image" name="IDR_ASSISTANT_PLACEHOLDER_GREY300_20DP" file="assistant/ic_placeholder_grey300_20dp.png" />
+
       <!-- Default user profile images. -->
       <structure type="chrome_scaled_image" name="IDR_LOGIN_DEFAULT_USER" file="default_user_images/avatar_anonymous.png" />
       <structure type="chrome_scaled_image" name="IDR_LOGIN_DEFAULT_USER_1" file="default_user_images/avatar_bee.png" />
diff --git a/ui/keyboard/display_util.cc b/ui/keyboard/display_util.cc
index d1431387..ff0339f 100644
--- a/ui/keyboard/display_util.cc
+++ b/ui/keyboard/display_util.cc
@@ -19,10 +19,6 @@
 
 DisplayUtil::DisplayUtil() {}
 
-int64_t DisplayUtil::GetNearestDisplayIdToWindow(aura::Window* window) const {
-  return GetNearestDisplayToWindow(window).id();
-}
-
 display::Display DisplayUtil::GetNearestDisplayToWindow(
     aura::Window* window) const {
   return display::Screen::GetScreen()->GetDisplayNearestWindow(window);
diff --git a/ui/keyboard/display_util.h b/ui/keyboard/display_util.h
index 8d4faf6..45ab74b 100644
--- a/ui/keyboard/display_util.h
+++ b/ui/keyboard/display_util.h
@@ -15,7 +15,6 @@
  public:
   DisplayUtil();
 
-  int64_t GetNearestDisplayIdToWindow(aura::Window* window) const;
   display::Display GetNearestDisplayToWindow(aura::Window* window) const;
   display::Display FindAdjacentDisplayIfPointIsNearMargin(
       const display::Display& current_display,
diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc
index 261b031..cd70e95e 100644
--- a/ui/keyboard/keyboard_controller.cc
+++ b/ui/keyboard/keyboard_controller.cc
@@ -312,7 +312,7 @@
         // Do not move the keyboard to another display after switch to an IME in
         // a different extension.
         ShowKeyboardInDisplay(
-            display_util_.GetNearestDisplayIdToWindow(GetContainerWindow()));
+            display_util_.GetNearestDisplayToWindow(GetContainerWindow()));
       } else {
         ShowKeyboard(false /* lock */);
       }
@@ -428,7 +428,7 @@
     }
 
     if (queued_display_change_) {
-      ShowKeyboardInDisplay(queued_display_change_->new_display().id());
+      ShowKeyboardInDisplay(queued_display_change_->new_display());
       container_->SetBounds(queued_display_change_->new_bounds_in_local());
       queued_display_change_ = nullptr;
     }
@@ -459,12 +459,13 @@
 
 void KeyboardController::ShowKeyboard(bool lock) {
   set_keyboard_locked(lock);
-  ShowKeyboardInternal(display::kInvalidDisplayId);
+  ShowKeyboardInternal(display::Display());
 }
 
-void KeyboardController::ShowKeyboardInDisplay(int64_t display_id) {
+void KeyboardController::ShowKeyboardInDisplay(
+    const display::Display& display) {
   set_keyboard_locked(true);
-  ShowKeyboardInternal(display_id);
+  ShowKeyboardInternal(display);
 }
 
 bool KeyboardController::IsKeyboardWindowCreated() {
@@ -575,7 +576,7 @@
 void KeyboardController::OnShowImeIfNeeded() {
   // Calling |ShowKeyboardInternal| may move the keyboard to another display.
   if (IsKeyboardEnabled() && !keyboard_locked())
-    ShowKeyboardInternal(display::kInvalidDisplayId);
+    ShowKeyboardInternal(display::Display());
 }
 
 void KeyboardController::LoadKeyboardUiInBackground() {
@@ -589,24 +590,25 @@
   // |Shell::CreateKeyboard| was called.
   DCHECK(container_.get());
 
-  PopulateKeyboardContent(display::kInvalidDisplayId, false);
+  PopulateKeyboardContent(display::Display(), false);
 }
 
-void KeyboardController::ShowKeyboardInternal(int64_t display_id) {
+void KeyboardController::ShowKeyboardInternal(const display::Display& display) {
   DCHECK(container_.get());
   keyboard::MarkKeyboardLoadStarted();
-  PopulateKeyboardContent(display_id, true);
+  PopulateKeyboardContent(display, true);
 }
 
-void KeyboardController::PopulateKeyboardContent(int64_t display_id,
-                                                 bool show_keyboard) {
+void KeyboardController::PopulateKeyboardContent(
+    const display::Display& display,
+    bool show_keyboard) {
   DCHECK(show_keyboard || state_ == KeyboardControllerState::INITIAL);
 
   TRACE_EVENT0("vk", "PopulateKeyboardContent");
 
   if (layout_delegate_ != nullptr) {
-    if (display_id != display::kInvalidDisplayId)
-      layout_delegate_->MoveKeyboardToDisplay(display_id);
+    if (display.is_valid())
+      layout_delegate_->MoveKeyboardToDisplay(display.id());
     else
       layout_delegate_->MoveKeyboardToTouchableDisplay();
   }
@@ -855,7 +857,7 @@
 bool KeyboardController::DisplayVirtualKeyboard() {
   // Calling |ShowKeyboardInternal| may move the keyboard to another display.
   if (IsKeyboardEnabled() && !keyboard_locked()) {
-    ShowKeyboardInternal(display::kInvalidDisplayId);
+    ShowKeyboardInternal(display::Display());
     return true;
   }
   return false;
diff --git a/ui/keyboard/keyboard_controller.h b/ui/keyboard/keyboard_controller.h
index 9fc292a..da63321 100644
--- a/ui/keyboard/keyboard_controller.h
+++ b/ui/keyboard/keyboard_controller.h
@@ -132,7 +132,7 @@
 
   // Force the keyboard to show up in the specific display if not showing and
   // lock the keyboard
-  void ShowKeyboardInDisplay(const int64_t display_id);
+  void ShowKeyboardInDisplay(const display::Display& display);
 
   // Sets the active keyboard controller. KeyboardController takes ownership of
   // the instance. Calling ResetIntance with a new instance destroys the
@@ -242,8 +242,9 @@
                           const bool contents_loaded);
 
   // Show virtual keyboard immediately with animation.
-  void ShowKeyboardInternal(int64_t display_id);
-  void PopulateKeyboardContent(int64_t display_id, bool show_keyboard);
+  void ShowKeyboardInternal(const display::Display& display);
+  void PopulateKeyboardContent(const display::Display& display,
+                               bool show_keyboard);
 
   // Returns true if keyboard is scheduled to hide.
   bool WillHideKeyboard() const;
diff --git a/ui/ozone/platform/cast/BUILD.gn b/ui/ozone/platform/cast/BUILD.gn
index eac0aae8..ade393a 100644
--- a/ui/ozone/platform/cast/BUILD.gn
+++ b/ui/ozone/platform/cast/BUILD.gn
@@ -51,5 +51,6 @@
     "//ui/ozone:ozone_base",
     "//ui/ozone/common",
     "//ui/platform_window",
+    "//ui/platform_window/stub",
   ]
 }
diff --git a/ui/ozone/platform/cast/platform_window_cast.cc b/ui/ozone/platform/cast/platform_window_cast.cc
index a24276ca..2b530be 100644
--- a/ui/ozone/platform/cast/platform_window_cast.cc
+++ b/ui/ozone/platform/cast/platform_window_cast.cc
@@ -8,15 +8,17 @@
 #include "ui/events/event.h"
 #include "ui/events/ozone/events_ozone.h"
 #include "ui/events/platform/platform_event_source.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/native_widget_types.h"
 #include "ui/platform_window/platform_window_delegate.h"
 
 namespace ui {
 
 PlatformWindowCast::PlatformWindowCast(PlatformWindowDelegate* delegate,
                                        const gfx::Rect& bounds)
-    : delegate_(delegate), bounds_(bounds) {
-  widget_ = (bounds.width() << 16) + bounds.height();
-  delegate_->OnAcceleratedWidgetAvailable(widget_, 1.f);
+    : StubWindow(delegate, false, bounds) {
+  gfx::AcceleratedWidget widget = (bounds.width() << 16) + bounds.height();
+  delegate->OnAcceleratedWidgetAvailable(widget, 1.f);
 
   if (PlatformEventSource::GetInstance())
     PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
@@ -27,26 +29,6 @@
     PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
 }
 
-gfx::Rect PlatformWindowCast::GetBounds() {
-  return bounds_;
-}
-
-void PlatformWindowCast::SetBounds(const gfx::Rect& bounds) {
-  bounds_ = bounds;
-  delegate_->OnBoundsChanged(bounds);
-}
-
-void PlatformWindowCast::SetTitle(const base::string16& title) {
-}
-
-bool PlatformWindowCast::HasCapture() const {
-  return false;
-}
-
-PlatformImeController* PlatformWindowCast::GetPlatformImeController() {
-  return nullptr;
-}
-
 bool PlatformWindowCast::CanDispatchEvent(const PlatformEvent& ne) {
   return true;
 }
@@ -54,7 +36,7 @@
 uint32_t PlatformWindowCast::DispatchEvent(const PlatformEvent& native_event) {
   DispatchEventFromNativeUiEvent(
       native_event, base::BindOnce(&PlatformWindowDelegate::DispatchEvent,
-                                   base::Unretained(delegate_)));
+                                   base::Unretained(delegate())));
 
   return ui::POST_DISPATCH_STOP_PROPAGATION;
 }
diff --git a/ui/ozone/platform/cast/platform_window_cast.h b/ui/ozone/platform/cast/platform_window_cast.h
index a7930ee..500a5bf8 100644
--- a/ui/ozone/platform/cast/platform_window_cast.h
+++ b/ui/ozone/platform/cast/platform_window_cast.h
@@ -7,49 +7,22 @@
 
 #include "base/macros.h"
 #include "ui/events/platform/platform_event_dispatcher.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/platform_window/platform_window.h"
+#include "ui/platform_window/stub/stub_window.h"
 
 namespace ui {
 
 class PlatformWindowDelegate;
 
-class PlatformWindowCast : public PlatformWindow,
-                           public PlatformEventDispatcher {
+class PlatformWindowCast : public StubWindow, public PlatformEventDispatcher {
  public:
   PlatformWindowCast(PlatformWindowDelegate* delegate, const gfx::Rect& bounds);
   ~PlatformWindowCast() override;
 
-  // PlatformWindow implementation:
-  gfx::Rect GetBounds() override;
-  void SetBounds(const gfx::Rect& bounds) override;
-  void SetTitle(const base::string16& title) override;
-  void Show() override {}
-  void Hide() override {}
-  void Close() override {}
-  void PrepareForShutdown() override {}
-  void SetCapture() override {}
-  void ReleaseCapture() override {}
-  bool HasCapture() const override;
-  void ToggleFullscreen() override {}
-  void Maximize() override {}
-  void Minimize() override {}
-  void Restore() override {}
-  void SetCursor(PlatformCursor cursor) override {}
-  void MoveCursorTo(const gfx::Point& location) override {}
-  void ConfineCursorToBounds(const gfx::Rect& bounds) override {}
-  PlatformImeController* GetPlatformImeController() override;
-
   // PlatformEventDispatcher implementation:
   bool CanDispatchEvent(const PlatformEvent& event) override;
   uint32_t DispatchEvent(const PlatformEvent& event) override;
 
  private:
-  PlatformWindowDelegate* delegate_;
-  gfx::Rect bounds_;
-  gfx::AcceleratedWidget widget_;
-
   DISALLOW_COPY_AND_ASSIGN(PlatformWindowCast);
 };
 
diff --git a/ui/ozone/platform/headless/BUILD.gn b/ui/ozone/platform/headless/BUILD.gn
index 0637f8e..848391d0 100644
--- a/ui/ozone/platform/headless/BUILD.gn
+++ b/ui/ozone/platform/headless/BUILD.gn
@@ -34,5 +34,6 @@
     "//ui/ozone:ozone_base",
     "//ui/ozone/common",
     "//ui/platform_window",
+    "//ui/platform_window/stub",
   ]
 }
diff --git a/ui/ozone/platform/headless/headless_window.cc b/ui/ozone/platform/headless/headless_window.cc
index 5bf6e7c9..c182fdb 100644
--- a/ui/ozone/platform/headless/headless_window.cc
+++ b/ui/ozone/platform/headless/headless_window.cc
@@ -16,13 +16,13 @@
 HeadlessWindow::HeadlessWindow(PlatformWindowDelegate* delegate,
                                HeadlessWindowManager* manager,
                                const gfx::Rect& bounds)
-    : delegate_(delegate), manager_(manager), bounds_(bounds) {
+    : StubWindow(delegate, false, bounds), manager_(manager) {
 #if defined(OS_WIN)
   widget_ = reinterpret_cast<gfx::AcceleratedWidget>(manager_->AddWindow(this));
 #else
   widget_ = manager_->AddWindow(this);
 #endif
-  delegate_->OnAcceleratedWidgetAvailable(widget_, 1.f);
+  delegate->OnAcceleratedWidgetAvailable(widget_, 1.f);
 }
 
 HeadlessWindow::~HeadlessWindow() {
@@ -33,49 +33,4 @@
 #endif
 }
 
-gfx::Rect HeadlessWindow::GetBounds() {
-  return bounds_;
-}
-
-void HeadlessWindow::SetBounds(const gfx::Rect& bounds) {
-  bounds_ = bounds;
-  delegate_->OnBoundsChanged(bounds);
-}
-
-void HeadlessWindow::SetTitle(const base::string16& title) {}
-
-void HeadlessWindow::Show() {}
-
-void HeadlessWindow::Hide() {}
-
-void HeadlessWindow::Close() {}
-
-void HeadlessWindow::PrepareForShutdown() {}
-
-void HeadlessWindow::SetCapture() {}
-
-void HeadlessWindow::ReleaseCapture() {}
-
-bool HeadlessWindow::HasCapture() const {
-  return false;
-}
-
-void HeadlessWindow::ToggleFullscreen() {}
-
-void HeadlessWindow::Maximize() {}
-
-void HeadlessWindow::Minimize() {}
-
-void HeadlessWindow::Restore() {}
-
-void HeadlessWindow::SetCursor(PlatformCursor cursor) {}
-
-void HeadlessWindow::MoveCursorTo(const gfx::Point& location) {}
-
-void HeadlessWindow::ConfineCursorToBounds(const gfx::Rect& bounds) {}
-
-PlatformImeController* HeadlessWindow::GetPlatformImeController() {
-  return nullptr;
-}
-
 }  // namespace ui
diff --git a/ui/ozone/platform/headless/headless_window.h b/ui/ozone/platform/headless/headless_window.h
index 2051d14..0690480 100644
--- a/ui/ozone/platform/headless/headless_window.h
+++ b/ui/ozone/platform/headless/headless_window.h
@@ -8,44 +8,22 @@
 #include "base/macros.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/native_widget_types.h"
-#include "ui/platform_window/platform_window.h"
+#include "ui/platform_window/stub/stub_window.h"
 
 namespace ui {
 
 class PlatformWindowDelegate;
 class HeadlessWindowManager;
 
-class HeadlessWindow : public PlatformWindow {
+class HeadlessWindow : public StubWindow {
  public:
   HeadlessWindow(PlatformWindowDelegate* delegate,
                  HeadlessWindowManager* manager,
                  const gfx::Rect& bounds);
   ~HeadlessWindow() override;
 
-  // PlatformWindow:
-  gfx::Rect GetBounds() override;
-  void SetBounds(const gfx::Rect& bounds) override;
-  void SetTitle(const base::string16& title) override;
-  void Show() override;
-  void Hide() override;
-  void Close() override;
-  void PrepareForShutdown() override;
-  void SetCapture() override;
-  void ReleaseCapture() override;
-  bool HasCapture() const override;
-  void ToggleFullscreen() override;
-  void Maximize() override;
-  void Minimize() override;
-  void Restore() override;
-  void SetCursor(PlatformCursor cursor) override;
-  void MoveCursorTo(const gfx::Point& location) override;
-  void ConfineCursorToBounds(const gfx::Rect& bounds) override;
-  PlatformImeController* GetPlatformImeController() override;
-
  private:
-  PlatformWindowDelegate* delegate_;
   HeadlessWindowManager* manager_;
-  gfx::Rect bounds_;
   gfx::AcceleratedWidget widget_;
 
   DISALLOW_COPY_AND_ASSIGN(HeadlessWindow);
diff --git a/ui/platform_window/android/BUILD.gn b/ui/platform_window/android/BUILD.gn
index 59a3ed27..9243259 100644
--- a/ui/platform_window/android/BUILD.gn
+++ b/ui/platform_window/android/BUILD.gn
@@ -30,6 +30,7 @@
     "//ui/gfx",
     "//ui/gfx/geometry",
     "//ui/platform_window",
+    "//ui/platform_window/stub",
   ]
 
   libs = [ "android" ]
diff --git a/ui/platform_window/android/platform_window_android.cc b/ui/platform_window/android/platform_window_android.cc
index ed53df5..6487092a 100644
--- a/ui/platform_window/android/platform_window_android.cc
+++ b/ui/platform_window/android/platform_window_android.cc
@@ -50,11 +50,7 @@
 // PlatformWindowAndroid, public:
 
 PlatformWindowAndroid::PlatformWindowAndroid(PlatformWindowDelegate* delegate)
-    : delegate_(delegate),
-      window_(NULL),
-      id_generator_(0),
-      weak_factory_(this) {
-}
+    : StubWindow(delegate, false), window_(nullptr) {}
 
 PlatformWindowAndroid::~PlatformWindowAndroid() {
   if (window_)
@@ -69,7 +65,7 @@
 
 void PlatformWindowAndroid::Destroy(JNIEnv* env,
                                     const JavaParamRef<jobject>& obj) {
-  delegate_->OnClosed();
+  delegate()->OnClosed();
 }
 
 void PlatformWindowAndroid::SurfaceCreated(
@@ -84,13 +80,13 @@
     base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env);
     window_ = ANativeWindow_fromSurface(env, jsurface);
   }
-  delegate_->OnAcceleratedWidgetAvailable(window_, device_pixel_ratio);
+  delegate()->OnAcceleratedWidgetAvailable(window_, device_pixel_ratio);
 }
 
 void PlatformWindowAndroid::SurfaceDestroyed(JNIEnv* env,
                                              const JavaParamRef<jobject>& obj) {
   DCHECK(window_);
-  delegate_->OnAcceleratedWidgetDestroyed();
+  delegate()->OnAcceleratedWidgetDestroyed();
   ReleaseWindow();
 }
 
@@ -100,7 +96,7 @@
                                            jint height,
                                            jfloat density) {
   size_ = gfx::Size(static_cast<int>(width), static_cast<int>(height));
-  delegate_->OnBoundsChanged(gfx::Rect(size_));
+  delegate()->OnBoundsChanged(gfx::Rect(size_));
 }
 
 bool PlatformWindowAndroid::TouchEvent(JNIEnv* env,
@@ -127,7 +123,7 @@
       ui::EF_NONE, orientation);
   touch.set_location_f(gfx::PointF(x, y));
   touch.set_root_location_f(gfx::PointF(x, y));
-  delegate_->DispatchEvent(&touch);
+  delegate()->DispatchEvent(&touch);
   return true;
 }
 
@@ -138,11 +134,11 @@
                                      jint unicode_character) {
   ui::KeyEvent key_event(pressed ? ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED,
                          ui::KeyboardCodeFromAndroidKeyCode(key_code), 0);
-  delegate_->DispatchEvent(&key_event);
+  delegate()->DispatchEvent(&key_event);
   if (pressed && unicode_character) {
     ui::KeyEvent char_event(unicode_character,
                             ui::KeyboardCodeFromAndroidKeyCode(key_code), 0);
-    delegate_->DispatchEvent(&char_event);
+    delegate()->DispatchEvent(&char_event);
   }
   return true;
 }
@@ -170,12 +166,6 @@
   // Nothing to do. View is always visible.
 }
 
-void PlatformWindowAndroid::Close() {
-  delegate_->OnCloseRequest();
-}
-
-void PlatformWindowAndroid::PrepareForShutdown() {}
-
 void PlatformWindowAndroid::SetBounds(const gfx::Rect& bounds) {
   NOTIMPLEMENTED();
 }
@@ -184,51 +174,6 @@
   return gfx::Rect(size_);
 }
 
-void PlatformWindowAndroid::SetTitle(const base::string16& title) {
-  NOTIMPLEMENTED();
-}
-
-void PlatformWindowAndroid::SetCapture() {
-  NOTIMPLEMENTED();
-}
-
-void PlatformWindowAndroid::ReleaseCapture() {
-  NOTIMPLEMENTED();
-}
-
-bool PlatformWindowAndroid::HasCapture() const {
-  NOTIMPLEMENTED();
-  return false;
-}
-
-void PlatformWindowAndroid::ToggleFullscreen() {
-  NOTIMPLEMENTED();
-}
-
-void PlatformWindowAndroid::Maximize() {
-  NOTIMPLEMENTED();
-}
-
-void PlatformWindowAndroid::Minimize() {
-  NOTIMPLEMENTED();
-}
-
-void PlatformWindowAndroid::Restore() {
-  NOTIMPLEMENTED();
-}
-
-void PlatformWindowAndroid::SetCursor(PlatformCursor cursor) {
-  NOTIMPLEMENTED();
-}
-
-void PlatformWindowAndroid::MoveCursorTo(const gfx::Point& location) {
-  NOTIMPLEMENTED();
-}
-
-void PlatformWindowAndroid::ConfineCursorToBounds(const gfx::Rect& bounds) {
-  NOTIMPLEMENTED();
-}
-
 PlatformImeController* PlatformWindowAndroid::GetPlatformImeController() {
   return &platform_ime_controller_;
 }
diff --git a/ui/platform_window/android/platform_window_android.h b/ui/platform_window/android/platform_window_android.h
index 803ab18..ec1f5a1 100644
--- a/ui/platform_window/android/platform_window_android.h
+++ b/ui/platform_window/android/platform_window_android.h
@@ -7,14 +7,12 @@
 
 #include "base/android/jni_weak_ref.h"
 #include "base/macros.h"
-#include "base/memory/weak_ptr.h"
 #include "ui/events/event_constants.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
-#include "ui/gfx/sequential_id_generator.h"
 #include "ui/platform_window/android/android_window_export.h"
 #include "ui/platform_window/android/platform_ime_controller_android.h"
-#include "ui/platform_window/platform_window.h"
+#include "ui/platform_window/stub/stub_window.h"
 
 struct ANativeWindow;
 
@@ -22,7 +20,9 @@
 
 class PlatformWindowDelegate;
 
-class ANDROID_WINDOW_EXPORT PlatformWindowAndroid : public PlatformWindow {
+// NOTE: This class extends StubWindow because it's very much a work in
+// progress. If we make it real then it should subclass PlatformWindow directly.
+class ANDROID_WINDOW_EXPORT PlatformWindowAndroid : public StubWindow {
  public:
   explicit PlatformWindowAndroid(PlatformWindowDelegate* delegate);
   ~PlatformWindowAndroid() override;
@@ -64,35 +64,17 @@
   // Overridden from PlatformWindow:
   void Show() override;
   void Hide() override;
-  void Close() override;
-  void PrepareForShutdown() override;
   void SetBounds(const gfx::Rect& bounds) override;
   gfx::Rect GetBounds() override;
-  void SetTitle(const base::string16& title) override;
-  void SetCapture() override;
-  void ReleaseCapture() override;
-  bool HasCapture() const override;
-  void ToggleFullscreen() override;
-  void Maximize() override;
-  void Minimize() override;
-  void Restore() override;
-  void SetCursor(PlatformCursor cursor) override;
-  void MoveCursorTo(const gfx::Point& location) override;
-  void ConfineCursorToBounds(const gfx::Rect& bounds) override;
   PlatformImeController* GetPlatformImeController() override;
 
-  PlatformWindowDelegate* delegate_;
-
   JavaObjectWeakGlobalRef java_platform_window_android_;
   ANativeWindow* window_;
-  ui::SequentialIDGenerator id_generator_;
 
   gfx::Size size_;  // Origin is always (0,0)
 
   PlatformImeControllerAndroid platform_ime_controller_;
 
-  base::WeakPtrFactory<PlatformWindowAndroid> weak_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(PlatformWindowAndroid);
 };
 
diff --git a/ui/platform_window/stub/stub_window.h b/ui/platform_window/stub/stub_window.h
index c94a847..fd9d7f66 100644
--- a/ui/platform_window/stub/stub_window.h
+++ b/ui/platform_window/stub/stub_window.h
@@ -15,6 +15,8 @@
 
 class PlatformWindowDelegate;
 
+// StubWindow is useful for tests, as well as implementations that only care
+// about bounds.
 class STUB_WINDOW_EXPORT StubWindow : public PlatformWindow {
  public:
   explicit StubWindow(PlatformWindowDelegate* delegate,
diff --git a/ui/views/animation/ink_drop_host_view.cc b/ui/views/animation/ink_drop_host_view.cc
index 2117040..1d02462 100644
--- a/ui/views/animation/ink_drop_host_view.cc
+++ b/ui/views/animation/ink_drop_host_view.cc
@@ -4,6 +4,7 @@
 
 #include "ui/views/animation/ink_drop_host_view.h"
 
+#include "build/build_config.h"
 #include "ui/events/event.h"
 #include "ui/events/scoped_target_handler.h"
 #include "ui/gfx/color_palette.h"
@@ -300,12 +301,9 @@
 }
 
 void InkDropHostView::InstallInkDropMask(ui::Layer* ink_drop_layer) {
-// Layer masks don't work on Windows. See crbug.com/713359
-#if !defined(OS_WIN)
   ink_drop_mask_ = CreateInkDropMask();
   if (ink_drop_mask_)
     ink_drop_layer->SetMaskLayer(ink_drop_mask_->layer());
-#endif
 }
 
 void InkDropHostView::ResetInkDropMask() {
diff --git a/ui/views/controls/native/native_view_host_aura.cc b/ui/views/controls/native/native_view_host_aura.cc
index 28033ad9..097bcd4 100644
--- a/ui/views/controls/native/native_view_host_aura.cc
+++ b/ui/views/controls/native/native_view_host_aura.cc
@@ -150,7 +150,8 @@
 
 bool NativeViewHostAura::SetCornerRadius(int corner_radius) {
 #if defined(OS_WIN)
-  // Layer masks don't work on Windows. See crbug.com/713359
+  // TODO(crbug/843250): On Aura, layer masks don't play with HiDPI. Fix this
+  // and enable this on Windows.
   return false;
 #else
   mask_ = views::Painter::CreatePaintedLayer(