diff --git a/DEPS b/DEPS
index de07b9ad..1a1f11de 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': '0caef298c2ff935b622673e09cd542151dc2ecc0',
+  'skia_revision': '2f62de01d3a703696dc1a51d2473a88be68a7574',
   # 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': '6a74bf33d5e0a680921b9ded45b68db0493b2ccd',
+  'v8_revision': '1f46296507805ddfb2bbb992a832bde528100351',
   # 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.
@@ -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': '6312bf94bb44e2edeb855008da0921c13103f66a',
+  'pdfium_revision': 'ccd9421589922b8f35ee5330d7fdac7edea081db',
   # 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.
@@ -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': '978be7439d1e5219def7dae75b182b77db185f01',
+  'catapult_revision': '19282cf9d32d6e656bc35dfea9e97c5b42d9e238',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -269,7 +269,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'd7b1f39ad946be67cd6a83b6f9cd36b41f29a619',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '942163f2be5c76ca5c67f6449941a777f839c15a',
       'condition': 'checkout_ios',
   },
 
@@ -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' + '@' + '5295eaac6d224a44bac89b9b919bff2532ffcda4',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '8642bcc3248fa1a791d9c287420487c817782ae6',
       'condition': 'checkout_linux',
   },
 
@@ -834,7 +834,7 @@
   },
 
   'src/third_party/openh264/src':
-    Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '2e96d62426547ac4fb5cbcd122e5f6eb68d66ee6',
+    Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '3b51f16a4a41df729f8d647f03e48c5f272911ff',
 
   'src/third_party/openmax_dl':
     Var('webrtc_git') + '/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
@@ -968,7 +968,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '7c0541da63f571512c49758cbc0767117997a270',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '6f7e6d6ff3533557ef99a0ceb01850f1fef071b3', # commit position 21742
+    Var('webrtc_git') + '/src.git' + '@' + 'a1f566b28a69512037e36f5194329d9ada46be01', # commit position 21742
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1876,8 +1876,9 @@
                 '--no_resume',
                 '--no_auth',
                 '--num_threads=4',
-                '--bucket', 'chromium-binary-patching',
-                '-d', 'src/components/zucchini/testdata',
+                '--bucket', 'chromium-binary-patching/zucchini_testdata',
+                '--recursive',
+                '-d', 'src/components/zucchini',
     ],
   },
 
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc
index 9bb1803..5ea645d 100644
--- a/ash/shelf/shelf_view_unittest.cc
+++ b/ash/shelf/shelf_view_unittest.cc
@@ -2053,10 +2053,13 @@
   EXPECT_TRUE(shelf_view_->IsShowingMenu());
   EXPECT_FALSE(shelf_view_->drag_view());
 
-  // Press left button. Menu should close and drag view is set to |button|.
+  // Press left button. Menu should close.
+  generator.PressLeftButton();
+  generator.ReleaseLeftButton();
+  EXPECT_FALSE(shelf_view_->IsShowingMenu());
+  // Press left button. Drag view is set to |button|.
   generator.PressLeftButton();
   base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(shelf_view_->IsShowingMenu());
   EXPECT_EQ(shelf_view_->drag_view(), button);
   generator.ReleaseLeftButton();
   EXPECT_FALSE(shelf_view_->drag_view());
diff --git a/ash/system/tray/tray_bubble_wrapper.cc b/ash/system/tray/tray_bubble_wrapper.cc
index 32616e2a..e79879e 100644
--- a/ash/system/tray/tray_bubble_wrapper.cc
+++ b/ash/system/tray/tray_bubble_wrapper.cc
@@ -13,6 +13,7 @@
 #include "ui/aura/window.h"
 #include "ui/views/bubble/tray_bubble_view.h"
 #include "ui/views/widget/widget.h"
+#include "ui/wm/core/transient_window_manager.h"
 #include "ui/wm/core/window_util.h"
 #include "ui/wm/public/activation_client.h"
 
@@ -43,6 +44,12 @@
 
   tray_->tray_event_filter()->RemoveWrapper(this);
   if (bubble_widget_) {
+    auto* transient_manager = ::wm::TransientWindowManager::GetOrCreate(
+        bubble_widget_->GetNativeWindow());
+    if (transient_manager) {
+      for (auto* window : transient_manager->transient_children())
+        transient_manager->RemoveTransientChild(window);
+    }
     bubble_widget_->GetNativeWindow()->GetRootWindow()->RemoveObserver(this);
     bubble_widget_->RemoveObserver(this);
     bubble_widget_->Close();
diff --git a/ash/system/user/user_view.cc b/ash/system/user/user_view.cc
index 0d6c30b2..397d5638 100644
--- a/ash/system/user/user_view.cc
+++ b/ash/system/user/user_view.cc
@@ -36,8 +36,11 @@
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/separator.h"
+#include "ui/views/focus/focus_search.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/painter.h"
+#include "ui/views/view_model.h"
+#include "ui/wm/core/transient_window_manager.h"
 
 namespace ash {
 namespace tray {
@@ -85,15 +88,14 @@
 
 // Creates the view shown in the user switcher popup ("AddUserMenuOption").
 views::View* CreateAddUserView(AddUserSessionPolicy policy) {
-  auto* view = new views::View;
+  auto* view = new views::View();
   const int icon_padding = (kMenuButtonSize - kMenuIconSize) / 2;
   auto layout = std::make_unique<views::BoxLayout>(
       views::BoxLayout::kHorizontal, gfx::Insets(),
       kTrayPopupLabelHorizontalPadding + icon_padding);
   layout->set_minimum_cross_axis_size(kTrayPopupItemMinHeight);
   view->SetLayoutManager(std::move(layout));
-  view->SetBackground(views::CreateThemedSolidBackground(
-      view, ui::NativeTheme::kColorId_BubbleBackground));
+  view->SetBackground(views::CreateSolidBackground(SK_ColorTRANSPARENT));
 
   base::string16 message;
   switch (policy) {
@@ -146,27 +148,85 @@
 // A view that acts as the contents of the widget that appears when clicking
 // the active user. If the mouse exits this view or an otherwise unhandled
 // click is detected, it will invoke a closure passed at construction time.
-class UserDropdownWidgetContents : public views::View {
+class UserDropdownWidgetContents : public views::View,
+                                   public views::FocusTraversable {
  public:
-  explicit UserDropdownWidgetContents(const base::Closure& close_widget)
-      : close_widget_(close_widget) {
+  explicit UserDropdownWidgetContents(base::OnceClosure close_widget_callback)
+      : close_widget_callback_(std::move(close_widget_callback)),
+        view_model_(std::make_unique<views::ViewModel>()),
+        focus_search_(
+            std::make_unique<DropDownFocusSearch>(this, view_model_.get())) {
     // Don't want to receive a mouse exit event when the cursor enters a child.
     set_notify_enter_exit_on_child(true);
   }
 
   ~UserDropdownWidgetContents() override = default;
 
+  void CloseWidget() { std::move(close_widget_callback_).Run(); }
+
+  views::ViewModel* view_model() { return view_model_.get(); }
+
+  // views::View:
+  FocusTraversable* GetPaneFocusTraversable() override { return this; }
   bool OnMousePressed(const ui::MouseEvent& event) override { return true; }
-  void OnMouseReleased(const ui::MouseEvent& event) override {
-    close_widget_.Run();
-  }
-  void OnMouseExited(const ui::MouseEvent& event) override {
-    close_widget_.Run();
-  }
-  void OnGestureEvent(ui::GestureEvent* event) override { close_widget_.Run(); }
+  void OnMouseReleased(const ui::MouseEvent& event) override { CloseWidget(); }
+  void OnMouseExited(const ui::MouseEvent& event) override { CloseWidget(); }
+  void OnGestureEvent(ui::GestureEvent* event) override { CloseWidget(); }
+
+  // views::FocusTraversable:
+  views::FocusSearch* GetFocusSearch() override { return focus_search_.get(); }
+  FocusTraversable* GetFocusTraversableParent() override { return nullptr; }
+  View* GetFocusTraversableParentView() override { return nullptr; }
 
  private:
-  base::Closure close_widget_;
+  // Custom FocusSearch used to navigate the drop down widget. The navigation is
+  // according to the view model, which should be populated the same order the
+  // views are added, but this search also closes the widget when tabbing past
+  // the boudaries.
+  class DropDownFocusSearch : public views::FocusSearch {
+   public:
+    DropDownFocusSearch(UserDropdownWidgetContents* owner,
+                        views::ViewModel* view_model)
+        : views::FocusSearch(nullptr, true, true),
+          owner_(owner),
+          view_model_(view_model) {}
+    ~DropDownFocusSearch() override = default;
+
+    // views::FocusSearch:
+    views::View* FindNextFocusableView(
+        views::View* starting_view,
+        SearchDirection search_direction,
+        TraversalDirection traversal_direction,
+        StartingViewPolicy check_starting_view,
+        views::FocusTraversable** focus_traversable,
+        views::View** focus_traversable_view) override {
+      int index = view_model_->GetIndexOfView(starting_view);
+      index += search_direction == SearchDirection::kForwards ? 1 : -1;
+      if (index == -1 || index == view_model_->view_size()) {
+        // |close_widget_| will delete the widget which has the view which owns
+        // this custom search, so do not run callback immediately.
+        base::ThreadTaskRunnerHandle::Get()->PostTask(
+            FROM_HERE, base::BindOnce(&DropDownFocusSearch::CloseWidget,
+                                      base::Unretained(this)));
+        return nullptr;
+      }
+      return view_model_->view_at(index);
+    }
+
+   private:
+    void CloseWidget() { owner_->CloseWidget(); }
+
+    UserDropdownWidgetContents* owner_;
+    views::ViewModel* view_model_;
+
+    DISALLOW_COPY_AND_ASSIGN(DropDownFocusSearch);
+  };
+
+  base::OnceClosure close_widget_callback_;
+  // Used to manage the focusable items in the drop down widget. There is a
+  // view per item in |view_model_|.
+  std::unique_ptr<views::ViewModel> view_model_;
+  std::unique_ptr<DropDownFocusSearch> focus_search_;
 
   DISALLOW_COPY_AND_ASSIGN(UserDropdownWidgetContents);
 };
@@ -250,7 +310,7 @@
     HideUserDropdownWidget();
     Shell::Get()->session_controller()->RequestSignOut();
   } else if (sender == user_card_container_ && IsUserDropdownEnabled()) {
-    ToggleUserDropdownWidget();
+    ToggleUserDropdownWidget(event.IsKeyEvent());
   } else if (user_dropdown_widget_ &&
              sender->GetWidget() == user_dropdown_widget_.get()) {
     DCHECK_EQ(Shell::Get()->session_controller()->NumberOfLoggedInUsers(),
@@ -301,7 +361,8 @@
   AddChildViewAt(user_card_container_, 0);
 }
 
-void UserView::ToggleUserDropdownWidget() {
+void UserView::ToggleUserDropdownWidget(bool toggled_by_key_event) {
+  user_dropdown_widget_toggled_by_key_event_ = toggled_by_key_event;
   if (user_dropdown_widget_) {
     HideUserDropdownWidget();
     return;
@@ -309,17 +370,20 @@
 
   // Note: We do not need to install a global event handler to delete this
   // item since it will destroyed automatically before the menu / user menu item
-  // gets destroyed..
+  // gets destroyed.
   user_dropdown_widget_.reset(new views::Widget);
   views::Widget::InitParams params;
   params.type = views::Widget::InitParams::TYPE_MENU;
   params.keep_on_top = true;
   params.accept_events = true;
+  params.activatable = views::Widget::InitParams::ACTIVATABLE_YES;
   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
   params.name = "AddUserMenuOption";
+  // Use |kShellWindowId_SettingBubbleContainer| as the widget has to be
+  // activatable.
   params.parent = GetWidget()->GetNativeWindow()->GetRootWindow()->GetChildById(
-      kShellWindowId_DragImageAndTooltipContainer);
+      kShellWindowId_SettingBubbleContainer);
   user_dropdown_widget_->Init(params);
 
   const SessionController* const session_controller =
@@ -335,8 +399,9 @@
   bounds.set_width(bounds.width() + kSeparatorWidth);
   int row_height = bounds.height();
 
-  views::View* container = new UserDropdownWidgetContents(
-      base::Bind(&UserView::HideUserDropdownWidget, base::Unretained(this)));
+  UserDropdownWidgetContents* container =
+      new UserDropdownWidgetContents(base::BindOnce(
+          &UserView::HideUserDropdownWidget, base::Unretained(this)));
   views::View* add_user_view = CreateAddUserView(add_user_policy);
   const SkColor bg_color = add_user_view->background()->get_color();
   container->SetBorder(views::CreatePaddedBorder(
@@ -359,11 +424,26 @@
   separator->SetBorder(views::CreateEmptyBorder(
       0, separator_horizontal_padding, 0, separator_horizontal_padding));
   user_dropdown_padding->AddChildView(separator);
+  user_dropdown_padding->SetBackground(views::CreateThemedSolidBackground(
+      user_dropdown_padding, ui::NativeTheme::kColorId_BubbleBackground));
 
   // Add other logged in users.
+  // Helper function to add a descendant view of |widget_content_view| which
+  // will need to grab focus with the custom search.
+  auto add_focusable_child = [](views::View* parent, views::View* child,
+                                UserDropdownWidgetContents* widget_content_view,
+                                int* out_model_index) {
+    DCHECK(out_model_index);
+    parent->AddChildView(child);
+    widget_content_view->view_model()->Add(child, *out_model_index);
+    ++(*out_model_index);
+  };
+
+  int model_index = 0;
   for (int i = 1; i < session_controller->NumberOfLoggedInUsers(); ++i) {
-    user_dropdown_padding->AddChildView(new ButtonFromView(
-        new UserCardView(i), this, TrayPopupInkDropStyle::INSET_BOUNDS));
+    auto* button = new ButtonFromView(new UserCardView(i), this,
+                                      TrayPopupInkDropStyle::INSET_BOUNDS);
+    add_focusable_child(user_dropdown_padding, button, container, &model_index);
   }
 
   // Add the "add user" option or the "can't add another user" message.
@@ -372,7 +452,7 @@
                                       TrayPopupInkDropStyle::INSET_BOUNDS);
     button->SetAccessibleName(
         l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT));
-    user_dropdown_padding->AddChildView(button);
+    add_focusable_child(user_dropdown_padding, button, container, &model_index);
   } else {
     user_dropdown_padding->AddChildView(add_user_view);
   }
@@ -388,9 +468,19 @@
   // is open (the icon will appear in the specific user rows).
   user_card_view_->SetSuppressCaptureIcon(true);
 
+  // Make |user_dropdown_widget_| a transient child of the tray bubble, so that
+  // the bubble does not close when |user_dropdown_widget_| loses activation.
+  ::wm::TransientWindowManager::GetOrCreate(
+      GetBubbleWidget()->GetNativeWindow())
+      ->AddTransientChild(user_dropdown_widget_->GetNativeWindow());
+
   // Show the content.
   user_dropdown_widget_->SetAlwaysOnTop(true);
   user_dropdown_widget_->Show();
+  if (toggled_by_key_event && container->view_model()->view_size() > 0) {
+    user_dropdown_widget_->GetFocusManager()->SetFocusedView(
+        container->view_model()->view_at(0));
+  }
 
   // Install a listener to focus changes so that we can remove the card when
   // the focus gets changed. When called through the destruction of the bubble,
@@ -404,11 +494,27 @@
     return;
   focus_manager_->RemoveFocusChangeListener(this);
   focus_manager_ = nullptr;
-  if (user_card_container_->GetFocusManager())
+  if (user_card_container_->GetFocusManager()) {
+    // Return activation to bubble before destroying |user_dropdown_widget_|,
+    // otherwise tray_bubble_wrapper will not know |user_dropdown_widget_| is
+    // a transient child of the bubble.
+    if (GetBubbleWidget())
+      GetBubbleWidget()->Activate();
     user_card_container_->GetFocusManager()->ClearFocus();
+    if (user_dropdown_widget_toggled_by_key_event_) {
+      user_card_container_->GetFocusManager()->SetFocusedView(
+          user_card_container_);
+    }
+  }
   user_card_view_->SetSuppressCaptureIcon(false);
   user_dropdown_widget_.reset();
 }
 
+views::Widget* UserView::GetBubbleWidget() {
+  if (!owner_->system_tray()->GetSystemBubble())
+    return nullptr;
+  return owner_->system_tray()->GetSystemBubble()->bubble_view()->GetWidget();
+}
+
 }  // namespace tray
 }  // namespace ash
diff --git a/ash/system/user/user_view.h b/ash/system/user/user_view.h
index de498772..998c61e 100644
--- a/ash/system/user/user_view.h
+++ b/ash/system/user/user_view.h
@@ -60,13 +60,14 @@
   void AddLogoutButton(LoginStatus login);
   void AddUserCard(LoginStatus login);
 
-  // Create the menu option to add another user. If |disabled| is set the user
-  // cannot actively click on the item.
-  void ToggleUserDropdownWidget();
+  // Create the menu option to add another user.
+  void ToggleUserDropdownWidget(bool toggled_by_key_event);
 
   // Removes the add user menu option.
   void HideUserDropdownWidget();
 
+  views::Widget* GetBubbleWidget();
+
   // If |user_card_view_| is clickable, this is a ButtonFromView that wraps it.
   // If |user_card_view_| is not clickable, this will be equal to
   // |user_card_view_|.
@@ -80,6 +81,9 @@
 
   views::View* logout_button_ = nullptr;
   std::unique_ptr<views::Widget> user_dropdown_widget_;
+  // Tracks whether |user_dropdown_widget_| was opened with a key event. If
+  // true, HideUserDropdownWidget() will return focus to |user_card_container_|.
+  bool user_dropdown_widget_toggled_by_key_event_ = false;
 
   // False when the add user panel is visible but not activatable.
   bool add_user_enabled_ = true;
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc
index 6081bda0..c6f558b 100644
--- a/ash/wm/workspace/workspace_layout_manager_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -1547,7 +1547,8 @@
   GetAppListTestHelper()->Dismiss();
 }
 
-TEST_F(WorkspaceLayoutManagerBackdropTest, OpenAppListInOverviewMode) {
+// TODO(minch): This test has a high flake rate. https://crbug.com/838756
+TEST_F(WorkspaceLayoutManagerBackdropTest, DISABLED_OpenAppListInOverviewMode) {
   WorkspaceController* wc = ShellTestApi(Shell::Get()).workspace_controller();
   WorkspaceControllerTestApi test_helper(wc);
 
diff --git a/build/android/gyp/OWNERS b/build/android/gyp/OWNERS
index c1d7385..74dca6f 100644
--- a/build/android/gyp/OWNERS
+++ b/build/android/gyp/OWNERS
@@ -1,6 +1,6 @@
 agrieve@chromium.org
 estevenson@chromium.org
-digit@google.com
+digit@chromium.org
 wnwen@chromium.org
 
 # COMPONENT: Build
diff --git a/build/config/android/OWNERS b/build/config/android/OWNERS
index c1d7385..74dca6f 100644
--- a/build/config/android/OWNERS
+++ b/build/config/android/OWNERS
@@ -1,6 +1,6 @@
 agrieve@chromium.org
 estevenson@chromium.org
-digit@google.com
+digit@chromium.org
 wnwen@chromium.org
 
 # COMPONENT: Build
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java
index 4d85da8..2c327d8c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java
@@ -119,10 +119,7 @@
     @CalledByNative
     private void show(AutofillSuggestion[] suggestions, boolean isRtl) {
         if (mAutofillSuggestions != null) mAutofillSuggestions.setSuggestions(suggestions, isRtl);
-        if (mKeyboardAccessory != null) {
-            mKeyboardAccessory.setSuggestions(mAutofillSuggestions);
-            mKeyboardAccessory.show();
-        }
+        if (mKeyboardAccessory != null) mKeyboardAccessory.setSuggestions(mAutofillSuggestions);
     }
 
     // Helper methods for AutofillSuggestion. These are copied from AutofillPopupBridge (which
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryCoordinator.java
index 65219d6..c4da0b04 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryCoordinator.java
@@ -46,13 +46,6 @@
     }
 
     /**
-     * Show the keyboard accessory. Independent from the keyboard.
-     */
-    public void show() {
-        mMediator.show();
-    }
-
-    /**
      * A {@link KeyboardAccessoryData.Tab} passed into this function will be represented as item at
      * the start of the accessory. It is meant to trigger various bottom sheets.
      * @param tab The tab which contains representation data and links back to a bottom sheet.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMediator.java
index 204952f..88963f51 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryMediator.java
@@ -4,8 +4,12 @@
 
 package org.chromium.chrome.browser.autofill.keyboard_accessory;
 
+import android.support.annotation.Nullable;
+
 import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.browser.autofill.AutofillKeyboardSuggestions;
+import org.chromium.chrome.browser.modelutil.ListObservable;
+import org.chromium.chrome.browser.modelutil.PropertyObservable;
 import org.chromium.ui.base.WindowAndroid;
 
 /**
@@ -16,15 +20,27 @@
  * generating passwords) and lets the {@link KeyboardAccessoryModel} know of these actions and which
  * callback to trigger when selecting them.
  */
-class KeyboardAccessoryMediator implements KeyboardAccessoryData.ActionListObserver,
-                                           WindowAndroid.KeyboardVisibilityListener {
+class KeyboardAccessoryMediator
+        implements KeyboardAccessoryData.ActionListObserver,
+                   WindowAndroid.KeyboardVisibilityListener, ListObservable.ListObserver,
+                   PropertyObservable.PropertyObserver<KeyboardAccessoryModel.PropertyKey> {
     private final KeyboardAccessoryModel mModel;
     private final WindowAndroid mWindowAndroid;
 
+    // TODO(fhorschig): Look stronger signals than |keyboardVisibilityChanged|.
+    // This variable remembers the last state of |keyboardVisibilityChanged| which might not be
+    // sufficient for edge cases like hardware keyboards, floating keyboards, etc.
+    private boolean mIsKeyboardVisible;
+
     KeyboardAccessoryMediator(KeyboardAccessoryModel model, WindowAndroid windowAndroid) {
         mModel = model;
         mWindowAndroid = windowAndroid;
         windowAndroid.addKeyboardVisibilityListener(this);
+
+        // Add mediator as observer so it can use model changes as signal for accessory visibility.
+        mModel.addObserver(this);
+        mModel.getTabList().addObserver(this);
+        mModel.getActionList().addObserver(this);
     }
 
     void destroy() {
@@ -38,17 +54,8 @@
 
     @Override
     public void keyboardVisibilityChanged(boolean isShowing) {
-        if (!isShowing) { // TODO(fhorschig): ... and no bottom sheet.
-            hide();
-        }
-    }
-
-    void hide() {
-        mModel.setVisible(false);
-    }
-
-    void show() {
-        mModel.setVisible(true);
+        mIsKeyboardVisible = isShowing;
+        updateVisibility();
     }
 
     void addTab(KeyboardAccessoryData.Tab tab) {
@@ -64,10 +71,8 @@
     }
 
     void dismiss() {
-        hide();
-        if (mModel.getAutofillSuggestions() != null) {
-            mModel.getAutofillSuggestions().dismiss();
-        }
+        if (mModel.getAutofillSuggestions() == null) return; // Nothing to do here.
+        mModel.getAutofillSuggestions().dismiss();
         mModel.setAutofillSuggestions(null);
     }
 
@@ -75,4 +80,45 @@
     KeyboardAccessoryModel getModelForTesting() {
         return mModel;
     }
+
+    @Override
+    public void onItemRangeInserted(ListObservable source, int index, int count) {
+        assert source == mModel.getActionList() || source == mModel.getTabList();
+        updateVisibility();
+    }
+
+    @Override
+    public void onItemRangeRemoved(ListObservable source, int index, int count) {
+        assert source == mModel.getActionList() || source == mModel.getTabList();
+        updateVisibility();
+    }
+
+    @Override
+    public void onItemRangeChanged(
+            ListObservable source, int index, int count, @Nullable Object payload) {
+        assert source == mModel.getActionList() || source == mModel.getTabList();
+        updateVisibility();
+    }
+
+    @Override
+    public void onPropertyChanged(PropertyObservable<KeyboardAccessoryModel.PropertyKey> source,
+            @Nullable KeyboardAccessoryModel.PropertyKey propertyKey) {
+        // Update the visibility only if we haven't set it just now.
+        if (propertyKey == KeyboardAccessoryModel.PropertyKey.VISIBLE) return;
+        if (propertyKey == KeyboardAccessoryModel.PropertyKey.SUGGESTIONS) {
+            updateVisibility();
+            return;
+        }
+        assert false : "Every property update needs to be handled explicitly!";
+    }
+
+    private boolean shouldShowAccessory() {
+        if (!mIsKeyboardVisible) return false;
+        return mModel.getAutofillSuggestions() != null || mModel.getActionList().getItemCount() > 0
+                || mModel.getTabList().getItemCount() > 0;
+    }
+
+    private void updateVisibility() {
+        mModel.setVisible(shouldShowAccessory());
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java
index fc0d56e8..46893ff 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java
@@ -6,6 +6,7 @@
 
 import android.support.annotation.LayoutRes;
 
+import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.metrics.ImpressionTracker;
 import org.chromium.chrome.browser.ntp.ContextMenuManager;
@@ -245,4 +246,9 @@
         mUiDelegate.getEventReporter().onSuggestionShown(mArticle);
         mRecyclerView.onSnippetImpression();
     }
+
+    @VisibleForTesting
+    public void setOfflineBadgeVisibilityForTesting(boolean visible) {
+        mSuggestionsBinder.updateOfflineBadgeVisibility(visible);
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsTest.java
index 4c4a7eef..77bf617 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/ContextualSuggestionsTest.java
@@ -50,6 +50,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.util.ChromeTabUtils;
+import org.chromium.chrome.test.util.RenderTestRule;
 import org.chromium.chrome.test.util.ViewUtils;
 import org.chromium.chrome.test.util.browser.ChromeModernDesign;
 import org.chromium.chrome.test.util.browser.Features;
@@ -87,6 +88,8 @@
     public ScreenShooter mScreenShooter = new ScreenShooter();
     @Rule
     public TestRule mDisableChromeAnimations = new DisableChromeAnimations();
+    @Rule
+    public RenderTestRule mRenderTestRule = new RenderTestRule();
 
     private static final String TEST_PAGE =
             "/chrome/test/data/android/contextual_suggestions/contextual_suggestions_test.html";
@@ -486,6 +489,48 @@
         mScreenShooter.shoot("Contextual suggestions: scrolled");
     }
 
+    @Test
+    @MediumTest
+    @Feature({"ContextualSuggestions", "RenderTest"})
+    @DisableFeatures(FeatureConstants.CONTEXTUAL_SUGGESTIONS_FEATURE)
+    public void testRender() throws Exception {
+        // Force suggestions to populate in the bottom sheet, then render the peeking bar.
+        forceShowSuggestions();
+        BottomSheetTestRule.waitForWindowUpdates();
+        mRenderTestRule.render(
+                mBottomSheet.getCurrentSheetContent().getToolbarView(), "peeking_bar");
+
+        // Open the sheet to cause the suggestions to be bound in the RecyclerView, then capture
+        // a suggestion with its thumbnail loading.
+        ThreadUtils.runOnUiThreadBlocking(
+                () -> mBottomSheet.setSheetState(BottomSheet.SHEET_STATE_FULL, false));
+        BottomSheetTestRule.waitForWindowUpdates();
+        mRenderTestRule.render(getFirstSuggestionViewHolder().itemView, "suggestion_image_loading");
+
+        // Run the image fetch callback so images load, then capture a suggestion with its
+        // thumbnail loaded.
+        ThreadUtils.runOnUiThreadBlocking(() -> mFakeSource.runImageFetchCallbacks());
+        BottomSheetTestRule.waitForWindowUpdates();
+        mRenderTestRule.render(getFirstSuggestionViewHolder().itemView, "suggestion_image_loaded");
+
+        // Render a thumbnail with an offline badge.
+        ThreadUtils.runOnUiThreadBlocking(
+                () -> getSuggestionViewHolder(2).setOfflineBadgeVisibilityForTesting(true));
+        mRenderTestRule.render(getSuggestionViewHolder(2).itemView, "suggestion_offline");
+
+        // Render the full suggestions sheet.
+        mRenderTestRule.render(mBottomSheet, "full_height");
+
+        // Scroll the suggestions and render the full suggestions sheet.
+        ThreadUtils.runOnUiThreadBlocking(() -> {
+            RecyclerView view =
+                    (RecyclerView) mBottomSheet.getCurrentSheetContent().getContentView();
+            view.scrollToPosition(5);
+        });
+        BottomSheetTestRule.waitForWindowUpdates();
+        mRenderTestRule.render(mBottomSheet, "full_height_scrolled");
+    }
+
     private void forceShowSuggestions() throws InterruptedException, TimeoutException {
         assertEquals("Model has incorrect number of items.",
                 (int) FakeContextualSuggestionsSource.TOTAL_ITEM_COUNT,
@@ -527,12 +572,20 @@
     }
 
     private SnippetArticleViewHolder getFirstSuggestionViewHolder(BottomSheet bottomSheet) {
+        return getSuggestionViewHolder(bottomSheet, 0);
+    }
+
+    private SnippetArticleViewHolder getSuggestionViewHolder(int index) {
+        return getSuggestionViewHolder(mBottomSheet, index);
+    }
+
+    private SnippetArticleViewHolder getSuggestionViewHolder(BottomSheet bottomSheet, int index) {
         ContextualSuggestionsBottomSheetContent content =
                 (ContextualSuggestionsBottomSheetContent) bottomSheet.getCurrentSheetContent();
         RecyclerView recyclerView = (RecyclerView) content.getContentView();
 
         RecyclerViewTestUtils.waitForStableRecyclerView(recyclerView);
 
-        return (SnippetArticleViewHolder) recyclerView.findViewHolderForAdapterPosition(0);
+        return (SnippetArticleViewHolder) recyclerView.findViewHolderForAdapterPosition(index);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeContextualSuggestionsSource.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeContextualSuggestionsSource.java
index e5e593a2..ab4998a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeContextualSuggestionsSource.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextual_suggestions/FakeContextualSuggestionsSource.java
@@ -89,7 +89,7 @@
         mPendingImageRequests.clear();
     }
 
-    private ContextualSuggestionsResult createDummyResults() {
+    private static ContextualSuggestionsResult createDummyResults() {
         SnippetArticle suggestion1 = new SnippetArticle(KnownCategories.CONTEXTUAL, "id1",
                 "Capybaras also love hats",
                 "Lorem ipsum dolor sit amet, consectetur adipiscing "
@@ -109,7 +109,8 @@
                 new SnippetArticle(KnownCategories.CONTEXTUAL, "id3", "Capybaras don't like ties",
                         "Pellentesque nec lorem nec velit convallis suscipit "
                                 + "non eget nunc.",
-                        "Capybara News", "https://site.com/url3", 0, 0, 0, false, null, true);
+                        "Breaking Capybara News Updates Delivered Daily", "https://site.com/url3",
+                        0, 0, 0, false, null, true);
         SnippetArticle article4 =
                 new SnippetArticle(KnownCategories.CONTEXTUAL, "id4", "Fancy watches",
                         "Duis egestas est vitae eros consectetur vulputate. Integer "
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java
index 3a65033..5ec66303 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/autofill/keyboard_accessory/KeyboardAccessoryControllerTest.java
@@ -7,7 +7,9 @@
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.nullValue;
 import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -25,6 +27,7 @@
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.autofill.AutofillKeyboardSuggestions;
 import org.chromium.chrome.browser.modelutil.ListObservable;
 import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor;
 import org.chromium.chrome.browser.modelutil.PropertyObservable.PropertyObserver;
@@ -102,14 +105,14 @@
     public void testModelNotifiesVisibilityChangeOnShowAndHide() {
         mModel.addObserver(mMockPropertyObserver);
 
-        // Calling show on the mediator should make model propagate that it's visible.
-        mMediator.show();
+        // Setting the visibility on the model should make it propagate that it's visible.
+        mModel.setVisible(true);
         verify(mMockPropertyObserver)
                 .onPropertyChanged(mModel, KeyboardAccessoryModel.PropertyKey.VISIBLE);
         assertThat(mModel.isVisible(), is(true));
 
-        // Calling hide on the mediator should make model propagate that it's invisible.
-        mMediator.hide();
+        // Resetting the visibility on the model to should make it propagate that it's visible.
+        mModel.setVisible(false);
         verify(mMockPropertyObserver, times(2))
                 .onPropertyChanged(mModel, KeyboardAccessoryModel.PropertyKey.VISIBLE);
         assertThat(mModel.isVisible(), is(false));
@@ -174,16 +177,81 @@
     public void testModelDoesntNotifyUnchangedData() {
         mModel.addObserver(mMockPropertyObserver);
 
-        // Calling show on the coordinator should make model propagate that it's visible.
-        mCoordinator.show();
+        // Setting the visibility on the model should make it propagate that it's visible.
+        mModel.setVisible(true);
         verify(mMockPropertyObserver)
                 .onPropertyChanged(mModel, KeyboardAccessoryModel.PropertyKey.VISIBLE);
         assertThat(mModel.isVisible(), is(true));
 
-        // Marking it as visible again should not result in a second notification.
-        mCoordinator.show();
+        // Marking it as visible again should not result in a notification.
+        mModel.setVisible(true);
         verify(mMockPropertyObserver) // Unchanged number of invocations.
                 .onPropertyChanged(mModel, KeyboardAccessoryModel.PropertyKey.VISIBLE);
         assertThat(mModel.isVisible(), is(true));
     }
+
+    @Test
+    @SmallTest
+    @Feature({"keyboard-accessory"})
+    public void testIsVisibleWithSuggestionsBeforeKeyboardComesUp() {
+        // Without suggestions, the accessory should remain invisible - even if the keyboard shows.
+        assertThat(mModel.getAutofillSuggestions(), is(nullValue()));
+        assertThat(mModel.isVisible(), is(false));
+        mMediator.keyboardVisibilityChanged(true);
+        assertThat(mModel.isVisible(), is(false));
+        mMediator.keyboardVisibilityChanged(false);
+
+        // Adding suggestions doesn't change the visibility by itself.
+        mMediator.setSuggestions(mock(AutofillKeyboardSuggestions.class));
+        assertThat(mModel.isVisible(), is(false));
+
+        // But as soon as the keyboard comes up, it should be showing.
+        mMediator.keyboardVisibilityChanged(true);
+        assertThat(mModel.isVisible(), is(true));
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"keyboard-accessory"})
+    public void testIsVisibleWithSuggestionsAfterKeyboardComesUp() {
+        // Without any suggestions, the accessory should remain invisible.
+        assertThat(mModel.getAutofillSuggestions(), is(nullValue()));
+        assertThat(mModel.isVisible(), is(false));
+
+        // If the keyboard comes up, but there are no suggestions set, keep the accessory hidden.
+        mMediator.keyboardVisibilityChanged(true);
+        assertThat(mModel.isVisible(), is(false));
+
+        // Adding suggestions while the keyboard is visible triggers the accessory.
+        mMediator.setSuggestions(mock(AutofillKeyboardSuggestions.class));
+        assertThat(mModel.isVisible(), is(true));
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"keyboard-accessory"})
+    public void testIsVisibleWithActions() {
+        // Without any actions, the accessory should remain invisible.
+        assertThat(mModel.getActionList().getItemCount(), is(0));
+        mMediator.keyboardVisibilityChanged(true);
+        assertThat(mModel.isVisible(), is(false));
+
+        // Adding actions while the keyboard is visible triggers the accessory.
+        mModel.getActionList().add(new FakeAction());
+        assertThat(mModel.isVisible(), is(true));
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"keyboard-accessory"})
+    public void testIsVisibleWithTabs() {
+        // Without any actions, the accessory should remain invisible.
+        assertThat(mModel.getActionList().getItemCount(), is(0));
+        mMediator.keyboardVisibilityChanged(true);
+        assertThat(mModel.isVisible(), is(false));
+
+        // Adding actions while the keyboard is visible triggers the accessory.
+        mCoordinator.addTab(new FakeTab());
+        assertThat(mModel.isVisible(), is(true));
+    }
 }
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index d3a5a91..fa32849 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -211,6 +211,8 @@
     "browsing_data/counters/site_data_counter.h",
     "browsing_data/counters/site_data_counting_helper.cc",
     "browsing_data/counters/site_data_counting_helper.h",
+    "browsing_data/counters/site_settings_counter.cc",
+    "browsing_data/counters/site_settings_counter.h",
     "browsing_data/local_data_container.cc",
     "browsing_data/local_data_container.h",
     "browsing_data/navigation_entry_remover.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index cca6b1f5..f583e30 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1527,6 +1527,10 @@
      flag_descriptions::kEasyUnlockPromotionsName,
      flag_descriptions::kEasyUnlockPromotionsDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(features::kEasyUnlockPromotions)},
+    {"enable-touchable-app-context-menu",
+     flag_descriptions::kTouchableAppContextMenuName,
+     flag_descriptions::kTouchableAppContextMenuDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(features::kTouchableAppContextMenu)},
     {
         "enable-pinch", flag_descriptions::kPinchScaleName,
         flag_descriptions::kPinchScaleDescription, kOsLinux | kOsWin | kOsCrOS,
diff --git a/chrome/browser/android/feed/feed_host_service_factory.cc b/chrome/browser/android/feed/feed_host_service_factory.cc
index 934a812c..d744d9b 100644
--- a/chrome/browser/android/feed/feed_host_service_factory.cc
+++ b/chrome/browser/android/feed/feed_host_service_factory.cc
@@ -4,9 +4,19 @@
 
 #include "chrome/browser/android/feed/feed_host_service_factory.h"
 
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
+#include "chrome/common/channel_info.h"
 #include "components/feed/core/feed_host_service.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "components/version_info/version_info.h"
 #include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
+#include "google_apis/google_api_keys.h"
 
 namespace feed {
 
@@ -31,7 +41,24 @@
 
 KeyedService* FeedHostServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
-  return new FeedHostService();
+  Profile* profile = Profile::FromBrowserContext(context);
+  content::StoragePartition* storage_partition =
+      content::BrowserContext::GetDefaultStoragePartition(context);
+
+  identity::IdentityManager* identity_manager =
+      IdentityManagerFactory::GetForProfile(profile);
+  std::string api_key;
+  if (google_apis::IsGoogleChromeAPIKeyUsed()) {
+    bool is_stable_channel =
+        chrome::GetChannel() == version_info::Channel::STABLE;
+    api_key = is_stable_channel ? google_apis::GetAPIKey()
+                                : google_apis::GetNonStableAPIKey();
+  }
+  auto networking_host = std::make_unique<FeedNetworkingHost>(
+      identity_manager, api_key,
+      storage_partition->GetURLLoaderFactoryForBrowserProcess());
+
+  return new FeedHostService(std::move(networking_host));
 }
 
 content::BrowserContext* FeedHostServiceFactory::GetBrowserContextToUse(
diff --git a/chrome/browser/android/vr/vr_dialog.cc b/chrome/browser/android/vr/vr_dialog.cc
index 29cea37..ac754277 100644
--- a/chrome/browser/android/vr/vr_dialog.cc
+++ b/chrome/browser/android/vr/vr_dialog.cc
@@ -11,6 +11,7 @@
 #include "base/callback_helpers.h"
 #include "base/time/time.h"
 #include "chrome/browser/android/vr/vr_shell_delegate.h"
+#include "third_party/blink/public/platform/web_gesture_event.h"
 #include "third_party/blink/public/platform/web_mouse_event.h"
 
 using base::android::JavaParamRef;
@@ -30,39 +31,8 @@
   width_ = width;
   height_ = height;
 }
-void VrDialog::OnContentEnter(const gfx::PointF& normalized_hit_point) {}
 
-void VrDialog::OnContentLeave() {}
-
-void VrDialog::OnContentMove(const gfx::PointF& normalized_hit_point) {
-  SendGestureToDialog(
-      MakeMouseEvent(blink::WebInputEvent::kMouseMove, normalized_hit_point));
-}
-
-void VrDialog::OnContentDown(const gfx::PointF& normalized_hit_point) {
-  SendGestureToDialog(
-      MakeMouseEvent(blink::WebInputEvent::kMouseDown, normalized_hit_point));
-}
-
-void VrDialog::OnContentUp(const gfx::PointF& normalized_hit_point) {
-  SendGestureToDialog(
-      MakeMouseEvent(blink::WebInputEvent::kMouseUp, normalized_hit_point));
-}
-
-void VrDialog::OnContentFlingCancel(
-    std::unique_ptr<blink::WebGestureEvent> gesture,
-    const gfx::PointF& normalized_hit_point) {}
-void VrDialog::OnContentScrollBegin(
-    std::unique_ptr<blink::WebGestureEvent> gesture,
-    const gfx::PointF& normalized_hit_point) {}
-void VrDialog::OnContentScrollUpdate(
-    std::unique_ptr<blink::WebGestureEvent> gesture,
-    const gfx::PointF& normalized_hit_point) {}
-void VrDialog::OnContentScrollEnd(
-    std::unique_ptr<blink::WebGestureEvent> gesture,
-    const gfx::PointF& normalized_hit_point) {}
-
-void VrDialog::SendGestureToDialog(
+void VrDialog::SendGestureToTarget(
     std::unique_ptr<blink::WebInputEvent> event) {
   if (!event || !dialog_)
     return;
@@ -91,4 +61,10 @@
   return mouse_event;
 }
 
+void VrDialog::UpdateGesture(const gfx::PointF& normalized_content_hit_point,
+                             blink::WebGestureEvent& gesture) {
+  gesture.SetPositionInWidget(
+      ScalePoint(normalized_content_hit_point, width_, height_));
+}
+
 }  //  namespace vr
diff --git a/chrome/browser/android/vr/vr_dialog.h b/chrome/browser/android/vr/vr_dialog.h
index fd7e86f..378efff 100644
--- a/chrome/browser/android/vr/vr_dialog.h
+++ b/chrome/browser/android/vr/vr_dialog.h
@@ -24,6 +24,8 @@
 using base::android::JavaParamRef;
 
 namespace vr {
+// TODO(bshe): refactor content_input_delegate and vr_dialog so the common
+// code can be shared in a more clear way (https://crbug.com/838925).
 class VrDialog : public ContentInputDelegate {
  public:
   VrDialog(int width, int height);
@@ -36,24 +38,14 @@
   ContentInputForwarder* dialog_ = nullptr;
 
   // ContentInputDelegate.
-  void OnContentEnter(const gfx::PointF& normalized_hit_point) override;
-  void OnContentLeave() override;
-  void OnContentMove(const gfx::PointF& normalized_hit_point) override;
-  void OnContentDown(const gfx::PointF& normalized_hit_point) override;
-  void OnContentUp(const gfx::PointF& normalized_hit_point) override;
-  void OnContentFlingCancel(std::unique_ptr<blink::WebGestureEvent> gesture,
-                            const gfx::PointF& normalized_hit_point) override;
-  void OnContentScrollBegin(std::unique_ptr<blink::WebGestureEvent> gesture,
-                            const gfx::PointF& normalized_hit_point) override;
-  void OnContentScrollUpdate(std::unique_ptr<blink::WebGestureEvent> gesture,
-                             const gfx::PointF& normalized_hit_point) override;
-  void OnContentScrollEnd(std::unique_ptr<blink::WebGestureEvent> gesture,
-                          const gfx::PointF& normalized_hit_point) override;
-  void SendGestureToDialog(std::unique_ptr<blink::WebInputEvent> event);
-
+  void SendGestureToTarget(
+      std::unique_ptr<blink::WebInputEvent> event) override;
+  void UpdateGesture(const gfx::PointF& normalized_content_hit_point,
+                     blink::WebGestureEvent& gesture) override;
   std::unique_ptr<blink::WebMouseEvent> MakeMouseEvent(
       blink::WebInputEvent::Type type,
-      const gfx::PointF& normalized_web_content_location);
+      const gfx::PointF& normalized_web_content_location) override;
+
   int width_;
   int height_;
 
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client_unittest.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client_unittest.cc
index 08b0363..ef002e0 100644
--- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client_unittest.cc
+++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 
+#include "base/strings/utf_string_conversions.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/prefs/pref_service.h"
@@ -15,6 +16,29 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
+namespace {
+
+class TestSchemeClassifier : public AutocompleteSchemeClassifier {
+ public:
+  TestSchemeClassifier() = default;
+  ~TestSchemeClassifier() override = default;
+
+  // Overridden from AutocompleteInputSchemeClassifier:
+  metrics::OmniboxInputType GetInputTypeForScheme(
+      const std::string& scheme) const override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestSchemeClassifier);
+};
+
+metrics::OmniboxInputType TestSchemeClassifier::GetInputTypeForScheme(
+    const std::string& scheme) const {
+  return scheme.empty() ? metrics::OmniboxInputType::INVALID
+                        : metrics::OmniboxInputType::URL;
+}
+
+};  // namespace
+
 class ChromeAutocompleteProviderClientTest : public testing::Test {
  public:
   void SetUp() override {
@@ -71,3 +95,50 @@
   EXPECT_FALSE(service_worker_context_
                    .start_service_worker_for_navigation_hint_called());
 }
+
+TEST_F(ChromeAutocompleteProviderClientTest, TestStrippedURLsAreEqual) {
+  struct {
+    const char* url1;
+    const char* url2;
+    const char* input;
+    bool equal;
+  } test_cases[] = {
+      // Sanity check cases.
+      {"http://google.com", "http://google.com", "", true},
+      {"http://google.com", "http://www.google.com", "", true},
+      {"http://google.com", "http://facebook.com", "", false},
+      {"http://google.com", "https://google.com", "", true},
+      // Because we provided scheme, must match in scheme.
+      {"http://google.com", "https://google.com", "http://google.com", false},
+      // Ignore ref if not in input.
+      {"http://drive.google.com/doc/blablabla#page=10",
+       "http://drive.google.com/doc/blablabla#page=111", "", true},
+      {"http://drive.google.com/doc/blablabla#page=10",
+       "http://drive.google.com/doc/blablabla#page=111",
+       "http://drive.google.com/doc/blablabla", true},
+      {"file:///usr/local/bin/tuxpenguin#ref1",
+       "file:///usr/local/bin/tuxpenguin#ref2", "", true},
+      {"file:///usr/local/bin/tuxpenguin#ref1",
+       "file:///usr/local/bin/tuxpenguin#ref2",
+       "file:///usr/local/bin/tuxpenguin", true},
+      // Do not ignore ref if in input.
+      {"http://drive.google.com/doc/blablabla#page=10",
+       "http://drive.google.com/doc/blablabla#page=111",
+       "http://drive.google.com/doc/blablabla#p", false},
+      {"file:///usr/local/bin/tuxpenguin#ref1",
+       "file:///usr/local/bin/tuxpenguin#ref2",
+       "file:///usr/local/bin/tuxpenguin#r", false}};
+
+  for (const auto& test_case : test_cases) {
+    SCOPED_TRACE(std::string(test_case.url1) + " vs " + test_case.url2 +
+                 ", input '" + test_case.input + "'");
+    AutocompleteInput input(base::ASCIIToUTF16(test_case.input),
+                            test_case.input[0]
+                                ? metrics::OmniboxEventProto::OTHER
+                                : metrics::OmniboxEventProto::BLANK,
+                            TestSchemeClassifier());
+    EXPECT_EQ(test_case.equal,
+              client_->StrippedURLsAreEqual(GURL(test_case.url1),
+                                            GURL(test_case.url2), &input));
+  }
+}
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index c8d7188..09085074 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -558,6 +558,7 @@
         <include name="IDR_SOUND_TOUCH_TYPE_WAV" file="resources\chromeos\sounds\touch_type.wav" type="BINDATA" />
         <include name="IDR_SOUND_DICTATION_END_WAV" file="resources\chromeos\sounds\earcons\audio_end.wav" type="BINDATA" />
         <include name="IDR_SOUND_DICTATION_START_WAV" file="resources\chromeos\sounds\earcons\audio_initiate.wav" type="BINDATA" />
+        <include name="IDR_SOUND_DICTATION_CANCEL_WAV" file="resources\chromeos\sounds\earcons\null_selection.wav" type="BINDATA" />
       </if>
      <if expr="chromeos">
         <include name="IDR_ABOUT_POWER_HTML" file="resources\chromeos\power.html" type="BINDATA" />
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
index fab350f..3714490 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -24,6 +24,8 @@
 #include "chrome/browser/browsing_data/navigation_entry_remover.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
+#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
 #include "chrome/browser/domain_reliability/service_factory.h"
 #include "chrome/browser/download/download_prefs.h"
 #include "chrome/browser/external_protocol/external_protocol_handler.h"
@@ -757,6 +759,12 @@
           info->website_settings_info()->type(), delete_begin_, delete_end_,
           HostContentSettingsMap::PatternSourcePredicate());
     }
+
+    auto* handler_registry =
+        ProtocolHandlerRegistryFactory::GetForBrowserContext(profile_);
+    if (handler_registry)
+      handler_registry->ClearUserDefinedHandlers(delete_begin_, delete_end_);
+
 #if !defined(OS_ANDROID)
     content::HostZoomMap* zoom_map =
         content::HostZoomMap::GetDefaultForBrowserContext(profile_);
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
index dd47061..3b15bd6 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -26,6 +26,8 @@
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_factory.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
+#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
 #include "chrome/browser/domain_reliability/service_factory.h"
 #include "chrome/browser/download/chrome_download_manager_delegate.h"
 #include "chrome/browser/download/download_core_service_factory.h"
@@ -573,6 +575,13 @@
   return base::WrapUnique(data->service);
 }
 
+std::unique_ptr<KeyedService> BuildProtocolHandlerRegistry(
+    content::BrowserContext* context) {
+  Profile* profile = Profile::FromBrowserContext(context);
+  return std::make_unique<ProtocolHandlerRegistry>(
+      profile, new ProtocolHandlerRegistry::Delegate());
+}
+
 class ClearDomainReliabilityTester {
  public:
   explicit ClearDomainReliabilityTester(TestingProfile* profile) :
@@ -1149,6 +1158,9 @@
         clear_domain_reliability_tester_(profile_.get()) {
     remover_ = content::BrowserContext::GetBrowsingDataRemover(profile_.get());
 
+    ProtocolHandlerRegistryFactory::GetInstance()->SetTestingFactory(
+        profile_.get(), &BuildProtocolHandlerRegistry);
+
 #if defined(OS_ANDROID)
     static_cast<ChromeBrowsingDataRemoverDelegate*>(
         profile_->GetBrowsingDataRemoverDelegate())
@@ -2068,6 +2080,40 @@
   EXPECT_EQ(CONTENT_SETTING_ALLOW, host_settings[0].GetContentSetting());
 }
 
+TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveProtocolHandler) {
+  auto* registry =
+      ProtocolHandlerRegistryFactory::GetForBrowserContext(GetProfile());
+  base::Time one_hour_ago = base::Time::Now() - base::TimeDelta::FromHours(1);
+  base::Time yesterday = base::Time::Now() - base::TimeDelta::FromDays(1);
+  registry->OnAcceptRegisterProtocolHandler(
+      ProtocolHandler::CreateProtocolHandler("test1", kOrigin1));
+  registry->OnAcceptRegisterProtocolHandler(
+      ProtocolHandler("test2", kOrigin1, yesterday));
+  EXPECT_TRUE(registry->IsHandledProtocol("test1"));
+  EXPECT_TRUE(registry->IsHandledProtocol("test2"));
+  EXPECT_EQ(
+      2U,
+      registry->GetUserDefinedHandlers(base::Time(), base::Time::Max()).size());
+  // Delete last hour.
+  BlockUntilBrowsingDataRemoved(
+      one_hour_ago, base::Time::Max(),
+      ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS, false);
+  EXPECT_FALSE(registry->IsHandledProtocol("test1"));
+  EXPECT_TRUE(registry->IsHandledProtocol("test2"));
+  EXPECT_EQ(
+      1U,
+      registry->GetUserDefinedHandlers(base::Time(), base::Time::Max()).size());
+  // Delete everything.
+  BlockUntilBrowsingDataRemoved(
+      base::Time(), base::Time::Max(),
+      ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS, false);
+  EXPECT_FALSE(registry->IsHandledProtocol("test1"));
+  EXPECT_FALSE(registry->IsHandledProtocol("test2"));
+  EXPECT_EQ(
+      0U,
+      registry->GetUserDefinedHandlers(base::Time(), base::Time::Max()).size());
+}
+
 TEST_F(ChromeBrowsingDataRemoverDelegateTest, RemoveSelectedClientHints) {
   // Add our settings.
   HostContentSettingsMap* host_content_settings_map =
diff --git a/chrome/browser/browsing_data/counters/browsing_data_counter_factory.cc b/chrome/browser/browsing_data/counters/browsing_data_counter_factory.cc
index 9ce355aa..bf67ded 100644
--- a/chrome/browser/browsing_data/counters/browsing_data_counter_factory.cc
+++ b/chrome/browser/browsing_data/counters/browsing_data_counter_factory.cc
@@ -12,7 +12,9 @@
 #include "chrome/browser/browsing_data/counters/downloads_counter.h"
 #include "chrome/browser/browsing_data/counters/media_licenses_counter.h"
 #include "chrome/browser/browsing_data/counters/site_data_counter.h"
+#include "chrome/browser/browsing_data/counters/site_settings_counter.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/history/web_history_service_factory.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
@@ -20,7 +22,6 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/web_data_service_factory.h"
 #include "components/browser_sync/profile_sync_service.h"
-#include "components/browsing_data/content/counters/site_settings_counter.h"
 #include "components/browsing_data/core/counters/autofill_counter.h"
 #include "components/browsing_data/core/counters/browsing_data_counter.h"
 #include "components/browsing_data/core/counters/history_counter.h"
@@ -99,14 +100,14 @@
   }
 
   if (pref_name == browsing_data::prefs::kDeleteSiteSettings) {
-    return std::make_unique<browsing_data::SiteSettingsCounter>(
+    return std::make_unique<SiteSettingsCounter>(
         HostContentSettingsMapFactory::GetForProfile(profile),
 #if !defined(OS_ANDROID)
-        content::HostZoomMap::GetDefaultForBrowserContext(profile)
+        content::HostZoomMap::GetDefaultForBrowserContext(profile),
 #else
-        nullptr
+        nullptr,
 #endif
-            );
+        ProtocolHandlerRegistryFactory::GetForBrowserContext(profile));
   }
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/chrome/browser/browsing_data/counters/cache_counter.h b/chrome/browser/browsing_data/counters/cache_counter.h
index 475b26d..a1784cd 100644
--- a/chrome/browser/browsing_data/counters/cache_counter.h
+++ b/chrome/browser/browsing_data/counters/cache_counter.h
@@ -12,10 +12,6 @@
 
 class Profile;
 
-namespace browsing_data {
-class ConditionalCacheCountingHelper;
-}
-
 class CacheCounter : public browsing_data::BrowsingDataCounter {
  public:
   class CacheResult : public FinishedResult {
@@ -43,8 +39,6 @@
  private:
   void Count() override;
   void OnCacheSizeCalculated(bool is_upper_limit, int64_t cache_bytes);
-  void FetchEstimate(
-      base::WeakPtr<browsing_data::ConditionalCacheCountingHelper>);
 
   Profile* profile_;
   int64_t calculated_size_;
diff --git a/components/browsing_data/content/counters/site_settings_counter.cc b/chrome/browser/browsing_data/counters/site_settings_counter.cc
similarity index 81%
rename from components/browsing_data/content/counters/site_settings_counter.cc
rename to chrome/browser/browsing_data/counters/site_settings_counter.cc
index 9d29c724..86d8174 100644
--- a/components/browsing_data/content/counters/site_settings_counter.cc
+++ b/chrome/browser/browsing_data/counters/site_settings_counter.cc
@@ -2,10 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/browsing_data/content/counters/site_settings_counter.h"
+#include "chrome/browser/browsing_data/counters/site_settings_counter.h"
 
 #include <set>
 #include "build/build_config.h"
+#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
 #include "components/browsing_data/core/pref_names.h"
 #include "components/content_settings/core/browser/content_settings_registry.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
@@ -14,12 +15,13 @@
 #include "content/public/browser/host_zoom_map.h"
 #endif
 
-namespace browsing_data {
-
-SiteSettingsCounter::SiteSettingsCounter(HostContentSettingsMap* map,
-                                         content::HostZoomMap* zoom_map)
-    : map_(map), zoom_map_(zoom_map) {
+SiteSettingsCounter::SiteSettingsCounter(
+    HostContentSettingsMap* map,
+    content::HostZoomMap* zoom_map,
+    ProtocolHandlerRegistry* handler_registry)
+    : map_(map), zoom_map_(zoom_map), handler_registry_(handler_registry) {
   DCHECK(map_);
+  DCHECK(handler_registry_);
 #if !defined(OS_ANDROID)
   DCHECK(zoom_map_);
 #else
@@ -40,6 +42,7 @@
   int empty_host_pattern = 0;
   base::Time period_start = GetPeriodStart();
   base::Time period_end = GetPeriodEnd();
+
   auto* registry = content_settings::ContentSettingsRegistry::GetInstance();
   for (const content_settings::ContentSettingsInfo* info : *registry) {
     ContentSettingsType type = info->website_settings_info()->type();
@@ -75,7 +78,10 @@
   }
 #endif
 
+  auto handlers =
+      handler_registry_->GetUserDefinedHandlers(period_start, period_end);
+  for (const ProtocolHandler& handler : handlers)
+    hosts.insert(handler.url().host());
+
   ReportResult(hosts.size() + empty_host_pattern);
 }
-
-}  // namespace browsing_data
diff --git a/components/browsing_data/content/counters/site_settings_counter.h b/chrome/browser/browsing_data/counters/site_settings_counter.h
similarity index 63%
rename from components/browsing_data/content/counters/site_settings_counter.h
rename to chrome/browser/browsing_data/counters/site_settings_counter.h
index 602e807..3422e69 100644
--- a/components/browsing_data/content/counters/site_settings_counter.h
+++ b/chrome/browser/browsing_data/counters/site_settings_counter.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 COMPONENTS_BROWSING_DATA_CONTENT_COUNTERS_SITE_SETTINGS_COUNTER_H_
-#define COMPONENTS_BROWSING_DATA_CONTENT_COUNTERS_SITE_SETTINGS_COUNTER_H_
+#ifndef CHROME_BROWSER_BROWSING_DATA_COUNTERS_SITE_SETTINGS_COUNTER_H_
+#define CHROME_BROWSER_BROWSING_DATA_COUNTERS_SITE_SETTINGS_COUNTER_H_
 
 #include "components/browsing_data/core/counters/browsing_data_counter.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
@@ -12,12 +12,13 @@
 class HostZoomMap;
 }
 
-namespace browsing_data {
+class ProtocolHandlerRegistry;
 
 class SiteSettingsCounter : public browsing_data::BrowsingDataCounter {
  public:
   explicit SiteSettingsCounter(HostContentSettingsMap* map,
-                               content::HostZoomMap* zoom_map);
+                               content::HostZoomMap* zoom_map,
+                               ProtocolHandlerRegistry* handler_registry);
   ~SiteSettingsCounter() override;
 
   const char* GetPrefName() const override;
@@ -29,8 +30,7 @@
 
   scoped_refptr<HostContentSettingsMap> map_;
   content::HostZoomMap* zoom_map_;
+  ProtocolHandlerRegistry* handler_registry_;
 };
 
-}  // namespace browsing_data
-
-#endif  // COMPONENTS_BROWSING_DATA_CONTENT_COUNTERS_SITE_SETTINGS_COUNTER_H_
+#endif  // CHROME_BROWSER_BROWSING_DATA_COUNTERS_SITE_SETTINGS_COUNTER_H_
diff --git a/chrome/browser/browsing_data/counters/site_settings_counter_unittest.cc b/chrome/browser/browsing_data/counters/site_settings_counter_unittest.cc
index 4d7de45..d247c10 100644
--- a/chrome/browser/browsing_data/counters/site_settings_counter_unittest.cc
+++ b/chrome/browser/browsing_data/counters/site_settings_counter_unittest.cc
@@ -2,11 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/browsing_data/content/counters/site_settings_counter.h"
+#include "chrome/browser/browsing_data/counters/site_settings_counter.h"
 
 #include "base/test/simple_test_clock.h"
 #include "build/build_config.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
+#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/browsing_data/core/browsing_data_utils.h"
 #include "components/browsing_data/core/pref_names.h"
@@ -22,7 +24,7 @@
 
 class SiteSettingsCounterTest : public testing::Test {
  public:
-  SiteSettingsCounterTest() {
+  void SetUp() override {
     profile_ = std::make_unique<TestingProfile>();
     map_ = HostContentSettingsMapFactory::GetForProfile(profile());
 #if !defined(OS_ANDROID)
@@ -30,6 +32,15 @@
 #else
     zoom_map_ = nullptr;
 #endif
+    handler_registry_ = std::make_unique<ProtocolHandlerRegistry>(
+        profile(), new ProtocolHandlerRegistry::Delegate());
+
+    counter_ = std::make_unique<SiteSettingsCounter>(map(), zoom_map(),
+                                                     handler_registry());
+    counter_->Init(profile()->GetPrefs(),
+                   browsing_data::ClearBrowsingDataTab::ADVANCED,
+                   base::BindRepeating(&SiteSettingsCounterTest::Callback,
+                                       base::Unretained(this)));
   }
 
   Profile* profile() { return profile_.get(); }
@@ -38,6 +49,12 @@
 
   content::HostZoomMap* zoom_map() { return zoom_map_; }
 
+  ProtocolHandlerRegistry* handler_registry() {
+    return handler_registry_.get();
+  }
+
+  SiteSettingsCounter* counter() { return counter_.get(); }
+
   void SetSiteSettingsDeletionPref(bool value) {
     profile()->GetPrefs()->SetBoolean(browsing_data::prefs::kDeleteSiteSettings,
                                       value);
@@ -69,6 +86,8 @@
 
   scoped_refptr<HostContentSettingsMap> map_;
   content::HostZoomMap* zoom_map_;
+  std::unique_ptr<ProtocolHandlerRegistry> handler_registry_;
+  std::unique_ptr<SiteSettingsCounter> counter_;
   bool finished_;
   browsing_data::BrowsingDataCounter::ResultInt result_;
 };
@@ -82,12 +101,7 @@
       GURL("http://maps.google.com"), GURL("http://maps.google.com"),
       CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string(), CONTENT_SETTING_ALLOW);
 
-  browsing_data::SiteSettingsCounter counter(map(), zoom_map());
-  counter.Init(
-      profile()->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
-      base::Bind(&SiteSettingsCounterTest::Callback, base::Unretained(this)));
-  counter.Restart();
-
+  counter()->Restart();
   EXPECT_EQ(2, GetResult());
 }
 
@@ -116,10 +130,6 @@
                                        std::string(), CONTENT_SETTING_ALLOW);
 
   test_clock.SetNow(base::Time::Now());
-  browsing_data::SiteSettingsCounter counter(map(), zoom_map());
-  counter.Init(
-      profile()->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
-      base::Bind(&SiteSettingsCounterTest::Callback, base::Unretained(this)));
   // Only one of the settings was created in the last hour.
   SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_HOUR);
   EXPECT_EQ(1, GetResult());
@@ -141,12 +151,7 @@
       CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, std::string(),
       std::make_unique<base::DictionaryValue>());
 
-  browsing_data::SiteSettingsCounter counter(map(), zoom_map());
-  counter.Init(
-      profile()->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
-      base::Bind(&SiteSettingsCounterTest::Callback, base::Unretained(this)));
-  counter.Restart();
-
+  counter()->Restart();
   EXPECT_EQ(1, GetResult());
 }
 
@@ -160,12 +165,7 @@
       GURL("http://www.google.com"), GURL("http://www.google.com"),
       CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string(), CONTENT_SETTING_ALLOW);
 
-  browsing_data::SiteSettingsCounter counter(map(), zoom_map());
-  counter.Init(
-      profile()->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
-      base::Bind(&SiteSettingsCounterTest::Callback, base::Unretained(this)));
-  counter.Restart();
-
+  counter()->Restart();
   EXPECT_EQ(1, GetResult());
 }
 
@@ -177,10 +177,6 @@
       GURL("http://www.google.com"), GURL("http://www.google.com"),
       CONTENT_SETTINGS_TYPE_POPUPS, std::string(), CONTENT_SETTING_ALLOW);
 
-  browsing_data::SiteSettingsCounter counter(map(), zoom_map());
-  counter.Init(
-      profile()->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
-      base::Bind(&SiteSettingsCounterTest::Callback, base::Unretained(this)));
   SetSiteSettingsDeletionPref(true);
   EXPECT_EQ(1, GetResult());
 }
@@ -191,11 +187,6 @@
       GURL("http://www.google.com"), GURL("http://www.google.com"),
       CONTENT_SETTINGS_TYPE_POPUPS, std::string(), CONTENT_SETTING_ALLOW);
 
-  browsing_data::SiteSettingsCounter counter(map(), zoom_map());
-  counter.Init(
-      profile()->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
-      base::Bind(&SiteSettingsCounterTest::Callback, base::Unretained(this)));
-
   SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_HOUR);
   EXPECT_EQ(1, GetResult());
 }
@@ -205,16 +196,11 @@
   zoom_map()->SetZoomLevelForHost("google.com", 1.5);
   zoom_map()->SetZoomLevelForHost("www.google.com", 1.5);
 
-  browsing_data::SiteSettingsCounter counter(map(), zoom_map());
-  counter.Init(
-      profile()->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
-      base::Bind(&SiteSettingsCounterTest::Callback, base::Unretained(this)));
-  counter.Restart();
-
+  counter()->Restart();
   EXPECT_EQ(2, GetResult());
 }
 
-TEST_F(SiteSettingsCounterTest, ZoomAndContentSettingCounting) {
+TEST_F(SiteSettingsCounterTest, ZoomAndContentSettingAndHandlers) {
   zoom_map()->SetZoomLevelForHost("google.com", 1.5);
   zoom_map()->SetZoomLevelForHost("www.google.com", 1.5);
   map()->SetContentSettingDefaultScope(
@@ -223,15 +209,32 @@
   map()->SetContentSettingDefaultScope(
       GURL("https://maps.google.com"), GURL("https://maps.google.com"),
       CONTENT_SETTINGS_TYPE_POPUPS, std::string(), CONTENT_SETTING_ALLOW);
+  base::Time now = base::Time::Now();
+  handler_registry()->OnAcceptRegisterProtocolHandler(
+      ProtocolHandler("test1", GURL("http://www.google.com"), now));
+  handler_registry()->OnAcceptRegisterProtocolHandler(
+      ProtocolHandler("test1", GURL("http://docs.google.com"), now));
 
-  browsing_data::SiteSettingsCounter counter(map(), zoom_map());
-  counter.Init(
-      profile()->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
-      base::Bind(&SiteSettingsCounterTest::Callback, base::Unretained(this)));
-  counter.Restart();
-
-  EXPECT_EQ(3, GetResult());
+  counter()->Restart();
+  EXPECT_EQ(4, GetResult());
 }
 #endif
 
+TEST_F(SiteSettingsCounterTest, ProtocolHandlerCounting) {
+  base::Time now = base::Time::Now();
+
+  handler_registry()->OnAcceptRegisterProtocolHandler(
+      ProtocolHandler("test1", GURL("http://www.google.com"), now));
+  handler_registry()->OnAcceptRegisterProtocolHandler(
+      ProtocolHandler("test2", GURL("http://maps.google.com"),
+                      now - base::TimeDelta::FromMinutes(90)));
+  EXPECT_TRUE(handler_registry()->IsHandledProtocol("test1"));
+  EXPECT_TRUE(handler_registry()->IsHandledProtocol("test2"));
+
+  SetDeletionPeriodPref(browsing_data::TimePeriod::ALL_TIME);
+  EXPECT_EQ(2, GetResult());
+  SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_HOUR);
+  EXPECT_EQ(1, GetResult());
+}
+
 }  // namespace
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 1af3f61..39685ae 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1235,12 +1235,8 @@
 
 #endif
 #if BUILDFLAG(ENABLE_NACL)
-  net::URLRequestContextGetter* context =
-      host->GetStoragePartition()->GetURLRequestContext();
-  host->AddFilter(new nacl::NaClHostMessageFilter(
-      id, profile->IsOffTheRecord(),
-      profile->GetPath(),
-      context));
+  host->AddFilter(new nacl::NaClHostMessageFilter(id, profile->IsOffTheRecord(),
+                                                  profile->GetPath()));
 #endif
 
   bool is_incognito_process = profile->IsOffTheRecord();
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
index 8c3a7afc9..ce8510a7 100644
--- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc
+++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -237,6 +237,9 @@
                       bundle.GetRawDataResource(IDR_SOUND_DICTATION_END_WAV));
   manager->Initialize(SOUND_DICTATION_START,
                       bundle.GetRawDataResource(IDR_SOUND_DICTATION_START_WAV));
+  manager->Initialize(
+      SOUND_DICTATION_CANCEL,
+      bundle.GetRawDataResource(IDR_SOUND_DICTATION_CANCEL_WAV));
 
   base::FilePath resources_path;
   if (!PathService::Get(chrome::DIR_RESOURCES, &resources_path))
diff --git a/chrome/browser/chromeos/accessibility/dictation_chromeos.cc b/chrome/browser/chromeos/accessibility/dictation_chromeos.cc
index 451ac8d..5ad80fc 100644
--- a/chrome/browser/chromeos/accessibility/dictation_chromeos.cc
+++ b/chrome/browser/chromeos/accessibility/dictation_chromeos.cc
@@ -35,7 +35,7 @@
 
 bool DictationChromeos::OnToggleDictation() {
   if (speech_recognizer_) {
-    media::SoundsManager::Get()->Play(chromeos::SOUND_DICTATION_END);
+    media::SoundsManager::Get()->Play(chromeos::SOUND_DICTATION_CANCEL);
     speech_recognizer_.reset();
     return false;
   }
@@ -57,6 +57,7 @@
   if (input_context)
     input_context->CommitText(base::UTF16ToASCII(query));
 
+  media::SoundsManager::Get()->Play(chromeos::SOUND_DICTATION_END);
   chromeos::AccessibilityStatusEventDetails details(
       chromeos::AccessibilityNotificationType::ACCESSIBILITY_TOGGLE_DICTATION,
       /*enabled=*/false);
diff --git a/chrome/browser/chromeos/arc/app_shortcuts/arc_app_shortcuts_request.cc b/chrome/browser/chromeos/arc/app_shortcuts/arc_app_shortcuts_request.cc
index c4ac25ad..823c122c 100644
--- a/chrome/browser/chromeos/arc/app_shortcuts/arc_app_shortcuts_request.cc
+++ b/chrome/browser/chromeos/arc/app_shortcuts/arc_app_shortcuts_request.cc
@@ -50,13 +50,13 @@
 
 void ArcAppShortcutsRequest::OnGetAppShortcutItems(
     std::vector<mojom::AppShortcutItemPtr> shortcut_items) {
+  items_ = std::make_unique<ArcAppShortcutItems>();
   // Using base::Unretained(this) here is safe since we own barrier_closure_.
   barrier_closure_ = base::BarrierClosure(
       shortcut_items.size(),
       base::BindOnce(&ArcAppShortcutsRequest::OnAllIconDecodeRequestsDone,
                      base::Unretained(this)));
 
-  items_ = std::make_unique<ArcAppShortcutItems>();
   const views::MenuConfig& menu_config = views::MenuConfig::instance();
   for (const auto& shortcut_item_ptr : shortcut_items) {
     ArcAppShortcutItem item;
diff --git a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc
index 6ee2bf3..d81117f 100644
--- a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc
+++ b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/notifications/notification_display_service.h"
 #include "chrome/browser/notifications/notification_display_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/common/pref_names.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/theme_resources.h"
@@ -71,10 +72,25 @@
   }
 }
 
+// Put canonicalization settings first depending on user policy. Whatever
+// setting comes first wins, so even if krb5.conf sets rdns or
+// dns_canonicalize_hostname below, it would get overridden.
+std::string AdjustConfig(const std::string& config, bool is_dns_cname_enabled) {
+  std::string adjusted_config = base::StringPrintf(
+      chromeos::kKrb5CnameSettings, is_dns_cname_enabled ? "true" : "false");
+  adjusted_config.append(config);
+  return adjusted_config;
+}
+
 }  // namespace
 
 namespace chromeos {
 
+const char* kKrb5CnameSettings =
+    "[libdefaults]\n"
+    "\tdns_canonicalize_hostname = %s\n"
+    "\trdns = false\n";
+
 AuthPolicyCredentialsManager::AuthPolicyCredentialsManager(Profile* profile)
     : profile_(profile) {
   const user_manager::User* user =
@@ -94,6 +110,12 @@
               kKrb5CCFilePrefix + path.Append(kKrb5CCFile).value());
   env->SetVar(kKrb5ConfEnvName, path.Append(kKrb5ConfFile).value());
 
+  negotiate_disable_cname_lookup_.Init(
+      prefs::kDisableAuthNegotiateCnameLookup, g_browser_process->local_state(),
+      base::BindRepeating(&AuthPolicyCredentialsManager::
+                              OnDisabledAuthNegotiateCnameLookupChanged,
+                          weak_factory_.GetWeakPtr()));
+
   // Connecting to the signal sent by authpolicyd notifying that Kerberos files
   // have changed.
   chromeos::DBusThreadManager::Get()->GetAuthPolicyClient()->ConnectToSignal(
@@ -220,7 +242,10 @@
         FROM_HERE,
         {base::MayBlock(), base::TaskPriority::BACKGROUND,
          base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
-        base::BindOnce(&WriteFile, kKrb5ConfFile, kerberos_files.krb5conf()));
+        base::BindOnce(
+            &WriteFile, kKrb5ConfFile,
+            AdjustConfig(kerberos_files.krb5conf(),
+                         !negotiate_disable_cname_lookup_.GetValue())));
   }
 }
 
@@ -339,6 +364,10 @@
   DCHECK(success);
 }
 
+void AuthPolicyCredentialsManager::OnDisabledAuthNegotiateCnameLookupChanged() {
+  GetUserKerberosFiles();
+}
+
 // static
 AuthPolicyCredentialsManagerFactory*
 AuthPolicyCredentialsManagerFactory::GetInstance() {
diff --git a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.h b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.h
index 4f58921..7297148 100644
--- a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.h
+++ b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.h
@@ -14,6 +14,7 @@
 #include "components/account_id/account_id.h"
 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
 #include "components/keyed_service/core/keyed_service.h"
+#include "components/prefs/pref_member.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 class Profile;
@@ -33,6 +34,11 @@
 
 namespace chromeos {
 
+// Kerberos defaults for canonicalization SPN. (see
+// https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html)
+// Exported for browsertests.
+extern const char* kKrb5CnameSettings;
+
 // A service responsible for tracking user credential status. Created for each
 // Active Directory user profile.
 class AuthPolicyCredentialsManager
@@ -96,6 +102,9 @@
                                  const std::string& signal_name,
                                  bool success);
 
+  // Called whenever prefs::kDisableAuthNegotiateCnameLookup is changed.
+  void OnDisabledAuthNegotiateCnameLookupChanged();
+
   Profile* const profile_;
   AccountId account_id_;
   std::string display_name_;
@@ -109,6 +118,7 @@
   std::set<int> shown_notifications_;
   authpolicy::ErrorType last_error_ = authpolicy::ERROR_NONE;
   base::CancelableClosure scheduled_get_user_status_call_;
+  PrefMember<bool> negotiate_disable_cname_lookup_;
 
   base::WeakPtrFactory<AuthPolicyCredentialsManager> weak_factory_{this};
   DISALLOW_COPY_AND_ASSIGN(AuthPolicyCredentialsManager);
diff --git a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager_unittest.cc b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager_unittest.cc
index d3b509e..3fef6ab 100644
--- a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager_unittest.cc
+++ b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager_unittest.cc
@@ -13,6 +13,8 @@
 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
 #include "chrome/browser/notifications/notification_display_service_tester.h"
 #include "chrome/grit/generated_resources.h"
+#include "chrome/test/base/scoped_testing_local_state.h"
+#include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/fake_auth_policy_client.h"
@@ -42,7 +44,8 @@
 class AuthPolicyCredentialsManagerTest : public testing::Test {
  public:
   AuthPolicyCredentialsManagerTest()
-      : user_manager_enabler_(std::make_unique<MockUserManager>()) {}
+      : user_manager_enabler_(std::make_unique<MockUserManager>()),
+        local_state_(TestingBrowserProcess::GetGlobal()) {}
   ~AuthPolicyCredentialsManagerTest() override = default;
 
   void SetUp() override {
@@ -76,6 +79,7 @@
 
   void TearDown() override {
     EXPECT_CALL(*mock_user_manager(), Shutdown());
+    profile_.reset();
     chromeos::NetworkHandler::Shutdown();
     chromeos::DBusThreadManager::Shutdown();
   }
@@ -129,6 +133,8 @@
 
   std::unique_ptr<NotificationDisplayServiceTester> display_service_;
 
+  ScopedTestingLocalState local_state_;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(AuthPolicyCredentialsManagerTest);
 };
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index d28376a..522f81fc 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -585,8 +585,12 @@
   }
   if (user_context.GetAccountId().GetAccountType() ==
           AccountType::ACTIVE_DIRECTORY &&
-      user_context.GetAuthFlow() == UserContext::AUTH_FLOW_OFFLINE) {
-    DCHECK(user_context.GetKey()->GetKeyType() == Key::KEY_TYPE_PASSWORD_PLAIN);
+      user_context.GetAuthFlow() == UserContext::AUTH_FLOW_OFFLINE &&
+      user_context.GetKey()->GetKeyType() == Key::KEY_TYPE_PASSWORD_PLAIN) {
+    // Skip TryAuthenticateUser() below when password is hashed. Views-based
+    // login sends hashed password back and TryAuthenticateUser() is called
+    // there before it sends back the hashed password
+
     // Try to get kerberos TGT while we have user's password typed on the pod
     // screen. Failure to get TGT here is OK - that could mean e.g. Active
     // Directory server is not reachable. We don't want to have user wait for
diff --git a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
index 2852fc2..080e5f8 100644
--- a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
@@ -5,16 +5,19 @@
 #include <string>
 #include <vector>
 
+#include "base/barrier_closure.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/callback.h"
 #include "base/command_line.h"
+#include "base/files/file_path_watcher.h"
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/run_loop.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/help_app_launcher.h"
 #include "chrome/browser/chromeos/login/helper.h"
@@ -50,6 +53,8 @@
 #include "components/policy/core/common/cloud/cloud_policy_store.h"
 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
 #include "components/policy/core/common/cloud/policy_builder.h"
+#include "components/policy/core/common/mock_configuration_policy_provider.h"
+#include "components/policy/policy_constants.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
 #include "components/policy/proto/device_management_backend.pb.h"
 #include "components/prefs/pref_service.h"
@@ -85,6 +90,7 @@
 const char kSupervisedUserID[] = "supervised_user@locally-managed.localhost";
 const char kPassword[] = "test_password";
 const char kActiveDirectoryRealm[] = "active.directory.realm";
+const char kKrb5CCFilePrefix[] = "FILE:";
 
 const char kPublicSessionUserEmail[] = "public_session_user@localhost";
 const int kAutoLoginNoDelay = 0;
@@ -755,9 +761,14 @@
   // Overriden from ExistingUserControllerTest:
   void SetUpInProcessBrowserTestFixture() override {
     ExistingUserControllerTest::SetUpInProcessBrowserTestFixture();
+    fake_authpolicy_client()->DisableOperationDelayForTesting();
     ASSERT_TRUE(AuthPolicyLoginHelper::LockDeviceActiveDirectoryForTesting(
         kActiveDirectoryRealm));
     RefreshDevicePolicy();
+    EXPECT_CALL(policy_provider_, IsInitializationComplete(_))
+        .WillRepeatedly(Return(true));
+    policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
+        &policy_provider_);
   }
 
   void TearDownOnMainThread() override {
@@ -766,6 +777,15 @@
   }
 
  protected:
+  chromeos::FakeAuthPolicyClient* fake_authpolicy_client() {
+    return static_cast<chromeos::FakeAuthPolicyClient*>(
+        chromeos::DBusThreadManager::Get()->GetAuthPolicyClient());
+  }
+
+  void UpdateProviderPolicy(const policy::PolicyMap& policy) {
+    policy_provider_.UpdateChromePolicy(policy);
+  }
+
   void ExpectLoginFailure() {
     EXPECT_CALL(*mock_login_display_, SetUIEnabled(false)).Times(2);
     EXPECT_CALL(*mock_login_display_,
@@ -785,6 +805,77 @@
     EXPECT_CALL(*mock_login_display_, SetUIEnabled(false)).Times(2);
     EXPECT_CALL(*mock_login_display_, SetUIEnabled(true)).Times(1);
   }
+
+  std::string GetExpectedKerberosConfig(bool enable_dns_cname_lookup) {
+    std::string config(base::StringPrintf(
+        kKrb5CnameSettings, enable_dns_cname_lookup ? "true" : "false"));
+    config += "configuration";
+    return config;
+  }
+
+  std::string GetKerberosConfigFileName() {
+    std::unique_ptr<base::Environment> env(base::Environment::Create());
+    std::string config_file;
+    EXPECT_TRUE(env->GetVar("KRB5_CONFIG", &config_file));
+    return config_file;
+  }
+
+  std::string GetKerberosCredentialsCacheFileName() {
+    std::unique_ptr<base::Environment> env(base::Environment::Create());
+    std::string creds_file;
+    EXPECT_TRUE(env->GetVar("KRB5CCNAME", &creds_file));
+    EXPECT_EQ(kKrb5CCFilePrefix,
+              creds_file.substr(0, strlen(kKrb5CCFilePrefix)));
+    return creds_file.substr(strlen(kKrb5CCFilePrefix));
+  }
+
+  void CheckKerberosFiles(bool enable_dns_cname_lookup) {
+    std::string file_contents;
+    EXPECT_TRUE(base::ReadFileToString(
+        base::FilePath(GetKerberosConfigFileName()), &file_contents));
+    EXPECT_EQ(GetExpectedKerberosConfig(enable_dns_cname_lookup),
+              file_contents);
+
+    EXPECT_TRUE(base::ReadFileToString(
+        base::FilePath(GetKerberosCredentialsCacheFileName()), &file_contents));
+    EXPECT_EQ(file_contents, "credentials");
+  }
+
+  // Applies policy and waits until both config and credentials files changed.
+  void ApplyPolicyAndWaitFilesChanged(bool enable_dns_cname_lookup) {
+    base::RunLoop loop;
+    base::RepeatingClosure barrier_closure(
+        base::BarrierClosure(2, loop.QuitClosure()));
+
+    auto watch_callback = base::BindRepeating(
+        [](const base::RepeatingClosure& barrier_closure,
+           const base::FilePath& path, bool error) -> void {
+          LOG(ERROR) << "Changed " << path.value();
+          EXPECT_FALSE(error);
+          barrier_closure.Run();
+        },
+        barrier_closure);
+
+    base::FilePathWatcher config_watcher;
+    config_watcher.Watch(base::FilePath(GetKerberosConfigFileName()),
+                         false /* recursive */, watch_callback);
+
+    base::FilePathWatcher creds_watcher;
+    creds_watcher.Watch(base::FilePath(GetKerberosCredentialsCacheFileName()),
+                        false /* recursive */, watch_callback);
+
+    policy::PolicyMap policies;
+    policies.Set(policy::key::kDisableAuthNegotiateCnameLookup,
+                 policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
+                 policy::POLICY_SOURCE_CLOUD,
+                 std::make_unique<base::Value>(!enable_dns_cname_lookup),
+                 nullptr);
+    UpdateProviderPolicy(policies);
+    loop.Run();
+  }
+
+ private:
+  policy::MockConfigurationPolicyProvider policy_provider_;
 };
 
 class ExistingUserControllerActiveDirectoryUserWhitelistTest
@@ -795,13 +886,10 @@
   void SetUpInProcessBrowserTestFixture() override {
     ExistingUserControllerActiveDirectoryTest::
         SetUpInProcessBrowserTestFixture();
-    chromeos::FakeAuthPolicyClient* fake_authpolicy_client =
-        static_cast<chromeos::FakeAuthPolicyClient*>(
-            chromeos::DBusThreadManager::Get()->GetAuthPolicyClient());
     em::ChromeDeviceSettingsProto device_policy;
     device_policy.mutable_user_whitelist()->add_user_whitelist()->assign(
         kUserWhitelist);
-    fake_authpolicy_client->set_device_policy(device_policy);
+    fake_authpolicy_client()->set_device_policy(device_policy);
   }
 
   void SetUpLoginDisplay() override {
@@ -833,6 +921,32 @@
   existing_user_controller()->CompleteLogin(user_context);
 
   profile_prepared_observer.Wait();
+  CheckKerberosFiles(true /* enable_dns_cname_lookup */);
+}
+
+// Tests if DisabledAuthNegotiateCnameLookup changes trigger updating user
+// Kerberos files.
+IN_PROC_BROWSER_TEST_F(ExistingUserControllerActiveDirectoryTest,
+                       PolicyChangeTriggersFileUpdate) {
+  ExpectLoginSuccess();
+  UserContext user_context(ad_account_id_);
+  user_context.SetKey(Key(kPassword));
+  user_context.SetUserIDHash(ad_account_id_.GetUserEmail());
+  user_context.SetAuthFlow(UserContext::AUTH_FLOW_ACTIVE_DIRECTORY);
+  user_context.SetUserType(user_manager::UserType::USER_TYPE_ACTIVE_DIRECTORY);
+  content::WindowedNotificationObserver profile_prepared_observer(
+      chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
+      content::NotificationService::AllSources());
+  existing_user_controller()->CompleteLogin(user_context);
+
+  profile_prepared_observer.Wait();
+  CheckKerberosFiles(true /* enable_dns_cname_lookup */);
+
+  ApplyPolicyAndWaitFilesChanged(false /* enable_dns_cname_lookup */);
+  CheckKerberosFiles(false /* enable_dns_cname_lookup */);
+
+  ApplyPolicyAndWaitFilesChanged(true /* enable_dns_cname_lookup */);
+  CheckKerberosFiles(true /* enable_dns_cname_lookup */);
 }
 
 // Tests that Active Directory offline login succeeds on the Active Directory
@@ -844,12 +958,14 @@
   user_context.SetKey(Key(kPassword));
   user_context.SetUserIDHash(ad_account_id_.GetUserEmail());
   user_context.SetUserType(user_manager::UserType::USER_TYPE_ACTIVE_DIRECTORY);
+
   content::WindowedNotificationObserver profile_prepared_observer(
       chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
       content::NotificationService::AllSources());
   existing_user_controller()->Login(user_context, SigninSpecifics());
 
   profile_prepared_observer.Wait();
+  CheckKerberosFiles(true /* enable_dns_cname_lookup */);
 }
 
 // Tests that Gaia login fails on the Active Directory managed device.
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc
index c691e70..571e5ae 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -454,6 +454,41 @@
 }
 
 ProtocolHandlerRegistry::ProtocolHandlerList
+ProtocolHandlerRegistry::GetUserDefinedHandlers(base::Time begin,
+                                                base::Time end) const {
+  ProtocolHandlerRegistry::ProtocolHandlerList result;
+  for (const auto& entry : user_protocol_handlers_) {
+    for (const ProtocolHandler& handler : entry.second) {
+      if (base::ContainsValue(predefined_protocol_handlers_, handler))
+        continue;
+      if (begin <= handler.last_modified() && handler.last_modified() < end)
+        result.push_back(handler);
+    }
+  }
+  return result;
+}
+
+ProtocolHandlerRegistry::ProtocolHandlerList
+ProtocolHandlerRegistry::GetUserIgnoredHandlers(base::Time begin,
+                                                base::Time end) const {
+  ProtocolHandlerRegistry::ProtocolHandlerList result;
+  for (const ProtocolHandler& handler : user_ignored_protocol_handlers_) {
+    if (begin <= handler.last_modified() && handler.last_modified() < end)
+      result.push_back(handler);
+  }
+  return result;
+}
+
+void ProtocolHandlerRegistry::ClearUserDefinedHandlers(base::Time begin,
+                                                       base::Time end) {
+  for (const ProtocolHandler& handler : GetUserDefinedHandlers(begin, end))
+    RemoveHandler(handler);
+
+  for (const ProtocolHandler& handler : GetUserIgnoredHandlers(begin, end))
+    RemoveIgnoredHandler(handler);
+}
+
+ProtocolHandlerRegistry::ProtocolHandlerList
 ProtocolHandlerRegistry::GetIgnoredHandlers() {
   return ignored_protocol_handlers_;
 }
@@ -906,6 +941,7 @@
   DCHECK(!is_loaded_);  // Must be called prior InitProtocolSettings.
   RegisterProtocolHandler(handler, USER);
   SetDefault(handler);
+  predefined_protocol_handlers_.push_back(handler);
 }
 
 shell_integration::DefaultWebClientWorkerCallback
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.h b/chrome/browser/custom_handlers/protocol_handler_registry.h
index 9260830..378f092 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.h
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.h
@@ -159,6 +159,15 @@
   // Get the list of protocol handlers for the given scheme.
   ProtocolHandlerList GetHandlersFor(const std::string& scheme) const;
 
+  // Get a list of protocol handlers registered in [begin, end).
+  // Does not include predefined or policy installed handlers.
+  ProtocolHandlerList GetUserDefinedHandlers(base::Time begin,
+                                             base::Time end) const;
+
+  // Clear all protocol handlers registered in [begin, end).
+  // Does not delete predefined or policy installed handlers.
+  void ClearUserDefinedHandlers(base::Time begin, base::Time end);
+
   // Get the list of ignored protocol handlers.
   ProtocolHandlerList GetIgnoredHandlers();
 
@@ -283,6 +292,16 @@
   void RegisterProtocolHandlersFromPref(const char* pref_name,
                                         const HandlerSource source);
 
+  // Get all handlers with a timestamp in [begin,end) from |handlers|.
+  ProtocolHandlerList GetHandlersBetween(
+      const ProtocolHandlerMultiMap& handlers,
+      base::Time begin,
+      base::Time end) const;
+
+  // Get all ignored handlers with a timestamp in [begin,end).
+  ProtocolHandlerList GetUserIgnoredHandlers(base::Time begin,
+                                             base::Time end) const;
+
   // Get the DictionaryValues stored under the given pref name that are valid
   // ProtocolHandler values.
   std::vector<const base::DictionaryValue*> GetHandlersFromPref(
@@ -337,6 +356,9 @@
   ProtocolHandlerList user_ignored_protocol_handlers_;
   ProtocolHandlerList policy_ignored_protocol_handlers_;
 
+  // A list of handlers that were preinstalled.
+  ProtocolHandlerList predefined_protocol_handlers_;
+
   // Protocol handlers that are the defaults for a given protocol.
   ProtocolHandlerMap default_handlers_;
 
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
index affce75..500e719 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
@@ -391,6 +391,82 @@
   ASSERT_TRUE(registry()->IsIgnored(stuff_protocol_handler));
 }
 
+TEST_F(ProtocolHandlerRegistryTest, Encode) {
+  base::Time now = base::Time::Now();
+  ProtocolHandler handler("test", GURL("http://example.com"), now);
+  auto value = handler.Encode();
+  ProtocolHandler recreated =
+      ProtocolHandler::CreateProtocolHandler(value.get());
+  EXPECT_EQ("test", recreated.protocol());
+  EXPECT_EQ(GURL("http://example.com"), recreated.url());
+  EXPECT_EQ(now, recreated.last_modified());
+}
+
+TEST_F(ProtocolHandlerRegistryTest, GetHandlersBetween) {
+  base::Time now = base::Time::Now();
+  base::Time one_hour_ago = now - base::TimeDelta::FromHours(1);
+  base::Time two_hours_ago = now - base::TimeDelta::FromHours(2);
+  ProtocolHandler handler1("test1", GURL("http://example.com"), two_hours_ago);
+  ProtocolHandler handler2("test2", GURL("http://example.com"), one_hour_ago);
+  ProtocolHandler handler3("test3", GURL("http://example.com"), now);
+  registry()->OnAcceptRegisterProtocolHandler(handler1);
+  registry()->OnAcceptRegisterProtocolHandler(handler2);
+  registry()->OnAcceptRegisterProtocolHandler(handler3);
+
+  EXPECT_EQ(
+      std::vector<ProtocolHandler>({handler1, handler2, handler3}),
+      registry()->GetUserDefinedHandlers(base::Time(), base::Time::Max()));
+  EXPECT_EQ(
+      std::vector<ProtocolHandler>({handler2, handler3}),
+      registry()->GetUserDefinedHandlers(one_hour_ago, base::Time::Max()));
+  EXPECT_EQ(std::vector<ProtocolHandler>({handler1, handler2}),
+            registry()->GetUserDefinedHandlers(base::Time(), now));
+}
+
+TEST_F(ProtocolHandlerRegistryTest, ClearHandlersBetween) {
+  base::Time now = base::Time::Now();
+  base::Time one_hour_ago = now - base::TimeDelta::FromHours(1);
+  base::Time two_hours_ago = now - base::TimeDelta::FromHours(2);
+  GURL url("http://example.com");
+  ProtocolHandler handler1("test1", url, two_hours_ago);
+  ProtocolHandler handler2("test2", url, one_hour_ago);
+  ProtocolHandler handler3("test3", url, now);
+  ProtocolHandler ignored1("ignored1", url, two_hours_ago);
+  ProtocolHandler ignored2("ignored2", url, one_hour_ago);
+  ProtocolHandler ignored3("ignored3", url, now);
+  registry()->OnAcceptRegisterProtocolHandler(handler1);
+  registry()->OnAcceptRegisterProtocolHandler(handler2);
+  registry()->OnAcceptRegisterProtocolHandler(handler3);
+  registry()->OnIgnoreRegisterProtocolHandler(ignored1);
+  registry()->OnIgnoreRegisterProtocolHandler(ignored2);
+  registry()->OnIgnoreRegisterProtocolHandler(ignored3);
+
+  EXPECT_TRUE(registry()->IsHandledProtocol("test1"));
+  EXPECT_TRUE(registry()->IsHandledProtocol("test2"));
+  EXPECT_TRUE(registry()->IsHandledProtocol("test3"));
+  EXPECT_TRUE(registry()->IsIgnored(ignored1));
+  EXPECT_TRUE(registry()->IsIgnored(ignored2));
+  EXPECT_TRUE(registry()->IsIgnored(ignored3));
+
+  // Delete handler2 and ignored2.
+  registry()->ClearUserDefinedHandlers(one_hour_ago, now);
+  EXPECT_TRUE(registry()->IsHandledProtocol("test1"));
+  EXPECT_FALSE(registry()->IsHandledProtocol("test2"));
+  EXPECT_TRUE(registry()->IsHandledProtocol("test3"));
+  EXPECT_TRUE(registry()->IsIgnored(ignored1));
+  EXPECT_FALSE(registry()->IsIgnored(ignored2));
+  EXPECT_TRUE(registry()->IsIgnored(ignored3));
+
+  // Delete all.
+  registry()->ClearUserDefinedHandlers(base::Time(), base::Time::Max());
+  EXPECT_FALSE(registry()->IsHandledProtocol("test1"));
+  EXPECT_FALSE(registry()->IsHandledProtocol("test2"));
+  EXPECT_FALSE(registry()->IsHandledProtocol("test3"));
+  EXPECT_FALSE(registry()->IsIgnored(ignored1));
+  EXPECT_FALSE(registry()->IsIgnored(ignored2));
+  EXPECT_FALSE(registry()->IsIgnored(ignored3));
+}
+
 TEST_F(ProtocolHandlerRegistryTest, TestEnabledDisabled) {
   registry()->Disable();
   ASSERT_FALSE(registry()->enabled());
@@ -838,6 +914,12 @@
   std::vector<std::string> protocols;
   registry()->GetRegisteredProtocols(&protocols);
   ASSERT_EQ(static_cast<size_t>(1), protocols.size());
+  EXPECT_TRUE(registry()->IsHandledProtocol("test"));
+  auto handlers =
+      registry()->GetUserDefinedHandlers(base::Time(), base::Time::Max());
+  EXPECT_TRUE(handlers.empty());
+  registry()->ClearUserDefinedHandlers(base::Time(), base::Time::Max());
+  EXPECT_TRUE(registry()->IsHandledProtocol("test"));
 }
 
 #define URL_p1u1 "http://p1u1.com/%s"
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 b8f4028..13840d1 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
@@ -31,6 +31,7 @@
 #include "components/proxy_config/proxy_config_pref_names.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/notification_source.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_utils.h"
@@ -43,12 +44,13 @@
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/extension_util.h"
+#include "extensions/browser/notification_types.h"
+#include "extensions/browser/runtime_data.h"
 #include "extensions/common/api/declarative_net_request/constants.h"
 #include "extensions/common/api/declarative_net_request/test_utils.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/extension_id.h"
 #include "extensions/common/url_pattern.h"
-#include "extensions/test/extension_test_message_listener.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
 #include "net/test/test_data_directory.h"
@@ -129,9 +131,6 @@
     host_resolver()->AddRule("*", "127.0.0.1");
 
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-    background_page_ready_listener_ =
-        std::make_unique<ExtensionTestMessageListener>("ready",
-                                                       false /*will_reply*/);
   }
 
  protected:
@@ -185,7 +184,6 @@
                             kJSONRulesFilename, rules, hosts,
                             has_background_script_);
 
-    background_page_ready_listener_->Reset();
     const Extension* extension = nullptr;
     switch (GetParam()) {
       case ExtensionLoadType::PACKED:
@@ -203,10 +201,6 @@
     // Ensure the ruleset is also loaded on the IO thread.
     content::RunAllTasksUntilIdle();
 
-    // Wait for the background page to load if needed.
-    if (has_background_script_)
-      WaitForBackgroundScriptToLoad(extension->id());
-
     // Ensure no load errors were reported.
     EXPECT_TRUE(LoadErrorReporter::GetInstance()->GetErrors()->empty());
 
@@ -226,16 +220,9 @@
                            {URLPattern::kAllUrlsPattern});
   }
 
-  void WaitForBackgroundScriptToLoad(const ExtensionId& extension_id) {
-    ASSERT_TRUE(background_page_ready_listener_->WaitUntilSatisfied());
-    ASSERT_EQ(extension_id,
-              background_page_ready_listener_->extension_id_for_message());
-  }
-
  private:
   base::ScopedTempDir temp_dir_;
   bool has_background_script_ = false;
-  std::unique_ptr<ExtensionTestMessageListener> background_page_ready_listener_;
 
   DISALLOW_COPY_AND_ASSIGN(DeclarativeNetRequestBrowserTest);
 };
@@ -1150,6 +1137,15 @@
   ASSERT_TRUE(dnr_extension);
   EXPECT_EQ("Test extension", dnr_extension->name());
 
+  // Ensure the background page is ready before dispatching the script to it.
+  if (!ExtensionSystem::Get(profile())->runtime_data()->IsBackgroundPageReady(
+          dnr_extension)) {
+    content::WindowedNotificationObserver(
+        NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY,
+        content::Source<Extension>(dnr_extension))
+        .Wait();
+  }
+
   // Whitelist "https://www.google.com/".
   const char* script1 = R"(
     chrome.declarativeNetRequest.addWhitelistedPages(
@@ -1195,7 +1191,13 @@
   ASSERT_TRUE(dnr_extension);
 
   // Ensure the background page is ready before dispatching the script to it.
-  WaitForBackgroundScriptToLoad(dnr_extension->id());
+  if (!ExtensionSystem::Get(profile())->runtime_data()->IsBackgroundPageReady(
+          dnr_extension)) {
+    content::WindowedNotificationObserver(
+        NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY,
+        content::Source<Extension>(dnr_extension))
+        .Wait();
+  }
 
   const char* script1 = R"(
     chrome.declarativeNetRequest.getWhitelistedPages(function(patterns) {
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc
index 5d9b995..2ed573f 100644
--- a/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc
+++ b/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc
@@ -196,7 +196,7 @@
       base::BindOnce(
           &PasswordsPrivateExportPasswordsFunction::ExportRequestCompleted,
           this),
-      GetAssociatedWebContentsDeprecated());
+      GetSenderWebContents());
   return RespondLater();
 }
 
diff --git a/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc b/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc
index 8a69866..6fbb881 100644
--- a/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc
+++ b/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc
@@ -1359,12 +1359,21 @@
   controller.reset();
 }
 
+// Fails on linux-chromeos-rel: crbug.com/839371
+#if defined(OS_CHROMEOS)
+#define MAYBE_TestUninstallExtensionAfterBrowserDestroyed \
+  DISABLED_TestUninstallExtensionAfterBrowserDestroyed
+#else
+#define MAYBE_TestUninstallExtensionAfterBrowserDestroyed \
+  TestUninstallExtensionAfterBrowserDestroyed
+#endif  // defined(OS_CHROMEOS)
+
 // Tests that when an extension -- associated with a bubble controller -- is
 // uninstalling after the browser is destroyed, the controller does not access
 // the associated browser object and therefore, no use-after-free occurs.
 // crbug.com/756316
 TEST_F(ExtensionMessageBubbleTest,
-       TestUninstallExtensionAfterBrowserDestroyed) {
+       MAYBE_TestUninstallExtensionAfterBrowserDestroyed) {
   FeatureSwitch::ScopedOverride force_dev_mode_highlighting(
       FeatureSwitch::force_dev_mode_highlighting(), true);
   Init();
diff --git a/chrome/browser/extensions/updater/update_service_browsertest.cc b/chrome/browser/extensions/updater/update_service_browsertest.cc
index ab575a7..f29d1ab 100644
--- a/chrome/browser/extensions/updater/update_service_browsertest.cc
+++ b/chrome/browser/extensions/updater/update_service_browsertest.cc
@@ -221,6 +221,42 @@
                                   disable_reason::DISABLE_CORRUPTED)));
 }
 
+IN_PROC_BROWSER_TEST_F(UpdateServiceTest, UninstallExtensionWhileUpdating) {
+  // This test is to verify that the extension updater engine (update client)
+  // works correctly when an extension is uninstalled when the extension updater
+  // is in progress.
+  base::ScopedAllowBlockingForTesting allow_io;
+
+  const base::FilePath crx_path = test_data_dir_.AppendASCII("updater/v1.crx");
+
+  const Extension* extension =
+      InstallExtension(crx_path, 1, Manifest::EXTERNAL_POLICY_DOWNLOAD);
+  ASSERT_TRUE(extension);
+  EXPECT_EQ(kExtensionId, extension->id());
+
+  base::RunLoop run_loop;
+
+  extensions::ExtensionUpdater::CheckParams params;
+  params.ids = {kExtensionId};
+  params.callback = run_loop.QuitClosure();
+  extension_service()->updater()->CheckNow(std::move(params));
+
+  // Uninstall the extension right before the message loop is executed to
+  // emulate uninstalling an extension in the middle of an extension update.
+  extension_service()->UninstallExtension(
+      kExtensionId, extensions::UNINSTALL_REASON_COMPONENT_REMOVED, nullptr);
+
+  // Update client should issue an update error event for this extension.
+  ASSERT_EQ(UpdateClientEvents::COMPONENT_UPDATE_ERROR,
+            WaitOnComponentUpdaterCompleteEvent(kExtensionId));
+
+  run_loop.Run();
+
+  EXPECT_EQ(0, update_interceptor_->GetCount())
+      << update_interceptor_->GetRequestsAsString();
+  EXPECT_EQ(0, get_interceptor_->GetHitCount());
+}
+
 class PolicyUpdateServiceTest : public ExtensionUpdateClientBaseTest {
  public:
   PolicyUpdateServiceTest() {}
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index be7fe83f..11b40d03 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1648,6 +1648,11 @@
     "Refine the position of a touch gesture in order to compensate for touches "
     "having poor resolution compared to a mouse.";
 
+const char kTouchableAppContextMenuName[] = "Touchable App Context Menu";
+const char kTouchableAppContextMenuDescription[] =
+    "Enable the touchable app context menu, which enlarges app context menus "
+    "in the Launcher and Shelf to make room for new features.";
+
 const char kTouchDragDropName[] = "Touch initiated drag and drop";
 const char kTouchDragDropDescription[] =
     "Touch drag and drop can be initiated through long press on a draggable "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 0e27682..9949be4 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1011,6 +1011,9 @@
 extern const char kTouchAdjustmentName[];
 extern const char kTouchAdjustmentDescription[];
 
+extern const char kTouchableAppContextMenuName[];
+extern const char kTouchableAppContextMenuDescription[];
+
 extern const char kTouchDragDropName[];
 extern const char kTouchDragDropDescription[];
 
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 29195217..f6918c5e 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -419,14 +419,6 @@
   ntlm_v2_enabled_.MoveToThread(io_thread_proxy);
 #endif
 
-  quick_check_enabled_.Init(prefs::kQuickCheckEnabled,
-                            local_state);
-  quick_check_enabled_.MoveToThread(io_thread_proxy);
-
-  pac_https_url_stripping_enabled_.Init(prefs::kPacHttpsUrlStrippingEnabled,
-                                        local_state);
-  pac_https_url_stripping_enabled_.MoveToThread(io_thread_proxy);
-
   chrome_browser_net::SetGlobalSTHDistributor(
       std::make_unique<certificate_transparency::STHDistributor>());
 
@@ -624,8 +616,6 @@
   registry->RegisterBooleanPref(prefs::kBuiltInDnsClientEnabled, true);
   registry->RegisterListPref(prefs::kDnsOverHttpsServers);
   registry->RegisterListPref(prefs::kDnsOverHttpsServerMethods);
-  registry->RegisterBooleanPref(prefs::kQuickCheckEnabled, true);
-  registry->RegisterBooleanPref(prefs::kPacHttpsUrlStrippingEnabled, true);
 #if defined(OS_POSIX)
   registry->RegisterBooleanPref(prefs::kNtlmV2Enabled, true);
 #endif
@@ -754,26 +744,12 @@
   chrome_browser_net::GetGlobalSTHDistributor()->UnregisterObserver(observer);
 }
 
-bool IOThread::WpadQuickCheckEnabled() const {
-  return quick_check_enabled_.GetValue();
-}
-
-bool IOThread::PacHttpsUrlStrippingEnabled() const {
-  return pac_https_url_stripping_enabled_.GetValue();
-}
-
 void IOThread::SetUpProxyService(
     network::URLRequestContextBuilderMojo* builder) const {
 #if defined(OS_CHROMEOS)
   builder->SetDhcpFetcherFactory(
       std::make_unique<chromeos::DhcpPacFileFetcherFactoryChromeos>());
 #endif
-
-  builder->set_pac_quick_check_enabled(WpadQuickCheckEnabled());
-  builder->set_pac_sanitize_url_policy(
-      PacHttpsUrlStrippingEnabled()
-          ? net::ProxyResolutionService::SanitizeUrlPolicy::SAFE
-          : net::ProxyResolutionService::SanitizeUrlPolicy::UNSAFE);
 }
 
 certificate_transparency::TreeStateTracker* IOThread::ct_tree_tracker() const {
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h
index f9724e8..b4c7a49 100644
--- a/chrome/browser/io_thread.h
+++ b/chrome/browser/io_thread.h
@@ -199,17 +199,6 @@
   // Un-registers the |observer|.
   void UnregisterSTHObserver(certificate_transparency::STHObserver* observer);
 
-  // Returns true if the indicated proxy resolution features are
-  // enabled. These features are controlled through
-  // preferences/policy/commandline.
-  //
-  // For a description of what these features are, and how they are
-  // configured, see the comments in pref_names.cc for
-  // |kQuickCheckEnabled| and |kPacHttpsUrlStrippingEnabled
-  // respectively.
-  bool WpadQuickCheckEnabled() const;
-  bool PacHttpsUrlStrippingEnabled() const;
-
   // Configures |builder|'s ProxyResolutionService based on prefs and policies.
   void SetUpProxyService(network::URLRequestContextBuilderMojo* builder) const;
 
@@ -275,10 +264,6 @@
 
   BooleanPrefMember dns_client_enabled_;
 
-  BooleanPrefMember quick_check_enabled_;
-
-  BooleanPrefMember pac_https_url_stripping_enabled_;
-
   StringListPrefMember dns_over_https_servers_;
 
   StringListPrefMember dns_over_https_server_methods_;
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc
index 673a21c..627d63f6 100644
--- a/chrome/browser/media/encrypted_media_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -572,7 +572,16 @@
   TestSimplePlayback("bear-320x240-opus-av_enc-v.webm", kWebMOpusAudioVp9Video);
 }
 
-IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Multiple_VideoAudio_WebM) {
+// TODO(xhwang): Test is flaky on Mac. https://crbug.com/835585
+#if defined(MACOS)
+#define MAYBE_Playback_Multiple_VideoAudio_WebM \
+  DISABLED_Playback_Multiple_VideoAudio_WebM
+#else
+#define MAYBE_Playback_Multiple_VideoAudio_WebM \
+  Playback_Multiple_VideoAudio_WebM
+#endif
+IN_PROC_BROWSER_TEST_P(EncryptedMediaTest,
+                       MAYBE_Playback_Multiple_VideoAudio_WebM) {
   if (!IsPlayBackPossible(CurrentKeySystem())) {
     DVLOG(0) << "Skipping test - Playback_Multiple test requires playback.";
     return;
diff --git a/chrome/browser/media/webrtc/webrtc_getmediadevices_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getmediadevices_browsertest.cc
index e4bdbc9..70ba5652 100644
--- a/chrome/browser/media/webrtc/webrtc_getmediadevices_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_getmediadevices_browsertest.cc
@@ -34,9 +34,7 @@
 // It needs to be a browser test (and not content browser test) to be able to
 // test that labels are cleared or not depending on if access to devices has
 // been granted.
-class WebRtcGetMediaDevicesBrowserTest
-    : public WebRtcTestBase,
-      public testing::WithParamInterface<bool> {
+class WebRtcGetMediaDevicesBrowserTest : public WebRtcTestBase {
  public:
   WebRtcGetMediaDevicesBrowserTest()
       : has_audio_output_devices_initialized_(false),
@@ -83,8 +81,7 @@
     bool found_audio_input = false;
     bool found_video_input = false;
 
-    for (base::ListValue::iterator it = values->begin();
-         it != values->end(); ++it) {
+    for (auto it = values->begin(); it != values->end(); ++it) {
       const base::DictionaryValue* dict;
       MediaDeviceInfo device;
       ASSERT_TRUE(it->GetAsDictionary(&dict));
@@ -123,12 +120,7 @@
   bool has_audio_output_devices_;
 };
 
-static const bool kParamsToRunTestsWith[] = { false, true };
-INSTANTIATE_TEST_CASE_P(WebRtcGetMediaDevicesBrowserTests,
-                        WebRtcGetMediaDevicesBrowserTest,
-                        testing::ValuesIn(kParamsToRunTestsWith));
-
-IN_PROC_BROWSER_TEST_P(WebRtcGetMediaDevicesBrowserTest,
+IN_PROC_BROWSER_TEST_F(WebRtcGetMediaDevicesBrowserTest,
                        EnumerateDevicesWithoutAccess) {
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url(embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage));
@@ -140,13 +132,12 @@
   EnumerateDevices(tab, &devices);
 
   // Labels should be empty if access has not been allowed.
-  for (std::vector<MediaDeviceInfo>::iterator it = devices.begin();
-       it != devices.end(); ++it) {
-    EXPECT_TRUE(it->label.empty());
+  for (const auto& device_info : devices) {
+    EXPECT_TRUE(device_info.label.empty());
   }
 }
 
-IN_PROC_BROWSER_TEST_P(WebRtcGetMediaDevicesBrowserTest,
+IN_PROC_BROWSER_TEST_F(WebRtcGetMediaDevicesBrowserTest,
                        EnumerateDevicesWithAccess) {
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url(embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage));
@@ -160,8 +151,41 @@
   EnumerateDevices(tab, &devices);
 
   // Labels should be non-empty if access has been allowed.
-  for (std::vector<MediaDeviceInfo>::iterator it = devices.begin();
-       it != devices.end(); ++it) {
-    EXPECT_TRUE(!it->label.empty());
+  for (const auto& device_info : devices) {
+    EXPECT_TRUE(!device_info.label.empty());
+  }
+}
+
+IN_PROC_BROWSER_TEST_F(WebRtcGetMediaDevicesBrowserTest,
+                       DeviceIdEqualsGroupIdDiffersAcrossTabs) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+  GURL url(embedded_test_server()->GetURL(kMainWebrtcTestHtmlPage));
+  ui_test_utils::NavigateToURL(browser(), url);
+  content::WebContents* tab1 =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  std::vector<MediaDeviceInfo> devices;
+  EnumerateDevices(tab1, &devices);
+
+  chrome::AddTabAt(browser(), GURL(), -1, true);
+  ui_test_utils::NavigateToURL(browser(), url);
+  content::WebContents* tab2 =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  std::vector<MediaDeviceInfo> devices2;
+  EnumerateDevices(tab2, &devices2);
+
+  EXPECT_NE(tab1, tab2);
+  EXPECT_EQ(devices.size(), devices2.size());
+  for (auto& device : devices) {
+    auto it = std::find_if(devices2.begin(), devices2.end(),
+                           [&device](const MediaDeviceInfo& device_info) {
+                             return device.device_id == device_info.device_id;
+                           });
+    EXPECT_NE(it, devices2.end());
+
+    it = std::find_if(devices2.begin(), devices2.end(),
+                      [&device](const MediaDeviceInfo& device_info) {
+                        return device.group_id == device_info.group_id;
+                      });
+    EXPECT_EQ(it, devices2.end());
   }
 }
diff --git a/chrome/browser/net/default_network_context_params.cc b/chrome/browser/net/default_network_context_params.cc
index aec0ef0..332c063 100644
--- a/chrome/browser/net/default_network_context_params.cc
+++ b/chrome/browser/net/default_network_context_params.cc
@@ -15,9 +15,12 @@
 #include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_content_client.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/common/pref_names.h"
 #include "components/policy/core/common/policy_namespace.h"
 #include "components/policy/core/common/policy_service.h"
 #include "components/policy/policy_constants.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
 #include "components/version_info/version_info.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
@@ -59,6 +62,12 @@
     }
   }
 
+  PrefService* local_state = g_browser_process->local_state();
+  network_context_params->pac_quick_check_enabled =
+      local_state->GetBoolean(prefs::kQuickCheckEnabled);
+  network_context_params->dangerously_allow_pac_access_to_secure_urls =
+      !local_state->GetBoolean(prefs::kPacHttpsUrlStrippingEnabled);
+
   bool http_09_on_non_default_ports_enabled = false;
   const base::Value* value =
       g_browser_process->policy_service()
@@ -72,3 +81,8 @@
 
   return network_context_params;
 }
+
+void RegisterNetworkContextCreationPrefs(PrefRegistrySimple* registry) {
+  registry->RegisterBooleanPref(prefs::kQuickCheckEnabled, true);
+  registry->RegisterBooleanPref(prefs::kPacHttpsUrlStrippingEnabled, true);
+}
diff --git a/chrome/browser/net/default_network_context_params.h b/chrome/browser/net/default_network_context_params.h
index 09c3028..27b7701 100644
--- a/chrome/browser/net/default_network_context_params.h
+++ b/chrome/browser/net/default_network_context_params.h
@@ -7,7 +7,12 @@
 
 #include "services/network/public/mojom/network_service.mojom.h"
 
+class PrefRegistrySimple;
+
 // Returns default set of parameters for configuring the network service.
 network::mojom::NetworkContextParamsPtr CreateDefaultNetworkContextParams();
 
+// Registers prefs used in creating the default NetworkContextParams.
+void RegisterNetworkContextCreationPrefs(PrefRegistrySimple* registry);
+
 #endif  // CHROME_BROWSER_NET_DEFAULT_NETWORK_CONTEXT_PARAMS_H_
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc
index 7fc1392b..c7a37262 100644
--- a/chrome/browser/net/network_context_configuration_browsertest.cc
+++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -4,11 +4,13 @@
 
 #include <string>
 
+#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/guid.h"
+#include "base/location.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -16,6 +18,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/net/default_network_context_params.h"
 #include "chrome/browser/net/profile_network_context_service.h"
 #include "chrome/browser/net/profile_network_context_service_factory.h"
 #include "chrome/browser/net/system_network_context_manager.h"
@@ -30,6 +33,7 @@
 #include "components/proxy_config/proxy_config_dictionary.h"
 #include "components/proxy_config/proxy_config_pref_names.h"
 #include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/url_constants.h"
@@ -40,9 +44,11 @@
 #include "net/base/host_port_pair.h"
 #include "net/base/load_flags.h"
 #include "net/base/net_errors.h"
+#include "net/dns/mock_host_resolver.h"
 #include "net/http/http_response_headers.h"
 #include "net/test/embedded_test_server/controllable_http_response.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/embedded_test_server_connection_listener.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
 #include "net/test/spawned_test_server/spawned_test_server.h"
@@ -125,6 +131,9 @@
   }
 
   void SetUpOnMainThread() override {
+    // Used in a bunch of proxy tests. Should not resolve.
+    host_resolver()->AddSimulatedFailure("does.not.resolve.test");
+
     controllable_http_response_ =
         std::make_unique<net::test_server::ControllableHttpResponse>(
             embedded_test_server(), kControllablePath);
@@ -151,7 +160,7 @@
   // a proxy.
   std::string GetPacScript() const {
     return base::StringPrintf(
-        "function FindProxyForURL(url, host){ return 'PROXY %s;'; }",
+        "function FindProxyForURL(url, host){ return 'PROXY %s;' }",
         net::HostPortPair::FromURL(embedded_test_server()->base_url())
             .ToString()
             .c_str());
@@ -259,7 +268,7 @@
     std::unique_ptr<network::ResourceRequest> request =
         std::make_unique<network::ResourceRequest>();
     // This URL should be directed to the test server because of the proxy.
-    request->url = GURL("http://jabberwocky.test:1872/echo");
+    request->url = GURL("http://does.not.resolve.test:1872/echo");
 
     content::SimpleURLLoaderTestHelper simple_loader_helper;
     std::unique_ptr<network::SimpleURLLoader> simple_loader =
@@ -820,7 +829,7 @@
   std::unique_ptr<network::ResourceRequest> request =
       std::make_unique<network::ResourceRequest>();
   // This URL should be directed to the test server because of the proxy.
-  request->url = GURL("http://jabberwocky.test:1872/echo");
+  request->url = GURL("http://does.not.resolve.test:1872/echo");
 
   content::SimpleURLLoaderTestHelper simple_loader_helper;
   std::unique_ptr<network::SimpleURLLoader> simple_loader =
@@ -834,6 +843,113 @@
   EXPECT_EQ(net::ERR_PROXY_CONNECTION_FAILED, simple_loader->NetError());
 }
 
+// Used to test that PAC HTTPS URL stripping works. A different test server is
+// used as the "proxy" based on whether the PAC script sees the full path or
+// not. The servers aren't correctly set up to mimic HTTP proxies that tunnel
+// to an HTTPS test server, so the test fixture just watches for any incoming
+// connection.
+class NetworkContextConfigurationHttpsStrippingPacBrowserTest
+    : public NetworkContextConfigurationBrowserTest {
+ public:
+  NetworkContextConfigurationHttpsStrippingPacBrowserTest() {}
+
+  ~NetworkContextConfigurationHttpsStrippingPacBrowserTest() override {}
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    // Test server HostPortPair, as a string.
+    std::string test_server_host_port_pair =
+        net::HostPortPair::FromURL(embedded_test_server()->base_url())
+            .ToString();
+    // Set up a PAC file that directs to different servers based on the URL it
+    // sees.
+    std::string pac_script = base::StringPrintf(
+        "function FindProxyForURL(url, host) {"
+        // With the test URL stripped of the path, try to use the embedded test
+        // server to establish a an SSL tunnel over an HTTP proxy. The request
+        // will fail with ERR_TUNNEL_CONNECTION_FAILED.
+        "  if (url == 'https://does.not.resolve.test:1872/')"
+        "    return 'PROXY %s';"
+        // With the full test URL, try to use a domain that does not resolve as
+        // a proxy. Errors connecting to the proxy result in
+        // ERR_PROXY_CONNECTION_FAILED.
+        "  if (url == 'https://does.not.resolve.test:1872/foo')"
+        "    return 'PROXY does.not.resolve.test';"
+        // Otherwise, use direct. If a connection to "does.not.resolve.test"
+        // tries to use a direction connection, it will fail with
+        // ERR_NAME_NOT_RESOLVED. This path will also
+        // be used by the initial request in NetworkServiceState::kRestarted
+        // tests to make sure the network service process is fully started
+        // before it's crashed and restarted. Using direct in this case avoids
+        // that request failing with an unexpeced error when being directed to a
+        // bogus proxy.
+        "  return 'DIRECT';"
+        "}",
+        test_server_host_port_pair.c_str());
+
+    command_line->AppendSwitchASCII(switches::kProxyPacUrl,
+                                    "data:," + pac_script);
+  }
+};
+
+// Start Chrome and check that PAC HTTPS path stripping is enabled.
+IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationHttpsStrippingPacBrowserTest,
+                       PRE_PacHttpsUrlStripping) {
+  ASSERT_FALSE(CreateDefaultNetworkContextParams()
+                   ->dangerously_allow_pac_access_to_secure_urls);
+
+  std::unique_ptr<network::ResourceRequest> request =
+      std::make_unique<network::ResourceRequest>();
+  // This URL should be directed to the proxy that fails with
+  // ERR_TUNNEL_CONNECTION_FAILED.
+  request->url = GURL("https://does.not.resolve.test:1872/foo");
+
+  content::SimpleURLLoaderTestHelper simple_loader_helper;
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
+                                       TRAFFIC_ANNOTATION_FOR_TESTS);
+
+  simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+      loader_factory(), simple_loader_helper.GetCallback());
+  simple_loader_helper.WaitForCallback();
+  EXPECT_FALSE(simple_loader_helper.response_body());
+  EXPECT_EQ(net::ERR_TUNNEL_CONNECTION_FAILED, simple_loader->NetError());
+
+  // Disable stripping paths from HTTPS PAC URLs for the next test.
+  g_browser_process->local_state()->SetBoolean(
+      prefs::kPacHttpsUrlStrippingEnabled, false);
+  // Check that the changed setting is reflected in the network context params.
+  // The changes aren't applied to existing URLRequestContexts, however, so have
+  // to restart to see the setting change respected.
+  EXPECT_TRUE(CreateDefaultNetworkContextParams()
+                  ->dangerously_allow_pac_access_to_secure_urls);
+}
+
+// Restart Chrome and check the case where PAC HTTPS path stripping is disabled.
+// Have to restart Chrome because the setting is only checked on NetworkContext
+// creation.
+IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationHttpsStrippingPacBrowserTest,
+                       PacHttpsUrlStripping) {
+  ASSERT_TRUE(CreateDefaultNetworkContextParams()
+                  ->dangerously_allow_pac_access_to_secure_urls);
+
+  std::unique_ptr<network::ResourceRequest> request =
+      std::make_unique<network::ResourceRequest>();
+  // This URL should be directed to the proxy that fails with
+  // ERR_PROXY_CONNECTION_FAILED.
+  request->url = GURL("https://does.not.resolve.test:1872/foo");
+
+  content::SimpleURLLoaderTestHelper simple_loader_helper;
+  std::unique_ptr<network::SimpleURLLoader> simple_loader =
+      network::SimpleURLLoader::Create(std::move(request),
+                                       TRAFFIC_ANNOTATION_FOR_TESTS);
+
+  simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+      loader_factory(), simple_loader_helper.GetCallback());
+  simple_loader_helper.WaitForCallback();
+  EXPECT_FALSE(simple_loader_helper.response_body());
+  EXPECT_EQ(net::ERR_PROXY_CONNECTION_FAILED, simple_loader->NetError());
+}
+
 // |NetworkServiceTestHelper| doesn't work on browser_tests on OSX.
 #if defined(OS_MACOSX)
 // Instiates tests with a prefix indicating which NetworkContext is being
@@ -907,5 +1023,7 @@
     NetworkContextConfigurationDataPacBrowserTest);
 INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(
     NetworkContextConfigurationFtpPacBrowserTest);
+INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(
+    NetworkContextConfigurationHttpsStrippingPacBrowserTest);
 
 }  // namespace
diff --git a/chrome/browser/password_manager/password_store_factory.cc b/chrome/browser/password_manager/password_store_factory.cc
index b90b233..40ca300b 100644
--- a/chrome/browser/password_manager/password_store_factory.cc
+++ b/chrome/browser/password_manager/password_store_factory.cc
@@ -243,6 +243,7 @@
         " for more information about password storage options.";
   }
 
+  login_db->disable_encryption();
   ps = new PasswordStoreX(std::move(login_db), std::move(backend));
   RecordBackendStatistics(desktop_env, store_type, used_backend);
 #elif defined(USE_OZONE)
diff --git a/chrome/browser/password_manager/password_store_x_unittest.cc b/chrome/browser/password_manager/password_store_x_unittest.cc
index ccfb41d..26c1b9b1 100644
--- a/chrome/browser/password_manager/password_store_x_unittest.cc
+++ b/chrome/browser/password_manager/password_store_x_unittest.cc
@@ -20,6 +20,7 @@
 #include "base/test/scoped_task_environment.h"
 #include "base/time/time.h"
 #include "chrome/test/base/testing_browser_process.h"
+#include "components/os_crypt/os_crypt_mocker.h"
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
 #include "components/password_manager/core/browser/password_store_change.h"
 #include "components/password_manager/core/browser/password_store_consumer.h"
@@ -338,9 +339,10 @@
 PasswordStoreXTestDelegate::PasswordStoreXTestDelegate(BackendType backend_type)
     : backend_type_(backend_type) {
   SetupTempDir();
-  store_ = new PasswordStoreX(std::make_unique<password_manager::LoginDatabase>(
-                                  test_login_db_file_path()),
-                              GetBackend(backend_type_));
+  auto login_db = std::make_unique<password_manager::LoginDatabase>(
+      test_login_db_file_path());
+  login_db->disable_encryption();
+  store_ = new PasswordStoreX(std::move(login_db), GetBackend(backend_type_));
   store_->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
 }
 
@@ -410,6 +412,7 @@
 TEST_P(PasswordStoreXTest, Notifications) {
   std::unique_ptr<password_manager::LoginDatabase> login_db(
       new password_manager::LoginDatabase(test_login_db_file_path()));
+  login_db->disable_encryption();
   scoped_refptr<PasswordStoreX> store(
       new PasswordStoreX(std::move(login_db), GetBackend(GetParam())));
   store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
@@ -488,6 +491,7 @@
   const base::FilePath login_db_file = test_login_db_file_path();
   std::unique_ptr<password_manager::LoginDatabase> login_db(
       new password_manager::LoginDatabase(login_db_file));
+  login_db->disable_encryption();
   ASSERT_TRUE(login_db->Init());
 
   // Get the initial size of the login DB file, before we populate it.
@@ -510,6 +514,7 @@
 
   // Initializing the PasswordStore shouldn't trigger a native migration (yet).
   login_db.reset(new password_manager::LoginDatabase(login_db_file));
+  login_db->disable_encryption();
   scoped_refptr<PasswordStoreX> store(
       new PasswordStoreX(std::move(login_db), GetBackend(GetParam())));
   store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index 8973309..63e05dfa 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -64,6 +64,7 @@
 #include "chrome/browser/media/router/media_router_feature.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "chrome/browser/media/webrtc/media_stream_devices_controller.h"
+#include "chrome/browser/net/default_network_context_params.h"
 #include "chrome/browser/net/prediction_options.h"
 #include "chrome/browser/net/url_request_mock_util.h"
 #include "chrome/browser/permissions/permission_request_manager.h"
@@ -212,6 +213,7 @@
 #include "net/url_request/url_request_interceptor.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/network_switches.h"
+#include "services/network/public/mojom/network_service.mojom.h"
 #include "services/network/public/mojom/network_service_test.mojom.h"
 #include "services/service_manager/public/cpp/connector.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -1341,24 +1343,10 @@
 
 namespace {
 
-// The following helpers retrieve whether https:// URL stripping is
-// enabled for PAC scripts. It needs to run on the IO thread.
-void GetPacHttpsUrlStrippingEnabledOnIOThread(IOThread* io_thread,
-                                              bool* enabled) {
-  *enabled = io_thread->PacHttpsUrlStrippingEnabled();
-}
-
 bool GetPacHttpsUrlStrippingEnabled() {
-  bool enabled;
-  base::RunLoop loop;
-  BrowserThread::PostTaskAndReply(
-      BrowserThread::IO, FROM_HERE,
-      base::BindOnce(&GetPacHttpsUrlStrippingEnabledOnIOThread,
-                     g_browser_process->io_thread(),
-                     base::Unretained(&enabled)),
-      loop.QuitClosure());
-  loop.Run();
-  return enabled;
+  network::mojom::NetworkContextParamsPtr network_context_params =
+      CreateDefaultNetworkContextParams();
+  return !network_context_params->dangerously_allow_pac_access_to_secure_urls;
 }
 
 }  // namespace
@@ -1368,6 +1356,8 @@
 // default.
 IN_PROC_BROWSER_TEST_F(PolicyTest, DisablePacHttpsUrlStripping) {
   // Stripping is enabled by default.
+  EXPECT_TRUE(g_browser_process->local_state()->GetBoolean(
+      prefs::kPacHttpsUrlStrippingEnabled));
   EXPECT_TRUE(GetPacHttpsUrlStrippingEnabled());
 
   // Disable it via a policy.
@@ -1379,6 +1369,8 @@
   content::RunAllPendingInMessageLoop();
 
   // It should now reflect as disabled.
+  EXPECT_FALSE(g_browser_process->local_state()->GetBoolean(
+      prefs::kPacHttpsUrlStrippingEnabled));
   EXPECT_FALSE(GetPacHttpsUrlStrippingEnabled());
 }
 
diff --git a/chrome/browser/predictors/loading_predictor_config.cc b/chrome/browser/predictors/loading_predictor_config.cc
index c9253363..a793f92 100644
--- a/chrome/browser/predictors/loading_predictor_config.cc
+++ b/chrome/browser/predictors/loading_predictor_config.cc
@@ -39,7 +39,7 @@
 const char kNoPreconnectMode[] = "no-preconnect";
 
 const base::Feature kSpeculativePreconnectFeature{
-    kSpeculativePreconnectFeatureName, base::FEATURE_DISABLED_BY_DEFAULT};
+    kSpeculativePreconnectFeatureName, base::FEATURE_ENABLED_BY_DEFAULT};
 
 bool MaybeEnableSpeculativePreconnect(LoadingPredictorConfig* config) {
   if (!base::FeatureList::IsEnabled(kSpeculativePreconnectFeature))
@@ -47,6 +47,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..270cde05 100644
--- a/chrome/browser/predictors/loading_predictor_config_unittest.cc
+++ b/chrome/browser/predictors/loading_predictor_config_unittest.cc
@@ -66,12 +66,14 @@
 LoadingPredictorConfigTest::LoadingPredictorConfigTest()
     : profile_(new TestingProfile()) {}
 
-TEST_F(LoadingPredictorConfigTest, IsDisabledByDefault) {
+TEST_F(LoadingPredictorConfigTest, IsEnabledByDefault) {
   LoadingPredictorConfig config;
-  EXPECT_FALSE(MaybeEnableSpeculativePreconnect(&config));
+  EXPECT_TRUE(MaybeEnableSpeculativePreconnect(&config));
 
-  EXPECT_FALSE(config.IsLearningEnabled());
-  EXPECT_FALSE(config.IsPreconnectEnabledForSomeOrigin(profile_.get()));
+  EXPECT_TRUE(config.IsLearningEnabled());
+  EXPECT_TRUE(config.should_disable_other_preconnects);
+  EXPECT_FALSE(IsNetPredictorEnabled());
+  EXPECT_TRUE(config.IsPreconnectEnabledForSomeOrigin(profile_.get()));
 }
 
 TEST_F(LoadingPredictorConfigTest, EnablePreconnectLearning) {
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index d0e4d8e..b7ba0b7 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -30,6 +30,7 @@
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "chrome/browser/media/webrtc/media_stream_devices_controller.h"
 #include "chrome/browser/metrics/chrome_metrics_service_client.h"
+#include "chrome/browser/net/default_network_context_params.h"
 #include "chrome/browser/net/nqe/ui_network_quality_estimator_service.h"
 #include "chrome/browser/net/prediction_options.h"
 #include "chrome/browser/net/predictor.h"
@@ -353,6 +354,7 @@
   ProfileInfoCache::RegisterPrefs(registry);
   profiles::RegisterPrefs(registry);
   rappor::RapporServiceImpl::RegisterPrefs(registry);
+  RegisterNetworkContextCreationPrefs(registry);
   RegisterScreenshotPrefs(registry);
   SigninManagerFactory::RegisterPrefs(registry);
   SSLConfigServiceManager::RegisterPrefs(registry);
diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc
index 79266fd0..83530a7 100644
--- a/chrome/browser/push_messaging/push_messaging_browsertest.cc
+++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc
@@ -1643,7 +1643,13 @@
   EXPECT_EQ("permission status - denied", script_result);
 }
 
-IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, UnsubscribeSuccess) {
+// TODO(peter): Flaky on Win buildbots. https://crbug.com/838759
+#if defined(OS_WIN)
+#define MAYBE_UnsubscribeSuccess DISABLED_UnsubscribeSuccess
+#else
+#define MAYBE_UnsubscribeSuccess UnsubscribeSucces
+#endif
+IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, MAYBE_UnsubscribeSuccess) {
   std::string script_result;
 
   std::string token1;
diff --git a/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe.cc b/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe.cc
index d7dc02b0..53eafce1 100644
--- a/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe.cc
+++ b/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe.cc
@@ -14,7 +14,6 @@
 #include "content/public/common/service_manager_connection.h"
 #include "services/resource_coordinator/public/cpp/process_resource_coordinator.h"
 #include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
-#include "services/resource_coordinator/public/cpp/system_resource_coordinator.h"
 #include "services/resource_coordinator/public/mojom/coordination_unit.mojom.h"
 
 #if defined(OS_MACOSX)
@@ -33,9 +32,11 @@
 
 }  // namespace
 
-RenderProcessInfo::RenderProcessInfo() = default;
+ResourceCoordinatorRenderProcessProbe::RenderProcessInfo::RenderProcessInfo() =
+    default;
 
-RenderProcessInfo::~RenderProcessInfo() = default;
+ResourceCoordinatorRenderProcessProbe::RenderProcessInfo::~RenderProcessInfo() =
+    default;
 
 ResourceCoordinatorRenderProcessProbe::ResourceCoordinatorRenderProcessProbe()
     : interval_(kDefaultMeasurementInterval) {
@@ -124,7 +125,6 @@
       render_process_info.metrics = base::ProcessMetrics::CreateProcessMetrics(
           render_process_info.process.Handle());
 #endif
-      render_process_info.render_process_host_id = host->GetID();
     }
   }
 
@@ -133,12 +133,12 @@
   content::BrowserThread::PostTask(
       content::BrowserThread::IO, FROM_HERE,
       base::BindOnce(&ResourceCoordinatorRenderProcessProbe::
-                         CollectRenderProcessMetricsOnIOThread,
+                         CollectAndDispatchRenderProcessMetricsOnIOThread,
                      base::Unretained(this)));
 }
 
 void ResourceCoordinatorRenderProcessProbe::
-    CollectRenderProcessMetricsOnIOThread() {
+    CollectAndDispatchRenderProcessMetricsOnIOThread() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   DCHECK(is_gathering_);
 
@@ -158,20 +158,40 @@
     }
   }
 
+  // Create the measurement batch.
+  mojom::ProcessResourceMeasurementBatchPtr batch =
+      mojom::ProcessResourceMeasurementBatch::New();
+
+  for (auto& render_process_info_map_entry : render_process_info_map_) {
+    auto& render_process_info = render_process_info_map_entry.second;
+    // TODO(oysteine): Move the multiplier used to avoid precision loss
+    // into a shared location, when this property gets used.
+    mojom::ProcessResourceMeasurementPtr measurement =
+        mojom::ProcessResourceMeasurement::New();
+
+    measurement->pid = render_process_info.process.Pid();
+    measurement->cpu_usage = render_process_info.cpu_usage;
+    // TODO(siggi): Add the private footprint.
+
+    batch->measurements.push_back(std::move(measurement));
+  }
+
+  bool should_restart = DispatchMetrics(std::move(batch));
+
   content::BrowserThread::PostTask(
       content::BrowserThread::UI, FROM_HERE,
-      base::BindOnce(&ResourceCoordinatorRenderProcessProbe::
-                         HandleRenderProcessMetricsOnUIThread,
-                     base::Unretained(this)));
+      base::BindOnce(
+          &ResourceCoordinatorRenderProcessProbe::FinishCollectionOnUIThread,
+          base::Unretained(this), should_restart));
 }
 
-void ResourceCoordinatorRenderProcessProbe::
-    HandleRenderProcessMetricsOnUIThread() {
+void ResourceCoordinatorRenderProcessProbe::FinishCollectionOnUIThread(
+    bool restart_cycle) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(is_gathering_);
   is_gathering_ = false;
 
-  if (DispatchMetrics() && is_gather_cycle_started_) {
+  if (restart_cycle && is_gather_cycle_started_) {
     timer_.Start(FROM_HERE, interval_, this,
                  &ResourceCoordinatorRenderProcessProbe::
                      RegisterAliveRenderProcessesOnUIThread);
@@ -190,7 +210,6 @@
 
 SystemResourceCoordinator*
 ResourceCoordinatorRenderProcessProbe::EnsureSystemResourceCoordinator() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (!system_resource_coordinator_) {
     content::ServiceManagerConnection* connection =
         content::ServiceManagerConnection::GetForProcess();
@@ -203,31 +222,14 @@
   return system_resource_coordinator_.get();
 }
 
-bool ResourceCoordinatorRenderProcessProbe::DispatchMetrics() {
+bool ResourceCoordinatorRenderProcessProbe::DispatchMetrics(
+    mojom::ProcessResourceMeasurementBatchPtr batch) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   SystemResourceCoordinator* system_resource_coordinator =
       EnsureSystemResourceCoordinator();
 
-  if (system_resource_coordinator) {
-    bool dispatched_measurement = false;
-    for (auto& render_process_info_map_entry : render_process_info_map_) {
-      auto& render_process_info = render_process_info_map_entry.second;
-      // TODO(oysteine): Move the multiplier used to avoid precision loss
-      // into a shared location, when this property gets used.
-
-      // Note that the RPH may have been deleted while the CPU metrics were
-      // acquired on a blocking thread.
-      content::RenderProcessHost* host = content::RenderProcessHost::FromID(
-          render_process_info.render_process_host_id);
-      if (host) {
-        dispatched_measurement = true;
-        host->GetProcessResourceCoordinator()->SetCPUUsage(
-            render_process_info.cpu_usage);
-      }
-    }
-
-    if (dispatched_measurement)
-      system_resource_coordinator->OnProcessCPUUsageReady();
-  }
+  if (system_resource_coordinator && !batch->measurements.empty())
+    system_resource_coordinator->DistributeMeasurementBatch(std::move(batch));
 
   return true;
 }
diff --git a/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe.h b/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe.h
index 7940d8f7..7849d48 100644
--- a/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe.h
+++ b/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe.h
@@ -14,31 +14,15 @@
 #include "base/process/process.h"
 #include "base/process/process_metrics.h"
 #include "base/timer/timer.h"
+#include "services/resource_coordinator/public/cpp/system_resource_coordinator.h"
 
 namespace resource_coordinator {
 
-class SystemResourceCoordinator;
-
-struct RenderProcessInfo {
-  RenderProcessInfo();
-  ~RenderProcessInfo();
-  base::Process process;
-  double cpu_usage = -1.0;
-  // This structure bounces from the UI thread to blocking threads and back.
-  // It's therefore not safe to store RenderProcessHost pointers, so the ID is
-  // used instead.
-  int render_process_host_id = 0;
-  size_t last_gather_cycle_active;
-  std::unique_ptr<base::ProcessMetrics> metrics;
-};
-
-using RenderProcessInfoMap = std::map<int, RenderProcessInfo>;
-
 // |ResourceCoordinatorRenderProcessProbe| collects measurements about render
 // processes and propagates them to the |resource_coordinator| service.
 // Currently this is only supported for Chrome Metrics experiments.
-// The measurements are initiated and results are dispatched from the UI
-// thread, while acquiring the measurements is done on the IO thread.
+// The measurements are initiated from the UI thread, while acquiring and
+// dispatching the measurements is done on the IO thread.
 class ResourceCoordinatorRenderProcessProbe {
  public:
   // Returns the current |ResourceCoordinatorRenderProcessProbe| instance
@@ -57,6 +41,16 @@
   void StartSingleGather();
 
  protected:
+  struct RenderProcessInfo {
+    RenderProcessInfo();
+    ~RenderProcessInfo();
+    base::Process process;
+    double cpu_usage = -1.0;
+    size_t last_gather_cycle_active = -1;
+    std::unique_ptr<base::ProcessMetrics> metrics;
+  };
+  using RenderProcessInfoMap = std::map<int, RenderProcessInfo>;
+
   // Internal state protected for testing.
   friend struct base::LazyInstanceTraitsBase<
       ResourceCoordinatorRenderProcessProbe>;
@@ -67,27 +61,27 @@
   // (1) Identify all of the render processes that are active to measure.
   // Child render processes can only be discovered in the browser's UI thread.
   void RegisterAliveRenderProcessesOnUIThread();
-  // (2) Collect render process metrics.
-  void CollectRenderProcessMetricsOnIOThread();
-  // (3) Send the collected render process metrics to the appropriate
-  // coordination units in the |resource_coordinator| service. Then
-  // initiates the next render process metrics collection cycle, which
-  // consists of a delayed call to perform (1) via a timer.
-  void HandleRenderProcessMetricsOnUIThread();
+  // (2) Collect and dispatch the render process metrics to the system
+  // coordination unit.
+  void CollectAndDispatchRenderProcessMetricsOnIOThread();
+  // (3) Initiate the next render process metrics collection cycle if the
+  // cycle has been started and |restart_cycle| is true, which consists of a
+  // delayed call to perform (1) via a timer.
+  // Virtual for testing.
+  virtual void FinishCollectionOnUIThread(bool restart_cycle);
 
   // Allows FieldTrial parameters to override defaults.
   void UpdateWithFieldTrialParams();
 
   SystemResourceCoordinator* EnsureSystemResourceCoordinator();
 
-  // Dispatch the collected metrics. Returns |true| if another metrics
-  // collection gather cycle should be initiated. Virtual for testing.
-  // Default implementation sends collected metrics back to the resource
-  // coordinator service and initiates another render process metrics gather
-  // cycle.
-  virtual bool DispatchMetrics();
+  // Dispatch the collected metrics, return true if the cycle should restart.
+  // Virtual for testing.
+  virtual bool DispatchMetrics(mojom::ProcessResourceMeasurementBatchPtr batch);
 
-  // A map of currently running render process host IDs to Process.
+  // A map of currently running render process host IDs to process.
+  // This map is accessed alternatively from the UI thread and the IO thread,
+  // but only one of the two at a time.
   RenderProcessInfoMap render_process_info_map_;
 
   // Time duration between measurements.
diff --git a/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe_browsertest.cc b/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe_browsertest.cc
index 0c2ffd5..80d9718 100644
--- a/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe_browsertest.cc
+++ b/chrome/browser/resource_coordinator/resource_coordinator_render_process_probe_browsertest.cc
@@ -27,14 +27,27 @@
 class TestingResourceCoordinatorRenderProcessProbe
     : public ResourceCoordinatorRenderProcessProbe {
  public:
+  // Make these types public for testing.
+  using ResourceCoordinatorRenderProcessProbe::RenderProcessInfo;
+  using ResourceCoordinatorRenderProcessProbe::RenderProcessInfoMap;
+
   TestingResourceCoordinatorRenderProcessProbe() = default;
   ~TestingResourceCoordinatorRenderProcessProbe() override = default;
 
-  bool DispatchMetrics() override {
-    current_run_loop_->QuitWhenIdle();
+  bool DispatchMetrics(
+      mojom::ProcessResourceMeasurementBatchPtr batch) override {
+    last_measurement_batch_ = std::move(batch);
+
     return false;
   }
 
+  void FinishCollectionOnUIThread(bool restart_cycle) override {
+    ResourceCoordinatorRenderProcessProbe::FinishCollectionOnUIThread(
+        restart_cycle);
+
+    current_run_loop_->QuitWhenIdle();
+  }
+
   // Returns |true| if all of the elements in |*render_process_info_map_|
   // are up-to-date with |current_gather_cycle_|.
   bool AllMeasurementsAreAtCurrentCycle() const {
@@ -49,6 +62,11 @@
     return true;
   }
 
+  const mojom::ProcessResourceMeasurementBatchPtr& last_measurement_batch()
+      const {
+    return last_measurement_batch_;
+  }
+
   const RenderProcessInfoMap& render_process_info_map() const {
     return render_process_info_map_;
   }
@@ -73,6 +91,8 @@
  private:
   base::RunLoop* current_run_loop_ = nullptr;
 
+  mojom::ProcessResourceMeasurementBatchPtr last_measurement_batch_;
+
   DISALLOW_COPY_AND_ASSIGN(TestingResourceCoordinatorRenderProcessProbe);
 };
 
@@ -112,6 +132,11 @@
   EXPECT_LE(1u, initial_size);
   EXPECT_GE(2u, initial_size);  // If a spare RenderProcessHost is present.
   EXPECT_TRUE(probe.AllMeasurementsAreAtCurrentCycle());
+  EXPECT_EQ(initial_size, probe.last_measurement_batch()->measurements.size());
+  // A quirk of the process_metrics implementation is that the first CPU
+  // measurement returns zero.
+  for (const auto& measurement : probe.last_measurement_batch()->measurements)
+    EXPECT_EQ(0.0, measurement->cpu_usage);
 
   // Open a second tab and complete a navigation.
   ui_test_utils::NavigateToURLWithDisposition(
@@ -122,20 +147,25 @@
   probe.StartGatherCycleAndWait();
   EXPECT_EQ(2u, probe.current_gather_cycle());
   EXPECT_EQ(initial_size + 1u, probe.render_process_info_map().size());
+  EXPECT_EQ(initial_size + 1u,
+            probe.last_measurement_batch()->measurements.size());
   EXPECT_TRUE(probe.AllMeasurementsAreAtCurrentCycle());
 
   // Verify that the elements in the map are reused across multiple
   // measurement cycles.
+  using RenderProcessInfo =
+      TestingResourceCoordinatorRenderProcessProbe::RenderProcessInfo;
   std::map<int, const RenderProcessInfo*> info_map;
   for (const auto& entry : probe.render_process_info_map()) {
-    const int key = entry.first;
     const RenderProcessInfo& info = entry.second;
-    EXPECT_EQ(key, info.render_process_host_id);
     EXPECT_TRUE(info_map.insert(std::make_pair(entry.first, &info)).second);
   }
 
   size_t info_map_size = info_map.size();
   probe.StartGatherCycleAndWait();
+  // The second and subsequent CPU measurements should return some data.
+  for (const auto& measurement : probe.last_measurement_batch()->measurements)
+    EXPECT_LE(0.0, measurement->cpu_usage);
 
   EXPECT_EQ(info_map_size, info_map.size());
   for (const auto& entry : probe.render_process_info_map()) {
@@ -155,6 +185,7 @@
   probe.StartGatherCycleAndWait();
   EXPECT_EQ(4u, probe.current_gather_cycle());
   EXPECT_EQ(initial_size, probe.render_process_info_map().size());
+  EXPECT_EQ(initial_size, probe.last_measurement_batch()->measurements.size());
   EXPECT_TRUE(probe.AllMeasurementsAreAtCurrentCycle());
 }
 
diff --git a/chrome/browser/resources/chromeos/sounds/earcons/null_selection.wav b/chrome/browser/resources/chromeos/sounds/earcons/null_selection.wav
new file mode 100644
index 0000000..3a8b5d7
--- /dev/null
+++ b/chrome/browser/resources/chromeos/sounds/earcons/null_selection.wav
Binary files differ
diff --git a/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.cc b/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.cc
index 6e15628c3..1438708 100644
--- a/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.cc
+++ b/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.cc
@@ -24,9 +24,11 @@
 #include "net/base/url_util.h"
 #include "net/http/http_status_code.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_fetcher_delegate.h"
 #include "services/data_decoder/public/cpp/safe_json_parser.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+#include "url/gurl.h"
 
 namespace {
 
@@ -128,52 +130,52 @@
 
 }  // namespace
 
-class OneGoogleBarFetcherImpl::AuthenticatedURLFetcher
-    : public net::URLFetcherDelegate {
+class OneGoogleBarFetcherImpl::AuthenticatedURLFetcher {
  public:
-  using FetchDoneCallback = base::OnceCallback<void(const net::URLFetcher*)>;
+  using LoadDoneCallback =
+      base::OnceCallback<void(const network::SimpleURLLoader* simple_loader,
+                              std::unique_ptr<std::string> response_body)>;
 
-  AuthenticatedURLFetcher(net::URLRequestContextGetter* request_context,
-                          GURL api_url,
-                          bool account_consistency_mirror_required,
-                          FetchDoneCallback callback);
-  ~AuthenticatedURLFetcher() override = default;
+  AuthenticatedURLFetcher(
+      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+      GURL api_url,
+      bool account_consistency_mirror_required,
+      LoadDoneCallback callback);
+  ~AuthenticatedURLFetcher() = default;
 
   void Start();
 
  private:
-  std::string GetExtraRequestHeaders() const;
+  net::HttpRequestHeaders GetRequestHeaders() const;
 
-  // URLFetcherDelegate implementation.
-  void OnURLFetchComplete(const net::URLFetcher* source) override;
+  void OnURLLoaderComplete(std::unique_ptr<std::string> response_body);
 
-  net::URLRequestContextGetter* const request_context_;
+  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
   const GURL api_url_;
 #if defined(OS_CHROMEOS)
   const bool account_consistency_mirror_required_;
 #endif
 
-  FetchDoneCallback callback_;
+  LoadDoneCallback callback_;
 
-  // The underlying URLFetcher which does the actual fetch.
-  std::unique_ptr<net::URLFetcher> url_fetcher_;
+  // The underlying SimpleURLLoader which does the actual load.
+  std::unique_ptr<network::SimpleURLLoader> simple_loader_;
 };
 
 OneGoogleBarFetcherImpl::AuthenticatedURLFetcher::AuthenticatedURLFetcher(
-    net::URLRequestContextGetter* request_context,
+    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
     GURL api_url,
     bool account_consistency_mirror_required,
-    FetchDoneCallback callback)
-    : request_context_(request_context),
+    LoadDoneCallback callback)
+    : url_loader_factory_(url_loader_factory),
       api_url_(std::move(api_url)),
 #if defined(OS_CHROMEOS)
       account_consistency_mirror_required_(account_consistency_mirror_required),
 #endif
       callback_(std::move(callback)) {}
 
-std::string
-OneGoogleBarFetcherImpl::AuthenticatedURLFetcher::GetExtraRequestHeaders()
-    const {
+net::HttpRequestHeaders
+OneGoogleBarFetcherImpl::AuthenticatedURLFetcher::GetRequestHeaders() const {
   net::HttpRequestHeaders headers;
   // Note: It's OK to pass SignedIn::kNo if it's unknown, as it does not affect
   // transmission of experiments coming from the variations server.
@@ -202,7 +204,7 @@
                       chrome_connected_header_value);
   }
 #endif
-  return headers.ToString();
+  return headers;
 }
 
 void OneGoogleBarFetcherImpl::AuthenticatedURLFetcher::Start() {
@@ -230,31 +232,36 @@
             }
           }
         })");
-  url_fetcher_ = net::URLFetcher::Create(0, api_url_, net::URLFetcher::GET,
-                                         this, traffic_annotation);
-  url_fetcher_->SetRequestContext(request_context_);
 
-  url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_AUTH_DATA);
-  url_fetcher_->SetExtraRequestHeaders(GetExtraRequestHeaders());
+  auto resource_request = std::make_unique<network::ResourceRequest>();
+  resource_request->url = api_url_;
+  resource_request->load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
+  resource_request->headers = GetRequestHeaders();
+  resource_request->request_initiator =
+      url::Origin::Create(GURL(chrome::kChromeUINewTabURL));
 
-  url_fetcher_->SetInitiator(
-      url::Origin::Create(GURL(chrome::kChromeUINewTabURL)));
-
-  url_fetcher_->Start();
+  simple_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
+                                                    traffic_annotation);
+  simple_loader_->DownloadToString(
+      url_loader_factory_.get(),
+      base::BindOnce(&OneGoogleBarFetcherImpl::AuthenticatedURLFetcher::
+                         OnURLLoaderComplete,
+                     base::Unretained(this)),
+      1024 * 1024);
 }
 
-void OneGoogleBarFetcherImpl::AuthenticatedURLFetcher::OnURLFetchComplete(
-    const net::URLFetcher* source) {
-  std::move(callback_).Run(source);
+void OneGoogleBarFetcherImpl::AuthenticatedURLFetcher::OnURLLoaderComplete(
+    std::unique_ptr<std::string> response_body) {
+  std::move(callback_).Run(simple_loader_.get(), std::move(response_body));
 }
 
 OneGoogleBarFetcherImpl::OneGoogleBarFetcherImpl(
-    net::URLRequestContextGetter* request_context,
+    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
     GoogleURLTracker* google_url_tracker,
     const std::string& application_locale,
     const base::Optional<std::string>& api_url_override,
     bool account_consistency_mirror_required)
-    : request_context_(request_context),
+    : url_loader_factory_(url_loader_factory),
       google_url_tracker_(google_url_tracker),
       application_locale_(application_locale),
       api_url_override_(api_url_override),
@@ -270,8 +277,8 @@
   // something has changed in the meantime (e.g. signin state) that would make
   // the result obsolete.
   pending_request_ = std::make_unique<AuthenticatedURLFetcher>(
-      request_context_, GetApiUrl(), account_consistency_mirror_required_,
-      base::BindOnce(&OneGoogleBarFetcherImpl::FetchDone,
+      url_loader_factory_, GetApiUrl(), account_consistency_mirror_required_,
+      base::BindOnce(&OneGoogleBarFetcherImpl::LoadDone,
                      base::Unretained(this)));
   pending_request_->Start();
 }
@@ -301,33 +308,22 @@
   return api_url.ReplaceComponents(replacements);
 }
 
-void OneGoogleBarFetcherImpl::FetchDone(const net::URLFetcher* source) {
-  // The fetcher will be deleted when the request is handled.
+void OneGoogleBarFetcherImpl::LoadDone(
+    const network::SimpleURLLoader* simple_loader,
+    std::unique_ptr<std::string> response_body) {
+  // The loader will be deleted when the request is handled.
   std::unique_ptr<AuthenticatedURLFetcher> deleter(std::move(pending_request_));
 
-  const net::URLRequestStatus& request_status = source->GetStatus();
-  if (request_status.status() != net::URLRequestStatus::SUCCESS) {
+  if (!response_body) {
     // This represents network errors (i.e. the server did not provide a
     // response).
-    DLOG(WARNING) << "Request failed with error: " << request_status.error()
-                  << ": " << net::ErrorToString(request_status.error());
+    DLOG(WARNING) << "Request failed with error: " << simple_loader->NetError();
     Respond(Status::TRANSIENT_ERROR, base::nullopt);
     return;
   }
 
-  const int response_code = source->GetResponseCode();
-  if (response_code != net::HTTP_OK) {
-    DLOG(WARNING) << "Response code: " << response_code;
-    std::string response;
-    source->GetResponseAsString(&response);
-    DLOG(WARNING) << "Response: " << response;
-    Respond(Status::FATAL_ERROR, base::nullopt);
-    return;
-  }
-
   std::string response;
-  bool success = source->GetResponseAsString(&response);
-  DCHECK(success);
+  response.swap(*response_body);
 
   // The response may start with )]}'. Ignore this.
   if (base::StartsWith(response, kResponsePreamble,
diff --git a/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.h b/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.h
index 2542ef8..c427bd5 100644
--- a/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.h
+++ b/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl.h
@@ -20,10 +20,10 @@
 class Value;
 }
 
-namespace net {
-class URLFetcher;
-class URLRequestContextGetter;
-}  // namespace net
+namespace network {
+class SimpleURLLoader;
+class SharedURLLoaderFactory;
+}  // namespace network
 
 struct OneGoogleBarData;
 
@@ -34,29 +34,32 @@
  public:
   // |api_url_override| can be either absolute, or relative to the Google base
   // URL.
-  OneGoogleBarFetcherImpl(net::URLRequestContextGetter* request_context,
-                          GoogleURLTracker* google_url_tracker,
-                          const std::string& application_locale,
-                          const base::Optional<std::string>& api_url_override,
-                          bool account_consistency_mirror_required);
+  OneGoogleBarFetcherImpl(
+      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+      GoogleURLTracker* google_url_tracker,
+      const std::string& application_locale,
+      const base::Optional<std::string>& api_url_override,
+      bool account_consistency_mirror_required);
   ~OneGoogleBarFetcherImpl() override;
 
   void Fetch(OneGoogleCallback callback) override;
 
+  GURL GetFetchURLForTesting() const override;
+
  private:
   class AuthenticatedURLFetcher;
 
-  GURL GetFetchURLForTesting() const override;
   GURL GetApiUrl() const;
 
-  void FetchDone(const net::URLFetcher* source);
+  void LoadDone(const network::SimpleURLLoader* simple_loader,
+                std::unique_ptr<std::string> response_body);
 
   void JsonParsed(std::unique_ptr<base::Value> value);
   void JsonParseFailed(const std::string& message);
 
   void Respond(Status status, const base::Optional<OneGoogleBarData>& data);
 
-  net::URLRequestContextGetter* request_context_;
+  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
   GoogleURLTracker* google_url_tracker_;
   const std::string application_locale_;
   const base::Optional<std::string> api_url_override_;
diff --git a/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl_unittest.cc b/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl_unittest.cc
index a2190ad..73c26e8 100644
--- a/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl_unittest.cc
+++ b/chrome/browser/search/one_google_bar/one_google_bar_fetcher_impl_unittest.cc
@@ -9,20 +9,21 @@
 #include "base/optional.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
+#include "base/test/bind_test_util.h"
 #include "base/test/mock_callback.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/time/time.h"
 #include "chrome/browser/search/one_google_bar/one_google_bar_data.h"
 #include "components/google/core/browser/google_url_tracker.h"
 #include "components/signin/core/browser/signin_header_helper.h"
+#include "content/public/common/weak_wrapper_shared_url_loader_factory.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_service_manager_context.h"
 #include "net/http/http_request_headers.h"
 #include "net/http/http_status_code.h"
-#include "net/url_request/test_url_fetcher_factory.h"
-#include "net/url_request/url_request_status.h"
-#include "net/url_request/url_request_test_util.h"
 #include "services/data_decoder/public/cpp/testing_json_parser.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "services/network/test/test_url_loader_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -32,6 +33,11 @@
 using testing::SaveArg;
 using testing::StartsWith;
 
+// Needed for GoogleURLTrackerClientStub below.
+namespace net {
+class URLRequestContextGetter;
+}
+
 namespace {
 
 const char kApplicationLocale[] = "de";
@@ -57,6 +63,10 @@
 
 }  // namespace
 
+ACTION_P(Quit, run_loop) {
+  run_loop->Quit();
+}
+
 class OneGoogleBarFetcherImplTest : public testing::Test {
  public:
   OneGoogleBarFetcherImplTest()
@@ -77,11 +87,12 @@
   OneGoogleBarFetcherImplTest(
       const base::Optional<std::string>& api_url_override,
       bool account_consistency_mirror_required)
-      : task_runner_(new base::TestSimpleTaskRunner()),
-        request_context_getter_(
-            new net::TestURLRequestContextGetter(task_runner_)),
+      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
         google_url_tracker_(std::make_unique<GoogleURLTrackerClientStub>(),
                             GoogleURLTracker::ALWAYS_DOT_COM_MODE),
+        test_shared_loader_factory_(
+            base::MakeRefCounted<content::WeakWrapperSharedURLLoaderFactory>(
+                &test_url_loader_factory_)),
         api_url_override_(api_url_override),
         account_consistency_mirror_required_(
             account_consistency_mirror_required) {}
@@ -94,44 +105,36 @@
     testing::Test::SetUp();
 
     one_google_bar_fetcher_ = std::make_unique<OneGoogleBarFetcherImpl>(
-        request_context_getter_.get(), &google_url_tracker_, kApplicationLocale,
+        test_shared_loader_factory_, &google_url_tracker_, kApplicationLocale,
         api_url_override_, account_consistency_mirror_required_);
   }
 
-  net::TestURLFetcher* GetRunningURLFetcher() {
-    // All created URLFetchers have ID 0 by default.
-    net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID(0);
-    DCHECK(url_fetcher);
-    return url_fetcher;
+  void SetUpResponseWithData(const std::string& response) {
+    test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting(
+        [&](const network::ResourceRequest& request) {
+          last_request_url_ = request.url;
+          last_request_headers_ = request.headers;
+        }));
+    test_url_loader_factory_.AddResponse(
+        one_google_bar_fetcher_->GetFetchURLForTesting().spec(), response);
   }
 
-  void RespondWithData(const std::string& data) {
-    net::TestURLFetcher* url_fetcher = GetRunningURLFetcher();
-    url_fetcher->set_status(net::URLRequestStatus());
-    url_fetcher->set_response_code(net::HTTP_OK);
-    url_fetcher->SetResponseString(data);
-    url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
-    // SafeJsonParser is asynchronous.
-    base::RunLoop().RunUntilIdle();
-  }
-
-  void RespondWithNetworkError() {
-    net::TestURLFetcher* url_fetcher = GetRunningURLFetcher();
-    url_fetcher->set_status(net::URLRequestStatus::FromError(net::ERR_FAILED));
-    url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
-  }
-
-  void RespondWithHttpError() {
-    net::TestURLFetcher* url_fetcher = GetRunningURLFetcher();
-    url_fetcher->set_status(net::URLRequestStatus());
-    url_fetcher->set_response_code(net::HTTP_NOT_FOUND);
-    url_fetcher->delegate()->OnURLFetchComplete(url_fetcher);
+  void SetUpResponseWithNetworkError() {
+    test_url_loader_factory_.AddResponse(
+        one_google_bar_fetcher_->GetFetchURLForTesting(),
+        network::ResourceResponseHead(), std::string(),
+        network::URLLoaderCompletionStatus(net::HTTP_NOT_FOUND));
   }
 
   OneGoogleBarFetcherImpl* one_google_bar_fetcher() {
     return one_google_bar_fetcher_.get();
   }
 
+  GURL last_request_url() { return last_request_url_; }
+  net::HttpRequestHeaders last_request_headers() {
+    return last_request_headers_;
+  }
+
  private:
   // variations::AppendVariationHeaders and SafeJsonParser require a
   // threads and a ServiceManagerConnection to be set.
@@ -140,65 +143,69 @@
 
   data_decoder::TestingJsonParser::ScopedFactoryOverride factory_override_;
 
-  net::TestURLFetcherFactory url_fetcher_factory_;
-
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
-  scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
   GoogleURLTracker google_url_tracker_;
-
+  network::TestURLLoaderFactory test_url_loader_factory_;
+  scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
   base::Optional<std::string> api_url_override_;
   bool account_consistency_mirror_required_;
+
+  GURL last_request_url_;
+  net::HttpRequestHeaders last_request_headers_;
+
   std::unique_ptr<OneGoogleBarFetcherImpl> one_google_bar_fetcher_;
 };
 
 TEST_F(OneGoogleBarFetcherImplTest, RequestUrlContainsLanguage) {
+  SetUpResponseWithData(kMinimalValidResponse);
+
   // Trigger a request.
   base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
   one_google_bar_fetcher()->Fetch(callback.Get());
 
-  net::TestURLFetcher* fetcher = GetRunningURLFetcher();
-  GURL request_url = fetcher->GetOriginalURL();
+  base::RunLoop loop;
+  EXPECT_CALL(callback, Run(_, _)).WillOnce(Quit(&loop));
+  loop.Run();
 
   // Make sure the request URL contains the "hl=" query param.
   std::string expected_query =
       base::StringPrintf("hl=%s&async=fixed:0", kApplicationLocale);
-  EXPECT_EQ(expected_query, request_url.query());
+  EXPECT_EQ(expected_query, last_request_url().query());
 }
 
 TEST_F(OneGoogleBarFetcherImplTest, RequestReturns) {
+  SetUpResponseWithData(kMinimalValidResponse);
+
   base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
   one_google_bar_fetcher()->Fetch(callback.Get());
 
   base::Optional<OneGoogleBarData> data;
+  base::RunLoop loop;
   EXPECT_CALL(callback, Run(OneGoogleBarFetcher::Status::OK, _))
-      .WillOnce(SaveArg<1>(&data));
-  RespondWithData(kMinimalValidResponse);
+      .WillOnce(DoAll(SaveArg<1>(&data), Quit(&loop)));
+  loop.Run();
 
   EXPECT_TRUE(data.has_value());
 }
 
 TEST_F(OneGoogleBarFetcherImplTest, HandlesResponsePreamble) {
+  // The reponse may contain a ")]}'" prefix. The fetcher should ignore that
+  // during parsing.
+  SetUpResponseWithData(std::string(")]}'") + kMinimalValidResponse);
+
   base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
   one_google_bar_fetcher()->Fetch(callback.Get());
 
-  // The reponse may contain a ")]}'" prefix. The fetcher should ignore that
-  // during parsing.
   base::Optional<OneGoogleBarData> data;
+  base::RunLoop loop;
   EXPECT_CALL(callback, Run(OneGoogleBarFetcher::Status::OK, _))
-      .WillOnce(SaveArg<1>(&data));
-  RespondWithData(std::string(")]}'") + kMinimalValidResponse);
+      .WillOnce(DoAll(SaveArg<1>(&data), Quit(&loop)));
+  loop.Run();
 
   EXPECT_TRUE(data.has_value());
 }
 
 TEST_F(OneGoogleBarFetcherImplTest, ParsesFullResponse) {
-  base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
-  one_google_bar_fetcher()->Fetch(callback.Get());
-
-  base::Optional<OneGoogleBarData> data;
-  EXPECT_CALL(callback, Run(OneGoogleBarFetcher::Status::OK, _))
-      .WillOnce(SaveArg<1>(&data));
-  RespondWithData(R"json({"update": { "ogb": {
+  SetUpResponseWithData(R"json({"update": { "ogb": {
     "html": {
       "private_do_not_access_or_else_safe_html_wrapped_value": "bar_html_value"
     },
@@ -226,6 +233,15 @@
     }
   }}})json");
 
+  base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
+  one_google_bar_fetcher()->Fetch(callback.Get());
+
+  base::Optional<OneGoogleBarData> data;
+  base::RunLoop loop;
+  EXPECT_CALL(callback, Run(OneGoogleBarFetcher::Status::OK, _))
+      .WillOnce(DoAll(SaveArg<1>(&data), Quit(&loop)));
+  loop.Run();
+
   ASSERT_TRUE(data.has_value());
   EXPECT_THAT(data->bar_html, Eq("bar_html_value"));
   EXPECT_THAT(data->in_head_script, Eq("in_head_script_value"));
@@ -235,29 +251,9 @@
   EXPECT_THAT(data->end_of_body_script, Eq("end_of_body_script_value"));
 }
 
-class MockURLFetcherDelegateForTests
-    : public net::TestURLFetcher::DelegateForTests {
- public:
-  MOCK_METHOD1(OnRequestStart, void(int fetcher_id));
-  MOCK_METHOD1(OnChunkUpload, void(int fetcher_id));
-  MOCK_METHOD1(OnRequestEnd, void(int fetcher_id));
-};
-
-TEST_F(OneGoogleBarFetcherImplTest, SecondRequestOverridesFirst) {
-  // Trigger the first request.
-  base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> first_callback;
-  one_google_bar_fetcher()->Fetch(first_callback.Get());
-  net::TestURLFetcher* first_fetcher = GetRunningURLFetcher();
-  testing::StrictMock<MockURLFetcherDelegateForTests> first_mock_delegate;
-  first_fetcher->SetDelegateForTests(&first_mock_delegate);
-
-  // Trigger a second request. That should cancel the first one.
-  EXPECT_CALL(first_mock_delegate, OnRequestEnd(0));
-  base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> second_callback;
-  one_google_bar_fetcher()->Fetch(second_callback.Get());
-}
-
 TEST_F(OneGoogleBarFetcherImplTest, CoalescesMultipleRequests) {
+  SetUpResponseWithData(kMinimalValidResponse);
+
   // Trigger two requests.
   base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> first_callback;
   one_google_bar_fetcher()->Fetch(first_callback.Get());
@@ -268,12 +264,12 @@
   base::Optional<OneGoogleBarData> first_data;
   base::Optional<OneGoogleBarData> second_data;
 
+  base::RunLoop loop;
   EXPECT_CALL(first_callback, Run(OneGoogleBarFetcher::Status::OK, _))
       .WillOnce(SaveArg<1>(&first_data));
   EXPECT_CALL(second_callback, Run(OneGoogleBarFetcher::Status::OK, _))
-      .WillOnce(SaveArg<1>(&second_data));
-
-  RespondWithData(kMinimalValidResponse);
+      .WillOnce(DoAll(SaveArg<1>(&second_data), Quit(&loop)));
+  loop.Run();
 
   // Ensure that both requests received a response.
   EXPECT_TRUE(first_data.has_value());
@@ -281,62 +277,70 @@
 }
 
 TEST_F(OneGoogleBarFetcherImplTest, NetworkErrorIsTransient) {
+  SetUpResponseWithNetworkError();
+
   base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
   one_google_bar_fetcher()->Fetch(callback.Get());
 
+  base::RunLoop loop;
   EXPECT_CALL(callback, Run(OneGoogleBarFetcher::Status::TRANSIENT_ERROR,
-                            Eq(base::nullopt)));
-  RespondWithNetworkError();
-}
-
-TEST_F(OneGoogleBarFetcherImplTest, HttpErrorIsFatal) {
-  base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
-  one_google_bar_fetcher()->Fetch(callback.Get());
-
-  EXPECT_CALL(callback,
-              Run(OneGoogleBarFetcher::Status::FATAL_ERROR, Eq(base::nullopt)));
-  RespondWithHttpError();
+                            Eq(base::nullopt)))
+      .WillOnce(Quit(&loop));
+  loop.Run();
 }
 
 TEST_F(OneGoogleBarFetcherImplTest, InvalidJsonErrorIsFatal) {
+  SetUpResponseWithData(kMinimalValidResponse + std::string(")"));
+
   base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
   one_google_bar_fetcher()->Fetch(callback.Get());
 
+  base::RunLoop loop;
   EXPECT_CALL(callback,
-              Run(OneGoogleBarFetcher::Status::FATAL_ERROR, Eq(base::nullopt)));
-  RespondWithData(kMinimalValidResponse + std::string(")"));
+              Run(OneGoogleBarFetcher::Status::FATAL_ERROR, Eq(base::nullopt)))
+      .WillOnce(Quit(&loop));
+  loop.Run();
 }
 
 TEST_F(OneGoogleBarFetcherImplTest, IncompleteJsonErrorIsFatal) {
-  base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
-  one_google_bar_fetcher()->Fetch(callback.Get());
-
-  EXPECT_CALL(callback,
-              Run(OneGoogleBarFetcher::Status::FATAL_ERROR, Eq(base::nullopt)));
-  RespondWithData(R"json({"update": { "ogb": {
+  SetUpResponseWithData(R"json({"update": { "ogb": {
   "html": {},
   "page_hooks": {}
 }}})json");
+
+  base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
+  one_google_bar_fetcher()->Fetch(callback.Get());
+
+  base::RunLoop loop;
+  EXPECT_CALL(callback,
+              Run(OneGoogleBarFetcher::Status::FATAL_ERROR, Eq(base::nullopt)))
+      .WillOnce(Quit(&loop));
+  loop.Run();
 }
 
 TEST_F(OneGoogleBarFetcherImplTest, MirrorAccountConsistencyNotRequired) {
+  SetUpResponseWithData(kMinimalValidResponse);
+
   // Trigger a request.
   base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
   one_google_bar_fetcher()->Fetch(callback.Get());
-  net::TestURLFetcher* fetcher = GetRunningURLFetcher();
 
-  net::HttpRequestHeaders headers;
-  fetcher->GetExtraRequestHeaders(&headers);
+  base::RunLoop loop;
+  EXPECT_CALL(callback, Run(_, _)).WillOnce(Quit(&loop));
+  loop.Run();
+
 #if defined(OS_CHROMEOS)
   // On Chrome OS, X-Chrome-Connected header is present, but
   // enable_account_consistency is set to false.
   std::string header_value;
-  EXPECT_TRUE(headers.GetHeader(signin::kChromeConnectedHeader, &header_value));
+  EXPECT_TRUE(last_request_headers().GetHeader(signin::kChromeConnectedHeader,
+                                               &header_value));
   // mode = PROFILE_MODE_DEFAULT
   EXPECT_EQ("mode=0,enable_account_consistency=false", header_value);
 #else
   // On not Chrome OS, the X-Chrome-Connected header must not be present.
-  EXPECT_FALSE(headers.HasHeader(signin::kChromeConnectedHeader));
+  EXPECT_FALSE(
+      last_request_headers().HasHeader(signin::kChromeConnectedHeader));
 #endif
 }
 
@@ -349,25 +353,30 @@
 
 TEST_F(OneGoogleBarFetcherImplWithMirrorAccountConsistencyTest,
        MirrorAccountConsistencyRequired) {
+  SetUpResponseWithData(kMinimalValidResponse);
+
   // Trigger a request.
   base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
   one_google_bar_fetcher()->Fetch(callback.Get());
-  net::TestURLFetcher* fetcher = GetRunningURLFetcher();
+
+  base::RunLoop loop;
+  EXPECT_CALL(callback, Run(_, _)).WillOnce(Quit(&loop));
+  loop.Run();
 
   // Make sure mirror account consistency is requested.
-  net::HttpRequestHeaders headers;
-  fetcher->GetExtraRequestHeaders(&headers);
 #if defined(OS_CHROMEOS)
   // On Chrome OS, X-Chrome-Connected header is present, and
   // enable_account_consistency is set to true.
   std::string header_value;
-  EXPECT_TRUE(headers.GetHeader(signin::kChromeConnectedHeader, &header_value));
+  EXPECT_TRUE(last_request_headers().GetHeader(signin::kChromeConnectedHeader,
+                                               &header_value));
   // mode = PROFILE_MODE_INCOGNITO_DISABLED | PROFILE_MODE_ADD_ACCOUNT_DISABLED
   EXPECT_EQ("mode=3,enable_account_consistency=true", header_value);
 #else
   // This is not a valid case (mirror account consistency can only be required
   // on Chrome OS). This ensures in this case nothing happens.
-  EXPECT_FALSE(headers.HasHeader(signin::kChromeConnectedHeader));
+  EXPECT_FALSE(
+      last_request_headers().HasHeader(signin::kChromeConnectedHeader));
 #endif
 }
 
@@ -380,17 +389,22 @@
 
 TEST_F(OneGoogleBarFetcherImplWithRelativeApiUrlOverrideTest,
        RequestUrlRespectsOverride) {
+  SetUpResponseWithData(kMinimalValidResponse);
+
   // Trigger a request.
   base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
   one_google_bar_fetcher()->Fetch(callback.Get());
 
+  base::RunLoop loop;
+  EXPECT_CALL(callback, Run(_, _)).WillOnce(Quit(&loop));
+  loop.Run();
+
   // Make sure the request URL corresponds to the override, but also contains
   // the "hl=" query param.
-  GURL request_url = GetRunningURLFetcher()->GetOriginalURL();
-  EXPECT_EQ("/testapi", request_url.path());
+  EXPECT_EQ("/testapi", last_request_url().path());
   std::string expected_query =
       base::StringPrintf("q=a&hl=%s&async=fixed:0", kApplicationLocale);
-  EXPECT_EQ(expected_query, request_url.query());
+  EXPECT_EQ(expected_query, last_request_url().query());
 }
 
 class OneGoogleBarFetcherImplWithAbsoluteApiUrlOverrideTest
@@ -402,14 +416,19 @@
 
 TEST_F(OneGoogleBarFetcherImplWithAbsoluteApiUrlOverrideTest,
        RequestUrlRespectsOverride) {
+  SetUpResponseWithData(kMinimalValidResponse);
+
   // Trigger a request.
   base::MockCallback<OneGoogleBarFetcher::OneGoogleCallback> callback;
   one_google_bar_fetcher()->Fetch(callback.Get());
 
+  base::RunLoop loop;
+  EXPECT_CALL(callback, Run(_, _)).WillOnce(Quit(&loop));
+  loop.Run();
+
   // Make sure the request URL corresponds to the override, but also contains
   // the "hl=" query param.
-  GURL request_url = GetRunningURLFetcher()->GetOriginalURL();
   GURL expected_url = GURL(base::StringPrintf(
       "http://test.com/path?q=a&hl=%s&async=fixed:0", kApplicationLocale));
-  EXPECT_EQ(expected_url, request_url);
+  EXPECT_EQ(expected_url, last_request_url());
 }
diff --git a/chrome/browser/search/one_google_bar/one_google_bar_service_factory.cc b/chrome/browser/search/one_google_bar/one_google_bar_service_factory.cc
index 320de8a..59c7f6f 100644
--- a/chrome/browser/search/one_google_bar/one_google_bar_service_factory.cc
+++ b/chrome/browser/search/one_google_bar/one_google_bar_service_factory.cc
@@ -20,8 +20,9 @@
 #include "chrome/common/chrome_features.h"
 #include "components/content_settings/core/browser/cookie_settings.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "components/signin/core/browser/signin_header_helper.h"
+#include "components/signin/core/browser/cookie_settings_util.h"
 #include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
 
 // static
 OneGoogleBarService* OneGoogleBarServiceFactory::GetForProfile(
@@ -65,10 +66,13 @@
   }
   content_settings::CookieSettings* cookie_settings =
       CookieSettingsFactory::GetForProfile(profile).get();
+  auto url_loader_factory =
+      content::BrowserContext::GetDefaultStoragePartition(context)
+          ->GetURLLoaderFactoryForBrowserProcess();
   return new OneGoogleBarService(
       cookie_service,
       std::make_unique<OneGoogleBarFetcherImpl>(
-          profile->GetRequestContext(), google_url_tracker,
+          url_loader_factory, google_url_tracker,
           g_browser_process->GetApplicationLocale(), override_api_url,
           AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile) &&
               signin::SettingsAllowSigninCookies(cookie_settings)));
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc
index f2446fc..322ecec 100644
--- a/chrome/browser/signin/chrome_signin_client.cc
+++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -37,6 +37,7 @@
 #include "components/content_settings/core/browser/cookie_settings.h"
 #include "components/metrics/metrics_service.h"
 #include "components/prefs/pref_service.h"
+#include "components/signin/core/browser/cookie_settings_util.h"
 #include "components/signin/core/browser/profile_management_switches.h"
 #include "components/signin/core/browser/profile_oauth2_token_service.h"
 #include "components/signin/core/browser/signin_buildflags.h"
diff --git a/chrome/browser/signin/mutable_profile_oauth2_token_service_delegate.cc b/chrome/browser/signin/mutable_profile_oauth2_token_service_delegate.cc
index 2d3afb6..b8402f4e 100644
--- a/chrome/browser/signin/mutable_profile_oauth2_token_service_delegate.cc
+++ b/chrome/browser/signin/mutable_profile_oauth2_token_service_delegate.cc
@@ -60,10 +60,12 @@
   // Token was loaded.
   TOKEN_LOADED = 0,
   // Token was revoked as part of Dice migration.
-  TOKEN_REVOKED_DICE_MIGRATION,
+  TOKEN_REVOKED_DICE_MIGRATION = 1,
   // Token was revoked because it is a secondary account and account consistency
   // is disabled.
-  TOKEN_REVOKED_SECONDARY_ACCOUNT,
+  TOKEN_REVOKED_SECONDARY_ACCOUNT = 2,
+  // Token was revoked on load due to cookie settings.
+  TOKEN_REVOKED_ON_LOAD = 3,
 
   NUM_LOAD_TOKEN_FROM_DB_STATUS
 };
@@ -339,7 +341,8 @@
         SigninClient* client,
         SigninErrorController* signin_error_controller,
         AccountTrackerService* account_tracker_service,
-        signin::AccountConsistencyMethod account_consistency)
+        signin::AccountConsistencyMethod account_consistency,
+        bool revoke_all_tokens_on_load)
     : web_data_service_request_(0),
       load_credentials_state_(LOAD_CREDENTIALS_NOT_STARTED),
       backoff_entry_(&backoff_policy_),
@@ -347,7 +350,8 @@
       client_(client),
       signin_error_controller_(signin_error_controller),
       account_tracker_service_(account_tracker_service),
-      account_consistency_(account_consistency) {
+      account_consistency_(account_consistency),
+      revoke_all_tokens_on_load_(revoke_all_tokens_on_load) {
   VLOG(1) << "MutablePO2TS::MutablePO2TS";
   DCHECK(client);
   DCHECK(signin_error_controller);
@@ -686,6 +690,17 @@
           }
         }
 
+        if (load_account && revoke_all_tokens_on_load_) {
+          if (account_id == loading_primary_account_id_) {
+            RevokeCredentialsOnServer(refresh_token);
+            refresh_token = kInvalidRefreshToken;
+            PersistCredentials(account_id, refresh_token);
+          } else {
+            load_account = false;
+          }
+          load_token_status = LoadTokenFromDBStatus::TOKEN_REVOKED_ON_LOAD;
+        }
+
         UMA_HISTOGRAM_ENUMERATION(
             "Signin.LoadTokenFromDB", load_token_status,
             LoadTokenFromDBStatus::NUM_LOAD_TOKEN_FROM_DB_STATUS);
diff --git a/chrome/browser/signin/mutable_profile_oauth2_token_service_delegate.h b/chrome/browser/signin/mutable_profile_oauth2_token_service_delegate.h
index 263755f..4eae8325 100644
--- a/chrome/browser/signin/mutable_profile_oauth2_token_service_delegate.h
+++ b/chrome/browser/signin/mutable_profile_oauth2_token_service_delegate.h
@@ -38,7 +38,8 @@
       SigninClient* client,
       SigninErrorController* signin_error_controller,
       AccountTrackerService* account_tracker_service,
-      signin::AccountConsistencyMethod account_consistency);
+      signin::AccountConsistencyMethod account_consistency,
+      bool revoke_all_tokens_on_load = false);
   ~MutableProfileOAuth2TokenServiceDelegate() override;
 
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
@@ -144,6 +145,8 @@
                            CanonAndNonCanonAccountId);
   FRIEND_TEST_ALL_PREFIXES(MutableProfileOAuth2TokenServiceDelegateTest,
                            ShutdownService);
+  FRIEND_TEST_ALL_PREFIXES(MutableProfileOAuth2TokenServiceDelegateTest,
+                           ClearTokensOnStartup);
 
   // WebDataServiceConsumer implementation:
   void OnWebDataServiceRequestDone(
@@ -214,6 +217,11 @@
   AccountTrackerService* account_tracker_service_;
   signin::AccountConsistencyMethod account_consistency_;
 
+  // Revokes all the tokens after loading them. Secondary accounts will be
+  // completely removed, and the primary account will be kept in authentication
+  // error state.
+  const bool revoke_all_tokens_on_load_;
+
   DISALLOW_COPY_AND_ASSIGN(MutableProfileOAuth2TokenServiceDelegate);
 };
 
diff --git a/chrome/browser/signin/mutable_profile_oauth2_token_service_delegate_unittest.cc b/chrome/browser/signin/mutable_profile_oauth2_token_service_delegate_unittest.cc
index 3b2430a11..fde52db 100644
--- a/chrome/browser/signin/mutable_profile_oauth2_token_service_delegate_unittest.cc
+++ b/chrome/browser/signin/mutable_profile_oauth2_token_service_delegate_unittest.cc
@@ -86,7 +86,8 @@
         tokens_loaded_count_(0),
         start_batch_changes_(0),
         end_batch_changes_(0),
-        auth_error_changed_count_(0) {}
+        auth_error_changed_count_(0),
+        revoke_all_tokens_on_load_(false) {}
 
   void SetUp() override {
     OSCryptMocker::SetUp();
@@ -119,7 +120,7 @@
       signin::AccountConsistencyMethod account_consistency) {
     oauth2_service_delegate_.reset(new MutableProfileOAuth2TokenServiceDelegate(
         client_.get(), &signin_error_controller_, &account_tracker_service_,
-        account_consistency));
+        account_consistency, revoke_all_tokens_on_load_));
     // Make sure PO2TS has a chance to load itself before continuing.
     base::RunLoop().RunUntilIdle();
     oauth2_service_delegate_->AddObserver(this);
@@ -217,6 +218,7 @@
   int start_batch_changes_;
   int end_batch_changes_;
   int auth_error_changed_count_;
+  bool revoke_all_tokens_on_load_;
 };
 
 TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, PersistenceDBUpgrade) {
@@ -1335,3 +1337,57 @@
   EXPECT_TRUE(token_service_observer.error_changed_);
   oauth2_service_delegate_->RemoveObserver(&token_service_observer);
 }
+
+// Checks that set_revoke_all_tokens_on_first_load() revokes the tokens,
+// updates the database, and is applied only once.
+TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, ClearTokensOnStartup) {
+  client_->SetNetworkCallsDelayed(true);
+  revoke_all_tokens_on_load_ = true;
+  CreateOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDisabled);
+  std::string primary_account = "primaryaccount";
+  std::string secondary_account = "secondaryaccount";
+
+  oauth2_service_delegate_->RevokeAllCredentials();
+  ResetObserverCounts();
+  AddAuthTokenManually("AccountId-" + primary_account, "refresh_token");
+  AddAuthTokenManually("AccountId-" + secondary_account, "refresh_token");
+  oauth2_service_delegate_->LoadCredentials(primary_account);
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(1, tokens_loaded_count_);
+  EXPECT_EQ(1, token_available_count_);
+  EXPECT_EQ(1, token_revoked_count_);
+  EXPECT_EQ(1, start_batch_changes_);
+  EXPECT_EQ(1, end_batch_changes_);
+  EXPECT_TRUE(
+      oauth2_service_delegate_->RefreshTokenIsAvailable(primary_account));
+  EXPECT_FALSE(
+      oauth2_service_delegate_->RefreshTokenIsAvailable(secondary_account));
+  EXPECT_STREQ(
+      MutableProfileOAuth2TokenServiceDelegate::kInvalidRefreshToken,
+      oauth2_service_delegate_->GetRefreshToken(primary_account).c_str());
+  EXPECT_EQ(GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
+                GoogleServiceAuthError::InvalidGaiaCredentialsReason::
+                    CREDENTIALS_REJECTED_BY_CLIENT),
+            oauth2_service_delegate_->GetAuthError(primary_account));
+
+  // Tokens are revoked on the server.
+  EXPECT_EQ(2u, oauth2_service_delegate_->server_revokes_.size());
+  client_->SetNetworkCallsDelayed(false);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
+
+  // Check that the changes have been persisted in the database: tokens are not
+  // revoked again on the server.
+  client_->SetNetworkCallsDelayed(true);
+  oauth2_service_delegate_->LoadCredentials(primary_account);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(
+      oauth2_service_delegate_->RefreshTokenIsAvailable(primary_account));
+  EXPECT_FALSE(
+      oauth2_service_delegate_->RefreshTokenIsAvailable(secondary_account));
+  EXPECT_STREQ(
+      MutableProfileOAuth2TokenServiceDelegate::kInvalidRefreshToken,
+      oauth2_service_delegate_->GetRefreshToken(primary_account).c_str());
+  EXPECT_TRUE(oauth2_service_delegate_->server_revokes_.empty());
+}
diff --git a/chrome/browser/signin/profile_oauth2_token_service_factory.cc b/chrome/browser/signin/profile_oauth2_token_service_factory.cc
index c52d306..5a8d985 100644
--- a/chrome/browser/signin/profile_oauth2_token_service_factory.cc
+++ b/chrome/browser/signin/profile_oauth2_token_service_factory.cc
@@ -17,8 +17,11 @@
 #if defined(OS_ANDROID)
 #include "chrome/browser/signin/oauth2_token_service_delegate_android.h"
 #else
+#include "chrome/browser/content_settings/cookie_settings_factory.h"
 #include "chrome/browser/signin/mutable_profile_oauth2_token_service_delegate.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
+#include "components/content_settings/core/browser/cookie_settings.h"
+#include "components/signin/core/browser/cookie_settings_util.h"
 #endif
 
 ProfileOAuth2TokenServiceFactory::ProfileOAuth2TokenServiceFactory()
@@ -64,11 +67,20 @@
   auto delegate = std::make_unique<OAuth2TokenServiceDelegateAndroid>(
       AccountTrackerServiceFactory::GetInstance()->GetForProfile(profile));
 #else
+  signin::AccountConsistencyMethod account_consistency =
+      AccountConsistencyModeManager::GetMethodForProfile(profile);
+  // When signin cookies are cleared on exit and Dice is enabled, all tokens
+  // should also be cleared.
+  bool revoke_all_tokens_on_load =
+      (account_consistency == signin::AccountConsistencyMethod::kDice) &&
+      signin::SettingsDeleteSigninCookiesOnExit(
+          CookieSettingsFactory::GetForProfile(profile).get());
+
   auto delegate = std::make_unique<MutableProfileOAuth2TokenServiceDelegate>(
       ChromeSigninClientFactory::GetInstance()->GetForProfile(profile),
       SigninErrorControllerFactory::GetInstance()->GetForProfile(profile),
       AccountTrackerServiceFactory::GetInstance()->GetForProfile(profile),
-      AccountConsistencyModeManager::GetMethodForProfile(profile));
+      account_consistency, revoke_all_tokens_on_load);
 #endif
   ProfileOAuth2TokenService* service =
       new ProfileOAuth2TokenService(std::move(delegate));
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm
index 355e1b9..5236891 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm
@@ -189,7 +189,7 @@
 }
 
 CGFloat GetBookmarkButtonHeightMinusPadding() {
-  return GetLayoutConstant(BOOKMARK_BAR_HEIGHT) -
+  return GetCocoaLayoutConstant(BOOKMARK_BAR_HEIGHT) -
          bookmarks::kBookmarkVerticalPadding * 2;
 }
 
@@ -571,7 +571,7 @@
   // The state of our morph (if any); 1 is total bubble, 0 is the regular bar.
   CGFloat morph = [self detachedMorphProgress];
   CGFloat padding = 0;
-  padding = GetLayoutConstant(BOOKMARK_BAR_NTP_PADDING);
+  padding = GetCocoaLayoutConstant(BOOKMARK_BAR_NTP_PADDING);
   buttonViewFrame =
       NSInsetRect(buttonViewFrame, morph * padding, morph * padding);
   [buttonView_ setFrame:buttonViewFrame];
@@ -952,10 +952,10 @@
     [view setHidden:NO];
     // Height takes into account the extra height we have since the toolbar
     // only compresses when we're done.
-    [view
-        animateToNewHeight:(GetLayoutConstant(BOOKMARK_BAR_HEIGHT_NO_OVERLAP) -
-                            bookmarks::kBookmarkBarOverlap)
-                  duration:kBookmarkBarAnimationDuration];
+    [view animateToNewHeight:(GetCocoaLayoutConstant(
+                                  BOOKMARK_BAR_HEIGHT_NO_OVERLAP) -
+                              bookmarks::kBookmarkBarOverlap)
+                    duration:kBookmarkBarAnimationDuration];
   } else if ([self isAnimatingFromState:BookmarkBar::SHOW
                                 toState:BookmarkBar::HIDDEN]) {
     [view setShowsDivider:YES];
@@ -966,7 +966,7 @@
                                 toState:BookmarkBar::DETACHED]) {
     [view setShowsDivider:YES];
     [view setHidden:NO];
-    [view animateToNewHeight:GetLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT)
+    [view animateToNewHeight:GetCocoaLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT)
                     duration:kBookmarkBarAnimationDuration];
   } else if ([self isAnimatingFromState:BookmarkBar::DETACHED
                                 toState:BookmarkBar::SHOW]) {
@@ -974,10 +974,10 @@
     [view setHidden:NO];
     // Height takes into account the extra height we have since the toolbar
     // only compresses when we're done.
-    [view
-        animateToNewHeight:(GetLayoutConstant(BOOKMARK_BAR_HEIGHT_NO_OVERLAP) -
-                            bookmarks::kBookmarkBarOverlap)
-                  duration:kBookmarkBarAnimationDuration];
+    [view animateToNewHeight:(GetCocoaLayoutConstant(
+                                  BOOKMARK_BAR_HEIGHT_NO_OVERLAP) -
+                              bookmarks::kBookmarkBarOverlap)
+                    duration:kBookmarkBarAnimationDuration];
   } else {
     // Oops! An animation we don't know how to handle.
     return NO;
@@ -1003,9 +1003,9 @@
 
   switch (currentState_) {
     case BookmarkBar::SHOW:
-      return GetLayoutConstant(BOOKMARK_BAR_HEIGHT_NO_OVERLAP);
+      return GetCocoaLayoutConstant(BOOKMARK_BAR_HEIGHT_NO_OVERLAP);
     case BookmarkBar::DETACHED:
-      return GetLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT);
+      return GetCocoaLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT);
     case BookmarkBar::HIDDEN:
       return 0;
   }
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
index b239d1e..81d47ef 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
@@ -1262,7 +1262,7 @@
   EXPECT_GT([buttons count], 0u);
 
   for (NSButton* button in buttons) {
-    EXPECT_FLOAT_EQ((GetLayoutConstant(BOOKMARK_BAR_HEIGHT_NO_OVERLAP) +
+    EXPECT_FLOAT_EQ((GetCocoaLayoutConstant(BOOKMARK_BAR_HEIGHT_NO_OVERLAP) +
                      bookmarks::kMaterialVisualHeightOffset) -
                         2 * bookmarks::kBookmarkVerticalPadding,
                     [button frame].size.height);
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
index f6276c7..1075223 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm
@@ -182,8 +182,8 @@
     NSRect frame = [[test_window() contentView] frame];
     frame = NSMakeRect(
         frame.origin.x,
-        frame.size.height - GetLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT),
-        frame.size.width, GetLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT));
+        frame.size.height - GetCocoaLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT),
+        frame.size.width, GetCocoaLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT));
     NSView* fakeToolbarView = [[[NSView alloc] initWithFrame:frame]
                                 autorelease];
     [[test_window() contentView] addSubview:fakeToolbarView];
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm
index f11dbc9..3096d12 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_button_cell.mm
@@ -378,7 +378,7 @@
   // Return the space needed to display the image and title, with a little
   // distance between them.
   cellSize = NSMakeSize(kIconLeadingPadding + [[self image] size].width,
-                        GetLayoutConstant(BOOKMARK_BAR_HEIGHT));
+                        GetCocoaLayoutConstant(BOOKMARK_BAR_HEIGHT));
   NSString* title = [self visibleTitle];
   if ([title length] > 0) {
     CGFloat textWidth =
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index b591a44..8a5a9e2e3 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -697,7 +697,7 @@
 BrowserWindowCocoa::GetRenderViewHeightInsetWithDetachedBookmarkBar() {
   if (browser_->bookmark_bar_state() != BookmarkBar::DETACHED)
     return 0;
-  return GetLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT);
+  return GetCocoaLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT);
 }
 
 void BrowserWindowCocoa::ExecuteExtensionCommand(
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
index 5fae165..836a0a41 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_controller.mm
@@ -44,6 +44,10 @@
 // of the popup 2px below the bottom of the Omnibox.
 const CGFloat kBrowserActionBubbleYOffset = 3.0;
 
+// The amount of horizontal padding the browser action container should have on
+// each side.
+const CGFloat kBrowserActionHorizontalPadding = 2.0;
+
 }  // namespace
 
 @interface BrowserActionsController(Private)
@@ -356,7 +360,9 @@
 }
 
 - (gfx::Size)preferredSize {
-  return toolbarActionsBar_->GetFullSize();
+  gfx::Size size = toolbarActionsBar_->GetFullSize();
+  size.Enlarge(kBrowserActionHorizontalPadding * 2, 0);
+  return size;
 }
 
 - (NSPoint)popupPointForId:(const std::string&)id {
@@ -410,7 +416,8 @@
 }
 
 - (void)updateMaxWidth {
-  const CGFloat ownMaxWidth = toolbarActionsBar_->GetMaximumWidth();
+  const CGFloat ownMaxWidth = toolbarActionsBar_->GetMaximumWidth() +
+                              kBrowserActionHorizontalPadding * 2;
   containerView_.maxWidth =
       (maxWidth_ ? std::min(maxWidth_, ownMaxWidth) : ownMaxWidth);
 }
@@ -538,7 +545,7 @@
   BOOL animate = !toolbarActionsBar_->suppress_animation() &&
       ![containerView_ isAnimating] && [[containerView_ window] isVisible];
   [self updateContainerVisibility];
-  [containerView_ resizeToWidth:width
+  [containerView_ resizeToWidth:width + kBrowserActionHorizontalPadding * 2
                         animate:animate];
   [containerView_ setNeedsDisplay:YES];
 
@@ -742,11 +749,15 @@
   NSRect frame = frameRect.IsEmpty()
                      ? NSMakeRect(-iconWidth - 1, 0, iconWidth, size.height())
                      : NSRectFromCGRect(frameRect.ToCGRect());
+
   // We need to flip the y coordinate for Cocoa's view system.
   frame.origin.y = NSHeight([containerView_ frame]) - NSMaxY(frame);
-  if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout())
-    frame.origin.x =
-        NSWidth([containerView_ frame]) - NSWidth(frame) - NSMinX(frame);
+  if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
+    frame.origin.x = NSWidth([containerView_ frame]) - NSWidth(frame) -
+                     NSMinX(frame) - kBrowserActionHorizontalPadding;
+  } else {
+    frame.origin.x += kBrowserActionHorizontalPadding;
+  }
   return frame;
 }
 
diff --git a/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm
index 00bbf62..60ebbb9 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm
@@ -47,16 +47,7 @@
   if ([super respondsToSelector:aSelector]) {
     return YES;
   }
-
-  // Only forward methods from the NSWindowDelegate protcol.
-  Protocol* nsWindowDelegateProtocol = objc_getProtocol("NSWindowDelegate");
-  struct objc_method_description methodDescription =
-      protocol_getMethodDescription(nsWindowDelegateProtocol, aSelector, NO,
-                                    YES);
-
-  return methodDescription.name
-             ? [self.tabWindowController respondsToSelector:aSelector]
-             : NO;
+  return [self.tabWindowController respondsToSelector:aSelector];
 }
 
 - (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector {
diff --git a/chrome/browser/ui/layout_constants.cc b/chrome/browser/ui/layout_constants.cc
index cf8ba0940..d2acc921 100644
--- a/chrome/browser/ui/layout_constants.cc
+++ b/chrome/browser/ui/layout_constants.cc
@@ -7,6 +7,25 @@
 #include "base/logging.h"
 #include "ui/base/material_design/material_design_controller.h"
 
+#if defined(OS_MACOSX)
+int GetCocoaLayoutConstant(LayoutConstant constant) {
+  switch (constant) {
+    case BOOKMARK_BAR_HEIGHT:
+      return 28;
+    case BOOKMARK_BAR_NTP_HEIGHT:
+      return 39;
+    case BOOKMARK_BAR_HEIGHT_NO_OVERLAP:
+      return GetCocoaLayoutConstant(BOOKMARK_BAR_HEIGHT) - 2;
+    case BOOKMARK_BAR_NTP_PADDING:
+      return (GetCocoaLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT) -
+              GetCocoaLayoutConstant(BOOKMARK_BAR_HEIGHT)) /
+             2;
+    default:
+      return GetLayoutConstant(constant);
+  }
+}
+#endif
+
 int GetLayoutConstant(LayoutConstant constant) {
   const int mode = ui::MaterialDesignController::GetMode();
   const bool hybrid = mode == ui::MaterialDesignController::MATERIAL_HYBRID;
@@ -16,19 +35,9 @@
   switch (constant) {
     case BOOKMARK_BAR_HEIGHT:
       return touch_optimized_material ? 40 : 32;
-#if defined(OS_MACOSX)
-    case BOOKMARK_BAR_HEIGHT_NO_OVERLAP:
-      return GetLayoutConstant(BOOKMARK_BAR_HEIGHT) - 2;
-#endif
     case BOOKMARK_BAR_NTP_HEIGHT:
       return touch_optimized_material ? GetLayoutConstant(BOOKMARK_BAR_HEIGHT)
                                       : 39;
-#if defined(OS_MACOSX)
-    case BOOKMARK_BAR_NTP_PADDING:
-      return (GetLayoutConstant(BOOKMARK_BAR_NTP_HEIGHT) -
-              GetLayoutConstant(BOOKMARK_BAR_HEIGHT)) /
-             2;
-#endif
     case HOSTED_APP_MENU_BUTTON_SIZE:
       return 24;
     case LOCATION_BAR_BUBBLE_VERTICAL_PADDING:
@@ -85,6 +94,8 @@
       constexpr int kSpacings[] = {4, 8, 12, 8};
       return kSpacings[mode];
     }
+    default:
+      break;
   }
   NOTREACHED();
   return 0;
diff --git a/chrome/browser/ui/layout_constants.h b/chrome/browser/ui/layout_constants.h
index 69ed7029e..2a12a2b 100644
--- a/chrome/browser/ui/layout_constants.h
+++ b/chrome/browser/ui/layout_constants.h
@@ -125,6 +125,13 @@
 };
 
 int GetLayoutConstant(LayoutConstant constant);
+#if defined(OS_MACOSX)
+// Use this function instead of GetLayoutConstant() for Cocoa browser.
+// This will handle Cocoa specific layout constants. For non Cocoa specific
+// constants, it will call GetLayoutConstant() anyway.
+int GetCocoaLayoutConstant(LayoutConstant constant);
+#endif
+
 gfx::Insets GetLayoutInsets(LayoutInset inset);
 gfx::Size GetLayoutSize(LayoutSize size, bool is_incognito);
 
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
index a63d81c1..d560004a 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -1869,7 +1869,11 @@
   }
 
   void Step3() {
+#if defined(OS_CHROMEOS)
+    ASSERT_EQ(test_view_->press_count(), 1);
+#else
     ASSERT_EQ(test_view_->press_count(), 2);
+#endif
     ASSERT_TRUE(bb_view_->GetMenu() == NULL);
     Done();
   }
diff --git a/chrome/browser/vr/content_input_delegate.cc b/chrome/browser/vr/content_input_delegate.cc
index babe1b8..e3410f22 100644
--- a/chrome/browser/vr/content_input_delegate.cc
+++ b/chrome/browser/vr/content_input_delegate.cc
@@ -27,7 +27,7 @@
 
 void ContentInputDelegate::OnContentEnter(
     const gfx::PointF& normalized_hit_point) {
-  SendGestureToContent(
+  SendGestureToTarget(
       MakeMouseEvent(blink::WebInputEvent::kMouseEnter, normalized_hit_point));
 }
 
@@ -37,25 +37,25 @@
   // Layout. Sending a mouse leave event at 0,0 will result continuous
   // MouseMove events sent to the content if the content keeps relayout itself.
   // See crbug.com/762573 for details.
-  SendGestureToContent(
+  SendGestureToTarget(
       MakeMouseEvent(blink::WebInputEvent::kMouseLeave, kOutOfBoundsPoint));
 }
 
 void ContentInputDelegate::OnContentMove(
     const gfx::PointF& normalized_hit_point) {
-  SendGestureToContent(
+  SendGestureToTarget(
       MakeMouseEvent(blink::WebInputEvent::kMouseMove, normalized_hit_point));
 }
 
 void ContentInputDelegate::OnContentDown(
     const gfx::PointF& normalized_hit_point) {
-  SendGestureToContent(
+  SendGestureToTarget(
       MakeMouseEvent(blink::WebInputEvent::kMouseDown, normalized_hit_point));
 }
 
 void ContentInputDelegate::OnContentUp(
     const gfx::PointF& normalized_hit_point) {
-  SendGestureToContent(
+  SendGestureToTarget(
       MakeMouseEvent(blink::WebInputEvent::kMouseUp, normalized_hit_point));
 }
 
@@ -87,28 +87,28 @@
     std::unique_ptr<blink::WebGestureEvent> gesture,
     const gfx::PointF& normalized_hit_point) {
   UpdateGesture(normalized_hit_point, *gesture);
-  SendGestureToContent(std::move(gesture));
+  SendGestureToTarget(std::move(gesture));
 }
 
 void ContentInputDelegate::OnContentScrollBegin(
     std::unique_ptr<blink::WebGestureEvent> gesture,
     const gfx::PointF& normalized_hit_point) {
   UpdateGesture(normalized_hit_point, *gesture);
-  SendGestureToContent(std::move(gesture));
+  SendGestureToTarget(std::move(gesture));
 }
 
 void ContentInputDelegate::OnContentScrollUpdate(
     std::unique_ptr<blink::WebGestureEvent> gesture,
     const gfx::PointF& normalized_hit_point) {
   UpdateGesture(normalized_hit_point, *gesture);
-  SendGestureToContent(std::move(gesture));
+  SendGestureToTarget(std::move(gesture));
 }
 
 void ContentInputDelegate::OnContentScrollEnd(
     std::unique_ptr<blink::WebGestureEvent> gesture,
     const gfx::PointF& normalized_hit_point) {
   UpdateGesture(normalized_hit_point, *gesture);
-  SendGestureToContent(std::move(gesture));
+  SendGestureToTarget(std::move(gesture));
 }
 
 void ContentInputDelegate::OnSwapContents(int new_content_id) {
@@ -123,7 +123,7 @@
                                          content_tex_css_height_));
 }
 
-void ContentInputDelegate::SendGestureToContent(
+void ContentInputDelegate::SendGestureToTarget(
     std::unique_ptr<blink::WebInputEvent> event) {
   if (!event || !content_ || ContentGestureIsLocked(event->GetType()))
     return;
diff --git a/chrome/browser/vr/content_input_delegate.h b/chrome/browser/vr/content_input_delegate.h
index 29de38b..e9e27ff9 100644
--- a/chrome/browser/vr/content_input_delegate.h
+++ b/chrome/browser/vr/content_input_delegate.h
@@ -108,18 +108,20 @@
 
   void ClearTextInputState();
 
+ protected:
+  virtual void UpdateGesture(const gfx::PointF& normalized_content_hit_point,
+                             blink::WebGestureEvent& gesture);
+  virtual void SendGestureToTarget(std::unique_ptr<blink::WebInputEvent> event);
+  virtual std::unique_ptr<blink::WebMouseEvent> MakeMouseEvent(
+      blink::WebInputEvent::Type type,
+      const gfx::PointF& normalized_web_content_location);
+
  private:
   enum TextRequestState {
     kNoPendingRequest,
     kRequested,
     kResponseReceived,
   };
-  void UpdateGesture(const gfx::PointF& normalized_content_hit_point,
-                     blink::WebGestureEvent& gesture);
-  void SendGestureToContent(std::unique_ptr<blink::WebInputEvent> event);
-  std::unique_ptr<blink::WebMouseEvent> MakeMouseEvent(
-      blink::WebInputEvent::Type type,
-      const gfx::PointF& normalized_web_content_location);
   bool ContentGestureIsLocked(blink::WebInputEvent::Type type);
   void OnWebInputTextChanged(const base::string16& text);
 
diff --git a/chrome/common/custom_handlers/protocol_handler.cc b/chrome/common/custom_handlers/protocol_handler.cc
index af1a30f..e2de8df6 100644
--- a/chrome/common/custom_handlers/protocol_handler.cc
+++ b/chrome/common/custom_handlers/protocol_handler.cc
@@ -6,21 +6,22 @@
 
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/value_conversions.h"
 #include "chrome/grit/generated_resources.h"
 #include "net/base/escape.h"
 #include "ui/base/l10n/l10n_util.h"
 
 ProtocolHandler::ProtocolHandler(const std::string& protocol,
-                                 const GURL& url)
-    : protocol_(protocol),
-      url_(url) {
-}
+                                 const GURL& url,
+                                 base::Time last_modified)
+    : protocol_(base::ToLowerASCII(protocol)),
+      url_(url),
+      last_modified_(last_modified) {}
 
 ProtocolHandler ProtocolHandler::CreateProtocolHandler(
     const std::string& protocol,
     const GURL& url) {
-  std::string lower_protocol = base::ToLowerASCII(protocol);
-  return ProtocolHandler(lower_protocol, url);
+  return ProtocolHandler(protocol, url, base::Time::Now());
 }
 
 ProtocolHandler::ProtocolHandler() {
@@ -28,6 +29,7 @@
 
 bool ProtocolHandler::IsValidDict(const base::DictionaryValue* value) {
   // Note that "title" parameter is ignored.
+  // The |last_modified| field is optional as it was introduced in M68.
   return value->HasKey("protocol") && value->HasKey("url");
 }
 
@@ -47,9 +49,17 @@
     return EmptyProtocolHandler();
   }
   std::string protocol, url;
+  // |time| defaults to the beginning of time if it is not specified.
+  base::Time time;
   value->GetString("protocol", &protocol);
   value->GetString("url", &url);
-  return ProtocolHandler::CreateProtocolHandler(protocol, GURL(url));
+  const base::Value* time_value = value->FindKey("last_modified");
+  if (time_value) {
+    base::TimeDelta time_delta;
+    if (base::GetValueAsTimeDelta(*time_value, &time_delta))
+      time = base::Time::FromDeltaSinceWindowsEpoch(time_delta);
+  }
+  return ProtocolHandler(protocol, GURL(url), time);
 }
 
 GURL ProtocolHandler::TranslateUrl(const GURL& url) const {
@@ -64,6 +74,8 @@
   auto d = std::make_unique<base::DictionaryValue>();
   d->SetString("protocol", protocol_);
   d->SetString("url", url_.spec());
+  d->Set("last_modified",
+         base::CreateTimeDeltaValue(last_modified_.ToDeltaSinceWindowsEpoch()));
   return d;
 }
 
diff --git a/chrome/common/custom_handlers/protocol_handler.h b/chrome/common/custom_handlers/protocol_handler.h
index ea9a0c06..36b56799 100644
--- a/chrome/common/custom_handlers/protocol_handler.h
+++ b/chrome/common/custom_handlers/protocol_handler.h
@@ -8,17 +8,23 @@
 #include <memory>
 #include <string>
 
+#include "base/time/time.h"
 #include "base/values.h"
 #include "url/gurl.h"
 
-// A single tuple of (protocol, url) that indicates how URLs of the
-// given protocol should be rewritten to be handled.
-
+// A single tuple of (protocol, url, last_modified) that indicates how URLs
+// of the given protocol should be rewritten to be handled.
+// The |last_modified| field is used to correctly perform deletion
+// of protocol handlers based on time ranges.
 class ProtocolHandler {
  public:
   static ProtocolHandler CreateProtocolHandler(const std::string& protocol,
                                                const GURL& url);
 
+  ProtocolHandler(const std::string& protocol,
+                  const GURL& url,
+                  base::Time last_modified);
+
   // Creates a ProtocolHandler with fields from the dictionary. Returns an
   // empty ProtocolHandler if the input is invalid.
   static ProtocolHandler CreateProtocolHandler(
@@ -55,6 +61,7 @@
 
   const std::string& protocol() const { return protocol_; }
   const GURL& url() const { return url_;}
+  const base::Time& last_modified() const { return last_modified_; }
 
   bool IsEmpty() const {
     return protocol_.empty();
@@ -70,12 +77,11 @@
   bool operator<(const ProtocolHandler& other) const;
 
  private:
-  ProtocolHandler(const std::string& protocol,
-                  const GURL& url);
   ProtocolHandler();
 
   std::string protocol_;
   GURL url_;
+  base::Time last_modified_;
 };
 
 #endif  // CHROME_COMMON_CUSTOM_HANDLERS_PROTOCOL_HANDLER_H_
diff --git a/chrome/test/data/android/render_tests/ContextualSuggestionsTest.contextual_suggestions_card.Nexus_5-19.png b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.contextual_suggestions_card.Nexus_5-19.png
deleted file mode 100644
index 591b164..0000000
--- a/chrome/test/data/android/render_tests/ContextualSuggestionsTest.contextual_suggestions_card.Nexus_5-19.png
+++ /dev/null
Binary files differ
diff --git a/chrome/test/data/android/render_tests/ContextualSuggestionsTest.full_height.Nexus_5-19.png b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.full_height.Nexus_5-19.png
new file mode 100644
index 0000000..b0cef41
--- /dev/null
+++ b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.full_height.Nexus_5-19.png
Binary files differ
diff --git a/chrome/test/data/android/render_tests/ContextualSuggestionsTest.full_height_scrolled.Nexus_5-19.png b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.full_height_scrolled.Nexus_5-19.png
new file mode 100644
index 0000000..066e7af
--- /dev/null
+++ b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.full_height_scrolled.Nexus_5-19.png
Binary files differ
diff --git a/chrome/test/data/android/render_tests/ContextualSuggestionsTest.peeking_bar.Nexus_5-19.png b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.peeking_bar.Nexus_5-19.png
new file mode 100644
index 0000000..50507c5f
--- /dev/null
+++ b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.peeking_bar.Nexus_5-19.png
Binary files differ
diff --git a/chrome/test/data/android/render_tests/ContextualSuggestionsTest.suggestion_image_loaded.Nexus_5-19.png b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.suggestion_image_loaded.Nexus_5-19.png
new file mode 100644
index 0000000..3db570c
--- /dev/null
+++ b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.suggestion_image_loaded.Nexus_5-19.png
Binary files differ
diff --git a/chrome/test/data/android/render_tests/ContextualSuggestionsTest.suggestion_image_loading.Nexus_5-19.png b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.suggestion_image_loading.Nexus_5-19.png
new file mode 100644
index 0000000..7092380
--- /dev/null
+++ b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.suggestion_image_loading.Nexus_5-19.png
Binary files differ
diff --git a/chrome/test/data/android/render_tests/ContextualSuggestionsTest.suggestion_offline.Nexus_5-19.png b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.suggestion_offline.Nexus_5-19.png
new file mode 100644
index 0000000..60220ea0
--- /dev/null
+++ b/chrome/test/data/android/render_tests/ContextualSuggestionsTest.suggestion_offline.Nexus_5-19.png
Binary files differ
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 c3b10f5..2897c058 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
@@ -81,6 +81,10 @@
   this.runMochaTest(settings_sections_tests.TestNames.MediaSize);
 });
 
+TEST_F('PrintPreviewSettingsSectionsTest', 'MediaSizeCustomNames', function() {
+  this.runMochaTest(settings_sections_tests.TestNames.MediaSizeCustomNames);
+});
+
 TEST_F('PrintPreviewSettingsSectionsTest', 'Margins', function() {
   this.runMochaTest(settings_sections_tests.TestNames.Margins);
 });
@@ -137,6 +141,31 @@
   this.runMochaTest(settings_sections_tests.TestNames.SetOther);
 });
 
+PrintPreviewSettingsSelectTest = class extends NewPrintPreviewTest {
+  /** @override */
+  get browsePreload() {
+    return 'chrome://print/new/settings_select.html';
+  }
+
+  /** @override */
+  get extraLibraries() {
+    return super.extraLibraries.concat([
+      'print_preview_test_utils.js',
+      'settings_select_test.js',
+    ]);
+  }
+
+  /** @override */
+  get suiteName() {
+    return settings_select_test.suiteName;
+  }
+};
+
+TEST_F('PrintPreviewSettingsSelectTest', 'CustomMediaNames',
+       function() {
+  this.runMochaTest(settings_select_test.TestNames.CustomMediaNames);
+});
+
 PrintPreviewRestoreStateTest = class extends NewPrintPreviewTest {
   /** @override */
   get browsePreload() {
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 ec9df184..c324d80d 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
@@ -157,6 +157,35 @@
     return destinations;
   }
 
+  /**
+   * Returns a media size capability with custom and localized names.
+   * @return {!{ option: Array<!print_preview_new.SelectOption> }}
+   */
+  function getMediaSizeCapabilityWithCustomNames() {
+    const customLocalizedMediaName = 'Vendor defined localized media name';
+    const customMediaName = 'Vendor defined media name';
+
+    return {
+      option: [
+        { name: 'CUSTOM',
+          width_microns: 15900,
+          height_microns: 79400,
+          is_default: true,
+          custom_display_name_localized: [
+            { locale: navigator.language,
+              value: customLocalizedMediaName
+            }
+          ]
+        },
+        { name: 'CUSTOM',
+          width_microns: 15900,
+          height_microns: 79400,
+          custom_display_name: customMediaName
+        }
+      ]
+    };
+  }
+
   return {
     getDefaultInitialSettings: getDefaultInitialSettings,
     getCddTemplate: getCddTemplate,
@@ -165,5 +194,7 @@
     createDestinationWithCertificateStatus:
         createDestinationWithCertificateStatus,
     getDestinations: getDestinations,
+    getMediaSizeCapabilityWithCustomNames:
+        getMediaSizeCapabilityWithCustomNames,
   };
 });
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 b6959c1b..759d5e9353 100644
--- a/chrome/test/data/webui/print_preview/settings_section_test.js
+++ b/chrome/test/data/webui/print_preview/settings_section_test.js
@@ -9,6 +9,7 @@
     Layout: 'layout',
     Color: 'color',
     MediaSize: 'media size',
+    MediaSizeCustomNames: 'media size custom names',
     Margins: 'margins',
     Dpi: 'dpi',
     Scaling: 'scaling',
@@ -273,6 +274,31 @@
       assertFalse(mediaSizeElement.hidden);
     });
 
+    test(assert(TestNames.MediaSizeCustomNames), function() {
+      const customLocalizedMediaName = 'Vendor defined localized media name';
+      const customMediaName = 'Vendor defined media name';
+      const mediaSizeElement = page.$$('print-preview-media-size-settings');
+
+      // Expand more settings to reveal the element.
+      toggleMoreSettings();
+      assertFalse(mediaSizeElement.hidden);
+
+      // Change capability to have custom paper sizes.
+      let capabilities =
+          print_preview_test_utils.getCddTemplate('FooPrinter').capabilities;
+      capabilities.printer.media_size =
+          print_preview_test_utils.getMediaSizeCapabilityWithCustomNames();
+      page.set('destination_.capabilities', capabilities);
+      Polymer.dom.flush();
+
+      const settingsSelect =
+          mediaSizeElement.$$('print-preview-settings-select');
+
+      assertEquals(capabilities.printer.media_size, settingsSelect.capability);
+      assertFalse(settingsSelect.disabled);
+      assertEquals('mediaSize', settingsSelect.settingName);
+    });
+
     test(assert(TestNames.Margins), function() {
       const marginsElement = page.$$('print-preview-margins-settings');
 
diff --git a/chrome/test/data/webui/print_preview/settings_select_test.js b/chrome/test/data/webui/print_preview/settings_select_test.js
new file mode 100644
index 0000000..f183178
--- /dev/null
+++ b/chrome/test/data/webui/print_preview/settings_select_test.js
@@ -0,0 +1,51 @@
+// 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.
+
+cr.define('settings_select_test', function() {
+  /** @enum {string} */
+  const TestNames = {
+    CustomMediaNames: 'custom media names',
+  };
+
+  const suiteName = 'SettingsSelectTest';
+  suite(suiteName, function() {
+    let settingsSelect = null;
+
+    /** @override */
+    setup(function() {
+      PolymerTest.clearBody();
+      settingsSelect = document.createElement('print-preview-settings-select');
+      settingsSelect.disabled = false;
+      document.body.appendChild(settingsSelect);
+    });
+
+    // Test that destinations are correctly displayed in the lists.
+    test(assert(TestNames.CustomMediaNames), function() {
+      // Set a capability with custom paper sizes.
+      settingsSelect.settingName = 'mediaSize';
+      settingsSelect.capability =
+          print_preview_test_utils.getMediaSizeCapabilityWithCustomNames();
+      const customLocalizedMediaName =
+          settingsSelect.capability.option[0].custom_display_name_localized[0]
+              .value;
+      const customMediaName =
+          settingsSelect.capability.option[1].custom_display_name;
+      Polymer.dom.flush();
+
+      const select = settingsSelect.$$('select');
+      // 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());
+    });
+  });
+
+  return {
+    suiteName: suiteName,
+    TestNames: TestNames,
+  };
+});
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn
index 994d99c0..1c39788 100644
--- a/chromecast/browser/BUILD.gn
+++ b/chromecast/browser/BUILD.gn
@@ -224,6 +224,8 @@
       "cast_web_view_extension.h",
       "extension_request_protocol_handler.cc",
       "extension_request_protocol_handler.h",
+      "extensions/api/automation_internal/automation_event_router.cc",
+      "extensions/api/automation_internal/automation_event_router.h",
       "extensions/api/automation_internal/automation_internal_api.cc",
       "extensions/api/automation_internal/automation_internal_api.h",
       "extensions/api/bookmarks/bookmarks_api.cc",
diff --git a/chromecast/browser/extensions/api/automation_internal/automation_event_router.cc b/chromecast/browser/extensions/api/automation_internal/automation_event_router.cc
new file mode 100644
index 0000000..639ff39
--- /dev/null
+++ b/chromecast/browser/extensions/api/automation_internal/automation_event_router.cc
@@ -0,0 +1,165 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/browser/extensions/api/automation_internal/automation_event_router.h"
+
+#include <algorithm>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/stl_util.h"
+#include "base/values.h"
+#include "build/build_config.h"
+#include "chromecast/common/extensions_api/automation_api_constants.h"
+#include "chromecast/common/extensions_api/automation_internal.h"
+#include "chromecast/common/extensions_api/cast_extension_messages.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_process_host.h"
+#include "extensions/browser/event_router.h"
+#include "extensions/common/extension.h"
+#include "ui/accessibility/ax_action_data.h"
+#include "ui/accessibility/ax_enums.mojom.h"
+#include "ui/accessibility/ax_node_data.h"
+
+namespace extensions {
+namespace cast {
+
+// static
+AutomationEventRouter* AutomationEventRouter::GetInstance() {
+  return base::Singleton<
+      AutomationEventRouter,
+      base::LeakySingletonTraits<AutomationEventRouter>>::get();
+}
+
+AutomationEventRouter::AutomationEventRouter() {
+  registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
+                 content::NotificationService::AllBrowserContextsAndSources());
+  registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
+                 content::NotificationService::AllBrowserContextsAndSources());
+}
+
+AutomationEventRouter::~AutomationEventRouter() {}
+
+void AutomationEventRouter::RegisterListenerForOneTree(
+    const ExtensionId& extension_id,
+    int listener_process_id,
+    int source_ax_tree_id) {
+  Register(extension_id, listener_process_id, source_ax_tree_id, false);
+}
+
+void AutomationEventRouter::RegisterListenerWithDesktopPermission(
+    const ExtensionId& extension_id,
+    int listener_process_id) {
+  Register(extension_id, listener_process_id,
+           ::extensions::api::automation::kDesktopTreeID, true);
+}
+
+void AutomationEventRouter::DispatchAccessibilityEvents(
+    const std::vector<ExtensionMsg_AccessibilityEventParams>& events) {
+  if (events.empty())
+    return;
+
+  for (const auto& listener : listeners_) {
+    // Skip listeners that don't want to listen to this tree.
+    if (!listener.desktop &&
+        listener.tree_ids.find(events[0].tree_id) == listener.tree_ids.end()) {
+      continue;
+    }
+
+    content::RenderProcessHost* rph =
+        content::RenderProcessHost::FromID(listener.process_id);
+    rph->Send(new ExtensionMsg_AccessibilityEvents(events, true));
+  }
+}
+
+void AutomationEventRouter::DispatchAccessibilityLocationChange(
+    const ExtensionMsg_AccessibilityLocationChangeParams& params) {
+  for (const auto& listener : listeners_) {
+    // Skip listeners that don't want to listen to this tree.
+    if (!listener.desktop &&
+        listener.tree_ids.find(params.tree_id) == listener.tree_ids.end()) {
+      continue;
+    }
+
+    content::RenderProcessHost* rph =
+        content::RenderProcessHost::FromID(listener.process_id);
+    rph->Send(new ExtensionMsg_AccessibilityLocationChange(params));
+  }
+}
+
+void AutomationEventRouter::DispatchTreeDestroyedEvent(
+    int tree_id,
+    content::BrowserContext* browser_context) {
+  if (listeners_.empty())
+    return;
+
+  std::unique_ptr<base::ListValue> args(
+      api::automation_internal::OnAccessibilityTreeDestroyed::Create(tree_id));
+  auto event = std::make_unique<Event>(
+      events::AUTOMATION_INTERNAL_ON_ACCESSIBILITY_TREE_DESTROYED,
+      api::automation_internal::OnAccessibilityTreeDestroyed::kEventName,
+      std::move(args), browser_context);
+  EventRouter::Get(browser_context)->BroadcastEvent(std::move(event));
+}
+
+AutomationEventRouter::AutomationListener::AutomationListener() {}
+
+AutomationEventRouter::AutomationListener::AutomationListener(
+    const AutomationListener& other) = default;
+
+AutomationEventRouter::AutomationListener::~AutomationListener() {}
+
+void AutomationEventRouter::Register(const ExtensionId& extension_id,
+                                     int listener_process_id,
+                                     int ax_tree_id,
+                                     bool desktop) {
+  auto iter =
+      std::find_if(listeners_.begin(), listeners_.end(),
+                   [listener_process_id](const AutomationListener& item) {
+                     return item.process_id == listener_process_id;
+                   });
+
+  // Add a new entry if we don't have one with that process.
+  if (iter == listeners_.end()) {
+    AutomationListener listener;
+    listener.extension_id = extension_id;
+    listener.process_id = listener_process_id;
+    listener.desktop = desktop;
+    listener.tree_ids.insert(ax_tree_id);
+    listeners_.push_back(listener);
+    return;
+  }
+
+  // We have an entry with that process so update the set of tree ids it wants
+  // to listen to, and update its desktop permission.
+  iter->tree_ids.insert(ax_tree_id);
+  if (desktop)
+    iter->desktop = true;
+}
+
+void AutomationEventRouter::Observe(
+    int type,
+    const content::NotificationSource& source,
+    const content::NotificationDetails& details) {
+  if (type != content::NOTIFICATION_RENDERER_PROCESS_TERMINATED &&
+      type != content::NOTIFICATION_RENDERER_PROCESS_CLOSED) {
+    NOTREACHED();
+    return;
+  }
+
+  content::RenderProcessHost* rph =
+      content::Source<content::RenderProcessHost>(source).ptr();
+  int process_id = rph->GetID();
+  listeners_.erase(std::remove_if(listeners_.begin(), listeners_.end(),
+                                  [process_id](const AutomationListener& item) {
+                                    return item.process_id == process_id;
+                                  }),
+                   listeners_.end());
+}
+
+}  // namespace cast
+}  // namespace extensions
diff --git a/chromecast/browser/extensions/api/automation_internal/automation_event_router.h b/chromecast/browser/extensions/api/automation_internal/automation_event_router.h
new file mode 100644
index 0000000..09b321b
--- /dev/null
+++ b/chromecast/browser/extensions/api/automation_internal/automation_event_router.h
@@ -0,0 +1,99 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMECAST_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_AUTOMATION_EVENT_ROUTER_H_
+#define CHROMECAST_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_AUTOMATION_EVENT_ROUTER_H_
+
+#include <set>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/singleton.h"
+#include "chromecast/common/extensions_api/automation_internal.h"
+#include "content/public/browser/ax_event_notification_details.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "extensions/common/extension_id.h"
+
+namespace content {
+class BrowserContext;
+}  // namespace content
+
+namespace ui {
+struct AXActionData;
+}  // namespace ui
+
+struct ExtensionMsg_AccessibilityEventParams;
+struct ExtensionMsg_AccessibilityLocationChangeParams;
+
+namespace extensions {
+namespace cast {
+struct AutomationListener;
+
+class AutomationEventRouter : public content::NotificationObserver {
+ public:
+  static AutomationEventRouter* GetInstance();
+
+  // Indicates that the listener at |listener_process_id| wants to receive
+  // automation events from the accessibility tree indicated by
+  // |source_ax_tree_id|. Automation events are forwarded from now on until the
+  // listener process dies.
+  void RegisterListenerForOneTree(const ExtensionId& extension_id,
+                                  int listener_process_id,
+                                  int source_ax_tree_id);
+
+  // Indicates that the listener at |listener_process_id| wants to receive
+  // automation events from all accessibility trees because it has Desktop
+  // permission.
+  void RegisterListenerWithDesktopPermission(const ExtensionId& extension_id,
+                                             int listener_process_id);
+
+  void DispatchAccessibilityEvents(
+      const std::vector<ExtensionMsg_AccessibilityEventParams>& events);
+
+  void DispatchAccessibilityLocationChange(
+      const ExtensionMsg_AccessibilityLocationChangeParams& params);
+
+  // Notify all automation extensions that an accessibility tree was
+  // destroyed. If |browser_context| is null,
+  void DispatchTreeDestroyedEvent(int tree_id,
+                                  content::BrowserContext* browser_context);
+
+ private:
+  struct AutomationListener {
+    AutomationListener();
+    AutomationListener(const AutomationListener& other);
+    ~AutomationListener();
+
+    ExtensionId extension_id;
+    int process_id;
+    bool desktop;
+    std::set<int> tree_ids;
+  };
+
+  AutomationEventRouter();
+  ~AutomationEventRouter() override;
+
+  void Register(const ExtensionId& extension_id,
+                int listener_process_id,
+                int source_ax_tree_id,
+                bool desktop);
+
+  // content::NotificationObserver interface.
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
+
+  content::NotificationRegistrar registrar_;
+  std::vector<AutomationListener> listeners_;
+
+  friend struct base::DefaultSingletonTraits<AutomationEventRouter>;
+
+  DISALLOW_COPY_AND_ASSIGN(AutomationEventRouter);
+};
+
+}  // namespace cast
+}  // namespace extensions
+
+#endif  // CHROMECAST_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_AUTOMATION_EVENT_ROUTER_H_
diff --git a/chromecast/common/BUILD.gn b/chromecast/common/BUILD.gn
index 8540444..96d9ce4d 100644
--- a/chromecast/common/BUILD.gn
+++ b/chromecast/common/BUILD.gn
@@ -30,6 +30,8 @@
     sources += [
       "cast_extensions_client.cc",
       "cast_extensions_client.h",
+      "extensions_api/cast_extension_messages.cc",
+      "extensions_api/cast_extension_messages.h",
     ]
 
     deps += [
diff --git a/chromecast/common/DEPS b/chromecast/common/DEPS
index 5733541..3feb54c9 100644
--- a/chromecast/common/DEPS
+++ b/chromecast/common/DEPS
@@ -5,6 +5,7 @@
   "+extensions/grit",
   "+extensions/shell/common/api",
   "+extensions/shell/grit",
+  "+ui/accessibility",
   "+ui/base",
   "+ui/gfx",
 ]
diff --git a/chromecast/common/extensions_api/OWNERS b/chromecast/common/extensions_api/OWNERS
new file mode 100644
index 0000000..0afdfaa
--- /dev/null
+++ b/chromecast/common/extensions_api/OWNERS
@@ -0,0 +1,4 @@
+per-file *_messages.cc=set noparent
+per-file *_messages.cc=file://ipc/SECURITY_OWNERS
+per-file *_messages*.h=set noparent
+per-file *_messages*.h=file://ipc/SECURITY_OWNERS
diff --git a/chromecast/common/extensions_api/cast_extension_messages.cc b/chromecast/common/extensions_api/cast_extension_messages.cc
new file mode 100644
index 0000000..cbbc2cb
--- /dev/null
+++ b/chromecast/common/extensions_api/cast_extension_messages.cc
@@ -0,0 +1,70 @@
+// Copyright (c) 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.
+//
+
+// Get basic type definitions.
+#define IPC_MESSAGE_IMPL
+#undef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#include "chromecast/common/extensions_api/cast_extension_messages.h"
+#include "content/public/common/common_param_traits.h"
+#ifndef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#error "Failed to include header chromecast/common/extensions_api/"
+"chrome_extension_messages.h"
+#endif
+
+// Generate constructors.
+#include "ipc/struct_constructor_macros.h"
+#undef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#include "chromecast/common/extensions_api/cast_extension_messages.h"
+#include "content/public/common/common_param_traits.h"
+#ifndef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#error "Failed to include header chromecast/common/extensions_api/"
+    "chrome_extension_messages.h"
+#endif
+
+// Generate destructors.
+#include "ipc/struct_destructor_macros.h"
+#undef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#include "chromecast/common/extensions_api/cast_extension_messages.h"
+#include "content/public/common/common_param_traits.h"
+#ifndef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#error "Failed to include header chromecast/common/extensions_api/"
+    "chrome_extension_messages.h"
+#endif
+
+// Generate param traits write methods.
+#include "ipc/param_traits_write_macros.h"
+    namespace IPC {
+#undef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#include "chromecast/common/extensions_api/cast_extension_messages.h"
+#include "content/public/common/common_param_traits.h"
+#ifndef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#error "Failed to include header chromecast/common/extensions_api/"
+  "chrome_extension_messages.h"
+#endif
+}  // namespace IPC
+
+// Generate param traits read methods.
+#include "ipc/param_traits_read_macros.h"
+namespace IPC {
+#undef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#include "chromecast/common/extensions_api/cast_extension_messages.h"
+#include "content/public/common/common_param_traits.h"
+#ifndef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#error "Failed to include header chromecast/common/extensions_api/"
+"chrome_extension_messages.h"
+#endif
+}  // namespace IPC
+
+// Generate param traits log methods.
+#include "ipc/param_traits_log_macros.h"
+namespace IPC {
+#undef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#include "chromecast/common/extensions_api/cast_extension_messages.h"
+#include "content/public/common/common_param_traits.h"
+#ifndef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#error "Failed to include header chromecast/common/extensions_api/"
+"chrome_extension_messages.h"
+#endif
+}  // namespace IPC
diff --git a/chromecast/common/extensions_api/cast_extension_messages.h b/chromecast/common/extensions_api/cast_extension_messages.h
new file mode 100644
index 0000000..33b63bbc
--- /dev/null
+++ b/chromecast/common/extensions_api/cast_extension_messages.h
@@ -0,0 +1,125 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+#define CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
+
+// Cast-specific IPC messages for extensions.
+// Extension-related messages that aren't specific to Chromecast live in
+// extensions/common/extension_messages.h.
+
+#include <stdint.h>
+
+#include <string>
+
+#include "base/strings/string16.h"
+#include "base/values.h"
+#include "chromecast/common/extensions_api/automation_internal.h"
+#include "extensions/common/stack_frame.h"
+#include "ipc/ipc_message_macros.h"
+#include "ui/accessibility/ax_enums.mojom.h"
+#include "ui/accessibility/ax_node_data.h"
+#include "ui/accessibility/ax_relative_bounds.h"
+#include "ui/accessibility/ax_tree_data.h"
+#include "ui/accessibility/ax_tree_update.h"
+#include "ui/gfx/transform.h"
+#include "url/gurl.h"
+
+#define IPC_MESSAGE_START ChromeExtensionMsgStart
+
+// Messages sent from the browser to the renderer.
+
+IPC_STRUCT_TRAITS_BEGIN(ui::AXNodeData)
+  IPC_STRUCT_TRAITS_MEMBER(id)
+  IPC_STRUCT_TRAITS_MEMBER(role)
+  IPC_STRUCT_TRAITS_MEMBER(state)
+  IPC_STRUCT_TRAITS_MEMBER(actions)
+  IPC_STRUCT_TRAITS_MEMBER(location)
+  IPC_STRUCT_TRAITS_MEMBER(transform)
+  IPC_STRUCT_TRAITS_MEMBER(string_attributes)
+  IPC_STRUCT_TRAITS_MEMBER(int_attributes)
+  IPC_STRUCT_TRAITS_MEMBER(float_attributes)
+  IPC_STRUCT_TRAITS_MEMBER(bool_attributes)
+  IPC_STRUCT_TRAITS_MEMBER(intlist_attributes)
+  IPC_STRUCT_TRAITS_MEMBER(stringlist_attributes)
+  IPC_STRUCT_TRAITS_MEMBER(html_attributes)
+  IPC_STRUCT_TRAITS_MEMBER(child_ids)
+  IPC_STRUCT_TRAITS_MEMBER(offset_container_id)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(ui::AXTreeData)
+  IPC_STRUCT_TRAITS_MEMBER(tree_id)
+  IPC_STRUCT_TRAITS_MEMBER(parent_tree_id)
+  IPC_STRUCT_TRAITS_MEMBER(focused_tree_id)
+  IPC_STRUCT_TRAITS_MEMBER(url)
+  IPC_STRUCT_TRAITS_MEMBER(title)
+  IPC_STRUCT_TRAITS_MEMBER(mimetype)
+  IPC_STRUCT_TRAITS_MEMBER(doctype)
+  IPC_STRUCT_TRAITS_MEMBER(loaded)
+  IPC_STRUCT_TRAITS_MEMBER(loading_progress)
+  IPC_STRUCT_TRAITS_MEMBER(focus_id)
+  IPC_STRUCT_TRAITS_MEMBER(sel_anchor_object_id)
+  IPC_STRUCT_TRAITS_MEMBER(sel_anchor_offset)
+  IPC_STRUCT_TRAITS_MEMBER(sel_anchor_affinity)
+  IPC_STRUCT_TRAITS_MEMBER(sel_focus_object_id)
+  IPC_STRUCT_TRAITS_MEMBER(sel_focus_offset)
+  IPC_STRUCT_TRAITS_MEMBER(sel_focus_affinity)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(ui::AXTreeUpdate)
+  IPC_STRUCT_TRAITS_MEMBER(has_tree_data)
+  IPC_STRUCT_TRAITS_MEMBER(tree_data)
+  IPC_STRUCT_TRAITS_MEMBER(node_id_to_clear)
+  IPC_STRUCT_TRAITS_MEMBER(root_id)
+  IPC_STRUCT_TRAITS_MEMBER(nodes)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_BEGIN(ExtensionMsg_AccessibilityEventParams)
+  // ID of the accessibility tree that this event applies to.
+  IPC_STRUCT_MEMBER(int, tree_id)
+
+  // The tree update.
+  IPC_STRUCT_MEMBER(ui::AXTreeUpdate, update)
+
+  // Type of event.
+  IPC_STRUCT_MEMBER(ax::mojom::Event, event_type)
+
+  // ID of the node that the event applies to.
+  IPC_STRUCT_MEMBER(int, id)
+
+  // The source of this event.
+  IPC_STRUCT_MEMBER(ax::mojom::EventFrom, event_from)
+
+  // The mouse location in screen coordinates.
+  IPC_STRUCT_MEMBER(gfx::Point, mouse_location)
+
+  // ID of the action request triggering this event.
+  IPC_STRUCT_MEMBER(int, action_request_id)
+IPC_STRUCT_END()
+
+IPC_STRUCT_BEGIN(ExtensionMsg_AccessibilityLocationChangeParams)
+  // ID of the accessibility tree that this event applies to.
+  IPC_STRUCT_MEMBER(int, tree_id)
+
+  // ID of the object whose location is changing.
+  IPC_STRUCT_MEMBER(int, id)
+
+  // The object's new location info.
+  IPC_STRUCT_MEMBER(ui::AXRelativeBounds, new_location)
+IPC_STRUCT_END()
+
+// Forward an accessibility message to an extension process where an
+// extension is using the automation API to listen for accessibility events.
+IPC_MESSAGE_CONTROL2(
+    ExtensionMsg_AccessibilityEvents,
+    std::vector<ExtensionMsg_AccessibilityEventParams> /* events */,
+    bool /* is_active_profile */)
+
+// Forward an accessibility location change message to an extension process
+// where an extension is using the automation API to listen for
+// accessibility events.
+IPC_MESSAGE_CONTROL1(ExtensionMsg_AccessibilityLocationChange,
+                     ExtensionMsg_AccessibilityLocationChangeParams)
+
+#endif  // CHROMECAST_COMMON_EXTENSIONS_API_CAST_EXTENSION_MESSAGES_H_
diff --git a/chromeos/audio/chromeos_sounds.h b/chromeos/audio/chromeos_sounds.h
index 288aa234..5bdbe93 100644
--- a/chromeos/audio/chromeos_sounds.h
+++ b/chromeos/audio/chromeos_sounds.h
@@ -28,6 +28,7 @@
   SOUND_COUNT,
   SOUND_DICTATION_END,
   SOUND_DICTATION_START,
+  SOUND_DICTATION_CANCEL,
 };
 
 }  // namespace chromeos
diff --git a/components/bookmarks/browser/BUILD.gn b/components/bookmarks/browser/BUILD.gn
index 4299512..bc0d9a3c 100644
--- a/components/bookmarks/browser/BUILD.gn
+++ b/components/bookmarks/browser/BUILD.gn
@@ -5,46 +5,49 @@
 import("//build/config/ui.gni")
 
 static_library("browser") {
-  sources = [
-    "base_bookmark_model_observer.cc",
+  public = [
     "base_bookmark_model_observer.h",
-    "bookmark_client.cc",
     "bookmark_client.h",
-    "bookmark_codec.cc",
     "bookmark_codec.h",
-    "bookmark_expanded_state_tracker.cc",
     "bookmark_expanded_state_tracker.h",
-    "bookmark_model.cc",
     "bookmark_model.h",
     "bookmark_model_observer.h",
-    "bookmark_node.cc",
     "bookmark_node.h",
-    "bookmark_node_data.cc",
     "bookmark_node_data.h",
-    "bookmark_node_data_ios.cc",
-    "bookmark_node_data_mac.cc",
     "bookmark_pasteboard_helper_mac.h",
-    "bookmark_pasteboard_helper_mac.mm",
-    "bookmark_storage.cc",
     "bookmark_storage.h",
     "bookmark_undo_delegate.h",
     "bookmark_undo_provider.h",
-    "bookmark_utils.cc",
     "bookmark_utils.h",
-    "scoped_group_bookmark_actions.cc",
     "scoped_group_bookmark_actions.h",
-    "startup_task_runner_service.cc",
     "startup_task_runner_service.h",
-    "titled_url_index.cc",
     "titled_url_index.h",
-    "titled_url_match.cc",
     "titled_url_match.h",
     "titled_url_node.h",
     "titled_url_node_sorter.h",
-    "typed_count_sorter.cc",
     "typed_count_sorter.h",
     "url_and_title.h",
   ]
+  sources = [
+    "base_bookmark_model_observer.cc",
+    "bookmark_client.cc",
+    "bookmark_codec.cc",
+    "bookmark_expanded_state_tracker.cc",
+    "bookmark_model.cc",
+    "bookmark_node.cc",
+    "bookmark_node_data.cc",
+    "bookmark_node_data_ios.cc",
+    "bookmark_node_data_mac.cc",
+    "bookmark_pasteboard_helper_mac.mm",
+    "bookmark_storage.cc",
+    "bookmark_utils.cc",
+    "scoped_group_bookmark_actions.cc",
+    "startup_task_runner_service.cc",
+    "titled_url_index.cc",
+    "titled_url_match.cc",
+    "typed_count_sorter.cc",
+    "typed_count_sorter.h",
+  ]
 
   public_deps = [
     "//components/bookmarks/common",
diff --git a/components/browsing_data/content/BUILD.gn b/components/browsing_data/content/BUILD.gn
index 63c1b92f..179a40a 100644
--- a/components/browsing_data/content/BUILD.gn
+++ b/components/browsing_data/content/BUILD.gn
@@ -6,8 +6,6 @@
   sources = [
     "conditional_cache_counting_helper.cc",
     "conditional_cache_counting_helper.h",
-    "counters/site_settings_counter.cc",
-    "counters/site_settings_counter.h",
   ]
 
   configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
diff --git a/components/browsing_data/core/counters/browsing_data_counter.h b/components/browsing_data/core/counters/browsing_data_counter.h
index bc52224..3c606bb7 100644
--- a/components/browsing_data/core/counters/browsing_data_counter.h
+++ b/components/browsing_data/core/counters/browsing_data_counter.h
@@ -77,7 +77,7 @@
     DISALLOW_COPY_AND_ASSIGN(SyncResult);
   };
 
-  typedef base::Callback<void(std::unique_ptr<Result>)> Callback;
+  typedef base::RepeatingCallback<void(std::unique_ptr<Result>)> Callback;
 
   // Every calculation progresses through a state machine. At initialization,
   // the counter is IDLE. If a result is calculated within a given time
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index f329c9ef..08ca006 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -1593,7 +1593,7 @@
   }
 }
 
-_maven_dir = "$_package_dir/maven"
+_maven_dir = "$_package_dir/maven-$current_cpu"
 _maven_modules_dir = "$_maven_dir/org/chromium/net"
 _maven_test_dir = "$_maven_dir/test"
 
diff --git a/components/cronet/stale_host_resolver_unittest.cc b/components/cronet/stale_host_resolver_unittest.cc
index d8ea7ac..ae85ef7 100644
--- a/components/cronet/stale_host_resolver_unittest.cc
+++ b/components/cronet/stale_host_resolver_unittest.cc
@@ -319,7 +319,13 @@
   WaitForIdle();
 }
 
-TEST_F(StaleHostResolverTest, StaleCache) {
+// Flaky on Linux ASan, crbug.com/838524.
+#if defined(ADDRESS_SANITIZER)
+#define MAYBE_StaleCache DISABLED_StaleCache
+#else
+#define MAYBE_StaleCache StaleCache
+#endif
+TEST_F(StaleHostResolverTest, MAYBE_StaleCache) {
   SetStaleDelay(kNoStaleDelaySec);
   CreateResolver();
   CreateCacheEntry(kAgeExpiredSec, net::OK);
diff --git a/components/feed/core/feed_host_service.cc b/components/feed/core/feed_host_service.cc
index 2d2214a..7047887b 100644
--- a/components/feed/core/feed_host_service.cc
+++ b/components/feed/core/feed_host_service.cc
@@ -4,10 +4,18 @@
 
 #include "components/feed/core/feed_host_service.h"
 
+#include <utility>
+
 namespace feed {
 
-FeedHostService::FeedHostService() {}
+FeedHostService::FeedHostService(
+    std::unique_ptr<FeedNetworkingHost> networking_host)
+    : networking_host_(std::move(networking_host)) {}
 
 FeedHostService::~FeedHostService() = default;
 
+FeedNetworkingHost* FeedHostService::GetFeedNetworkingHost() {
+  return networking_host_.get();
+}
+
 }  // namespace feed
diff --git a/components/feed/core/feed_host_service.h b/components/feed/core/feed_host_service.h
index 4ec7c592..c94f049 100644
--- a/components/feed/core/feed_host_service.h
+++ b/components/feed/core/feed_host_service.h
@@ -5,7 +5,10 @@
 #ifndef COMPONENTS_FEED_CORE_FEED_HOST_SERVICE_H_
 #define COMPONENTS_FEED_CORE_FEED_HOST_SERVICE_H_
 
+#include <memory>
+
 #include "base/macros.h"
+#include "components/feed/core/feed_networking_host.h"
 #include "components/keyed_service/core/keyed_service.h"
 
 namespace feed {
@@ -17,10 +20,13 @@
 // yet.
 class FeedHostService : public KeyedService {
  public:
-  FeedHostService();
+  explicit FeedHostService(std::unique_ptr<FeedNetworkingHost> networking_host);
   ~FeedHostService() override;
+  FeedNetworkingHost* GetFeedNetworkingHost();
 
  private:
+  std::unique_ptr<FeedNetworkingHost> networking_host_;
+
   DISALLOW_COPY_AND_ASSIGN(FeedHostService);
 };
 
diff --git a/components/mirroring/service/video_capture_client.h b/components/mirroring/service/video_capture_client.h
index 9108c30..0df429e81 100644
--- a/components/mirroring/service/video_capture_client.h
+++ b/components/mirroring/service/video_capture_client.h
@@ -16,6 +16,7 @@
 
 namespace media {
 class VideoFrame;
+class VideoFrameMetadata;
 }  // namespace media
 
 namespace mirroring {
diff --git a/components/mirroring/service/video_capture_client_unittest.cc b/components/mirroring/service/video_capture_client_unittest.cc
index 2768de5..2d07245 100644
--- a/components/mirroring/service/video_capture_client_unittest.cc
+++ b/components/mirroring/service/video_capture_client_unittest.cc
@@ -8,6 +8,8 @@
 #include "base/test/mock_callback.h"
 #include "base/test/scoped_task_environment.h"
 #include "components/mirroring/service/fake_video_capture_host.h"
+#include "media/base/video_frame.h"
+#include "media/base/video_frame_metadata.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/nacl/browser/nacl_host_message_filter.cc b/components/nacl/browser/nacl_host_message_filter.cc
index fbf1c0c..603fdad6 100644
--- a/components/nacl/browser/nacl_host_message_filter.cc
+++ b/components/nacl/browser/nacl_host_message_filter.cc
@@ -23,8 +23,6 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
 #include "ipc/ipc_platform_file.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
 #include "ppapi/shared_impl/ppapi_permissions.h"
 #include "url/gurl.h"
 
@@ -77,15 +75,12 @@
 NaClHostMessageFilter::NaClHostMessageFilter(
     int render_process_id,
     bool is_off_the_record,
-    const base::FilePath& profile_directory,
-    net::URLRequestContextGetter* request_context)
+    const base::FilePath& profile_directory)
     : BrowserMessageFilter(NaClHostMsgStart),
       render_process_id_(render_process_id),
       off_the_record_(is_off_the_record),
       profile_directory_(profile_directory),
-      request_context_(request_context),
-      weak_ptr_factory_(this) {
-}
+      weak_ptr_factory_(this) {}
 
 NaClHostMessageFilter::~NaClHostMessageFilter() {
 }
@@ -122,10 +117,6 @@
   return handled;
 }
 
-net::HostResolver* NaClHostMessageFilter::GetHostResolver() {
-  return request_context_->GetURLRequestContext()->host_resolver();
-}
-
 void NaClHostMessageFilter::OnLaunchNaCl(
     const nacl::NaClLaunchParams& launch_params,
     IPC::Message* reply_msg) {
diff --git a/components/nacl/browser/nacl_host_message_filter.h b/components/nacl/browser/nacl_host_message_filter.h
index 56192293..6948e9a 100644
--- a/components/nacl/browser/nacl_host_message_filter.h
+++ b/components/nacl/browser/nacl_host_message_filter.h
@@ -22,11 +22,6 @@
 struct PnaclCacheInfo;
 }
 
-namespace net {
-class HostResolver;
-class URLRequestContextGetter;
-}
-
 namespace nacl {
 
 // This class filters out incoming Chrome-specific IPC messages for the renderer
@@ -35,8 +30,7 @@
  public:
   NaClHostMessageFilter(int render_process_id,
                         bool is_off_the_record,
-                        const base::FilePath& profile_directory,
-                        net::URLRequestContextGetter* request_context);
+                        const base::FilePath& profile_directory);
 
   // content::BrowserMessageFilter methods:
   bool OnMessageReceived(const IPC::Message& message) override;
@@ -45,7 +39,6 @@
   int render_process_id() { return render_process_id_; }
   bool off_the_record() { return off_the_record_; }
   const base::FilePath& profile_directory() const { return profile_directory_; }
-  net::HostResolver* GetHostResolver();
 
  private:
   friend class content::BrowserThread;
@@ -93,7 +86,6 @@
   // read on the IO thread.
   bool off_the_record_;
   base::FilePath profile_directory_;
-  scoped_refptr<net::URLRequestContextGetter> request_context_;
 
   base::WeakPtrFactory<NaClHostMessageFilter> weak_ptr_factory_;
 
diff --git a/components/omnibox/browser/autocomplete_input.cc b/components/omnibox/browser/autocomplete_input.cc
index 42e80de..3130623 100644
--- a/components/omnibox/browser/autocomplete_input.cc
+++ b/components/omnibox/browser/autocomplete_input.cc
@@ -175,6 +175,21 @@
 }
 
 // static
+void AutocompleteInput::ParseFilePath(const base::string16& text,
+                                      size_t offset,
+                                      url::Parsed* parts) {
+  parts->path.begin = offset;
+  size_t hash_offset = text.find('#', offset);
+  if (hash_offset != text.npos) {
+    parts->path.len = hash_offset - offset;
+    parts->ref.begin = hash_offset + 1;
+    parts->ref.len = text.size() - parts->ref.begin;
+  } else {
+    parts->path.len = text.size() - offset;
+  }
+}
+
+// static
 metrics::OmniboxInputType AutocompleteInput::Parse(
     const base::string16& text,
     const std::string& desired_tld,
@@ -213,6 +228,8 @@
     // A user might or might not type a scheme when entering a file URL.  In
     // either case, |parsed_scheme_utf8| will tell us that this is a file URL,
     // but |parts->scheme| might be empty, e.g. if the user typed "C:\foo".
+    ParseFilePath(text, parts->scheme.is_nonempty() ? parts->scheme.end() : 0,
+                  parts);
     return metrics::OmniboxInputType::URL;
   }
 
diff --git a/components/omnibox/browser/autocomplete_input.h b/components/omnibox/browser/autocomplete_input.h
index f1220c3..c456b61 100644
--- a/components/omnibox/browser/autocomplete_input.h
+++ b/components/omnibox/browser/autocomplete_input.h
@@ -61,6 +61,11 @@
   // Converts |type| to a string representation.  Used in logging.
   static std::string TypeToString(metrics::OmniboxInputType type);
 
+  // Parses the |path| and |ref| fields of |parts| from a file path input.
+  static void ParseFilePath(const base::string16& text,
+                            size_t offset,
+                            url::Parsed* parts);
+
   // Parses |text| (including an optional |desired_tld|) and returns the type of
   // input this will be interpreted as.  |scheme_classifier| is used to check
   // the scheme in |text| is known and registered in the current environment.
diff --git a/components/omnibox/browser/autocomplete_match.cc b/components/omnibox/browser/autocomplete_match.cc
index 8de984c..864a3d7 100644
--- a/components/omnibox/browser/autocomplete_match.cc
+++ b/components/omnibox/browser/autocomplete_match.cc
@@ -521,6 +521,11 @@
     needs_replacement = true;
   }
 
+  if (!input.parts().ref.is_nonempty() && url.has_ref()) {
+    replacements.ClearRef();
+    needs_replacement = true;
+  }
+
   if (needs_replacement)
     stripped_destination_url = stripped_destination_url.ReplaceComponents(
         replacements);
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn
index 54b2df4..7f510a1 100644
--- a/components/password_manager/core/browser/BUILD.gn
+++ b/components/password_manager/core/browser/BUILD.gn
@@ -400,6 +400,7 @@
     "//components/autofill/core/browser:test_support",
     "//components/autofill/core/browser/proto",
     "//components/autofill/core/common",
+    "//components/os_crypt",
     "//components/os_crypt:test_support",
     "//components/password_manager/core/browser:proto",
     "//components/password_manager/core/browser/form_parsing/fuzzer:unit_tests",
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc
index 8a8e1df..19b17d4 100644
--- a/components/password_manager/core/browser/login_database.cc
+++ b/components/password_manager/core/browser/login_database.cc
@@ -987,10 +987,9 @@
   return s.Run();
 }
 
-// static
 LoginDatabase::EncryptionResult LoginDatabase::InitPasswordFormFromStatement(
     PasswordForm* form,
-    const sql::Statement& s) {
+    const sql::Statement& s) const {
   std::string encrypted_password;
   s.ColumnBlobAsString(COLUMN_PASSWORD_VALUE, &encrypted_password);
   base::string16 decrypted_password;
@@ -1268,11 +1267,10 @@
   return encrypted_password;
 }
 
-// static
 bool LoginDatabase::StatementToForms(
     sql::Statement* statement,
     const PasswordStore::FormDigest* matched_form,
-    std::vector<std::unique_ptr<PasswordForm>>* forms) {
+    std::vector<std::unique_ptr<PasswordForm>>* forms) const {
   PSLDomainMatchMetric psl_domain_match_metric = PSL_DOMAIN_MATCH_NONE;
 
   forms->clear();
diff --git a/components/password_manager/core/browser/login_database.h b/components/password_manager/core/browser/login_database.h
index d49b3a1..ef15125 100644
--- a/components/password_manager/core/browser/login_database.h
+++ b/components/password_manager/core/browser/login_database.h
@@ -147,6 +147,11 @@
 
   StatisticsTable& stats_table() { return stats_table_; }
 
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
+  // This instance should not encrypt/decrypt password values using OSCrypt.
+  void disable_encryption() { use_encryption_ = false; }
+#endif  // defined(OS_POSIX)
+
  private:
 #if defined(OS_IOS)
   friend class LoginDatabaseIOSTest;
@@ -175,23 +180,25 @@
   // successful, or returning false and leaving cipher_text unchanged if
   // encryption fails (e.g., if the underlying OS encryption system is
   // temporarily unavailable).
-  static EncryptionResult EncryptedString(const base::string16& plain_text,
-                                          std::string* cipher_text);
+  EncryptionResult EncryptedString(const base::string16& plain_text,
+                                   std::string* cipher_text) const
+      WARN_UNUSED_RESULT;
 
   // Decrypts cipher_text, setting the value of plain_text and returning true if
   // successful, or returning false and leaving plain_text unchanged if
   // decryption fails (e.g., if the underlying OS encryption system is
   // temporarily unavailable).
-  static EncryptionResult DecryptedString(const std::string& cipher_text,
-                                          base::string16* plain_text);
+  EncryptionResult DecryptedString(const std::string& cipher_text,
+                                   base::string16* plain_text) const
+      WARN_UNUSED_RESULT;
 
   // Fills |form| from the values in the given statement (which is assumed to
   // be of the form used by the Get*Logins methods).
   // Returns the EncryptionResult from decrypting the password in |s|; if not
   // ENCRYPTION_RESULT_SUCCESS, |form| is not filled.
-  static EncryptionResult InitPasswordFormFromStatement(
-      autofill::PasswordForm* form,
-      const sql::Statement& s);
+  EncryptionResult InitPasswordFormFromStatement(autofill::PasswordForm* form,
+                                                 const sql::Statement& s) const
+      WARN_UNUSED_RESULT;
 
   // Gets all blacklisted or all non-blacklisted (depending on |blacklisted|)
   // credentials. On success returns true and overwrites |forms| with the
@@ -203,10 +210,10 @@
   // Overwrites |forms| with credentials retrieved from |statement|. If
   // |matched_form| is not null, filters out all results but those PSL-matching
   // |*matched_form| or federated credentials for it. On success returns true.
-  static bool StatementToForms(
-      sql::Statement* statement,
-      const PasswordStore::FormDigest* matched_form,
-      std::vector<std::unique_ptr<autofill::PasswordForm>>* forms);
+  bool StatementToForms(sql::Statement* statement,
+                        const PasswordStore::FormDigest* matched_form,
+                        std::vector<std::unique_ptr<autofill::PasswordForm>>*
+                            forms) const WARN_UNUSED_RESULT;
 
   // Initializes all the *_statement_ data members with appropriate SQL
   // fragments based on |builder|.
@@ -233,6 +240,13 @@
   std::string blacklisted_statement_;
   std::string encrypted_statement_;
 
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
+  // Whether password values should be encrypted.
+  // TODO(crbug.com/571003) Only linux doesn't use encryption. Remove this once
+  // Linux is fully migrated into LoginDatabase.
+  bool use_encryption_ = true;
+#endif  // defined(OS_POSIX)
+
   DISALLOW_COPY_AND_ASSIGN(LoginDatabase);
 };
 
diff --git a/components/password_manager/core/browser/login_database_ios.cc b/components/password_manager/core/browser/login_database_ios.cc
index 41bd8de..91b29cf 100644
--- a/components/password_manager/core/browser/login_database_ios.cc
+++ b/components/password_manager/core/browser/login_database_ios.cc
@@ -31,7 +31,7 @@
 
 LoginDatabase::EncryptionResult LoginDatabase::EncryptedString(
     const base::string16& plain_text,
-    std::string* cipher_text) {
+    std::string* cipher_text) const {
   if (plain_text.size() == 0) {
     *cipher_text = std::string();
     return ENCRYPTION_RESULT_SUCCESS;
@@ -73,7 +73,7 @@
 
 LoginDatabase::EncryptionResult LoginDatabase::DecryptedString(
     const std::string& cipher_text,
-    base::string16* plain_text) {
+    base::string16* plain_text) const {
   if (cipher_text.size() == 0) {
     *plain_text = base::string16();
     return ENCRYPTION_RESULT_SUCCESS;
diff --git a/components/password_manager/core/browser/login_database_mac.cc b/components/password_manager/core/browser/login_database_mac.cc
index ffaa1c34..7e15cf3a 100644
--- a/components/password_manager/core/browser/login_database_mac.cc
+++ b/components/password_manager/core/browser/login_database_mac.cc
@@ -8,19 +8,17 @@
 
 namespace password_manager {
 
-// static
 LoginDatabase::EncryptionResult LoginDatabase::EncryptedString(
     const base::string16& plain_text,
-    std::string* cipher_text) {
+    std::string* cipher_text) const {
   return OSCrypt::EncryptString16(plain_text, cipher_text)
              ? ENCRYPTION_RESULT_SUCCESS
              : ENCRYPTION_RESULT_SERVICE_FAILURE;
 }
 
-// static
 LoginDatabase::EncryptionResult LoginDatabase::DecryptedString(
     const std::string& cipher_text,
-    base::string16* plain_text) {
+    base::string16* plain_text) const {
   return OSCrypt::DecryptString16(cipher_text, plain_text)
              ? ENCRYPTION_RESULT_SUCCESS
              : ENCRYPTION_RESULT_SERVICE_FAILURE;
diff --git a/components/password_manager/core/browser/login_database_posix.cc b/components/password_manager/core/browser/login_database_posix.cc
index a700d9c..7ac5ad95 100644
--- a/components/password_manager/core/browser/login_database_posix.cc
+++ b/components/password_manager/core/browser/login_database_posix.cc
@@ -5,25 +5,34 @@
 #include "components/password_manager/core/browser/login_database.h"
 
 #include "base/strings/utf_string_conversions.h"
+#include "components/os_crypt/os_crypt.h"
 
 namespace password_manager {
 
-// TODO: Actually encrypt passwords on Linux.
-
-// static
 LoginDatabase::EncryptionResult LoginDatabase::EncryptedString(
     const base::string16& plain_text,
-    std::string* cipher_text) {
-  *cipher_text = base::UTF16ToUTF8(plain_text);
-  return ENCRYPTION_RESULT_SUCCESS;
+    std::string* cipher_text) const {
+  if (!use_encryption_) {
+    *cipher_text = base::UTF16ToUTF8(plain_text);
+    return ENCRYPTION_RESULT_SUCCESS;
+  }
+
+  return OSCrypt::EncryptString16(plain_text, cipher_text)
+             ? ENCRYPTION_RESULT_SUCCESS
+             : ENCRYPTION_RESULT_SERVICE_FAILURE;
 }
 
-// static
 LoginDatabase::EncryptionResult LoginDatabase::DecryptedString(
     const std::string& cipher_text,
-    base::string16* plain_text) {
-  *plain_text = base::UTF8ToUTF16(cipher_text);
-  return ENCRYPTION_RESULT_SUCCESS;
+    base::string16* plain_text) const {
+  if (!use_encryption_) {
+    *plain_text = base::UTF8ToUTF16(cipher_text);
+    return ENCRYPTION_RESULT_SUCCESS;
+  }
+
+  return OSCrypt::DecryptString16(cipher_text, plain_text)
+             ? ENCRYPTION_RESULT_SUCCESS
+             : ENCRYPTION_RESULT_SERVICE_FAILURE;
 }
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc
index 6597f19..eb9f636b 100644
--- a/components/password_manager/core/browser/login_database_unittest.cc
+++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -20,6 +20,7 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "components/autofill/core/common/password_form.h"
+#include "components/os_crypt/os_crypt.h"
 #include "components/os_crypt/os_crypt_mocker.h"
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
 #include "components/password_manager/core/browser/psl_matching_helper.h"
@@ -92,6 +93,28 @@
   return s.ColumnString(0);
 }
 
+// Returns an empty vector on failure. Otherwise returns values in the column
+// |column_name| of the logins table. The order of the
+// returned rows is well-defined.
+template <class T>
+std::vector<T> GetColumnValuesFromDatabase(const base::FilePath& database_path,
+                                           const std::string& column_name) {
+  sql::Connection db;
+  std::vector<T> results;
+  CHECK(db.Open(database_path));
+
+  std::string statement = base::StringPrintf(
+      "SELECT %s FROM logins ORDER BY username_value, %s DESC",
+      column_name.c_str(), column_name.c_str());
+  sql::Statement s(db.GetCachedStatement(SQL_FROM_HERE, statement.c_str()));
+  EXPECT_TRUE(s.is_valid());
+
+  while (s.Step())
+    results.push_back(GetFirstColumn<T>(s));
+
+  return results;
+}
+
 bool AddZeroClickableLogin(LoginDatabase* db,
                            const std::string& unique_string,
                            const GURL& origin) {
@@ -1693,6 +1716,45 @@
 }
 #endif  // defined(OS_POSIX)
 
+#if !defined(OS_IOS)
+// Test that LoginDatabase encrypts the password values that it stores.
+TEST_F(LoginDatabaseTest, EncryptionEnabled) {
+  PasswordForm password_form;
+  GenerateExamplePasswordForm(&password_form);
+  base::FilePath file = temp_dir_.GetPath().AppendASCII("TestUnencryptedDB");
+  {
+    LoginDatabase db(file);
+    ASSERT_TRUE(db.Init());
+    EXPECT_EQ(AddChangeForForm(password_form), db.AddLogin(password_form));
+  }
+  base::string16 decrypted_pw;
+  ASSERT_TRUE(OSCrypt::DecryptString16(
+      GetColumnValuesFromDatabase<std::string>(file, "password_value").at(0),
+      &decrypted_pw));
+  EXPECT_EQ(decrypted_pw, password_form.password_value);
+}
+#endif  // !defined(OS_IOS)
+
+#if defined(OS_LINUX)
+// Test that LoginDatabase does not encrypt values when encryption is disabled.
+// TODO(crbug.com/829857) This is supported only for Linux, while transitioning
+// into LoginDB with full encryption.
+TEST_F(LoginDatabaseTest, EncryptionDisabled) {
+  PasswordForm password_form;
+  GenerateExamplePasswordForm(&password_form);
+  base::FilePath file = temp_dir_.GetPath().AppendASCII("TestUnencryptedDB");
+  {
+    LoginDatabase db(file);
+    db.disable_encryption();
+    ASSERT_TRUE(db.Init());
+    EXPECT_EQ(AddChangeForForm(password_form), db.AddLogin(password_form));
+  }
+  EXPECT_EQ(
+      GetColumnValuesFromDatabase<std::string>(file, "password_value").at(0),
+      base::UTF16ToUTF8(password_form.password_value));
+}
+#endif  // defined(OS_LINUX)
+
 // If the database initialisation fails, the initialisation transaction should
 // roll back without crashing.
 TEST(LoginDatabaseFailureTest, Init_NoCrashOnFailedRollback) {
@@ -1747,33 +1809,6 @@
       sql::Connection::Delete(database_path_);
   }
 
-  // Returns an empty vector on failure. Otherwise returns values in the column
-  // |column_name| of the logins table. The order of the
-  // returned rows is well-defined.
-  template <class T>
-  std::vector<T> GetValues(const std::string& column_name) {
-    sql::Connection db;
-    std::vector<T> results;
-    if (!db.Open(database_path_))
-      return results;
-
-    std::string statement = base::StringPrintf(
-        "SELECT %s FROM logins ORDER BY username_value, %s DESC",
-        column_name.c_str(), column_name.c_str());
-    sql::Statement s(db.GetCachedStatement(SQL_FROM_HERE, statement.c_str()));
-    if (!s.is_valid()) {
-      db.Close();
-      return results;
-    }
-
-    while (s.Step())
-      results.push_back(GetFirstColumn<T>(s));
-
-    s.Clear();
-    db.Close();
-    return results;
-  }
-
   // Returns the database version for the test.
   int version() const { return GetParam(); }
 
@@ -1792,7 +1827,8 @@
   SCOPED_TRACE(testing::Message("Version file = ") << sql_file);
   CreateDatabase(sql_file);
   // Original date, in seconds since UTC epoch.
-  std::vector<int64_t> date_created(GetValues<int64_t>("date_created"));
+  std::vector<int64_t> date_created(
+      GetColumnValuesFromDatabase<int64_t>(database_path_, "date_created"));
   if (version() == 10)  // Version 10 has a duplicate entry.
     ASSERT_EQ(4U, date_created.size());
   else
@@ -1840,7 +1876,8 @@
     EXPECT_TRUE(db.RemoveLogin(form));
   }
   // New date, in microseconds since platform independent epoch.
-  std::vector<int64_t> new_date_created(GetValues<int64_t>("date_created"));
+  std::vector<int64_t> new_date_created(
+      GetColumnValuesFromDatabase<int64_t>(database_path_, "date_created"));
   ASSERT_EQ(3U, new_date_created.size());
   if (version() <= 8) {
     // Check that the two dates match up.
@@ -1858,7 +1895,8 @@
     // The "avatar_url" column first appeared in version 7. In version 14,
     // it was renamed to "icon_url". Migration from a version <= 13
     // to >= 14 should not break theses URLs.
-    std::vector<std::string> urls(GetValues<std::string>("icon_url"));
+    std::vector<std::string> urls(
+        GetColumnValuesFromDatabase<std::string>(database_path_, "icon_url"));
 
     EXPECT_THAT(urls, UnorderedElementsAre("", "https://www.google.com/icon",
                                            "https://www.google.com/icon"));
diff --git a/components/password_manager/core/browser/login_database_win.cc b/components/password_manager/core/browser/login_database_win.cc
index 6cf9c218..bd1e3b0 100644
--- a/components/password_manager/core/browser/login_database_win.cc
+++ b/components/password_manager/core/browser/login_database_win.cc
@@ -9,19 +9,17 @@
 
 namespace password_manager {
 
-// static
 LoginDatabase::EncryptionResult LoginDatabase::EncryptedString(
     const base::string16& plain_text,
-    std::string* cipher_text) {
+    std::string* cipher_text) const {
   if (OSCrypt::EncryptString16(plain_text, cipher_text))
     return ENCRYPTION_RESULT_SUCCESS;
   return ENCRYPTION_RESULT_ITEM_FAILURE;
 }
 
-// static
 LoginDatabase::EncryptionResult LoginDatabase::DecryptedString(
     const std::string& cipher_text,
-    base::string16* plain_text) {
+    base::string16* plain_text) const {
   // Unittests need to read sample database entries. If these entries had real
   // passwords, their encoding would need to be different for every platform.
   // To avoid the need for that, the entries have empty passwords. OSCrypt on
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc
index dad9a79..130717d 100644
--- a/components/password_manager/core/browser/password_manager.cc
+++ b/components/password_manager/core/browser/password_manager.cc
@@ -438,11 +438,6 @@
   return !pending_login_managers_.empty();
 }
 
-void PasswordManager::AddSubmissionCallback(
-    const PasswordSubmittedCallback& callback) {
-  submission_callbacks_.push_back(callback);
-}
-
 void PasswordManager::AddObserverAndDeliverCredentials(
     LoginModelObserver* observer,
     const PasswordForm& observed_form) {
@@ -472,10 +467,6 @@
     password_manager::PasswordManagerDriver* driver,
     const PasswordForm& password_form) {
   ProvisionallySavePassword(password_form, driver);
-  for (size_t i = 0; i < submission_callbacks_.size(); ++i) {
-    submission_callbacks_[i].Run(password_form);
-  }
-
   pending_login_managers_.clear();
 }
 
diff --git a/components/password_manager/core/browser/password_manager.h b/components/password_manager/core/browser/password_manager.h
index bdb8f1b..777554cf 100644
--- a/components/password_manager/core/browser/password_manager.h
+++ b/components/password_manager/core/browser/password_manager.h
@@ -56,14 +56,6 @@
   explicit PasswordManager(PasswordManagerClient* client);
   ~PasswordManager() override;
 
-  typedef base::Callback<void(const autofill::PasswordForm&)>
-      PasswordSubmittedCallback;
-
-  // There is no corresponding remove function as currently all of the
-  // owners of these callbacks have sufficient lifetimes so that the callbacks
-  // should always be valid when called.
-  void AddSubmissionCallback(const PasswordSubmittedCallback& callback);
-
   // Called by a PasswordFormManager when it decides a form can be autofilled
   // on the page.
   void Autofill(
@@ -301,9 +293,6 @@
   // notification in const member functions.
   mutable base::ObserverList<LoginModelObserver> observers_;
 
-  // Callbacks to be notified when a password form has been submitted.
-  std::vector<PasswordSubmittedCallback> submission_callbacks_;
-
   // Records all visible forms seen during a page load, in all frames of the
   // page. When the page stops loading, the password manager checks if one of
   // the recorded forms matches the login form from the previous page
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc
index 3763a30..8aa0b31 100644
--- a/components/password_manager/core/browser/password_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -265,13 +265,6 @@
     manager()->OnPasswordFormSubmitted(&driver_, form);
   }
 
-  PasswordManager::PasswordSubmittedCallback SubmissionCallback() {
-    return base::Bind(&PasswordManagerTest::FormSubmitted,
-                      base::Unretained(this));
-  }
-
-  void FormSubmitted(const PasswordForm& form) { submitted_form_ = form; }
-
   const GURL test_url_;
   base::MessageLoop message_loop_;
   scoped_refptr<MockPasswordStore> store_;
@@ -753,18 +746,6 @@
   manager()->OnPasswordFormsParsed(&driver_, observed);
 }
 
-TEST_F(PasswordManagerTest, SubmissionCallbackTest) {
-  manager()->AddSubmissionCallback(SubmissionCallback());
-  PasswordForm form = MakeSimpleForm();
-  // Prefs are needed for failure logging about having no matching observed
-  // form.
-  EXPECT_CALL(client_, GetPrefs()).WillRepeatedly(Return(nullptr));
-  EXPECT_CALL(client_, IsSavingAndFillingEnabledForCurrentPage())
-      .WillRepeatedly(Return(true));
-  OnPasswordFormSubmitted(form);
-  EXPECT_EQ(form, submitted_form_);
-}
-
 TEST_F(PasswordManagerTest, PasswordFormReappearance) {
   // If the password form reappears after submit, PasswordManager should deduce
   // that the login failed and not offer saving.
diff --git a/components/password_manager/core/browser/password_store_default_unittest.cc b/components/password_manager/core/browser/password_store_default_unittest.cc
index b241c01..15a5b43 100644
--- a/components/password_manager/core/browser/password_store_default_unittest.cc
+++ b/components/password_manager/core/browser/password_store_default_unittest.cc
@@ -16,6 +16,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_task_environment.h"
 #include "base/time/time.h"
+#include "components/os_crypt/os_crypt_mocker.h"
 #include "components/password_manager/core/browser/login_database.h"
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
 #include "components/password_manager/core/browser/password_store_change.h"
@@ -106,6 +107,7 @@
 PasswordStoreDefaultTestDelegate::PasswordStoreDefaultTestDelegate()
     : scoped_task_environment_(
           base::test::ScopedTaskEnvironment::MainThreadType::UI) {
+  OSCryptMocker::SetUp();
   SetupTempDir();
   store_ = CreateInitializedStore(
       std::make_unique<LoginDatabase>(test_login_db_file_path()));
@@ -115,12 +117,14 @@
     std::unique_ptr<LoginDatabase> database)
     : scoped_task_environment_(
           base::test::ScopedTaskEnvironment::MainThreadType::UI) {
+  OSCryptMocker::SetUp();
   SetupTempDir();
   store_ = CreateInitializedStore(std::move(database));
 }
 
 PasswordStoreDefaultTestDelegate::~PasswordStoreDefaultTestDelegate() {
   ClosePasswordStore();
+  OSCryptMocker::TearDown();
 }
 
 void PasswordStoreDefaultTestDelegate::FinishAsyncProcessing() {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 30746da..927a01b 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -11522,11 +11522,14 @@
       'supported_on': ['chrome.*:67-', 'chrome_os:67-'],
       'type': 'int',
       'schema': { 'type': 'integer', 'minimum': 3600000 },
-      'caption': '''Set the period for update relaunch notifications''',
+      'caption': '''Set the time period for update notifications''',
+      'label': '''Time period (milliseconds)''',
       'example_value': 604800000,
-      'desc': '''Allows you to set the time period over which <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> relaunch notifications are shown to apply a pending update.
+      'desc': '''Allows you to set the time period, in milliseconds, over which users are notified that <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> must be relaunched or that a <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> device must be restarted to apply a pending update.
 
-      This policy setting can be used to control the time period, in milliseconds, over which a user is progressively informed that <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> must be relaunched (or <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> must be restarted) for an update. Over this time period, the user will be repeatedly informed of the need for an update based on the setting of the <ph name="RELAUNCH_NOTIFICATION_POLICY_NAME">RelaunchNotification</ph> policy. If not set, the default period of 345600000 milliseconds (four days) is used for <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> and 604800000 milliseconds (one week) for all other platforms.''',
+      Over this time period, the user will be repeatedly informed of the need for an update. For <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices, a restart notification appears in the system tray when an upgrade is detected. This notification changes color once half of the notification period passes, and again once the full notification period has passed. For <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> browsers, the app menu changes to indicate that a relaunch is needed once one third of the notification period passes. This notification changes color once two thirds of the notification period passes, and again once the full notification period has passed. The additional notifications enabled by the <ph name="RELAUNCH_NOTIFICATION_POLICY_NAME">RelaunchNotification</ph> policy for browsers follow this same schedule.
+
+      If not set, the default period of 345600000 milliseconds (four days) is used for <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices and 604800000 milliseconds (one week) for browsers.''',
     },
     {
       'name': 'VirtualMachinesAllowed',
diff --git a/components/signin/core/browser/BUILD.gn b/components/signin/core/browser/BUILD.gn
index eb198a10..98eed32 100644
--- a/components/signin/core/browser/BUILD.gn
+++ b/components/signin/core/browser/BUILD.gn
@@ -71,6 +71,8 @@
     "child_account_info_fetcher_impl.h",
     "chrome_connected_header_helper.cc",
     "chrome_connected_header_helper.h",
+    "cookie_settings_util.cc",
+    "cookie_settings_util.h",
     "dice_account_reconcilor_delegate.cc",
     "dice_account_reconcilor_delegate.h",
     "dice_header_helper.cc",
diff --git a/components/signin/core/browser/cookie_settings_util.cc b/components/signin/core/browser/cookie_settings_util.cc
new file mode 100644
index 0000000..54233035
--- /dev/null
+++ b/components/signin/core/browser/cookie_settings_util.cc
@@ -0,0 +1,36 @@
+// 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 "components/signin/core/browser/cookie_settings_util.h"
+
+#include "components/content_settings/core/browser/cookie_settings.h"
+#include "google_apis/gaia/gaia_urls.h"
+#include "url/gurl.h"
+
+namespace signin {
+
+bool SettingsAllowSigninCookies(
+    const content_settings::CookieSettings* cookie_settings) {
+  GURL gaia_url = GaiaUrls::GetInstance()->gaia_url();
+  GURL google_url = GaiaUrls::GetInstance()->google_url();
+  return cookie_settings &&
+         cookie_settings->IsCookieAccessAllowed(gaia_url, gaia_url) &&
+         cookie_settings->IsCookieAccessAllowed(google_url, google_url);
+}
+
+bool SettingsDeleteSigninCookiesOnExit(
+    const content_settings::CookieSettings* cookie_settings) {
+  GURL gaia_url = GaiaUrls::GetInstance()->gaia_url();
+  GURL google_url = GaiaUrls::GetInstance()->google_url();
+  ContentSettingsForOneType settings;
+  cookie_settings->GetCookieSettings(&settings);
+
+  return !cookie_settings ||
+         cookie_settings->ShouldDeleteCookieOnExit(
+             settings, "." + gaia_url.host(), true) ||
+         cookie_settings->ShouldDeleteCookieOnExit(
+             settings, "." + google_url.host(), true);
+}
+
+}  // namespace signin
diff --git a/components/signin/core/browser/cookie_settings_util.h b/components/signin/core/browser/cookie_settings_util.h
new file mode 100644
index 0000000..d2fdcd4
--- /dev/null
+++ b/components/signin/core/browser/cookie_settings_util.h
@@ -0,0 +1,24 @@
+// 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 COMPONENTS_SIGNIN_CORE_BROWSER_COOKIE_SETTINGS_UTIL_H_
+#define COMPONENTS_SIGNIN_CORE_BROWSER_COOKIE_SETTINGS_UTIL_H_
+
+namespace content_settings {
+class CookieSettings;
+}
+
+namespace signin {
+
+// Returns true if signin cookies are allowed.
+bool SettingsAllowSigninCookies(
+    const content_settings::CookieSettings* cookie_settings);
+
+// Returns true if signin cookies are cleared on exit.
+bool SettingsDeleteSigninCookiesOnExit(
+    const content_settings::CookieSettings* cookie_settings);
+
+}  // namespace signin
+
+#endif  // COMPONENTS_SIGNIN_CORE_BROWSER_COOKIE_SETTINGS_UTIL_H_
diff --git a/components/signin/core/browser/signin_header_helper.cc b/components/signin/core/browser/signin_header_helper.cc
index 6c5a0ec..720d726 100644
--- a/components/signin/core/browser/signin_header_helper.cc
+++ b/components/signin/core/browser/signin_header_helper.cc
@@ -9,11 +9,10 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/strings/string_split.h"
-#include "components/content_settings/core/browser/cookie_settings.h"
 #include "components/google/core/browser/google_util.h"
 #include "components/signin/core/browser/chrome_connected_header_helper.h"
+#include "components/signin/core/browser/cookie_settings_util.h"
 #include "google_apis/gaia/gaia_auth_util.h"
-#include "google_apis/gaia/gaia_urls.h"
 #include "net/base/escape.h"
 #include "net/url_request/url_request.h"
 
@@ -66,15 +65,6 @@
 DiceResponseParams::EnableSyncInfo::EnableSyncInfo(const EnableSyncInfo&) =
     default;
 
-bool SettingsAllowSigninCookies(
-    const content_settings::CookieSettings* cookie_settings) {
-  GURL gaia_url = GaiaUrls::GetInstance()->gaia_url();
-  GURL google_url = GaiaUrls::GetInstance()->google_url();
-  return cookie_settings &&
-         cookie_settings->IsCookieAccessAllowed(gaia_url, gaia_url) &&
-         cookie_settings->IsCookieAccessAllowed(google_url, google_url);
-}
-
 std::string BuildMirrorRequestCookieIfPossible(
     const GURL& url,
     const std::string& account_id,
diff --git a/components/signin/core/browser/signin_header_helper.h b/components/signin/core/browser/signin_header_helper.h
index f3d260f..7e10bf1 100644
--- a/components/signin/core/browser/signin_header_helper.h
+++ b/components/signin/core/browser/signin_header_helper.h
@@ -178,9 +178,6 @@
   virtual bool IsUrlEligibleForRequestHeader(const GURL& url) = 0;
 };
 
-// Returns true if signin cookies are allowed.
-bool SettingsAllowSigninCookies(
-    const content_settings::CookieSettings* cookie_settings);
 
 // Returns the CHROME_CONNECTED cookie, or an empty string if it should not be
 // added to the request to |url|.
diff --git a/components/subresource_filter/tools/ruleset_converter/BUILD.gn b/components/subresource_filter/tools/ruleset_converter/BUILD.gn
index de4389c..4373641 100644
--- a/components/subresource_filter/tools/ruleset_converter/BUILD.gn
+++ b/components/subresource_filter/tools/ruleset_converter/BUILD.gn
@@ -9,6 +9,8 @@
     "//third_party/protobuf:protobuf_lite",
     "rule_stream.cc",
     "rule_stream.h",
+    "ruleset_converter.cc",
+    "ruleset_converter.h",
     "ruleset_format.cc",
     "ruleset_format.h",
   ]
@@ -25,6 +27,7 @@
   testonly = true
   sources = [
     "rule_stream_unittest.cc",
+    "ruleset_converter_unittest.cc",
     "ruleset_test_util.cc",
     "ruleset_test_util.h",
   ]
diff --git a/components/subresource_filter/tools/ruleset_converter/main.cc b/components/subresource_filter/tools/ruleset_converter/main.cc
index b2f2df69..ed5dd4e2 100644
--- a/components/subresource_filter/tools/ruleset_converter/main.cc
+++ b/components/subresource_filter/tools/ruleset_converter/main.cc
@@ -2,25 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <cstdio>
-#include <fstream>
-#include <iostream>
-#include <memory>
-#include <string>
-#include <vector>
-
 #include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_split.h"
-#include "base/strings/utf_string_conversions.h"
-#include "build/build_config.h"
-#include "components/subresource_filter/tools/ruleset_converter/rule_stream.h"
-#include "components/subresource_filter/tools/ruleset_converter/ruleset_format.h"
+#include "components/subresource_filter/tools/ruleset_converter/ruleset_converter.h"
 
 namespace {
 
@@ -44,7 +27,7 @@
   ruleset_converter is a utility for converting subresource_filter rulesets
   across multiple formats:
 
-  * --input_files: Colon-separated list of input files with rules. The files
+  * --input_files: Comma-separated list of input files with rules. The files
      are processed in the order of declaration
 
   * --output_file: The file to output the rules. Either this option or at least
@@ -82,126 +65,53 @@
     return 1;
   }
 
-  if (!command_line.HasSwitch(kSwitchInputFiles)) {
-    std::fprintf(stderr, "--input_files flag is not specified.\n");
+  subresource_filter::RulesetConverter converter;
+  if (!converter.SetInputFiles(
+          command_line.GetSwitchValueNative(kSwitchInputFiles))) {
     PrintHelp();
     return 1;
   }
 
-  if (command_line.GetSwitchValueASCII(kSwitchOutputFile).empty() &&
-      command_line.GetSwitchValueASCII(kSwitchOutputFileUrl).empty() &&
-      command_line.GetSwitchValueASCII(kSwitchOutputFileCss).empty()) {
-    std::fprintf(stderr,
-                 "Either --output_file, or at least of one "
-                 "--output_file_url|--output_file_css should be specified.\n");
+  if (command_line.HasSwitch(kSwitchOutputFile) &&
+      !converter.SetOutputFile(
+          command_line.GetSwitchValuePath(kSwitchOutputFile))) {
+    PrintHelp();
+    return 1;
+  }
+  if (command_line.HasSwitch(kSwitchOutputFileUrl) &&
+      !converter.SetOutputFileUrl(
+          command_line.GetSwitchValuePath(kSwitchOutputFileUrl))) {
+    PrintHelp();
+    return 1;
+  }
+  if (command_line.HasSwitch(kSwitchOutputFileCss) &&
+      !converter.SetOutputFileCss(
+          command_line.GetSwitchValuePath(kSwitchOutputFileCss))) {
     PrintHelp();
     return 1;
   }
 
-  const subresource_filter::RulesetFormat input_format =
-      command_line.HasSwitch(kSwitchInputFormat)
-          ? subresource_filter::ParseFlag(
-                command_line.GetSwitchValueASCII(kSwitchInputFormat))
-          : subresource_filter::RulesetFormat::kFilterList;
-  if (input_format == subresource_filter::RulesetFormat::kUndefined) {
-    std::fprintf(stderr, "Input format is not defined.\n");
+  if (command_line.HasSwitch(kSwitchChromeVersion) &&
+      !converter.SetChromeVersion(
+          command_line.GetSwitchValueASCII(kSwitchChromeVersion))) {
+    PrintHelp();
     return 1;
   }
 
-  const subresource_filter::RulesetFormat output_format =
-      subresource_filter::ParseFlag(
-          command_line.GetSwitchValueASCII(kSwitchOutputFormat));
-  if (output_format == subresource_filter::RulesetFormat::kUndefined) {
-    std::fprintf(stderr, "Output format is not defined.\n");
+  if (command_line.HasSwitch(kSwitchInputFormat) &&
+      !converter.SetInputFormat(
+          command_line.GetSwitchValueASCII(kSwitchInputFormat))) {
+    PrintHelp();
+    return 1;
+  }
+  if (command_line.HasSwitch(kSwitchOutputFormat) &&
+      !converter.SetOutputFormat(
+          command_line.GetSwitchValueASCII(kSwitchOutputFormat))) {
+    PrintHelp();
     return 1;
   }
 
-  int chrome_version = 59;
-  if (command_line.HasSwitch(kSwitchChromeVersion)) {
-    if (!base::StringToInt(
-            command_line.GetSwitchValueASCII(kSwitchChromeVersion),
-            &chrome_version)) {
-      fprintf(stderr, "Unable to parse chrome version");
-      return 1;
-    }
-  }
-  if (chrome_version != 0 && chrome_version != 54 && chrome_version != 59) {
-    std::fprintf(stderr, "chrome_version should be in {0, 54, 59}.\n");
+  if (!converter.Convert())
     return 1;
-  }
-
-  // Vet the input paths.
-  base::CommandLine::StringType inputs =
-      command_line.GetSwitchValueNative(kSwitchInputFiles);
-  std::vector<base::FilePath> input_paths;
-#if defined(OS_WIN)
-  base::StringPiece16 separator(base::ASCIIToUTF16(":"));
-#else
-  base::StringPiece separator(":");
-#endif
-  for (const auto& piece :
-       base::SplitStringPiece(inputs, separator, base::TRIM_WHITESPACE,
-                              base::SPLIT_WANT_NONEMPTY)) {
-    base::FilePath path(piece);
-    if (!base::PathExists(path)) {
-      std::fprintf(stderr, "Input path does not exist\n");
-      return 1;
-    }
-    input_paths.push_back(path);
-  }
-
-  // Create output stream(s).
-  std::unique_ptr<subresource_filter::RuleOutputStream> primary_output;
-  std::unique_ptr<subresource_filter::RuleOutputStream> secondary_output;
-  subresource_filter::RuleOutputStream* css_rules_output = nullptr;
-
-  base::FilePath primary_filename =
-      command_line.GetSwitchValuePath(kSwitchOutputFile);
-  const bool single_output = !primary_filename.empty();
-  if (!single_output)
-    primary_filename = command_line.GetSwitchValuePath(kSwitchOutputFileUrl);
-
-  if (!primary_filename.empty()) {
-    if (!base::DirectoryExists(primary_filename.DirName())) {
-      std::fprintf(stderr, "Output directory does not exist\n");
-      return 1;
-    }
-    primary_output = subresource_filter::RuleOutputStream::Create(
-        std::make_unique<std::ofstream>(primary_filename.AsUTF8Unsafe(),
-                                        std::ios::binary | std::ios::out),
-        output_format);
-  }
-
-  base::FilePath secondary_filename =
-      command_line.GetSwitchValuePath(kSwitchOutputFileCss);
-  if (single_output || secondary_filename == primary_filename) {
-    css_rules_output = primary_output.get();
-  } else if (!secondary_filename.empty()) {
-    if (!base::DirectoryExists(secondary_filename.DirName())) {
-      std::fprintf(stderr, "Output directory does not exist\n");
-      return 1;
-    }
-    secondary_output = subresource_filter::RuleOutputStream::Create(
-        std::make_unique<std::ofstream>(secondary_filename.AsUTF8Unsafe(),
-                                        std::ios::binary | std::ios::out),
-        output_format);
-    css_rules_output = secondary_output.get();
-  }
-
-  // Iterate through input files and stream them to the outputs.
-  for (const auto& path : input_paths) {
-    auto input_stream = subresource_filter::RuleInputStream::Create(
-        std::make_unique<std::ifstream>(path.AsUTF8Unsafe(),
-                                        std::ios::binary | std::ios::in),
-        input_format);
-    CHECK(input_stream);
-    CHECK(subresource_filter::TransferRules(input_stream.get(),
-                                            primary_output.get(),
-                                            css_rules_output, chrome_version));
-  }
-  if (primary_output)
-    CHECK(primary_output->Finish());
-  if (secondary_output)
-    CHECK(secondary_output->Finish());
   return 0;
 }
diff --git a/components/subresource_filter/tools/ruleset_converter/ruleset_converter.cc b/components/subresource_filter/tools/ruleset_converter/ruleset_converter.cc
new file mode 100644
index 0000000..a10ba91
--- /dev/null
+++ b/components/subresource_filter/tools/ruleset_converter/ruleset_converter.cc
@@ -0,0 +1,176 @@
+// 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 "components/subresource_filter/tools/ruleset_converter/ruleset_converter.h"
+
+#include <fstream>
+#include <iostream>
+
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/strings/string16.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
+#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
+#include "components/subresource_filter/tools/ruleset_converter/rule_stream.h"
+#include "components/subresource_filter/tools/ruleset_converter/ruleset_format.h"
+
+namespace subresource_filter {
+
+RulesetConverter::RulesetConverter() = default;
+RulesetConverter::~RulesetConverter() = default;
+
+bool RulesetConverter::Convert() {
+  if (inputs_.empty()) {
+    std::fprintf(stderr, "No input files specified\n");
+    return false;
+  }
+
+  std::unique_ptr<RuleOutputStream> primary_output;
+  std::unique_ptr<RuleOutputStream> secondary_output;
+  subresource_filter::RuleOutputStream* css_rules_output = nullptr;
+
+  auto make_output = [](const base::FilePath& path, RulesetFormat format) {
+    return RuleOutputStream::Create(
+        std::make_unique<std::ofstream>(path.AsUTF8Unsafe(),
+                                        std::ios::binary | std::ios::out),
+        format);
+  };
+
+  if (!output_file_.empty()) {
+    primary_output = make_output(output_file_, output_format_);
+    css_rules_output = primary_output.get();
+  } else {
+    if (!output_url_.empty()) {
+      primary_output = make_output(output_url_, output_format_);
+    }
+    if (output_css_ == output_url_) {
+      css_rules_output = primary_output.get();
+    } else if (!output_css_.empty()) {
+      secondary_output = make_output(output_css_, output_format_);
+      css_rules_output = secondary_output.get();
+    }
+  }
+
+  if (!primary_output && !secondary_output) {
+    std::fprintf(stderr,
+                 "Must specify an output_file, or one of "
+                 "output_file_url|output_file_css\n");
+    return false;
+  }
+
+  // Iterate through input files and stream them to the outputs.
+  for (const auto& path : inputs_) {
+    auto input_stream = subresource_filter::RuleInputStream::Create(
+        std::make_unique<std::ifstream>(path.AsUTF8Unsafe(),
+                                        std::ios::binary | std::ios::in),
+        input_format_);
+    CHECK(input_stream);
+    CHECK(TransferRules(input_stream.get(), primary_output.get(),
+                        css_rules_output, chrome_version_));
+  }
+
+  if (primary_output)
+    CHECK(primary_output->Finish());
+  if (secondary_output)
+    CHECK(secondary_output->Finish());
+  return true;
+}
+
+bool RulesetConverter::SetInputFiles(
+    const base::CommandLine::StringType& comma_separated_paths) {
+#if defined(OS_WIN)
+  base::string16 separator16 = base::ASCIIToUTF16(",");
+  base::StringPiece16 separator(separator16);
+#else
+  base::StringPiece separator(",");
+#endif
+  for (const auto& piece : base::SplitStringPiece(
+           comma_separated_paths, separator, base::TRIM_WHITESPACE,
+           base::SPLIT_WANT_NONEMPTY)) {
+    base::FilePath path(piece);
+
+    if (!base::PathExists(path)) {
+      std::fprintf(stderr, "Path not found: %s\n", path.AsUTF8Unsafe().c_str());
+      return false;
+    }
+
+    inputs_.push_back(path);
+  }
+
+  if (inputs_.empty()) {
+    std::fprintf(stderr, "Received no input files\n");
+    return false;
+  }
+  return true;
+}
+
+bool RulesetConverter::SetChromeVersion(const std::string& version) {
+  int parsed_version = 0;
+  if (!base::StringToInt(version, &parsed_version)) {
+    std::fprintf(stderr,
+                 "chrome_version could not be parsed into an integer.\n");
+    return false;
+  }
+  if (parsed_version != 0 && parsed_version != 54 && parsed_version != 59) {
+    std::fprintf(stderr, "chrome_version should be in {0, 54, 59}.\n");
+    return false;
+  }
+  chrome_version_ = parsed_version;
+  return true;
+}
+
+bool RulesetConverter::SetOutputFile(const base::FilePath& path) {
+  if (!base::DirectoryExists(path.DirName())) {
+    std::printf("Directory does not exist: %s\n",
+                path.DirName().AsUTF8Unsafe().c_str());
+    return false;
+  }
+  output_file_ = path;
+  return true;
+}
+
+bool RulesetConverter::SetOutputFileUrl(const base::FilePath& path) {
+  if (!base::DirectoryExists(path.DirName())) {
+    std::printf("Directory does not exist: %s\n",
+                path.DirName().AsUTF8Unsafe().c_str());
+    return false;
+  }
+  output_url_ = path;
+  return true;
+}
+
+bool RulesetConverter::SetOutputFileCss(const base::FilePath& path) {
+  if (!base::DirectoryExists(path.DirName())) {
+    std::printf("Directory does not exist: %s\n",
+                path.DirName().AsUTF8Unsafe().c_str());
+    return false;
+  }
+  output_css_ = path;
+  return true;
+}
+
+bool RulesetConverter::SetInputFormat(const std::string& format) {
+  RulesetFormat ruleset_format = ParseFlag(format);
+  if (ruleset_format == subresource_filter::RulesetFormat::kUndefined) {
+    std::fprintf(stderr, "Input format is not defined.\n");
+    return false;
+  }
+  input_format_ = ruleset_format;
+  return true;
+}
+
+bool RulesetConverter::SetOutputFormat(const std::string& format) {
+  RulesetFormat ruleset_format = ParseFlag(format);
+  if (ruleset_format == subresource_filter::RulesetFormat::kUndefined) {
+    std::fprintf(stderr, "Output format is not defined.\n");
+    return false;
+  }
+  output_format_ = ruleset_format;
+  return true;
+}
+
+}  // namespace subresource_filter
diff --git a/components/subresource_filter/tools/ruleset_converter/ruleset_converter.h b/components/subresource_filter/tools/ruleset_converter/ruleset_converter.h
new file mode 100644
index 0000000..1e4c39c
--- /dev/null
+++ b/components/subresource_filter/tools/ruleset_converter/ruleset_converter.h
@@ -0,0 +1,73 @@
+// 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 COMPONENTS_SUBRESOURCE_FILTER_TOOLS_RULESET_CONVERTER_RULESET_CONVERTER_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_TOOLS_RULESET_CONVERTER_RULESET_CONVERTER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "components/subresource_filter/tools/ruleset_converter/rule_stream.h"
+#include "components/subresource_filter/tools/ruleset_converter/ruleset_format.h"
+
+namespace subresource_filter {
+
+// The RulesetConverter converts subresource_filter rulesets across multiple
+// formats.
+// This class is a thin abstraction to enable testing of the |ruleset_converter|
+// command line tool. See comments in main.cc for more information.
+class RulesetConverter {
+ public:
+  RulesetConverter();
+  ~RulesetConverter();
+
+  // Converts rulesets based on Set* configurations.
+  bool Convert();
+
+  // Returns false if the input files are invalid or cannot be found.
+  // Corresponds to --input_files parameter.
+  bool SetInputFiles(
+      const base::CommandLine::StringType& comma_separated_paths);
+
+  // These methods will return false if the directory does not exist.
+  //
+  // Corresponds to --output_file parameter.
+  bool SetOutputFile(const base::FilePath& path);
+
+  // Corresponds to --output_file_url parameter.
+  bool SetOutputFileUrl(const base::FilePath& path);
+
+  // Corresponds to --output_file_css parameter.
+  bool SetOutputFileCss(const base::FilePath& path);
+
+  // Corresponds to --chrome_version.
+  bool SetChromeVersion(const std::string& version);
+
+  // Corresponds to --input_format / --output_format.
+  bool SetInputFormat(const std::string& format);
+  bool SetOutputFormat(const std::string& format);
+
+ private:
+  std::vector<base::FilePath> inputs_;
+
+  base::FilePath output_file_;
+  base::FilePath output_url_;
+  base::FilePath output_css_;
+
+  RulesetFormat input_format_ = RulesetFormat::kFilterList;
+  RulesetFormat output_format_ = RulesetFormat::kUnindexedRuleset;
+
+  // Increase this if rule_stream gets more custom logic for versions > 59.
+  int chrome_version_ = 59;
+
+  DISALLOW_COPY_AND_ASSIGN(RulesetConverter);
+};
+
+}  // namespace subresource_filter
+
+#endif  // COMPONENTS_SUBRESOURCE_FILTER_TOOLS_RULESET_CONVERTER_RULESET_CONVERTER_H_
diff --git a/components/subresource_filter/tools/ruleset_converter/ruleset_converter_unittest.cc b/components/subresource_filter/tools/ruleset_converter/ruleset_converter_unittest.cc
new file mode 100644
index 0000000..76aed3c
--- /dev/null
+++ b/components/subresource_filter/tools/ruleset_converter/ruleset_converter_unittest.cc
@@ -0,0 +1,310 @@
+// 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 "components/subresource_filter/tools/ruleset_converter/ruleset_converter.h"
+
+#include <string>
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
+#include "components/subresource_filter/tools/ruleset_converter/ruleset_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace subresource_filter {
+
+// Returns a small number of predefined rules in text format.
+std::vector<std::string> GetSomeRules() {
+  return std::vector<std::string>{
+      "example.com",
+      "||ex.com$image",
+      "|http://example.com/?key=value$~third-party,domain=ex.com",
+      "&key1=value1&key2=value2|$script,image,font",
+      "domain1.com,domain1.com###id",
+      "@@whitelisted.com$document,domain=example.com|~sub.example.com",
+      "###absolute_evil_id",
+      "@@whitelisted.com$match-case,document,domain=another.example.com",
+      "domain.com,~sub.domain.com,sub.sub.domain.com#@#id",
+      "#@#absolute_good_id",
+      "host$websocket",
+  };
+}
+
+base::CommandLine::StringType AsciiToNativeString(std::string ascii) {
+#if defined(OS_WIN)
+  return base::ASCIIToUTF16(ascii);
+#else
+  return ascii;
+#endif
+}
+
+class RulesetConverterTest : public testing::Test {
+ public:
+  RulesetConverterTest() { test_content_.AppendRules(GetSomeRules()); }
+  TestRulesetContents test_content_;
+};
+
+TEST_F(RulesetConverterTest, InputNotFound_Fails) {
+  RulesetConverter converter;
+  EXPECT_FALSE(converter.SetInputFiles(AsciiToNativeString("/not-a-file")));
+}
+
+TEST_F(RulesetConverterTest, NoInputFiles_Fails) {
+  RulesetConverter converter;
+  EXPECT_FALSE(converter.SetInputFiles(AsciiToNativeString("")));
+}
+
+TEST_F(RulesetConverterTest, OutputDirNotFound_Fails) {
+  RulesetConverter converter;
+  base::FilePath path(FILE_PATH_LITERAL("/not-a-dir/output"));
+  EXPECT_FALSE(converter.SetOutputFile(path));
+}
+
+TEST_F(RulesetConverterTest, BadInputFormat_Fails) {
+  RulesetConverter converter;
+  EXPECT_FALSE(converter.SetInputFormat("badformat"));
+}
+
+TEST_F(RulesetConverterTest, BadOutputFormat_Fails) {
+  RulesetConverter converter;
+  EXPECT_FALSE(converter.SetOutputFormat("badformat"));
+}
+
+TEST_F(RulesetConverterTest, BadChromeVersions_Fail) {
+  RulesetConverter converter;
+  EXPECT_FALSE(converter.SetChromeVersion("not-a-number"));
+  EXPECT_FALSE(converter.SetChromeVersion("1"));
+  EXPECT_FALSE(converter.SetChromeVersion("60"));
+}
+
+TEST_F(RulesetConverterTest, NoInput_Fails) {
+  RulesetConverter converter;
+  base::FilePath path(FILE_PATH_LITERAL("/output"));
+  EXPECT_TRUE(converter.SetOutputFile(path));
+  EXPECT_FALSE(converter.Convert());
+}
+
+TEST_F(RulesetConverterTest, NoOutput_Fails) {
+  RulesetConverter converter;
+  ScopedTempRulesetFile ruleset_file(RulesetFormat::kFilterList);
+  ruleset_file.WriteRuleset(test_content_);
+  EXPECT_TRUE(converter.SetInputFiles(
+      AsciiToNativeString(ruleset_file.ruleset_path().AsUTF8Unsafe())));
+  EXPECT_FALSE(converter.Convert());
+}
+
+TEST_F(RulesetConverterTest, InputAndOneOutput_Succeeds) {
+  RulesetConverter converter;
+  ScopedTempRulesetFile input_file(RulesetFormat::kFilterList);
+  ScopedTempRulesetFile output_file(RulesetFormat::kUnindexedRuleset);
+
+  input_file.WriteRuleset(test_content_);
+  EXPECT_TRUE(converter.SetInputFiles(
+      AsciiToNativeString(input_file.ruleset_path().AsUTF8Unsafe())));
+  EXPECT_TRUE(converter.SetOutputFile(output_file.ruleset_path()));
+  EXPECT_TRUE(converter.Convert());
+}
+
+TEST_F(RulesetConverterTest, MultipleInputs) {
+  RulesetConverter converter;
+  ScopedTempRulesetFile input_1(RulesetFormat::kFilterList);
+  ScopedTempRulesetFile input_2(RulesetFormat::kFilterList);
+  ScopedTempRulesetFile input_3(RulesetFormat::kFilterList);
+  ScopedTempRulesetFile output_file(RulesetFormat::kFilterList);
+
+  input_1.WriteRuleset(test_content_);
+
+  TestRulesetContents content_2;
+  content_2.AppendRules({"foo.com", "eggs*waffles.org"});
+  input_2.WriteRuleset(content_2);
+
+  TestRulesetContents content_3;
+  content_3.AppendRules({"@@bar.net/some/path"});
+  input_3.WriteRuleset(content_3);
+
+  std::string joined = base::JoinString({input_1.ruleset_path().AsUTF8Unsafe(),
+                                         input_2.ruleset_path().AsUTF8Unsafe(),
+                                         input_3.ruleset_path().AsUTF8Unsafe()},
+                                        ",");
+  EXPECT_TRUE(converter.SetInputFiles(AsciiToNativeString(joined)));
+  EXPECT_TRUE(converter.SetOutputFile(output_file.ruleset_path()));
+  EXPECT_TRUE(converter.SetOutputFormat("filter-list"));
+  EXPECT_TRUE(converter.Convert());
+
+  TestRulesetContents expected_output = test_content_;
+  expected_output.AppendParsedRules(content_2);
+  expected_output.AppendParsedRules(content_3);
+  EXPECT_EQ(expected_output, output_file.ReadContents());
+}
+
+TEST_F(RulesetConverterTest, MultipleOutputs) {
+  RulesetConverter converter;
+  ScopedTempRulesetFile input_file(RulesetFormat::kFilterList);
+  ScopedTempRulesetFile output_url(RulesetFormat::kFilterList);
+  ScopedTempRulesetFile output_css(RulesetFormat::kFilterList);
+
+  input_file.WriteRuleset(test_content_);
+
+  EXPECT_TRUE(converter.SetInputFiles(
+      AsciiToNativeString(input_file.ruleset_path().AsUTF8Unsafe())));
+  EXPECT_TRUE(converter.SetOutputFileUrl(output_url.ruleset_path()));
+  EXPECT_TRUE(converter.SetOutputFileCss(output_url.ruleset_path()));
+  EXPECT_TRUE(converter.SetOutputFormat("filter-list"));
+  EXPECT_TRUE(converter.Convert());
+
+  TestRulesetContents expected_url_output;
+  expected_url_output.url_rules = test_content_.url_rules;
+  TestRulesetContents expected_css_output;
+  expected_url_output.css_rules = test_content_.css_rules;
+
+  EXPECT_EQ(expected_url_output, output_url.ReadContents());
+  EXPECT_EQ(expected_css_output, output_css.ReadContents());
+}
+
+TEST_F(RulesetConverterTest, UrlOutput) {
+  RulesetConverter converter;
+  ScopedTempRulesetFile input_file(RulesetFormat::kFilterList);
+  ScopedTempRulesetFile output_url(RulesetFormat::kFilterList);
+  ScopedTempRulesetFile output_css(RulesetFormat::kFilterList);
+
+  input_file.WriteRuleset(test_content_);
+
+  EXPECT_TRUE(converter.SetInputFiles(
+      AsciiToNativeString(input_file.ruleset_path().AsUTF8Unsafe())));
+  EXPECT_TRUE(converter.SetOutputFileUrl(output_url.ruleset_path()));
+  EXPECT_TRUE(converter.SetOutputFormat("filter-list"));
+  EXPECT_TRUE(converter.Convert());
+
+  TestRulesetContents expected_url_output;
+  expected_url_output.url_rules = test_content_.url_rules;
+
+  // Expect no CSS output.
+  TestRulesetContents expected_css_output;
+
+  EXPECT_EQ(expected_url_output, output_url.ReadContents());
+  EXPECT_EQ(expected_css_output, output_css.ReadContents());
+}
+
+TEST_F(RulesetConverterTest, CssOutput) {
+  RulesetConverter converter;
+  ScopedTempRulesetFile input_file(RulesetFormat::kFilterList);
+  ScopedTempRulesetFile output_url(RulesetFormat::kFilterList);
+  ScopedTempRulesetFile output_css(RulesetFormat::kFilterList);
+
+  input_file.WriteRuleset(test_content_);
+
+  EXPECT_TRUE(converter.SetInputFiles(
+      AsciiToNativeString(input_file.ruleset_path().AsUTF8Unsafe())));
+  EXPECT_TRUE(converter.SetOutputFileCss(output_css.ruleset_path()));
+  EXPECT_TRUE(converter.SetOutputFormat("filter-list"));
+  EXPECT_TRUE(converter.Convert());
+
+  // Expect no URL output.
+  TestRulesetContents expected_url_output;
+
+  TestRulesetContents expected_css_output;
+  expected_css_output.css_rules = test_content_.css_rules;
+
+  EXPECT_EQ(expected_url_output, output_url.ReadContents());
+  EXPECT_EQ(expected_css_output, output_css.ReadContents());
+}
+
+TEST_F(RulesetConverterTest, ChromeVersions) {
+  ScopedTempRulesetFile input_file(RulesetFormat::kFilterList);
+
+  std::vector<std::string> kUnfriendlyRules{
+      // No Chrome version supports regexes.
+      "/a[0-9].com/$image",
+
+      // No Chrome version supports badly defined rules.
+      "a.com$image,~image",
+
+      // No Chrome version supports popups.
+      "a.com$popup",
+
+      // Only genericblock/document activations are supported.
+      "@@a.com$generichide", "@@a.com$elemhide",
+
+      // Chrome 59+ supports websocket.
+      "host.com$websocket",
+  };
+  TestRulesetContents unfriendly_contents;
+  unfriendly_contents.AppendRules(kUnfriendlyRules);
+  input_file.WriteRuleset(unfriendly_contents);
+  {
+    RulesetConverter converter;
+    ScopedTempRulesetFile output_file(RulesetFormat::kFilterList);
+    EXPECT_TRUE(converter.SetInputFiles(
+        AsciiToNativeString(input_file.ruleset_path().AsUTF8Unsafe())));
+    EXPECT_TRUE(converter.SetOutputFile(output_file.ruleset_path()));
+    EXPECT_TRUE(converter.SetOutputFormat("filter-list"));
+    EXPECT_TRUE(converter.SetChromeVersion("0"));
+    EXPECT_TRUE(converter.Convert());
+    EXPECT_EQ(unfriendly_contents, output_file.ReadContents());
+  }
+  {
+    RulesetConverter converter;
+    ScopedTempRulesetFile output_file(RulesetFormat::kFilterList);
+    EXPECT_TRUE(converter.SetInputFiles(
+        AsciiToNativeString(input_file.ruleset_path().AsUTF8Unsafe())));
+    EXPECT_TRUE(converter.SetOutputFile(output_file.ruleset_path()));
+    EXPECT_TRUE(converter.SetOutputFormat("filter-list"));
+    EXPECT_TRUE(converter.SetChromeVersion("54"));
+    EXPECT_TRUE(converter.Convert());
+    EXPECT_EQ(0u, output_file.ReadContents().url_rules.size());
+  }
+  {
+    RulesetConverter converter;
+    ScopedTempRulesetFile output_file(RulesetFormat::kFilterList);
+    EXPECT_TRUE(converter.SetInputFiles(
+        AsciiToNativeString(input_file.ruleset_path().AsUTF8Unsafe())));
+    EXPECT_TRUE(converter.SetOutputFile(output_file.ruleset_path()));
+    EXPECT_TRUE(converter.SetOutputFormat("filter-list"));
+    EXPECT_TRUE(converter.SetChromeVersion("59"));
+    EXPECT_TRUE(converter.Convert());
+
+    TestRulesetContents expected_contents;
+    expected_contents.AppendRules({"host.com$websocket"});
+    EXPECT_EQ(expected_contents, output_file.ReadContents());
+  }
+}
+
+TEST_F(RulesetConverterTest, FormatConversions) {
+  std::vector<std::string> kSupportedFormats = {"filter-list",
+                                                "unindexed-ruleset", "proto"};
+  for (const auto& input_format : kSupportedFormats) {
+    for (const auto& output_format : kSupportedFormats) {
+      SCOPED_TRACE(testing::Message() << "input: " << input_format
+                                      << " output: " << output_format);
+      RulesetConverter converter;
+      ScopedTempRulesetFile input_file(ParseFlag(input_format));
+      input_file.WriteRuleset(test_content_);
+
+      ScopedTempRulesetFile output_file(ParseFlag(output_format));
+      EXPECT_TRUE(converter.SetInputFiles(
+          AsciiToNativeString(input_file.ruleset_path().AsUTF8Unsafe())));
+      EXPECT_TRUE(converter.SetOutputFile(output_file.ruleset_path()));
+      EXPECT_TRUE(converter.SetInputFormat(input_format));
+      EXPECT_TRUE(converter.SetOutputFormat(output_format));
+      EXPECT_TRUE(converter.Convert());
+
+      TestRulesetContents input_contents = input_file.ReadContents();
+      TestRulesetContents output_contents = output_file.ReadContents();
+      TestRulesetContents expected_output;
+
+      // Unindexed format strips CSS rules.
+      if (output_format == "unindexed-ruleset" &&
+          input_format != output_format) {
+        expected_output.url_rules = input_contents.url_rules;
+      } else {
+        expected_output = input_contents;
+      }
+      EXPECT_EQ(expected_output, output_contents);
+    }
+  }
+}
+
+}  // namespace subresource_filter
diff --git a/components/sync_sessions/session_store.cc b/components/sync_sessions/session_store.cc
index 9927986e..c1d1c38 100644
--- a/components/sync_sessions/session_store.cc
+++ b/components/sync_sessions/session_store.cc
@@ -574,7 +574,10 @@
           [](syncer::MutableDataBatch* batch, const std::string& session_name,
              sync_pb::SessionSpecifics* specifics) {
             // Local variable used to avoid assuming argument evaluation order.
-            const std::string storage_key = GetStorageKey(*specifics);
+            // We also avoid GetStorageKey() because specifics might not be
+            // valid according to AreValidSpecifics().
+            const std::string storage_key = EncodeStorageKey(
+                specifics->session_tag(), specifics->tab_node_id());
             batch->Put(storage_key, MoveToEntityData(session_name, specifics));
           },
           batch.get()));
@@ -589,7 +592,10 @@
           [](syncer::MutableDataBatch* batch, const std::string& session_name,
              sync_pb::SessionSpecifics* specifics) {
             // Local variable used to avoid assuming argument evaluation order.
-            const std::string storage_key = GetStorageKey(*specifics);
+            // We also avoid GetStorageKey() because specifics might not be
+            // valid according to AreValidSpecifics().
+            const std::string storage_key = EncodeStorageKey(
+                specifics->session_tag(), specifics->tab_node_id());
             batch->Put(storage_key, MoveToEntityData(session_name, specifics));
           },
           batch.get()));
diff --git a/components/sync_sessions/session_store_unittest.cc b/components/sync_sessions/session_store_unittest.cc
index 5b50cc7..a13cbf5 100644
--- a/components/sync_sessions/session_store_unittest.cc
+++ b/components/sync_sessions/session_store_unittest.cc
@@ -575,5 +575,65 @@
                            /*urls=*/_)))));
 }
 
+TEST_F(SessionStoreTest, ShouldReturnForeignOrphanTabs) {
+  const std::string kForeignSessionTag = "SomeForeignTag";
+  const int kWindowId = 5;
+  const int kTabId = 7;
+  // Both tab nodes point to the same tab ID.
+  const int kTabNodeId1 = 2;
+  const int kTabNodeId2 = 3;
+
+  const std::string local_header_storage_key =
+      SessionStore::GetHeaderStorageKey(kLocalSessionTag);
+  const std::string foreign_header_storage_key =
+      SessionStore::GetHeaderStorageKey(kForeignSessionTag);
+  const std::string foreign_tab_storage_key1 =
+      SessionStore::GetTabStorageKey(kForeignSessionTag, kTabNodeId1);
+  const std::string foreign_tab_storage_key2 =
+      SessionStore::GetTabStorageKey(kForeignSessionTag, kTabNodeId2);
+
+  // Local header entity is present initially.
+  ASSERT_THAT(BatchToEntityDataMap(session_store()->GetAllSessionData()),
+              ElementsAre(Pair(local_header_storage_key, _)));
+
+  SessionSpecifics tab1;
+  tab1.set_session_tag(kForeignSessionTag);
+  tab1.set_tab_node_id(kTabNodeId1);
+  tab1.mutable_tab()->set_window_id(kWindowId);
+  tab1.mutable_tab()->set_tab_id(kTabId);
+  ASSERT_TRUE(SessionStore::AreValidSpecifics(tab1));
+
+  SessionSpecifics tab2;
+  tab2.set_session_tag(kForeignSessionTag);
+  tab2.set_tab_node_id(kTabNodeId2);
+  tab2.mutable_tab()->set_window_id(kWindowId);
+  tab2.mutable_tab()->set_tab_id(kTabId);
+  ASSERT_TRUE(SessionStore::AreValidSpecifics(tab2));
+
+  std::unique_ptr<SessionStore::WriteBatch> batch =
+      session_store()->CreateWriteBatch(/*error_handler=*/base::DoNothing());
+  ASSERT_THAT(batch, NotNull());
+  batch->PutAndUpdateTracker(tab1, base::Time::Now());
+  batch->PutAndUpdateTracker(tab2, base::Time::Now());
+  SessionStore::WriteBatch::Commit(std::move(batch));
+
+  EXPECT_THAT(BatchToEntityDataMap(session_store()->GetAllSessionData()),
+              UnorderedElementsAre(
+                  Pair(local_header_storage_key, _),
+                  Pair(foreign_header_storage_key,
+                       EntityDataHasSpecifics(MatchesHeader(kForeignSessionTag,
+                                                            /*window_ids=*/{},
+                                                            /*tab_ids=*/{}))),
+                  Pair(foreign_tab_storage_key1,
+                       EntityDataHasSpecifics(
+                           MatchesTab(kForeignSessionTag, /*window_id=*/0,
+                                      /*tab_id=*/-1, kTabNodeId1,
+                                      /*urls=*/_))),
+                  Pair(foreign_tab_storage_key2,
+                       EntityDataHasSpecifics(MatchesTab(
+                           kForeignSessionTag, kWindowId, kTabId, kTabNodeId2,
+                           /*urls=*/_)))));
+}
+
 }  // namespace
 }  // namespace sync_sessions
diff --git a/components/sync_sessions/synced_session_tracker.cc b/components/sync_sessions/synced_session_tracker.cc
index 7c78a4d1f..c46ef20 100644
--- a/components/sync_sessions/synced_session_tracker.cc
+++ b/components/sync_sessions/synced_session_tracker.cc
@@ -773,7 +773,9 @@
         // Associated tab node.
         const sessions::SessionTab* tab =
             tracker.LookupSessionTab(session_tag, tab_id);
-        DCHECK(tab);
+        // TODO(crbug.com/837517): Replace with DCHECK once the crasher
+        // investigation is finalized.
+        CHECK(tab);
 
         sync_pb::SessionSpecifics tab_pb;
         tab_pb.set_session_tag(session_tag);
diff --git a/components/ui_devtools/devtools_server.cc b/components/ui_devtools/devtools_server.cc
index 1a29635..294e430 100644
--- a/components/ui_devtools/devtools_server.cc
+++ b/components/ui_devtools/devtools_server.cc
@@ -67,12 +67,9 @@
 
 UiDevToolsServer* UiDevToolsServer::devtools_server_ = nullptr;
 
-UiDevToolsServer::UiDevToolsServer(
-    network::mojom::NetworkContext* network_context,
-    const char* enable_devtools_flag,
-    int default_port)
-    : network_context_(network_context),
-      port_(GetUiDevToolsPort(enable_devtools_flag, default_port)),
+UiDevToolsServer::UiDevToolsServer(const char* enable_devtools_flag,
+                                   int default_port)
+    : port_(GetUiDevToolsPort(enable_devtools_flag, default_port)),
       weak_ptr_factory_(this) {
   DCHECK(!devtools_server_);
   devtools_server_ = this;
@@ -90,9 +87,8 @@
   std::unique_ptr<UiDevToolsServer> server;
   if (IsDevToolsEnabled(enable_devtools_flag) && !devtools_server_) {
     // TODO(mhashmi): Change port if more than one inspectable clients
-    server.reset(new UiDevToolsServer(network_context, enable_devtools_flag,
-                                      default_port));
-    server->Start("0.0.0.0");
+    server.reset(new UiDevToolsServer(enable_devtools_flag, default_port));
+    server->Start(network_context, "0.0.0.0");
   }
   return server;
 }
@@ -125,7 +121,8 @@
   server_->SendOverWebSocket(connection_id, message, kUIDevtoolsServer);
 }
 
-void UiDevToolsServer::Start(const std::string& address_string) {
+void UiDevToolsServer::Start(network::mojom::NetworkContext* network_context,
+                             const std::string& address_string) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(devtools_server_sequence_);
   DCHECK(!server_);
 
@@ -136,7 +133,7 @@
     return;
 
   constexpr int kBacklog = 1;
-  network_context_->CreateTCPServerSocket(
+  network_context->CreateTCPServerSocket(
       net::IPEndPoint(address, port_), kBacklog,
       net::MutableNetworkTrafficAnnotationTag(kUIDevtoolsServer),
       mojo::MakeRequest(&server_socket),
diff --git a/components/ui_devtools/devtools_server.h b/components/ui_devtools/devtools_server.h
index 8ff8644..572ed3e 100644
--- a/components/ui_devtools/devtools_server.h
+++ b/components/ui_devtools/devtools_server.h
@@ -44,11 +44,10 @@
   int port() const { return port_; }
 
  private:
-  UiDevToolsServer(network::mojom::NetworkContext* network_context,
-                   const char* enable_devtools_flag,
-                   int default_port);
+  UiDevToolsServer(const char* enable_devtools_flag, int default_port);
 
-  void Start(const std::string& address_string);
+  void Start(network::mojom::NetworkContext* network_context,
+             const std::string& address_string);
   void MakeServer(network::mojom::TCPServerSocketPtr server_socket,
                   int result,
                   const base::Optional<net::IPEndPoint>& local_addr);
@@ -70,7 +69,6 @@
   ConnectionsMap connections_;
 
   std::unique_ptr<network::server::HttpServer> server_;
-  network::mojom::NetworkContext* network_context_;
 
   // The port the devtools server listens on
   const int port_;
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index d468c347..2dd1cca 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -174,6 +174,7 @@
     "//components/viz/common",
     "//gpu/command_buffer/client:gles2_implementation",
     "//gpu/command_buffer/client:raster",
+    "//gpu/command_buffer/service:gles2",
     "//gpu/ipc:gl_in_process_context",
 
     # Note that dependency on //gpu/ipc/client is for GpuMemoryBufferImpl. This
diff --git a/components/viz/service/display/skia_output_surface.h b/components/viz/service/display/skia_output_surface.h
index e291e425..a93bfc26 100644
--- a/components/viz/service/display/skia_output_surface.h
+++ b/components/viz/service/display/skia_output_surface.h
@@ -30,14 +30,25 @@
   // And this SkCanvas may become invalid, when the frame is swapped out.
   virtual SkCanvas* GetSkCanvasForCurrentFrame() = 0;
 
-  // Make a SkImage from the given |metadata|. The SkiaRenderer can use the
-  // image with SkCanvas returned by |GetSkCanvasForCurrentFrame|, but Skia will
-  // not read the content of the resource until the sync token in the |metadata|
-  // is satisfied. The SwapBuffers should take care of this by scheduling a GPU
-  // task with all resource sync tokens recorded by MakePromiseSkImage for the
-  // current frame.
+  // Make a promise SkImage from the given |metadata|. The SkiaRenderer can use
+  // the image with SkCanvas returned by |GetSkCanvasForCurrentFrame|, but Skia
+  // will not read the content of the resource until the sync token in the
+  // |metadata| is satisfied. The SwapBuffers should take care of this by
+  // scheduling a GPU task with all resource sync tokens recorded by
+  // MakePromiseSkImage for the current frame.
   virtual sk_sp<SkImage> MakePromiseSkImage(ResourceMetadata metadata) = 0;
 
+  // Make a promise SkImage from the given |metadata| and the |yuv_color_space|.
+  // For YUV format, three resource metadatas should be provided. metadatas[0]
+  // contains pixels from y panel, metadatas[1] contains pixels from u panel,
+  // metadatas[2] contains pixels from v panel.
+  // For NV12 format, two resource metadatas should be provided. metadatas[0]
+  // contains pixels from y panel, metadatas[1] contains pixels from u and v
+  // panels.
+  virtual sk_sp<SkImage> MakePromiseSkImageFromYUV(
+      std::vector<ResourceMetadata> metadatas,
+      SkYUVColorSpace yuv_color_space) = 0;
+
   // Swaps the current backbuffer to the screen and return a sync token which
   // can be waited on in a command buffer to ensure the frame is completed. This
   // token is released when the GPU ops from drawing the frame have been seen
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc
index ec08c19..e14c76d 100644
--- a/components/viz/service/display/skia_renderer.cc
+++ b/components/viz/service/display/skia_renderer.cc
@@ -17,6 +17,7 @@
 #include "components/viz/common/quads/solid_color_draw_quad.h"
 #include "components/viz/common/quads/texture_draw_quad.h"
 #include "components/viz/common/quads/tile_draw_quad.h"
+#include "components/viz/common/quads/yuv_video_draw_quad.h"
 #include "components/viz/common/resources/platform_color.h"
 #include "components/viz/common/resources/resource_fence.h"
 #include "components/viz/common/resources/resource_format_utils.h"
@@ -83,7 +84,7 @@
 class SkiaRenderer::ScopedSkImageBuilder {
  public:
   ScopedSkImageBuilder(SkiaRenderer* skia_renderer, ResourceId resource_id);
-  ~ScopedSkImageBuilder();
+  ~ScopedSkImageBuilder() = default;
 
   const SkImage* sk_image() const { return sk_image_; }
 
@@ -115,17 +116,76 @@
     if (!image) {
       auto metadata =
           skia_renderer->lock_set_for_external_use_.LockResource(resource_id);
-      if (!metadata.mailbox.IsZero()) {
-        image = skia_renderer->skia_output_surface_->MakePromiseSkImage(
-            std::move(metadata));
-        DCHECK(image);
-      }
+      DCHECK(!metadata.mailbox.IsZero());
+      image = skia_renderer->skia_output_surface_->MakePromiseSkImage(
+          std::move(metadata));
+      DCHECK(image);
     }
     sk_image_ = image.get();
   }
 }
 
-SkiaRenderer::ScopedSkImageBuilder::~ScopedSkImageBuilder() = default;
+class SkiaRenderer::ScopedYUVSkImageBuilder {
+ public:
+  ScopedYUVSkImageBuilder(SkiaRenderer* skia_renderer,
+                          const YUVVideoDrawQuad* quad) {
+    DCHECK(skia_renderer->skia_output_surface_);
+    DCHECK(IsTextureResource(skia_renderer->resource_provider_,
+                             quad->y_plane_resource_id()));
+    DCHECK(IsTextureResource(skia_renderer->resource_provider_,
+                             quad->u_plane_resource_id()));
+    DCHECK(IsTextureResource(skia_renderer->resource_provider_,
+                             quad->v_plane_resource_id()));
+    DCHECK(quad->a_plane_resource_id() == kInvalidResourceId ||
+           IsTextureResource(skia_renderer->resource_provider_,
+                             quad->a_plane_resource_id()));
+
+    YUVIds ids(quad->y_plane_resource_id(), quad->u_plane_resource_id(),
+               quad->v_plane_resource_id(), quad->a_plane_resource_id());
+    auto& image = skia_renderer->yuv_promise_images_[std::move(ids)];
+
+    if (!image) {
+      auto yuv_color_space = kRec601_SkYUVColorSpace;
+      quad->video_color_space.ToSkYUVColorSpace(&yuv_color_space);
+
+      std::vector<ResourceMetadata> metadatas;
+      bool is_yuv = quad->u_plane_resource_id() != quad->v_plane_resource_id();
+      metadatas.reserve(is_yuv ? 3 : 2);
+      auto y_metadata = skia_renderer->lock_set_for_external_use_.LockResource(
+          quad->y_plane_resource_id());
+      metadatas.push_back(std::move(y_metadata));
+      auto u_metadata = skia_renderer->lock_set_for_external_use_.LockResource(
+          quad->u_plane_resource_id());
+      metadatas.push_back(std::move(u_metadata));
+      if (is_yuv) {
+        auto v_metadata =
+            skia_renderer->lock_set_for_external_use_.LockResource(
+                quad->v_plane_resource_id());
+        metadatas.push_back(std::move(v_metadata));
+      }
+
+      if (quad->a_plane_resource_id() != kInvalidResourceId) {
+        // TODO(penghuang): Handle alpha channel when Skia supports YUVA format.
+        NOTIMPLEMENTED();
+      }
+
+      image = skia_renderer->skia_output_surface_->MakePromiseSkImageFromYUV(
+          std::move(metadatas), yuv_color_space);
+      DCHECK(image);
+    }
+    sk_image_ = image.get();
+  }
+
+  ~ScopedYUVSkImageBuilder() = default;
+
+  const SkImage* sk_image() const { return sk_image_; }
+
+ private:
+  std::unique_ptr<cc::DisplayResourceProvider::ScopedReadLockSkImage> lock_;
+  SkImage* sk_image_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedYUVSkImageBuilder);
+};
 
 SkiaRenderer::SkiaRenderer(const RendererSettings* settings,
                            OutputSurface* output_surface,
@@ -241,6 +301,7 @@
     auto sync_token =
         skia_output_surface_->SkiaSwapBuffers(std::move(output_frame));
     promise_images_.clear();
+    yuv_promise_images_.clear();
     lock_set_for_external_use_.UnlockResources(sync_token);
   } else {
     // TODO(penghuang): remove it when SkiaRenderer and SkDDL are always used.
@@ -508,8 +569,15 @@
       // reaching a direct renderer.
       NOTREACHED();
       break;
-    case DrawQuad::INVALID:
     case DrawQuad::YUV_VIDEO_CONTENT:
+      if (skia_output_surface_) {
+        DrawYUVVideoQuad(YUVVideoDrawQuad::MaterialCast(quad));
+      } else {
+        DrawUnsupportedQuad(quad);
+        NOTIMPLEMENTED();
+      }
+      break;
+    case DrawQuad::INVALID:
     case DrawQuad::STREAM_VIDEO_CONTENT:
       DrawUnsupportedQuad(quad);
       NOTREACHED();
@@ -655,6 +723,26 @@
                                  &current_paint_);
 }
 
+void SkiaRenderer::DrawYUVVideoQuad(const YUVVideoDrawQuad* quad) {
+  DCHECK(resource_provider_);
+  ScopedYUVSkImageBuilder builder(this, quad);
+  const SkImage* image = builder.sk_image();
+  if (!image)
+    return;
+  gfx::RectF visible_tex_coord_rect = cc::MathUtil::ScaleRectProportional(
+      quad->ya_tex_coord_rect, gfx::RectF(quad->rect),
+      gfx::RectF(quad->visible_rect));
+  gfx::RectF visible_quad_vertex_rect = cc::MathUtil::ScaleRectProportional(
+      QuadVertexRect(), gfx::RectF(quad->rect), gfx::RectF(quad->visible_rect));
+
+  SkRect uv_rect = gfx::RectFToSkRect(visible_tex_coord_rect);
+  // TODO(penghuang): figure out how to set correct filter quality.
+  current_paint_.setFilterQuality(kLow_SkFilterQuality);
+  current_canvas_->drawImageRect(image, uv_rect,
+                                 gfx::RectFToSkRect(visible_quad_vertex_rect),
+                                 &current_paint_);
+}
+
 bool SkiaRenderer::CalculateRPDQParams(sk_sp<SkImage> content,
                                        const RenderPassDrawQuad* quad,
                                        DrawRenderPassDrawQuadParams* params) {
@@ -870,6 +958,7 @@
     if (is_drawing_render_pass_) {
       gpu::SyncToken sync_token = skia_output_surface_->FinishPaintRenderPass();
       promise_images_.clear();
+      yuv_promise_images_.clear();
       lock_set_for_external_use_.UnlockResources(sync_token);
       is_drawing_render_pass_ = false;
     }
@@ -942,7 +1031,8 @@
                         src_image->alphaType(), nullptr);
 
 #if BUILDFLAG(ENABLE_VULKAN)
-// TODO(xing.xu):  Handle Vulkan related logic here.
+  // TODO(xing.xu):  Handle Vulkan related logic here.
+  return nullptr;
 #else
   GrContext* gr_context = output_surface_->context_provider()->GrContext();
   // TODO(weiliangc): Set up correct can_use_lcd_text for SkSurfaceProps flags.
@@ -952,7 +1042,6 @@
   sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
       gr_context, SkBudgeted::kNo, image_info, 0, kBottomLeft_GrSurfaceOrigin,
       &surface_props, false);
-#endif
 
   if (!surface) {
     return nullptr;
@@ -966,6 +1055,7 @@
   surface->getCanvas()->drawImage(src_image, rect.x(), rect.y(), &paint);
 
   return surface->makeImageSnapshot();
+#endif
 }
 
 sk_sp<SkShader> SkiaRenderer::GetBackgroundFilterShader(
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h
index 0f13970c..e7505d8b 100644
--- a/components/viz/service/display/skia_renderer.h
+++ b/components/viz/service/display/skia_renderer.h
@@ -5,6 +5,8 @@
 #ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_SKIA_RENDERER_H_
 #define COMPONENTS_VIZ_SERVICE_DISPLAY_SKIA_RENDERER_H_
 
+#include <tuple>
+
 #include "base/macros.h"
 #include "cc/cc_export.h"
 #include "components/viz/service/display/direct_renderer.h"
@@ -26,6 +28,7 @@
 class SolidColorDrawQuad;
 class TextureDrawQuad;
 class TileDrawQuad;
+class YUVVideoDrawQuad;
 
 class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
  public:
@@ -76,6 +79,7 @@
  private:
   struct DrawRenderPassDrawQuadParams;
   class ScopedSkImageBuilder;
+  class ScopedYUVSkImageBuilder;
 
   void ClearCanvas(SkColor color);
   void ClearFramebuffer();
@@ -87,6 +91,7 @@
   void DrawSolidColorQuad(const SolidColorDrawQuad* quad);
   void DrawTextureQuad(const TextureDrawQuad* quad);
   void DrawTileQuad(const TileDrawQuad* quad);
+  void DrawYUVVideoQuad(const YUVVideoDrawQuad* quad);
   void DrawUnsupportedQuad(const DrawQuad* quad);
   bool CalculateRPDQParams(sk_sp<SkImage> src_image,
                            const RenderPassDrawQuad* quad,
@@ -164,6 +169,9 @@
   // It is only used with DDL.
   base::flat_map<ResourceId, sk_sp<SkImage>> promise_images_;
 
+  using YUVIds = std::tuple<ResourceId, ResourceId, ResourceId, ResourceId>;
+  base::flat_map<YUVIds, sk_sp<SkImage>> yuv_promise_images_;
+
   DISALLOW_COPY_AND_ASSIGN(SkiaRenderer);
 };
 
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc
index 650e9984..afbae27 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -21,6 +21,7 @@
 #include "gpu/command_buffer/service/scheduler.h"
 #include "gpu/command_buffer/service/sync_point_manager.h"
 #include "gpu/command_buffer/service/texture_base.h"
+#include "gpu/command_buffer/service/texture_manager.h"
 #include "gpu/ipc/service/image_transport_surface.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
@@ -29,21 +30,53 @@
 #include "ui/gl/gl_version_info.h"
 
 namespace viz {
-
 namespace {
 
 base::AtomicSequenceNumber g_next_command_buffer_id;
 
 }  // namespace
 
+// Metadata for YUV promise SkImage.
+class SkiaOutputSurfaceImpl::YUVResourceMetadata {
+ public:
+  YUVResourceMetadata(std::vector<ResourceMetadata> metadatas,
+                      SkYUVColorSpace yuv_color_space)
+      : metadatas_(std::move(metadatas)), yuv_color_space_(yuv_color_space) {
+    DCHECK(metadatas_.size() == 2 || metadatas_.size() == 3);
+  }
+  YUVResourceMetadata(YUVResourceMetadata&& other) = default;
+  ~YUVResourceMetadata() = default;
+  YUVResourceMetadata& operator=(YUVResourceMetadata&& other) = default;
+
+  const std::vector<ResourceMetadata>& metadatas() const { return metadatas_; }
+  SkYUVColorSpace yuv_color_space() const { return yuv_color_space_; }
+  const sk_sp<SkImage> image() const { return image_; }
+  void set_image(sk_sp<SkImage> image) { image_ = image; }
+  const gfx::Size size() const { return metadatas_[0].size; }
+
+ private:
+  // Resource metadatas for YUV planes.
+  std::vector<ResourceMetadata> metadatas_;
+
+  SkYUVColorSpace yuv_color_space_;
+
+  // The image copied from YUV textures, it is for fullfilling the promise
+  // image.
+  // TODO(penghuang): Remove it when Skia supports drawing YUV textures
+  // directly.
+  sk_sp<SkImage> image_;
+
+  DISALLOW_COPY_AND_ASSIGN(YUVResourceMetadata);
+};
+
 // A helper class for fullfilling promise image on the GPU thread.
-template <class T>
+template <class FullfillContextType>
 class SkiaOutputSurfaceImpl::PromiseTextureHelper {
  public:
-  using HelperType = PromiseTextureHelper<T>;
+  using HelperType = PromiseTextureHelper<FullfillContextType>;
 
-  PromiseTextureHelper(SkiaOutputSurfaceImpl* impl, T data)
-      : impl_(impl), data_(std::move(data)) {}
+  PromiseTextureHelper(SkiaOutputSurfaceImpl* impl, FullfillContextType context)
+      : impl_(impl), context_(std::move(context)) {}
   ~PromiseTextureHelper() = default;
 
   static sk_sp<SkImage> MakePromiseSkImage(
@@ -56,25 +89,29 @@
       SkColorType color_type,
       SkAlphaType alpha_type,
       sk_sp<SkColorSpace> color_space,
-      T data) {
+      FullfillContextType context) {
     DCHECK_CALLED_ON_VALID_THREAD(impl->client_thread_checker_);
-    auto helper = std::make_unique<HelperType>(impl, std::move(data));
+    auto helper = std::make_unique<HelperType>(impl, std::move(context));
     auto image = recorder->makePromiseTexture(
         backend_format, size.width(), size.height(), mip_mapped, origin,
         color_type, alpha_type, color_space, HelperType::Fullfill,
         HelperType::Release, HelperType::Done, helper.get());
-    if (image)
+    if (image) {
+      helper->Init(impl);
       helper.release();
+    }
     return image;
   }
 
  private:
+  void Init(SkiaOutputSurfaceImpl* impl);
+
   static void Fullfill(void* texture_context,
                        GrBackendTexture* backend_texture) {
     DCHECK(texture_context);
     auto* helper = static_cast<HelperType*>(texture_context);
     DCHECK_CALLED_ON_VALID_THREAD(helper->impl_->gpu_thread_checker_);
-    helper->impl_->OnPromiseTextureFullfill(helper->data_, backend_texture);
+    helper->impl_->OnPromiseTextureFullfill(helper->context_, backend_texture);
   }
 
   static void Release(void* texture_context) { DCHECK(texture_context); }
@@ -86,11 +123,29 @@
   }
 
   SkiaOutputSurfaceImpl* const impl_;
-  const T data_;
+
+  // The data for calling the fullfill methods in SkiaOutputSurfaceImpl.
+  FullfillContextType context_;
 
   DISALLOW_COPY_AND_ASSIGN(PromiseTextureHelper);
 };
 
+template <class T>
+void SkiaOutputSurfaceImpl::PromiseTextureHelper<T>::Init(
+    SkiaOutputSurfaceImpl* impl) {}
+
+// For YUVResourceMetadata, we need to record the |context_| pointer in
+// |impl->yuv_resource_metadatas_|, because we have to create SkImage from YUV
+// textures before drawing the ddl to a SKSurface.
+// TODO(penghuang): Remove this hack when Skia supports drawing YUV textures
+// directly.
+template <>
+void SkiaOutputSurfaceImpl::PromiseTextureHelper<
+    SkiaOutputSurfaceImpl::YUVResourceMetadata>::Init(SkiaOutputSurfaceImpl*
+                                                          impl) {
+  impl->yuv_resource_metadatas_.push_back(&context_);
+}
+
 SkiaOutputSurfaceImpl::SkiaOutputSurfaceImpl(
     GpuServiceImpl* gpu_service,
     gpu::SurfaceHandle surface_handle,
@@ -177,8 +232,8 @@
   } else {
     characterization = &characterization_;
     // TODO(penghuang): avoid blocking compositor thread.
-    // We don't have a valid surface characterization, so we have to wait until
-    // reshape is finished on Gpu thread.
+    // We don't have a valid surface characterization, so we have to wait
+    // until reshape is finished on Gpu thread.
     event = std::make_unique<base::WaitableEvent>(
         base::WaitableEvent::ResetPolicy::MANUAL,
         base::WaitableEvent::InitialState::NOT_SIGNALED);
@@ -248,6 +303,7 @@
 SkCanvas* SkiaOutputSurfaceImpl::GetSkCanvasForCurrentFrame() {
   DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_);
   DCHECK(recorder_);
+  DCHECK_EQ(current_render_pass_id_, 0u);
 
   return recorder_->getCanvas();
 }
@@ -273,6 +329,29 @@
       metadata.alpha_type, metadata.color_space, std::move(metadata));
 }
 
+sk_sp<SkImage> SkiaOutputSurfaceImpl::MakePromiseSkImageFromYUV(
+    std::vector<ResourceMetadata> metadatas,
+    SkYUVColorSpace yuv_color_space) {
+  DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_);
+  DCHECK(recorder_);
+
+  DCHECK(metadatas.size() == 2 || metadatas.size() == 3);
+
+  // TODO(penghuang): Create SkImage from YUV textures directly when it is
+  // supported by Skia.
+  YUVResourceMetadata yuv_metadata(std::move(metadatas), yuv_color_space);
+
+  // Convert internal format from GLES2 to platform GL.
+  const auto* version_info = gpu_service_->context_for_skia()->GetVersionInfo();
+  auto backend_format = GrBackendFormat::MakeGL(
+      gl::GetInternalFormat(version_info, GL_BGRA8_EXT), GL_TEXTURE_2D);
+
+  return PromiseTextureHelper<YUVResourceMetadata>::MakePromiseSkImage(
+      this, recorder_.get(), backend_format, yuv_metadata.size(),
+      GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin, kBGRA_8888_SkColorType,
+      kPremul_SkAlphaType, nullptr /* color_space */, std::move(yuv_metadata));
+}
+
 gpu::SyncToken SkiaOutputSurfaceImpl::SkiaSwapBuffers(
     OutputSurfaceFrame frame) {
   DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_);
@@ -286,9 +365,10 @@
   DCHECK(ddl);
   RecreateRecorder();
   auto sequence_id = gpu_service_->skia_output_surface_sequence_id();
-  auto callback = base::BindOnce(&SkiaOutputSurfaceImpl::SwapBuffersOnGpuThread,
-                                 base::Unretained(this), base::Passed(&frame),
-                                 base::Passed(&ddl), sync_fence_release_);
+  auto callback =
+      base::BindOnce(&SkiaOutputSurfaceImpl::SwapBuffersOnGpuThread,
+                     base::Unretained(this), std::move(frame), std::move(ddl),
+                     std::move(yuv_resource_metadatas_), sync_fence_release_);
   gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task(
       sequence_id, std::move(callback), std::move(resource_sync_tokens_)));
   return sync_token;
@@ -348,10 +428,10 @@
   DCHECK(ddl);
 
   auto sequence_id = gpu_service_->skia_output_surface_sequence_id();
-  auto callback =
-      base::BindOnce(&SkiaOutputSurfaceImpl::FinishPaintRenderPassOnGpuThread,
-                     base::Unretained(this), current_render_pass_id_,
-                     base::Passed(&ddl), sync_fence_release_);
+  auto callback = base::BindOnce(
+      &SkiaOutputSurfaceImpl::FinishPaintRenderPassOnGpuThread,
+      base::Unretained(this), current_render_pass_id_, std::move(ddl),
+      std::move(yuv_resource_metadatas_), sync_fence_release_);
   gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task(
       sequence_id, std::move(callback), std::move(resource_sync_tokens_)));
   current_render_pass_id_ = 0;
@@ -387,7 +467,7 @@
   auto sequence_id = gpu_service_->skia_output_surface_sequence_id();
   auto callback = base::BindOnce(
       &SkiaOutputSurfaceImpl::RemoveRenderPassResourceOnGpuThread,
-      base::Unretained(this), base::Passed(&ids));
+      base::Unretained(this), std::move(ids));
   gpu_service_->scheduler()->ScheduleTask(gpu::Scheduler::Task(
       sequence_id, std::move(callback), std::vector<gpu::SyncToken>()));
 }
@@ -508,8 +588,8 @@
       base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(event)));
   gpu_thread_weak_ptr_factory_.InvalidateWeakPtrs();
 
-  // Destroy the surface with the context current, some surface destructors make
-  // GL calls.
+  // Destroy the surface with the context current, some surface destructors
+  // make GL calls.
   if (!gpu_service_->context_for_skia()->MakeCurrent(surface_.get())) {
     LOG(FATAL) << "Failed to make current.";
     // TODO(penghuang): Handle the failure.
@@ -575,6 +655,7 @@
 void SkiaOutputSurfaceImpl::SwapBuffersOnGpuThread(
     OutputSurfaceFrame frame,
     std::unique_ptr<SkDeferredDisplayList> ddl,
+    std::vector<YUVResourceMetadata*> yuv_resource_metadatas,
     uint64_t sync_fence_release) {
   DCHECK_CALLED_ON_VALID_THREAD(gpu_thread_checker_);
   DCHECK(ddl);
@@ -584,6 +665,9 @@
     LOG(FATAL) << "Failed to make current.";
     // TODO(penghuang): Handle the failure.
   }
+
+  PreprocessYUVResources(std::move(yuv_resource_metadatas));
+
   sk_surface_->draw(ddl.get());
   gpu_service_->gr_context()->flush();
   surface_->SwapBuffers(
@@ -594,6 +678,7 @@
 void SkiaOutputSurfaceImpl::FinishPaintRenderPassOnGpuThread(
     RenderPassId id,
     std::unique_ptr<SkDeferredDisplayList> ddl,
+    std::vector<YUVResourceMetadata*> yuv_resource_metadatas,
     uint64_t sync_fence_release) {
   DCHECK_CALLED_ON_VALID_THREAD(gpu_thread_checker_);
   DCHECK(ddl);
@@ -603,6 +688,8 @@
     // TODO(penghuang): Handle resize failure.
   }
 
+  PreprocessYUVResources(std::move(yuv_resource_metadatas));
+
   auto& surface = offscreen_surfaces_[id];
   SkSurfaceCharacterization characterization;
   // TODO(penghuang): Using characterization != ddl->characterization(), when
@@ -614,7 +701,7 @@
     DCHECK(surface);
   }
   surface->draw(ddl.get());
-  gpu_service_->gr_context()->flush();
+  surface->flush();
   sync_point_client_state_->ReleaseFenceSync(sync_fence_release);
 }
 
@@ -633,11 +720,85 @@
   DCHECK(characterization_.isValid());
   recorder_ =
       std::make_unique<SkDeferredDisplayListRecorder>(characterization_);
-  // TODO(penghuang): remove the unnecessary getCanvas() call, when the recorder
-  // crash is fixed in skia.
+  // TODO(penghuang): remove the unnecessary getCanvas() call, when the
+  // recorder crash is fixed in skia.
   recorder_->getCanvas();
 }
 
+void SkiaOutputSurfaceImpl::PreprocessYUVResources(
+    std::vector<YUVResourceMetadata*> yuv_resource_metadatas) {
+  DCHECK_CALLED_ON_VALID_THREAD(gpu_thread_checker_);
+
+  // Create SkImage for fullfilling YUV promise image, before drawing the ddl.
+  // TODO(penghuang): Remove the extra step when Skia supports drawing YUV
+  // textures directly.
+  auto* mailbox_manager = gpu_service_->mailbox_manager();
+  for (auto* yuv_metadata : yuv_resource_metadatas) {
+    const auto& metadatas = yuv_metadata->metadatas();
+    DCHECK(metadatas.size() == 2 || metadatas.size() == 3);
+    GrBackendTexture backend_textures[3];
+    size_t i = 0;
+    for (const auto& metadata : metadatas) {
+      auto* texture_base = mailbox_manager->ConsumeTexture(metadata.mailbox);
+      if (!texture_base)
+        break;
+      BindOrCopyTextureIfNecessary(texture_base);
+      GrGLTextureInfo texture_info;
+      texture_info.fTarget = texture_base->target();
+      texture_info.fID = texture_base->service_id();
+      texture_info.fFormat = *metadata.backend_format.getGLFormat();
+      backend_textures[i++] =
+          GrBackendTexture(metadata.size.width(), metadata.size.height(),
+                           GrMipMapped::kNo, texture_info);
+    }
+
+    if (i != metadatas.size())
+      continue;
+
+    sk_sp<SkImage> image;
+    if (metadatas.size() == 2) {
+      image = SkImage::MakeFromNV12TexturesCopy(
+          gpu_service_->gr_context(), yuv_metadata->yuv_color_space(),
+          backend_textures, kTopLeft_GrSurfaceOrigin,
+          nullptr /* image_color_space */);
+      DCHECK(image);
+    } else {
+      image = SkImage::MakeFromYUVTexturesCopy(
+          gpu_service_->gr_context(), yuv_metadata->yuv_color_space(),
+          backend_textures, kTopLeft_GrSurfaceOrigin,
+          nullptr /* image_color_space */);
+      DCHECK(image);
+    }
+    yuv_metadata->set_image(std::move(image));
+  }
+}
+
+void SkiaOutputSurfaceImpl::BindOrCopyTextureIfNecessary(
+    gpu::TextureBase* texture_base) {
+  DCHECK_CALLED_ON_VALID_THREAD(gpu_thread_checker_);
+  if (gpu_service_->gpu_preferences().use_passthrough_cmd_decoder)
+    return;
+
+  // If a texture created with non-passthrough command buffer and bind with
+  // an image, the Chrome will defer copying the image to the texture until
+  // the texture is used. It is for implementing low latency drawing and
+  // avoiding unnecessary texture copy. So we need check the texture image
+  // state, and bind or copy the image to the texture if necessary.
+  auto* texture = static_cast<gpu::gles2::Texture*>(texture_base);
+  gpu::gles2::Texture::ImageState image_state;
+  auto* image = texture->GetLevelImage(GL_TEXTURE_2D, 0, &image_state);
+  if (image && image_state == gpu::gles2::Texture::UNBOUND) {
+    glBindTexture(texture_base->target(), texture_base->service_id());
+    if (image->BindTexImage(texture_base->target())) {
+    } else {
+      texture->SetLevelImageState(texture_base->target(), 0,
+                                  gpu::gles2::Texture::COPIED);
+      if (!image->CopyTexImage(texture_base->target()))
+        LOG(ERROR) << "Failed to copy a gl image to texture.";
+    }
+  }
+}
+
 void SkiaOutputSurfaceImpl::DidSwapBuffersCompleteOnClientThread(
     gpu::SwapBuffersCompleteParams params) {
   DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_);
@@ -682,18 +843,28 @@
     DLOG(ERROR) << "Failed to full fill the promise texture.";
     return;
   }
-
+  BindOrCopyTextureIfNecessary(texture_base);
   GrGLTextureInfo texture_info;
   texture_info.fTarget = texture_base->target();
   texture_info.fID = texture_base->service_id();
-  // TODO(penghuang): Get the format correctly.
-  texture_info.fFormat = GL_RGBA8;
+  texture_info.fFormat = *metadata.backend_format.getGLFormat();
   *backend_texture =
       GrBackendTexture(metadata.size.width(), metadata.size.height(),
                        metadata.mip_mapped, texture_info);
 }
 
 void SkiaOutputSurfaceImpl::OnPromiseTextureFullfill(
+    const YUVResourceMetadata& yuv_metadata,
+    GrBackendTexture* backend_texture) {
+  DCHECK_CALLED_ON_VALID_THREAD(gpu_thread_checker_);
+
+  if (yuv_metadata.image())
+    *backend_texture = yuv_metadata.image()->getBackendTexture(true);
+  DLOG_IF(ERROR, !backend_texture->isValid())
+      << "Failed to full fill the promise texture from yuv resources.";
+}
+
+void SkiaOutputSurfaceImpl::OnPromiseTextureFullfill(
     const RenderPassId id,
     GrBackendTexture* backend_texture) {
   auto it = offscreen_surfaces_.find(id);
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h
index 1083049e..197e61ab 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl.h
+++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -25,6 +25,7 @@
 
 namespace gpu {
 class SyncPointClientState;
+class TextureBase;
 }
 
 namespace viz {
@@ -77,6 +78,9 @@
   // SkiaOutputSurface implementation:
   SkCanvas* GetSkCanvasForCurrentFrame() override;
   sk_sp<SkImage> MakePromiseSkImage(ResourceMetadata metadata) override;
+  sk_sp<SkImage> MakePromiseSkImageFromYUV(
+      std::vector<ResourceMetadata> metadatas,
+      SkYUVColorSpace yuv_color_space) override;
   gpu::SyncToken SkiaSwapBuffers(OutputSurfaceFrame frame) override;
   SkCanvas* BeginPaintRenderPass(const RenderPassId& id,
                                  const gfx::Size& surface_size,
@@ -104,6 +108,7 @@
   int32_t GetRouteID() const override;
 
  private:
+  class YUVResourceMetadata;
   void InitializeOnGpuThread(base::WaitableEvent* event);
   void DestroyOnGpuThread(base::WaitableEvent* event);
   void ReshapeOnGpuThread(const gfx::Size& size,
@@ -113,15 +118,21 @@
                           bool use_stencil,
                           SkSurfaceCharacterization* characterization,
                           base::WaitableEvent* event);
-  void SwapBuffersOnGpuThread(OutputSurfaceFrame frame,
-                              std::unique_ptr<SkDeferredDisplayList> ddl,
-                              uint64_t sync_fence_release);
+  void SwapBuffersOnGpuThread(
+      OutputSurfaceFrame frame,
+      std::unique_ptr<SkDeferredDisplayList> ddl,
+      std::vector<YUVResourceMetadata*> yuv_resource_metadatas,
+      uint64_t sync_fence_release);
   void FinishPaintRenderPassOnGpuThread(
       RenderPassId id,
       std::unique_ptr<SkDeferredDisplayList> ddl,
+      std::vector<YUVResourceMetadata*> yuv_resource_metadatas,
       uint64_t sync_fence_release);
   void RemoveRenderPassResourceOnGpuThread(std::vector<RenderPassId> ids);
   void RecreateRecorder();
+  void PreprocessYUVResources(
+      std::vector<YUVResourceMetadata*> yuv_resource_metadatas);
+  void BindOrCopyTextureIfNecessary(gpu::TextureBase* texture_base);
   void DidSwapBuffersCompleteOnClientThread(
       gpu::SwapBuffersCompleteParams params);
   void UpdateVSyncParametersOnClientThread(base::TimeTicks timebase,
@@ -131,11 +142,12 @@
 
   template <class T>
   class PromiseTextureHelper;
-
   // Fullfill callback for promise SkImage created from a resource.
   void OnPromiseTextureFullfill(const ResourceMetadata& metadata,
                                 GrBackendTexture* backend_texture);
-
+  // Fullfill callback for promise SkImage created from YUV resources.
+  void OnPromiseTextureFullfill(const YUVResourceMetadata& metadata,
+                                GrBackendTexture* backend_texture);
   // Fullfill callback for promise SkImage created from a render pass.
   void OnPromiseTextureFullfill(const RenderPassId id,
                                 GrBackendTexture* backend_texture);
@@ -171,6 +183,12 @@
   // Sync tokens for resources which are used for the current frame.
   std::vector<gpu::SyncToken> resource_sync_tokens_;
 
+  // YUV resource metadatas for the current frame or the current render pass.
+  // They should be preprocessed for playing recorded frame into a surface.
+  // TODO(penghuang): Remove it when Skia supports drawing YUV textures
+  // directly.
+  std::vector<YUVResourceMetadata*> yuv_resource_metadatas_;
+
   // The task runner for running task on the client (compositor) thread.
   scoped_refptr<base::SingleThreadTaskRunner> client_thread_task_runner_;
 
diff --git a/components/zucchini/image_utils.h b/components/zucchini/image_utils.h
index de8cfee..9f561ba1a52 100644
--- a/components/zucchini/image_utils.h
+++ b/components/zucchini/image_utils.h
@@ -183,7 +183,9 @@
 
 inline std::string CastExecutableTypeToString(ExecutableType exe_type) {
   uint32_t v = static_cast<uint32_t>(exe_type);
-  return {v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF, (v >> 24) & 0xFF};
+  char result[] = {v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF,
+                   (v >> 24) & 0xFF, 0};
+  return result;
 }
 
 // A region in an image with associated executable type |exe_type|. If
diff --git a/content/browser/background_fetch/background_fetch.proto b/content/browser/background_fetch/background_fetch.proto
index ae48f05..2feb0bc 100644
--- a/content/browser/background_fetch/background_fetch.proto
+++ b/content/browser/background_fetch/background_fetch.proto
@@ -95,10 +95,8 @@
   optional BackgroundFetchRegistration registration = 3;
   optional BackgroundFetchOptions options = 4;
 
-  // Defaults to BackgroundFetchOptions.title.
-  // Can be updated by calling `BackgroundFetchUpdateEvent.updateUI`.
-  // https://wicg.github.io/background-fetch/#backgroundfetchupdateevent.
-  optional string ui_title = 5;
+  // Number of fetches initiated by the developer.
+  optional int32 num_fetches = 5;
 }
 
 // A background fetch request that is still in a pending state.
diff --git a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
index 7b2ca5ea..e6791266 100644
--- a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
@@ -576,6 +576,7 @@
   ASSERT_TRUE(metadata);
   EXPECT_EQ(metadata->origin(), origin().Serialize());
   EXPECT_NE(metadata->creation_microseconds_since_unix_epoch(), 0);
+  EXPECT_EQ(metadata->num_fetches(), static_cast<int>(requests.size()));
 
   // Verify that retrieving using the wrong developer id doesn't work.
   metadata = GetMetadata(sw_id, origin(), kAlternativeDeveloperId, &error);
@@ -590,6 +591,7 @@
   ASSERT_TRUE(metadata);
   EXPECT_EQ(metadata->origin(), origin().Serialize());
   EXPECT_NE(metadata->creation_microseconds_since_unix_epoch(), 0);
+  EXPECT_EQ(metadata->num_fetches(), static_cast<int>(requests.size()));
 }
 
 TEST_P(BackgroundFetchDataManagerTest, UpdateRegistrationUI) {
@@ -609,15 +611,20 @@
   options.title = kInitialTitle;
   blink::mojom::BackgroundFetchError error;
 
+  // There should be no title before the registration.
+  std::vector<std::string> title = GetRegistrationUserDataByKeyPrefix(
+      sw_id, background_fetch::kTitleKeyPrefix);
+  EXPECT_TRUE(title.empty());
+
   // Create a single registration.
   CreateRegistration(registration_id, requests, options, &error);
   EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
 
   // Verify that the title can be retrieved.
-  auto metadata = GetMetadata(sw_id, origin(), kExampleDeveloperId, &error);
-  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
-  ASSERT_TRUE(metadata);
-  EXPECT_EQ(metadata->ui_title(), kInitialTitle);
+  title = GetRegistrationUserDataByKeyPrefix(sw_id,
+                                             background_fetch::kTitleKeyPrefix);
+  EXPECT_EQ(title.size(), 1u);
+  ASSERT_EQ(title.front(), kInitialTitle);
 
   // Update the title.
   UpdateRegistrationUI(registration_id, kUpdatedTitle, &error);
@@ -625,10 +632,10 @@
   RestartDataManagerFromPersistentStorage();
 
   // After a restart, GetMetadata should find the new title.
-  metadata = GetMetadata(sw_id, origin(), kExampleDeveloperId, &error);
-  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
-  ASSERT_TRUE(metadata);
-  EXPECT_EQ(metadata->ui_title(), kUpdatedTitle);
+  title = GetRegistrationUserDataByKeyPrefix(sw_id,
+                                             background_fetch::kTitleKeyPrefix);
+  EXPECT_EQ(title.size(), 1u);
+  ASSERT_EQ(title.front(), kUpdatedTitle);
 }
 
 TEST_P(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
@@ -828,7 +835,7 @@
                       sw_id, background_fetch::kPendingRequestKeyPrefix)
                       .size());
     EXPECT_EQ(
-        1u,  // All the registration data is stored in the metadata proto.
+        2u,  // Metadata proto + title.
         GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
   }
 
diff --git a/content/browser/background_fetch/storage/README.md b/content/browser/background_fetch/storage/README.md
index 6ab7bd01..e21e9c3 100644
--- a/content/browser/background_fetch/storage/README.md
+++ b/content/browser/background_fetch/storage/README.md
@@ -19,12 +19,18 @@
 key: "bgfetch_active_registration_unique_id_<developer_id>"
 value: "<unique_id>"
 ```
+
 ```
 key: "bgfetch_registration_<unique_id>"
 value: "<serialized content::proto::BackgroundFetchMetadata>"
 ```
 
 ```
+key: "bgfetch_title_<unique_id>"
+value: "<ui_title>"
+```
+
+```
 key: "bgfetch_pending_request_<unique_id>_<request_index>"
 value: "<serialized content::proto::BackgroundFetchPendingRequest>"
 ```
@@ -49,4 +55,6 @@
 * `<request_index>` is an `int` containing the index of a request within a
 multi-part fetch. These must be padded with zeros to ensure that the ordering
 is maintain when reading back from the database, e.g. `0000000000`.
+* `<ui_title>` is the notification title provided by the developer. It can also
+be updated by calling `BackgroundFetchUpdateEvent.updateUI`.
 
diff --git a/content/browser/background_fetch/storage/create_metadata_task.cc b/content/browser/background_fetch/storage/create_metadata_task.cc
index 970c915..20e744f 100644
--- a/content/browser/background_fetch/storage/create_metadata_task.cc
+++ b/content/browser/background_fetch/storage/create_metadata_task.cc
@@ -85,7 +85,7 @@
   metadata_proto_->set_origin(registration_id_.origin().Serialize());
   metadata_proto_->set_creation_microseconds_since_unix_epoch(
       (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds());
-  metadata_proto_->set_ui_title(options_.title);
+  metadata_proto_->set_num_fetches(requests_.size());
 }
 
 void CreateMetadataTask::StoreMetadata() {
@@ -108,6 +108,7 @@
       registration_id_.unique_id());
   entries.emplace_back(RegistrationKey(registration_id_.unique_id()),
                        std::move(serialized_metadata_proto));
+  entries.emplace_back(TitleKey(registration_id_.unique_id()), options_.title);
 
   // Signed integers are used for request indexes to avoid unsigned gotchas.
   for (int i = 0; i < base::checked_cast<int>(requests_.size()); i++) {
diff --git a/content/browser/background_fetch/storage/database_helpers.cc b/content/browser/background_fetch/storage/database_helpers.cc
index 6fe58b7..0315e83 100644
--- a/content/browser/background_fetch/storage/database_helpers.cc
+++ b/content/browser/background_fetch/storage/database_helpers.cc
@@ -23,6 +23,10 @@
   return kRegistrationKeyPrefix + unique_id;
 }
 
+std::string TitleKey(const std::string& unique_id) {
+  return kTitleKeyPrefix + unique_id;
+}
+
 std::string PendingRequestKeyPrefix(const std::string& unique_id) {
   return kPendingRequestKeyPrefix + unique_id + kSeparator;
 }
diff --git a/content/browser/background_fetch/storage/database_helpers.h b/content/browser/background_fetch/storage/database_helpers.h
index 558ff0e..fe0550b 100644
--- a/content/browser/background_fetch/storage/database_helpers.h
+++ b/content/browser/background_fetch/storage/database_helpers.h
@@ -25,6 +25,7 @@
 const char kActiveRegistrationUniqueIdKeyPrefix[] =
     "bgfetch_active_registration_unique_id_";
 const char kRegistrationKeyPrefix[] = "bgfetch_registration_";
+const char kTitleKeyPrefix[] = "bgfetch_title_";
 const char kPendingRequestKeyPrefix[] = "bgfetch_pending_request_";
 const char kActiveRequestKeyPrefix[] = "bgfetch_active_request_";
 const char kCompletedRequestKeyPrefix[] = "bgfetch_completed_request_";
@@ -33,6 +34,8 @@
 
 std::string RegistrationKey(const std::string& unique_id);
 
+std::string TitleKey(const std::string& unique_id);
+
 std::string PendingRequestKeyPrefix(const std::string& unique_id);
 
 std::string PendingRequestKey(const std::string& unique_id, int request_index);
diff --git a/content/browser/background_fetch/storage/delete_registration_task.cc b/content/browser/background_fetch/storage/delete_registration_task.cc
index a5ea13c6..e5c2d759 100644
--- a/content/browser/background_fetch/storage/delete_registration_task.cc
+++ b/content/browser/background_fetch/storage/delete_registration_task.cc
@@ -86,7 +86,8 @@
 #endif  // DCHECK_IS_ON()
 
   service_worker_context()->ClearRegistrationUserDataByKeyPrefixes(
-      service_worker_registration_id_, {RegistrationKey(unique_id_)},
+      service_worker_registration_id_,
+      {RegistrationKey(unique_id_), TitleKey(unique_id_)},
       base::BindOnce(&DeleteRegistrationTask::DidDeleteRegistration,
                      weak_factory_.GetWeakPtr()));
 }
diff --git a/content/browser/background_fetch/storage/update_registration_ui_task.cc b/content/browser/background_fetch/storage/update_registration_ui_task.cc
index 0c2bafb..5927855 100644
--- a/content/browser/background_fetch/storage/update_registration_ui_task.cc
+++ b/content/browser/background_fetch/storage/update_registration_ui_task.cc
@@ -26,61 +26,21 @@
 UpdateRegistrationUITask::~UpdateRegistrationUITask() = default;
 
 void UpdateRegistrationUITask::Start() {
-  service_worker_context()->GetRegistrationUserData(
-      registration_id_.service_worker_registration_id(),
-      {RegistrationKey(registration_id_.unique_id())},
-      base::BindOnce(&UpdateRegistrationUITask::DidGetMetadata,
-                     weak_factory_.GetWeakPtr()));
-}
-
-void UpdateRegistrationUITask::DidGetMetadata(
-    const std::vector<std::string>& data,
-    ServiceWorkerStatusCode status) {
-  switch (ToDatabaseStatus(status)) {
-    case DatabaseStatus::kNotFound:
-    case DatabaseStatus::kFailed:
-      std::move(callback_).Run(
-          blink::mojom::BackgroundFetchError::STORAGE_ERROR);
-      Finished();  // Destroys |this|.
-      return;
-    case DatabaseStatus::kOk:
-      if (data.size() != 1u) {
-        std::move(callback_).Run(
-            blink::mojom::BackgroundFetchError::STORAGE_ERROR);
-        Finished();  // Destroys |this|.
-        return;
-      }
-      UpdateUI(data[0]);
-      return;
-  }
-}
-
-void UpdateRegistrationUITask::UpdateUI(
-    const std::string& serialized_metadata_proto) {
-  proto::BackgroundFetchMetadata metadata_proto;
-  if (!metadata_proto.ParseFromString(serialized_metadata_proto)) {
-    std::move(callback_).Run(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
-    Finished();  // Destroys |this|.
-    return;
-  }
-
-  metadata_proto.set_ui_title(updated_title_);
-
   service_worker_context()->StoreRegistrationUserData(
       registration_id_.service_worker_registration_id(),
       registration_id_.origin().GetURL(),
-      {{RegistrationKey(registration_id_.unique_id()),
-        metadata_proto.SerializeAsString()}},
-      base::BindOnce(&UpdateRegistrationUITask::DidUpdateUI,
+      {{TitleKey(registration_id_.unique_id()), updated_title_}},
+      base::BindOnce(&UpdateRegistrationUITask::DidUpdateTitle,
                      weak_factory_.GetWeakPtr()));
 }
 
-void UpdateRegistrationUITask::DidUpdateUI(ServiceWorkerStatusCode status) {
+void UpdateRegistrationUITask::DidUpdateTitle(ServiceWorkerStatusCode status) {
   switch (ToDatabaseStatus(status)) {
     case DatabaseStatus::kOk:
       break;
     case DatabaseStatus::kFailed:
     case DatabaseStatus::kNotFound:
+      // TODO(crbug.com/780025): Log failures to UMA.
       std::move(callback_).Run(
           blink::mojom::BackgroundFetchError::STORAGE_ERROR);
       Finished();  // Destroys |this|.
diff --git a/content/browser/background_fetch/storage/update_registration_ui_task.h b/content/browser/background_fetch/storage/update_registration_ui_task.h
index 54aebf6e..0816797 100644
--- a/content/browser/background_fetch/storage/update_registration_ui_task.h
+++ b/content/browser/background_fetch/storage/update_registration_ui_task.h
@@ -33,12 +33,7 @@
   void Start() override;
 
  private:
-  void DidGetMetadata(const std::vector<std::string>& data,
-                      ServiceWorkerStatusCode status);
-
-  void UpdateUI(const std::string& serialized_metadata_proto);
-
-  void DidUpdateUI(ServiceWorkerStatusCode status);
+  void DidUpdateTitle(ServiceWorkerStatusCode status);
 
   BackgroundFetchRegistrationId registration_id_;
   std::string updated_title_;
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index 475a2bd..004b046 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -1845,6 +1845,156 @@
   delegate()->NotifyNavigationEntriesDeleted();
 }
 
+void NavigationControllerImpl::DiscardPendingEntry(bool was_failure) {
+  // It is not safe to call DiscardPendingEntry while NavigateToEntry is in
+  // progress, since this will cause a use-after-free.  (We only allow this
+  // when the tab is being destroyed for shutdown, since it won't return to
+  // NavigateToEntry in that case.)  http://crbug.com/347742.
+  CHECK(!in_navigate_to_pending_entry_ || delegate_->IsBeingDestroyed());
+
+  if (was_failure && pending_entry_) {
+    failed_pending_entry_id_ = pending_entry_->GetUniqueID();
+  } else {
+    failed_pending_entry_id_ = 0;
+  }
+
+  if (pending_entry_) {
+    if (pending_entry_index_ == -1)
+      delete pending_entry_;
+    pending_entry_index_ = -1;
+    pending_entry_ = nullptr;
+  }
+}
+
+void NavigationControllerImpl::SetPendingNavigationSSLError(bool error) {
+  if (pending_entry_)
+    pending_entry_->set_ssl_error(error);
+}
+
+bool NavigationControllerImpl::StartHistoryNavigationInNewSubframe(
+    RenderFrameHostImpl* render_frame_host,
+    const GURL& default_url) {
+  NavigationEntryImpl* entry =
+      GetEntryWithUniqueID(render_frame_host->nav_entry_id());
+  if (!entry)
+    return false;
+
+  FrameNavigationEntry* frame_entry =
+      entry->GetFrameEntry(render_frame_host->frame_tree_node());
+  if (!frame_entry)
+    return false;
+
+  // Track how often history navigations load a different URL into a subframe
+  // than the frame's default URL.
+  bool restoring_different_url = frame_entry->url() != default_url;
+  UMA_HISTOGRAM_BOOLEAN("SessionRestore.RestoredSubframeURL",
+                        restoring_different_url);
+  // If this frame's unique name uses a frame path, record the name length.
+  // If these names are long in practice, then a proposed plan to truncate
+  // unique names might affect restore behavior, since it is complex to deal
+  // with truncated names inside frame paths.
+  if (restoring_different_url) {
+    const std::string& unique_name =
+        render_frame_host->frame_tree_node()->unique_name();
+    const char kFramePathPrefix[] = "<!--framePath ";
+    if (base::StartsWith(unique_name, kFramePathPrefix,
+                         base::CompareCase::SENSITIVE)) {
+      UMA_HISTOGRAM_COUNTS("SessionRestore.RestoreSubframeFramePathLength",
+                           unique_name.size());
+    }
+  }
+
+  // TODO(clamy): Create a NavigationRequest here and pass it to Navigator for
+  // navigating.
+  return render_frame_host->frame_tree_node()->navigator()->NavigateToEntry(
+      render_frame_host->frame_tree_node(), *frame_entry, *entry,
+      ReloadType::NONE, false, true, false, nullptr,
+      nullptr /* navigation_ui_data */);
+}
+
+void NavigationControllerImpl::NavigateFromFrameProxy(
+    RenderFrameHostImpl* render_frame_host,
+    const GURL& url,
+    bool is_renderer_initiated,
+    SiteInstance* source_site_instance,
+    const Referrer& referrer,
+    ui::PageTransition page_transition,
+    bool should_replace_current_entry,
+    const std::string& method,
+    scoped_refptr<network::ResourceRequestBody> post_body,
+    const std::string& extra_headers,
+    const base::Optional<std::string>& suggested_filename) {
+  FrameTreeNode* node = render_frame_host->frame_tree_node();
+  // Create a NavigationEntry for the transfer, without making it the pending
+  // entry. Subframe transfers should have a clone of the last committed entry
+  // with a FrameNavigationEntry for the target frame. Main frame transfers
+  // should have a new NavigationEntry.
+  // TODO(creis): Make this unnecessary by creating (and validating) the params
+  // directly, passing them to the destination RenderFrameHost.  See
+  // https://crbug.com/536906.
+  std::unique_ptr<NavigationEntryImpl> entry;
+  if (!node->IsMainFrame()) {
+    // Subframe case: create FrameNavigationEntry.
+    if (GetLastCommittedEntry()) {
+      entry = GetLastCommittedEntry()->Clone();
+      entry->set_extra_headers(extra_headers);
+      // TODO(arthursonzogni): What about |is_renderer_initiated|?
+      // Renderer-initiated navigation that target a remote frame are currently
+      // classified as browser-initiated when this one has already navigated.
+      // See https://crbug.com/722251.
+    } else {
+      // If there's no last committed entry, create an entry for about:blank
+      // with a subframe entry for our destination.
+      // TODO(creis): Ensure this case can't exist in https://crbug.com/524208.
+      entry = NavigationEntryImpl::FromNavigationEntry(CreateNavigationEntry(
+          GURL(url::kAboutBlankURL), referrer, page_transition,
+          is_renderer_initiated, extra_headers, browser_context_));
+    }
+    entry->AddOrUpdateFrameEntry(
+        node, -1, -1, nullptr,
+        static_cast<SiteInstanceImpl*>(source_site_instance), url, referrer,
+        std::vector<GURL>(), PageState(), method, -1);
+  } else {
+    // Main frame case.
+    entry = NavigationEntryImpl::FromNavigationEntry(CreateNavigationEntry(
+        url, referrer, page_transition, is_renderer_initiated, extra_headers,
+        browser_context_));
+    entry->root_node()->frame_entry->set_source_site_instance(
+        static_cast<SiteInstanceImpl*>(source_site_instance));
+    entry->root_node()->frame_entry->set_method(method);
+  }
+  entry->set_suggested_filename(suggested_filename);
+
+  // Don't allow an entry replacement if there is no entry to replace.
+  // http://crbug.com/457149
+  if (should_replace_current_entry && GetEntryCount() > 0)
+    entry->set_should_replace_entry(true);
+  if (GetLastCommittedEntry() &&
+      GetLastCommittedEntry()->GetIsOverridingUserAgent()) {
+    entry->SetIsOverridingUserAgent(true);
+  }
+  // TODO(creis): Set user gesture and intent received timestamp on Android.
+
+  // We may not have successfully added the FrameNavigationEntry to |entry|
+  // above (per https://crbug.com/608402), in which case we create it from
+  // scratch.  This works because we do not depend on |frame_entry| being inside
+  // |entry| during NavigateToEntry.  This will go away when we shortcut this
+  // further in https://crbug.com/536906.
+  scoped_refptr<FrameNavigationEntry> frame_entry(entry->GetFrameEntry(node));
+  if (!frame_entry) {
+    frame_entry = new FrameNavigationEntry(
+        node->unique_name(), -1, -1, nullptr,
+        static_cast<SiteInstanceImpl*>(source_site_instance), url, referrer,
+        std::vector<GURL>(), PageState(), method, -1);
+  }
+
+  // TODO(clamy): Create a NavigationRequest here and pass it to Navigator for
+  // navigating.
+  render_frame_host->frame_tree_node()->navigator()->NavigateToEntry(
+      node, *frame_entry, *entry.get(), ReloadType::NONE, false, false, false,
+      post_body, nullptr /* navigation_ui_data */);
+}
+
 void NavigationControllerImpl::ClearAllScreenshots() {
   screenshot_manager_->ClearAllScreenshots();
 }
@@ -2299,32 +2449,6 @@
   DiscardTransientEntry();
 }
 
-void NavigationControllerImpl::DiscardPendingEntry(bool was_failure) {
-  // It is not safe to call DiscardPendingEntry while NavigateToEntry is in
-  // progress, since this will cause a use-after-free.  (We only allow this
-  // when the tab is being destroyed for shutdown, since it won't return to
-  // NavigateToEntry in that case.)  http://crbug.com/347742.
-  CHECK(!in_navigate_to_pending_entry_ || delegate_->IsBeingDestroyed());
-
-  if (was_failure && pending_entry_) {
-    failed_pending_entry_id_ = pending_entry_->GetUniqueID();
-  } else {
-    failed_pending_entry_id_ = 0;
-  }
-
-  if (pending_entry_) {
-    if (pending_entry_index_ == -1)
-      delete pending_entry_;
-    pending_entry_index_ = -1;
-    pending_entry_ = nullptr;
-  }
-}
-
-void NavigationControllerImpl::SetPendingNavigationSSLError(bool error) {
-  if (pending_entry_)
-    pending_entry_->set_ssl_error(error);
-}
-
 void NavigationControllerImpl::DiscardTransientEntry() {
   if (transient_entry_index_ == -1)
     return;
diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h
index d3be697..0897fb7e 100644
--- a/content/browser/frame_host/navigation_controller_impl.h
+++ b/content/browser/frame_host/navigation_controller_impl.h
@@ -93,6 +93,29 @@
   void DeleteNavigationEntries(
       const DeletionPredicate& deletionPredicate) override;
 
+  // Starts a navigation in a newly created subframe as part of a history
+  // navigation. Returns true if the history navigation could start, false
+  // otherwise.  If this returns false, the caller should do a regular
+  // navigation to |default_url| should be done instead.
+  bool StartHistoryNavigationInNewSubframe(
+      RenderFrameHostImpl* render_frame_host,
+      const GURL& default_url);
+
+  // Called when a document requests a navigation through a
+  // RenderFrameProxyHost.
+  void NavigateFromFrameProxy(
+      RenderFrameHostImpl* render_frame_host,
+      const GURL& url,
+      bool is_renderer_initiated,
+      SiteInstance* source_site_instance,
+      const Referrer& referrer,
+      ui::PageTransition page_transition,
+      bool should_replace_current_entry,
+      const std::string& method,
+      scoped_refptr<network::ResourceRequestBody> post_body,
+      const std::string& extra_headers,
+      const base::Optional<std::string>& suggested_filename);
+
   void ClearAllScreenshots() override;
 
   // Whether this is the initial navigation in an unmodified new tab.  In this
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
index ee48fdd3..0a0f777 100644
--- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -1430,79 +1430,73 @@
 
 // Verify that reloading a page with url anchor scrolls to correct position.
 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, ReloadWithUrlAnchor) {
-  GURL url1(embedded_test_server()->GetURL(
-      "/navigation_controller/reload-with-url-anchor.html#d2"));
-  EXPECT_TRUE(NavigateToURL(shell(), url1));
+  GURL url(embedded_test_server()->GetURL(
+      "/navigation_controller/reload-with-url-anchor.html#center-element"));
+  EXPECT_TRUE(NavigateToURL(shell(), url));
 
-  std::string script =
-      "domAutomationController.send(document.getElementById('div').scrollTop)";
-  double value = 0;
-  EXPECT_TRUE(ExecuteScriptAndExtractDouble(shell(), script, &value));
+  double window_scroll_y = 0;
+  std::string get_window_scroll_y =
+      "domAutomationController.send(window.scrollY);";
+  EXPECT_TRUE(ExecuteScriptAndExtractDouble(shell(), get_window_scroll_y,
+                                            &window_scroll_y));
 
-  double expected = 100;
+  // The 'center-element' y-position is 2000px. 2000px is an arbitrary value.
+  double expected_window_scroll_y = 2000;
   if (IsUseZoomForDSFEnabled()) {
     float device_scale_factor = shell()
                                     ->web_contents()
                                     ->GetRenderWidgetHostView()
                                     ->GetDeviceScaleFactor();
-    expected = floor(device_scale_factor * expected) / device_scale_factor;
+    expected_window_scroll_y =
+        floor(device_scale_factor * expected_window_scroll_y) /
+        device_scale_factor;
   }
-  EXPECT_FLOAT_EQ(expected, value);
+  EXPECT_FLOAT_EQ(expected_window_scroll_y, window_scroll_y);
 
   // Reload.
   ReloadBlockUntilNavigationsComplete(shell(), 1);
 
-  EXPECT_TRUE(ExecuteScriptAndExtractDouble(shell(), script, &value));
-  EXPECT_FLOAT_EQ(expected, value);
+  EXPECT_TRUE(ExecuteScriptAndExtractDouble(shell(), get_window_scroll_y,
+                                            &window_scroll_y));
+  EXPECT_FLOAT_EQ(expected_window_scroll_y, window_scroll_y);
 }
 
 // Verify that reloading a page with url anchor and scroll scrolls to correct
 // position.
 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
                        ReloadWithUrlAnchorAndScroll) {
-  GURL url1(embedded_test_server()->GetURL(
-      "/navigation_controller/reload-with-url-anchor.html#d2"));
-  EXPECT_TRUE(NavigateToURL(shell(), url1));
+  GURL url(embedded_test_server()->GetURL(
+      "/navigation_controller/reload-with-url-anchor.html#center-element"));
+  EXPECT_TRUE(NavigateToURL(shell(), url));
 
-  std::string script_scroll_down = "window.scroll(0, 10)";
+  // The 'center-element' y-position is 2000px. This script scrolls the view
+  // 100px below this element. 2000px and 100px are arbitrary values.
+  std::string script_scroll_down = "window.scroll(0, 2100)";
   EXPECT_TRUE(ExecuteScript(shell(), script_scroll_down));
 
-  std::string get_div_scroll_top =
-      "domAutomationController.send(document.getElementById('div').scrollTop)";
   std::string get_window_scroll_y =
       "domAutomationController.send(window.scrollY)";
-  double div_scroll_top = 0;
   double window_scroll_y = 0;
-  EXPECT_TRUE(ExecuteScriptAndExtractDouble(shell(), get_div_scroll_top,
-                                            &div_scroll_top));
   EXPECT_TRUE(ExecuteScriptAndExtractDouble(shell(), get_window_scroll_y,
                                             &window_scroll_y));
 
-  double expected_div_scroll_top = 100;
-  double expected_window_scroll_y = 10;
+  double expected_window_scroll_y = 2100;
   if (IsUseZoomForDSFEnabled()) {
     float device_scale_factor = shell()
                                     ->web_contents()
                                     ->GetRenderWidgetHostView()
                                     ->GetDeviceScaleFactor();
-    expected_div_scroll_top =
-        floor(device_scale_factor * expected_div_scroll_top) /
-        device_scale_factor;
     expected_window_scroll_y =
         floor(device_scale_factor * expected_window_scroll_y) /
         device_scale_factor;
   }
-  EXPECT_FLOAT_EQ(expected_div_scroll_top, div_scroll_top);
   EXPECT_FLOAT_EQ(expected_window_scroll_y, window_scroll_y);
 
   // Reload.
   ReloadBlockUntilNavigationsComplete(shell(), 1);
 
-  EXPECT_TRUE(ExecuteScriptAndExtractDouble(shell(), get_div_scroll_top,
-                                            &div_scroll_top));
   EXPECT_TRUE(ExecuteScriptAndExtractDouble(shell(), get_window_scroll_y,
                                             &window_scroll_y));
-  EXPECT_FLOAT_EQ(expected_div_scroll_top, div_scroll_top);
   EXPECT_FLOAT_EQ(expected_window_scroll_y, window_scroll_y);
 }
 
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc
index e8f695a..034a62f 100644
--- a/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -651,8 +651,6 @@
     EXPECT_EQ(should_override, entry->GetIsOverridingUserAgent());
   }
   EXPECT_EQ(load_params.post_data, entry->GetPostData());
-  EXPECT_EQ(load_params.transferred_global_request_id,
-      entry->transferred_global_request_id());
 }
 
 TEST_F(NavigationControllerTest, LoadURLWithParams) {
diff --git a/content/browser/frame_host/navigator.cc b/content/browser/frame_host/navigator.cc
index ff6457f3..0876a389 100644
--- a/content/browser/frame_host/navigator.cc
+++ b/content/browser/frame_host/navigator.cc
@@ -26,8 +26,22 @@
   return false;
 }
 
-bool Navigator::NavigateNewChildFrame(RenderFrameHostImpl* render_frame_host,
-                                      const GURL& default_url) {
+bool Navigator::NavigateToEntry(
+    FrameTreeNode* frame_tree_node,
+    const FrameNavigationEntry& frame_entry,
+    const NavigationEntryImpl& entry,
+    ReloadType reload_type,
+    bool is_same_document_history_load,
+    bool is_history_navigation_in_new_child,
+    bool is_pending_entry,
+    const scoped_refptr<network::ResourceRequestBody>& post_body,
+    std::unique_ptr<NavigationUIData> navigation_ui_data) {
+  return false;
+}
+
+bool Navigator::StartHistoryNavigationInNewSubframe(
+    RenderFrameHostImpl* render_frame_host,
+    const GURL& default_url) {
   return false;
 }
 
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h
index 1ae19f9..960b0190 100644
--- a/content/browser/frame_host/navigator.h
+++ b/content/browser/frame_host/navigator.h
@@ -101,16 +101,29 @@
       ReloadType reload_type,
       bool is_same_document_history_load,
       std::unique_ptr<NavigationUIData> navigation_ui_data);
+  // DEPRECATED. Callers should use NavigateToPendingEntry instead.
+  // TODO(clamy): This is only briefly exposed to facilitate a larger
+  // refactoring of NavigationController and will go away soon.
+  virtual bool NavigateToEntry(
+      FrameTreeNode* frame_tree_node,
+      const FrameNavigationEntry& frame_entry,
+      const NavigationEntryImpl& entry,
+      ReloadType reload_type,
+      bool is_same_document_history_load,
+      bool is_history_navigation_in_new_child,
+      bool is_pending_entry,
+      const scoped_refptr<network::ResourceRequestBody>& post_body,
+      std::unique_ptr<NavigationUIData> navigation_ui_data);
 
   // Called on a newly created subframe during a history navigation. The browser
   // process looks up the corresponding FrameNavigationEntry for the new frame
   // navigates it in the correct process. Returns false if the
-  // FrameNavigationEntry can't be found or the navigation fails. This is only
-  // used in OOPIF-enabled modes.
+  // FrameNavigationEntry can't be found or the navigation fails.
   // TODO(creis): Remove |default_url| once we have collected UMA stats on the
   // cases that we use a different URL from history than the frame's src.
-  virtual bool NavigateNewChildFrame(RenderFrameHostImpl* render_frame_host,
-                                     const GURL& default_url);
+  virtual bool StartHistoryNavigationInNewSubframe(
+      RenderFrameHostImpl* render_frame_host,
+      const GURL& default_url);
 
   // Navigation requests -------------------------------------------------------
 
@@ -131,18 +144,15 @@
       blink::WebTriggeringEventInfo triggering_event_info,
       const base::Optional<std::string>& suggested_filename) {}
 
-  // The RenderFrameHostImpl wants to transfer the request to a new renderer.
-  // |redirect_chain| contains any redirect URLs (excluding |url|) that happened
-  // before the transfer.  If |method| is "POST", then |post_body| needs to
-  // specify the request body, otherwise |post_body| should be null.
-  virtual void RequestTransferURL(
+  // Called when a document requests a navigation in another document through a
+  // RenderFrameProxy. If |method| is "POST", then |post_body| needs to specify
+  // the request body, otherwise |post_body| should be null.
+  virtual void NavigateFromFrameProxy(
       RenderFrameHostImpl* render_frame_host,
       const GURL& url,
       SiteInstance* source_site_instance,
-      const std::vector<GURL>& redirect_chain,
       const Referrer& referrer,
       ui::PageTransition page_transition,
-      const GlobalRequestID& transferred_global_request_id,
       bool should_replace_current_entry,
       const std::string& method,
       scoped_refptr<network::ResourceRequestBody> post_body,
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index bb33fd3..a42e7e3 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -393,42 +393,11 @@
                          std::move(navigation_ui_data));
 }
 
-bool NavigatorImpl::NavigateNewChildFrame(
+bool NavigatorImpl::StartHistoryNavigationInNewSubframe(
     RenderFrameHostImpl* render_frame_host,
     const GURL& default_url) {
-  NavigationEntryImpl* entry =
-      controller_->GetEntryWithUniqueID(render_frame_host->nav_entry_id());
-  if (!entry)
-    return false;
-
-  FrameNavigationEntry* frame_entry =
-      entry->GetFrameEntry(render_frame_host->frame_tree_node());
-  if (!frame_entry)
-    return false;
-
-  // Track how often history navigations load a different URL into a subframe
-  // than the frame's default URL.
-  bool restoring_different_url = frame_entry->url() != default_url;
-  UMA_HISTOGRAM_BOOLEAN("SessionRestore.RestoredSubframeURL",
-                        restoring_different_url);
-  // If this frame's unique name uses a frame path, record the name length.
-  // If these names are long in practice, then a proposed plan to truncate
-  // unique names might affect restore behavior, since it is complex to deal
-  // with truncated names inside frame paths.
-  if (restoring_different_url) {
-    const std::string& unique_name =
-        render_frame_host->frame_tree_node()->unique_name();
-    const char kFramePathPrefix[] = "<!--framePath ";
-    if (base::StartsWith(unique_name, kFramePathPrefix,
-                         base::CompareCase::SENSITIVE)) {
-      UMA_HISTOGRAM_COUNTS("SessionRestore.RestoreSubframeFramePathLength",
-                           unique_name.size());
-    }
-  }
-
-  return NavigateToEntry(render_frame_host->frame_tree_node(), *frame_entry,
-                         *entry, ReloadType::NONE, false, true, false, nullptr,
-                         nullptr /* navigation_ui_data */);
+  return controller_->StartHistoryNavigationInNewSubframe(render_frame_host,
+                                                          default_url);
 }
 
 void NavigatorImpl::DidNavigate(
@@ -607,7 +576,7 @@
   // redirects.  http://crbug.com/311721.
   std::vector<GURL> redirect_chain;
 
-  // Note that unlike RequestTransferURL, this uses the navigating
+  // Note that unlike NavigateFromFrameProxy, this uses the navigating
   // RenderFrameHost's current SiteInstance, as that's where this navigation
   // originated.
   GURL dest_url(url);
@@ -643,7 +612,7 @@
   // RequestOpenURL is used only for local frames, so we can get here only if
   // the navigation is initiated by a frame in the same SiteInstance as this
   // frame.  Note that navigations on RenderFrameProxies do not use
-  // RequestOpenURL and go through RequestTransferURL instead.
+  // RequestOpenURL and go through NavigateFromFrameProxy instead.
   params.source_site_instance = current_site_instance;
 
   params.source_render_frame_id = render_frame_host->GetRoutingID();
@@ -668,14 +637,12 @@
     delegate_->OpenURL(params);
 }
 
-void NavigatorImpl::RequestTransferURL(
+void NavigatorImpl::NavigateFromFrameProxy(
     RenderFrameHostImpl* render_frame_host,
     const GURL& url,
     SiteInstance* source_site_instance,
-    const std::vector<GURL>& redirect_chain,
     const Referrer& referrer,
     ui::PageTransition page_transition,
-    const GlobalRequestID& transferred_global_request_id,
     bool should_replace_current_entry,
     const std::string& method,
     scoped_refptr<network::ResourceRequestBody> post_body,
@@ -692,20 +659,18 @@
           render_frame_host->frame_tree_node()->IsMainFrame()))
     return;
 
-  GURL dest_url(url);
   Referrer referrer_to_use(referrer);
-  FrameTreeNode* node = render_frame_host->frame_tree_node();
   SiteInstance* current_site_instance = render_frame_host->GetSiteInstance();
   // It is important to pass in the source_site_instance if it is available
   // (such as when navigating a proxy).  See https://crbug.com/656752.
   if (!GetContentClient()->browser()->ShouldAllowOpenURL(
           source_site_instance ? source_site_instance : current_site_instance,
           url)) {
-    // It is important to return here, rather than rewrite the dest_url to
+    // It is important to return here, rather than rewrite the url to
     // about:blank.  The latter won't actually have any effect when
     // transferring, as NavigateToEntry will think that the transfer is to the
-    // same RFH that started the navigation and let the existing navigation
-    // (for the disallowed URL) proceed.
+    // same RFH that started the navigation and let the existing navigation (for
+    // the disallowed URL) proceed.
     return;
   }
 
@@ -727,76 +692,10 @@
       current_site_instance, &page_transition, &is_renderer_initiated,
       &referrer_to_use);
 
-  // Create a NavigationEntry for the transfer, without making it the pending
-  // entry.  Subframe transfers should only be possible in OOPIF-enabled modes,
-  // and should have a clone of the last committed entry with a
-  // FrameNavigationEntry for the target frame.  Main frame transfers should
-  // have a new NavigationEntry.
-  // TODO(creis): Make this unnecessary by creating (and validating) the params
-  // directly, passing them to the destination RenderFrameHost.  See
-  // https://crbug.com/536906.
-  std::unique_ptr<NavigationEntryImpl> entry;
-  if (!node->IsMainFrame()) {
-    // Subframe case: create FrameNavigationEntry.
-    if (controller_->GetLastCommittedEntry()) {
-      entry = controller_->GetLastCommittedEntry()->Clone();
-      entry->set_extra_headers(extra_headers);
-      // TODO(arthursonzogni): What about |is_renderer_initiated|?
-      // Renderer-initiated navigation that target a remote frame are currently
-      // classified as browser-initiated when this one has already navigated.
-      // See https://crbug.com/722251.
-    } else {
-      // If there's no last committed entry, create an entry for about:blank
-      // with a subframe entry for our destination.
-      // TODO(creis): Ensure this case can't exist in https://crbug.com/524208.
-      entry = NavigationEntryImpl::FromNavigationEntry(
-          controller_->CreateNavigationEntry(
-              GURL(url::kAboutBlankURL), referrer_to_use, page_transition,
-              is_renderer_initiated, extra_headers,
-              controller_->GetBrowserContext()));
-    }
-    entry->AddOrUpdateFrameEntry(
-        node, -1, -1, nullptr,
-        static_cast<SiteInstanceImpl*>(source_site_instance), dest_url,
-        referrer_to_use, redirect_chain, PageState(), method, -1);
-  } else {
-    // Main frame case.
-    entry = NavigationEntryImpl::FromNavigationEntry(
-        controller_->CreateNavigationEntry(
-            dest_url, referrer_to_use, page_transition, is_renderer_initiated,
-            extra_headers, controller_->GetBrowserContext()));
-    entry->root_node()->frame_entry->set_source_site_instance(
-        static_cast<SiteInstanceImpl*>(source_site_instance));
-    entry->root_node()->frame_entry->set_method(method);
-    entry->SetRedirectChain(redirect_chain);
-  }
-  entry->set_suggested_filename(suggested_filename);
-
-  // Don't allow an entry replacement if there is no entry to replace.
-  // http://crbug.com/457149
-  if (should_replace_current_entry && controller_->GetEntryCount() > 0)
-    entry->set_should_replace_entry(true);
-  if (controller_->GetLastCommittedEntry() &&
-      controller_->GetLastCommittedEntry()->GetIsOverridingUserAgent()) {
-    entry->SetIsOverridingUserAgent(true);
-  }
-  entry->set_transferred_global_request_id(transferred_global_request_id);
-  // TODO(creis): Set user gesture and intent received timestamp on Android.
-
-  // We may not have successfully added the FrameNavigationEntry to |entry|
-  // above (per https://crbug.com/608402), in which case we create it from
-  // scratch.  This works because we do not depend on |frame_entry| being inside
-  // |entry| during NavigateToEntry.  This will go away when we shortcut this
-  // further in https://crbug.com/536906.
-  scoped_refptr<FrameNavigationEntry> frame_entry(entry->GetFrameEntry(node));
-  if (!frame_entry) {
-    frame_entry = new FrameNavigationEntry(
-        node->unique_name(), -1, -1, nullptr,
-        static_cast<SiteInstanceImpl*>(source_site_instance), dest_url,
-        referrer_to_use, redirect_chain, PageState(), method, -1);
-  }
-  NavigateToEntry(node, *frame_entry, *entry.get(), ReloadType::NONE, false,
-                  false, false, post_body, nullptr /* navigation_ui_data */);
+  controller_->NavigateFromFrameProxy(
+      render_frame_host, url, is_renderer_initiated, source_site_instance,
+      referrer_to_use, page_transition, should_replace_current_entry, method,
+      post_body, extra_headers, suggested_filename);
 }
 
 void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node,
diff --git a/content/browser/frame_host/navigator_impl.h b/content/browser/frame_host/navigator_impl.h
index b1bb76b..99aeea9e 100644
--- a/content/browser/frame_host/navigator_impl.h
+++ b/content/browser/frame_host/navigator_impl.h
@@ -63,8 +63,19 @@
       ReloadType reload_type,
       bool is_same_document_history_load,
       std::unique_ptr<NavigationUIData> navigation_ui_data) override;
-  bool NavigateNewChildFrame(RenderFrameHostImpl* render_frame_host,
-                             const GURL& default_url) override;
+  bool NavigateToEntry(
+      FrameTreeNode* frame_tree_node,
+      const FrameNavigationEntry& frame_entry,
+      const NavigationEntryImpl& entry,
+      ReloadType reload_type,
+      bool is_same_document_history_load,
+      bool is_history_navigation_in_new_child,
+      bool is_pending_entry,
+      const scoped_refptr<network::ResourceRequestBody>& post_body,
+      std::unique_ptr<NavigationUIData> navigation_ui_data) override;
+  bool StartHistoryNavigationInNewSubframe(
+      RenderFrameHostImpl* render_frame_host,
+      const GURL& default_url) override;
   void RequestOpenURL(
       RenderFrameHostImpl* render_frame_host,
       const GURL& url,
@@ -77,14 +88,12 @@
       bool user_gesture,
       blink::WebTriggeringEventInfo triggering_event_info,
       const base::Optional<std::string>& suggested_filename) override;
-  void RequestTransferURL(
+  void NavigateFromFrameProxy(
       RenderFrameHostImpl* render_frame_host,
       const GURL& url,
       SiteInstance* source_site_instance,
-      const std::vector<GURL>& redirect_chain,
       const Referrer& referrer,
       ui::PageTransition page_transition,
-      const GlobalRequestID& transferred_global_request_id,
       bool should_replace_current_entry,
       const std::string& method,
       scoped_refptr<network::ResourceRequestBody> post_body,
@@ -118,20 +127,6 @@
   friend class NavigatorTestWithBrowserSideNavigation;
   ~NavigatorImpl() override;
 
-  // Navigates to the given entry, which might be the pending entry (if
-  // |is_pending_entry| is true).  Private because all callers should use either
-  // NavigateToPendingEntry or NavigateToNewChildFrame.
-  bool NavigateToEntry(
-      FrameTreeNode* frame_tree_node,
-      const FrameNavigationEntry& frame_entry,
-      const NavigationEntryImpl& entry,
-      ReloadType reload_type,
-      bool is_same_document_history_load,
-      bool is_history_navigation_in_new_child,
-      bool is_pending_entry,
-      const scoped_refptr<network::ResourceRequestBody>& post_body,
-      std::unique_ptr<NavigationUIData> navigation_ui_data);
-
   // If needed, sends a BeforeUnload IPC to the renderer to ask it to execute
   // the beforeUnload event. Otherwise, the navigation request will be started.
   void RequestNavigation(
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index e6300fe..3430e16 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1477,9 +1477,10 @@
     // Try to find a FrameNavigationEntry that matches this frame instead, based
     // on the frame's unique name.  If this can't be found, fall back to the
     // default params using RequestOpenURL below.
-    if (frame_tree_node_->navigator()->NavigateNewChildFrame(this,
-                                                             validated_url))
+    if (frame_tree_node_->navigator()->StartHistoryNavigationInNewSubframe(
+            this, validated_url)) {
       return;
+    }
   }
 
   TRACE_EVENT1("navigation", "RenderFrameHostImpl::OpenURL", "url",
diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc
index b44b0fd..6dcca03 100644
--- a/content/browser/frame_host/render_frame_proxy_host.cc
+++ b/content/browser/frame_host/render_frame_proxy_host.cc
@@ -300,12 +300,13 @@
   // RequestTransferURL method once both RenderFrameProxyHost and
   // RenderFrameHostImpl call RequestOpenURL from their OnOpenURL handlers.
   // See also https://crbug.com/647772.
-  frame_tree_node_->navigator()->RequestTransferURL(
-      current_rfh, validated_url, site_instance_.get(), std::vector<GURL>(),
-      params.referrer, ui::PAGE_TRANSITION_LINK, GlobalRequestID(),
-      params.should_replace_current_entry, params.uses_post ? "POST" : "GET",
-      params.resource_request_body, params.extra_headers,
-      params.suggested_filename);
+  // TODO(clamy): The transition should probably be changed for POST navigations
+  // to PAGE_TRANSITION_FORM_SUBMIT. See https://crbug.com/829827.
+  frame_tree_node_->navigator()->NavigateFromFrameProxy(
+      current_rfh, validated_url, site_instance_.get(), params.referrer,
+      ui::PAGE_TRANSITION_LINK, params.should_replace_current_entry,
+      params.uses_post ? "POST" : "GET", params.resource_request_body,
+      params.extra_headers, params.suggested_filename);
 }
 
 void RenderFrameProxyHost::OnCheckCompleted() {
diff --git a/content/browser/indexed_db/indexed_db_internals_ui.cc b/content/browser/indexed_db/indexed_db_internals_ui.cc
index 48bf8b2..616d0b0 100644
--- a/content/browser/indexed_db/indexed_db_internals_ui.cc
+++ b/content/browser/indexed_db/indexed_db_internals_ui.cc
@@ -41,7 +41,7 @@
 bool AllowWhitelistedPaths(const std::vector<base::FilePath>& allowed_paths,
                            const base::FilePath& candidate_path) {
   for (const base::FilePath& allowed_path : allowed_paths) {
-    if (allowed_path.IsParent(candidate_path))
+    if (candidate_path == allowed_path || allowed_path.IsParent(candidate_path))
       return true;
   }
   return false;
diff --git a/content/browser/media/media_devices_util.cc b/content/browser/media/media_devices_util.cc
index 9440bc7..58badef 100644
--- a/content/browser/media/media_devices_util.cc
+++ b/content/browser/media/media_devices_util.cc
@@ -13,10 +13,12 @@
 #include "base/strings/string_tokenizer.h"
 #include "content/browser/frame_host/render_frame_host_delegate.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/media_device_id.h"
 #include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/common/media_stream_request.h"
 #include "media/base/media_switches.h"
 
@@ -91,6 +93,15 @@
 
 }  // namespace
 
+MediaDeviceSaltAndOrigin::MediaDeviceSaltAndOrigin() = default;
+
+MediaDeviceSaltAndOrigin::MediaDeviceSaltAndOrigin(std::string device_id_salt,
+                                                   std::string group_id_salt,
+                                                   url::Origin origin)
+    : device_id_salt(std::move(device_id_salt)),
+      group_id_salt(std::move(group_id_salt)),
+      origin(std::move(origin)) {}
+
 void GetDefaultMediaDeviceID(
     MediaDeviceType device_type,
     int render_process_id,
@@ -113,46 +124,55 @@
       callback);
 }
 
-std::pair<std::string, url::Origin> GetMediaDeviceSaltAndOrigin(
-    int render_process_id,
-    int render_frame_id) {
+MediaDeviceSaltAndOrigin GetMediaDeviceSaltAndOrigin(int render_process_id,
+                                                     int render_frame_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   RenderFrameHost* frame_host =
       RenderFrameHost::FromID(render_process_id, render_frame_id);
   RenderProcessHost* process_host =
       RenderProcessHost::FromID(render_process_id);
-  return std::make_pair(
+  WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
+      WebContents::FromRenderFrameHost(frame_host));
+
+  std::string device_id_salt =
       process_host ? process_host->GetBrowserContext()->GetMediaDeviceIDSalt()
-                   : std::string(),
-      frame_host ? frame_host->GetLastCommittedOrigin() : url::Origin());
+                   : std::string();
+  std::string group_id_salt =
+      device_id_salt + (web_contents
+                            ? web_contents->GetMediaDeviceGroupIDSaltBase()
+                            : std::string());
+  url::Origin origin =
+      frame_host ? frame_host->GetLastCommittedOrigin() : url::Origin();
+
+  return {std::move(device_id_salt), std::move(group_id_salt),
+          std::move(origin)};
 }
 
-MediaDeviceInfo TranslateMediaDeviceInfo(bool has_permission,
-                                         const std::string& device_id_salt,
-                                         const std::string& group_id_salt,
-                                         const url::Origin& security_origin,
-                                         const MediaDeviceInfo& device_info) {
+MediaDeviceInfo TranslateMediaDeviceInfo(
+    bool has_permission,
+    const MediaDeviceSaltAndOrigin& salt_and_origin,
+    const MediaDeviceInfo& device_info) {
   return MediaDeviceInfo(
-      GetHMACForMediaDeviceID(device_id_salt, security_origin,
-                              device_info.device_id),
+      GetHMACForMediaDeviceID(salt_and_origin.device_id_salt,
+                              salt_and_origin.origin, device_info.device_id),
       has_permission ? device_info.label : std::string(),
       device_info.group_id.empty()
           ? std::string()
-          : GetHMACForMediaDeviceID(group_id_salt, security_origin,
-                                    device_info.group_id));
+          : GetHMACForMediaDeviceID(salt_and_origin.group_id_salt,
+                                    salt_and_origin.origin,
+                                    device_info.group_id),
+      has_permission ? device_info.video_facing
+                     : media::MEDIA_VIDEO_FACING_NONE);
 }
 
 MediaDeviceInfoArray TranslateMediaDeviceInfoArray(
     bool has_permission,
-    const std::string& device_id_salt,
-    const std::string& group_id_salt,
-    const url::Origin& security_origin,
+    const MediaDeviceSaltAndOrigin& salt_and_origin,
     const MediaDeviceInfoArray& device_infos) {
   MediaDeviceInfoArray result;
   for (const auto& device_info : device_infos) {
-    result.push_back(TranslateMediaDeviceInfo(has_permission, device_id_salt,
-                                              group_id_salt, security_origin,
-                                              device_info));
+    result.push_back(
+        TranslateMediaDeviceInfo(has_permission, salt_and_origin, device_info));
   }
   return result;
 }
diff --git a/content/browser/media/media_devices_util.h b/content/browser/media/media_devices_util.h
index c43e690..d2a02ef 100644
--- a/content/browser/media/media_devices_util.h
+++ b/content/browser/media/media_devices_util.h
@@ -17,45 +17,52 @@
 
 // Returns the ID of the user-default device ID via |callback|.
 // If no such device ID can be found, |callback| receives an empty string.
-void CONTENT_EXPORT GetDefaultMediaDeviceID(
+CONTENT_EXPORT void GetDefaultMediaDeviceID(
     MediaDeviceType device_type,
     int render_process_id,
     int render_frame_id,
     const base::Callback<void(const std::string&)>& callback);
 
+struct CONTENT_EXPORT MediaDeviceSaltAndOrigin {
+  MediaDeviceSaltAndOrigin();
+  MediaDeviceSaltAndOrigin(std::string device_id_salt,
+                           std::string group_id_salt,
+                           url::Origin origin);
+
+  std::string device_id_salt;
+  std::string group_id_salt;
+  url::Origin origin;
+};
+
 // Returns the current media device ID salt and security origin for the given
 // |render_process_id| and |render_frame_id|. These values are used to produce
 // unique media-device IDs for each origin and renderer process. These values
 // should not be cached since the user can explicitly change them at any time.
 // This function must run on the UI thread.
-std::pair<std::string, url::Origin> GetMediaDeviceSaltAndOrigin(
-    int render_process_id,
-    int render_frame_id);
+MediaDeviceSaltAndOrigin GetMediaDeviceSaltAndOrigin(int render_process_id,
+                                                     int render_frame_id);
 
 // Returns a translated version of |device_info| suitable for use in a renderer
 // process.
 // The |device_id| field is hashed using |device_id_salt| and |security_origin|.
 // The |group_id| field is hashed using |group_id_salt| and |security_origin|.
 // The |label| field is removed if |has_permission| is false.
-MediaDeviceInfo TranslateMediaDeviceInfo(bool has_permission,
-                                         const std::string& device_id_salt,
-                                         const std::string& group_id_salt,
-                                         const url::Origin& security_origin,
-                                         const MediaDeviceInfo& device_info);
+MediaDeviceInfo TranslateMediaDeviceInfo(
+    bool has_permission,
+    const MediaDeviceSaltAndOrigin& salt_and_origin,
+    const MediaDeviceInfo& device_info);
 
 // Returns a translated version of |device_infos|, with each element translated
 // using TranslateMediaDeviceInfo().
 MediaDeviceInfoArray TranslateMediaDeviceInfoArray(
     bool has_permission,
-    const std::string& device_id_salt,
-    const std::string& group_id_salt,
-    const url::Origin& security_origin,
+    const MediaDeviceSaltAndOrigin& salt_and_origin,
     const MediaDeviceInfoArray& device_infos);
 
 // Type definition to make it easier to use mock alternatives to
 // GetMediaDeviceSaltAndOrigin.
 using MediaDeviceSaltAndOriginCallback =
-    base::RepeatingCallback<std::pair<std::string, url::Origin>(int, int)>;
+    base::RepeatingCallback<MediaDeviceSaltAndOrigin(int, int)>;
 
 }  // namespace content
 
diff --git a/content/browser/renderer_host/input/fling_browsertest.cc b/content/browser/renderer_host/input/fling_browsertest.cc
index 72d6c9d..2497163d 100644
--- a/content/browser/renderer_host/input/fling_browsertest.cc
+++ b/content/browser/renderer_host/input/fling_browsertest.cc
@@ -85,10 +85,11 @@
   DISALLOW_COPY_AND_ASSIGN(BrowserSideFlingBrowserTest);
 };
 
-#if !defined(OS_ANDROID)
-#define MAYBE_AutoscrollFling AutoscrollFling
-#else
+// TODO(sahel): This test is flaking on OS_CHROMEOS https://crbug.com/838769
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
 #define MAYBE_AutoscrollFling DISABLED_AutoscrollFling
+#else
+#define MAYBE_AutoscrollFling AutoscrollFling
 #endif
 IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, MAYBE_AutoscrollFling) {
   LoadURL(kBrowserFlingDataURL);
@@ -155,4 +156,4 @@
   }
 }
 
-}  // namespace content
\ No newline at end of file
+}  // namespace content
diff --git a/content/browser/renderer_host/media/audio_output_authorization_handler.cc b/content/browser/renderer_host/media/audio_output_authorization_handler.cc
index 83d47fd..75822439 100644
--- a/content/browser/renderer_host/media/audio_output_authorization_handler.cc
+++ b/content/browser/renderer_host/media/audio_output_authorization_handler.cc
@@ -28,15 +28,14 @@
     int render_frame_id,
     bool override_permissions,
     bool permissions_override_value,
-    base::OnceCallback<void(std::string, const url::Origin&, bool)> cb) {
+    base::OnceCallback<void(std::string, url::Origin, bool)> cb) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  const auto& salt_and_origin =
+  MediaDeviceSaltAndOrigin salt_and_origin =
       GetMediaDeviceSaltAndOrigin(render_process_id, render_frame_id);
-  std::string salt = salt_and_origin.first;
-  const url::Origin& origin = salt_and_origin.second;
 
-  if (!MediaStreamManager::IsOriginAllowed(render_process_id, origin)) {
+  if (!MediaStreamManager::IsOriginAllowed(render_process_id,
+                                           salt_and_origin.origin)) {
     // In this case, it's likely a navigation has occurred while processing this
     // request.
     std::move(cb).Run(std::string(), url::Origin(), false);
@@ -46,12 +45,15 @@
   // Check that MediaStream device permissions have been granted for
   // nondefault devices.
   if (override_permissions) {
-    std::move(cb).Run(std::move(salt), origin, permissions_override_value);
+    std::move(cb).Run(std::move(salt_and_origin.device_id_salt),
+                      std::move(salt_and_origin.origin),
+                      permissions_override_value);
     return;
   }
 
   std::move(cb).Run(
-      std::move(salt), origin,
+      std::move(salt_and_origin.device_id_salt),
+      std::move(salt_and_origin.origin),
       MediaDevicesPermissionChecker().CheckPermissionOnUIThread(
           MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, render_process_id, render_frame_id));
 }
@@ -147,11 +149,11 @@
 void AudioOutputAuthorizationHandler::HashDeviceId(
     AuthorizationCompletedCallback cb,
     const std::string& raw_device_id,
-    const std::pair<std::string, url::Origin>& salt_and_origin) const {
+    const MediaDeviceSaltAndOrigin& salt_and_origin) const {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(!raw_device_id.empty());
   std::string hashed_device_id = GetHMACForMediaDeviceID(
-      salt_and_origin.first, salt_and_origin.second, raw_device_id);
+      salt_and_origin.device_id_salt, salt_and_origin.origin, raw_device_id);
   audio_system_->GetOutputStreamParameters(
       raw_device_id,
       base::BindOnce(&AudioOutputAuthorizationHandler::DeviceParametersReceived,
@@ -163,7 +165,7 @@
     AuthorizationCompletedCallback cb,
     const std::string& device_id,
     std::string salt,
-    const url::Origin& security_origin,
+    url::Origin security_origin,
     bool has_access) const {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
@@ -180,7 +182,7 @@
       devices_to_enumerate,
       base::Bind(&AudioOutputAuthorizationHandler::TranslateDeviceID,
                  weak_factory_.GetWeakPtr(), base::Passed(&cb), device_id,
-                 std::move(salt), security_origin));
+                 std::move(salt), std::move(security_origin)));
 }
 
 void AudioOutputAuthorizationHandler::TranslateDeviceID(
diff --git a/content/browser/renderer_host/media/audio_output_authorization_handler.h b/content/browser/renderer_host/media/audio_output_authorization_handler.h
index 4cc2fdd8..aa3e31f 100644
--- a/content/browser/renderer_host/media/audio_output_authorization_handler.h
+++ b/content/browser/renderer_host/media/audio_output_authorization_handler.h
@@ -65,15 +65,14 @@
   static void UMALogDeviceAuthorizationTime(base::TimeTicks auth_start_time);
 
  private:
-  void HashDeviceId(
-      AuthorizationCompletedCallback cb,
-      const std::string& raw_device_id,
-      const std::pair<std::string, url::Origin>& salt_and_origin) const;
+  void HashDeviceId(AuthorizationCompletedCallback cb,
+                    const std::string& raw_device_id,
+                    const MediaDeviceSaltAndOrigin& salt_and_origin) const;
 
   void AccessChecked(AuthorizationCompletedCallback cb,
                      const std::string& device_id,
                      std::string salt,
-                     const url::Origin& security_origin,
+                     url::Origin security_origin,
                      bool has_access) const;
 
   void TranslateDeviceID(AuthorizationCompletedCallback cb,
diff --git a/content/browser/renderer_host/media/in_process_launched_video_capture_device.cc b/content/browser/renderer_host/media/in_process_launched_video_capture_device.cc
index 7a2844a..5e65102 100644
--- a/content/browser/renderer_host/media/in_process_launched_video_capture_device.cc
+++ b/content/browser/renderer_host/media/in_process_launched_video_capture_device.cc
@@ -7,6 +7,7 @@
 #include "base/bind_helpers.h"
 #include "base/metrics/histogram_macros.h"
 #include "content/public/browser/browser_thread.h"
+#include "media/media_buildflags.h"
 
 #if defined(ENABLE_SCREEN_CAPTURE) && !defined(OS_ANDROID)
 #include "content/browser/media/capture/desktop_capture_device.h"
diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host.cc b/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
index 16af5dcd..c050afe3 100644
--- a/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
+++ b/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
@@ -72,7 +72,6 @@
     MediaStreamManager* media_stream_manager)
     : render_process_id_(render_process_id),
       render_frame_id_(render_frame_id),
-      group_id_salt_base_(BrowserContext::CreateRandomMediaDeviceIDSalt()),
       media_stream_manager_(media_stream_manager),
       num_pending_audio_input_parameters_(0),
       weak_factory_(this) {
@@ -112,9 +111,8 @@
   devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = request_audio_output;
 
   media_stream_manager_->media_devices_manager()->EnumerateDevices(
-      render_process_id_, render_frame_id_, group_id_salt_base_,
-      devices_to_enumerate, request_video_input_capabilities,
-      std::move(client_callback));
+      render_process_id_, render_frame_id_, devices_to_enumerate,
+      request_video_input_capabilities, std::move(client_callback));
 }
 
 void MediaDevicesDispatcherHost::GetVideoInputCapabilities(
@@ -175,50 +173,47 @@
   devices_to_subscribe[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = subscribe_video_input;
   devices_to_subscribe[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = subscribe_audio_output;
 
-  uint32_t subscription_id =
-      media_stream_manager_->media_devices_manager()
-          ->SubscribeDeviceChangeNotifications(
-              render_process_id_, render_frame_id_, group_id_salt_base_,
-              devices_to_subscribe, std::move(listener));
+  uint32_t subscription_id = media_stream_manager_->media_devices_manager()
+                                 ->SubscribeDeviceChangeNotifications(
+                                     render_process_id_, render_frame_id_,
+                                     devices_to_subscribe, std::move(listener));
   subscription_ids_.push_back(subscription_id);
 }
 
 void MediaDevicesDispatcherHost::GetDefaultVideoInputDeviceID(
     GetVideoInputCapabilitiesCallback client_callback,
-    const std::pair<std::string, url::Origin>& salt_and_origin) {
+    MediaDeviceSaltAndOrigin salt_and_origin) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   GetDefaultMediaDeviceID(
       MEDIA_DEVICE_TYPE_VIDEO_INPUT, render_process_id_, render_frame_id_,
       base::Bind(&MediaDevicesDispatcherHost::GotDefaultVideoInputDeviceID,
                  weak_factory_.GetWeakPtr(), base::Passed(&client_callback),
-                 salt_and_origin.first, salt_and_origin.second));
+                 std::move(salt_and_origin)));
 }
 
 void MediaDevicesDispatcherHost::GotDefaultVideoInputDeviceID(
     GetVideoInputCapabilitiesCallback client_callback,
-    std::string device_id_salt,
-    const url::Origin& security_origin,
+    MediaDeviceSaltAndOrigin salt_and_origin,
     const std::string& default_device_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   media_stream_manager_->video_capture_manager()->EnumerateDevices(
       base::Bind(&MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities,
                  weak_factory_.GetWeakPtr(), base::Passed(&client_callback),
-                 std::move(device_id_salt), security_origin,
-                 std::move(default_device_id)));
+                 std::move(salt_and_origin), std::move(default_device_id)));
 }
 
 void MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities(
     GetVideoInputCapabilitiesCallback client_callback,
-    const std::string& device_id_salt,
-    const url::Origin& security_origin,
+    const MediaDeviceSaltAndOrigin& salt_and_origin,
     const std::string& default_device_id,
     const media::VideoCaptureDeviceDescriptors& device_descriptors) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   std::vector<blink::mojom::VideoInputDeviceCapabilitiesPtr>
       video_input_capabilities;
   for (const auto& descriptor : device_descriptors) {
-    std::string hmac_device_id = GetHMACForMediaDeviceID(
-        device_id_salt, security_origin, descriptor.device_id);
+    std::string hmac_device_id =
+        GetHMACForMediaDeviceID(salt_and_origin.device_id_salt,
+                                salt_and_origin.origin, descriptor.device_id);
     blink::mojom::VideoInputDeviceCapabilitiesPtr capabilities =
         blink::mojom::VideoInputDeviceCapabilities::New();
     capabilities->device_id = std::move(hmac_device_id);
@@ -257,12 +252,13 @@
     GetVideoInputDeviceFormatsCallback client_callback,
     const std::string& device_id,
     bool try_in_use_first,
-    const std::pair<std::string, url::Origin>& salt_and_origin) {
+    const MediaDeviceSaltAndOrigin& salt_and_origin) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   media_stream_manager_->video_capture_manager()->EnumerateDevices(base::Bind(
       &MediaDevicesDispatcherHost::FinalizeGetVideoInputDeviceFormats,
       weak_factory_.GetWeakPtr(), base::Passed(&client_callback), device_id,
-      try_in_use_first, salt_and_origin.first, salt_and_origin.second));
+      try_in_use_first, salt_and_origin.device_id_salt,
+      salt_and_origin.origin));
 }
 
 void MediaDevicesDispatcherHost::FinalizeGetVideoInputDeviceFormats(
@@ -294,11 +290,11 @@
 
 void MediaDevicesDispatcherHost::GetDefaultAudioInputDeviceID(
     GetAudioInputCapabilitiesCallback client_callback,
-    const std::pair<std::string, url::Origin>& salt_and_origin) {
+    const MediaDeviceSaltAndOrigin& salt_and_origin) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   pending_audio_input_capabilities_requests_.push_back(
-      AudioInputCapabilitiesRequest{salt_and_origin.first,
-                                    salt_and_origin.second,
+      AudioInputCapabilitiesRequest{salt_and_origin.device_id_salt,
+                                    salt_and_origin.origin,
                                     std::move(client_callback)});
   if (pending_audio_input_capabilities_requests_.size() > 1U)
     return;
diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host.h b/content/browser/renderer_host/media/media_devices_dispatcher_host.h
index 6098e61..1222cb1 100644
--- a/content/browser/renderer_host/media/media_devices_dispatcher_host.h
+++ b/content/browser/renderer_host/media/media_devices_dispatcher_host.h
@@ -63,24 +63,22 @@
 
   void GetDefaultVideoInputDeviceID(
       GetVideoInputCapabilitiesCallback client_callback,
-      const std::pair<std::string, url::Origin>& salt_and_origin);
+      MediaDeviceSaltAndOrigin salt_and_origin);
 
   void GotDefaultVideoInputDeviceID(
       GetVideoInputCapabilitiesCallback client_callback,
-      std::string device_id_salt,
-      const url::Origin& security_origin,
+      MediaDeviceSaltAndOrigin salt_and_origin,
       const std::string& default_device_id);
 
   void FinalizeGetVideoInputCapabilities(
       GetVideoInputCapabilitiesCallback client_callback,
-      const std::string& device_id_salt,
-      const url::Origin& security_origin,
+      const MediaDeviceSaltAndOrigin& salt_and_origin,
       const std::string& default_device_id,
       const media::VideoCaptureDeviceDescriptors& device_descriptors);
 
   void GetDefaultAudioInputDeviceID(
       GetAudioInputCapabilitiesCallback client_callback,
-      const std::pair<std::string, url::Origin>& salt_and_origin);
+      const MediaDeviceSaltAndOrigin& salt_and_origin);
 
   void GotDefaultAudioInputDeviceID(const std::string& default_device_id);
 
@@ -101,7 +99,7 @@
       GetVideoInputDeviceFormatsCallback client_callback,
       const std::string& device_id,
       bool try_in_use_first,
-      const std::pair<std::string, url::Origin>& salt_and_origin);
+      const MediaDeviceSaltAndOrigin& salt_and_origin);
   void FinalizeGetVideoInputDeviceFormats(
       GetVideoInputDeviceFormatsCallback client_callback,
       const std::string& device_id,
@@ -113,11 +111,6 @@
   // The following const fields can be accessed on any thread.
   const int render_process_id_;
   const int render_frame_id_;
-  // This value is combined with the device ID salt to produce a salt for group
-  // IDs that, unlike the device ID salt, is not persistent across browsing
-  // sessions, but like the device ID salt, is reset when the user clears
-  // browsing data.
-  const std::string group_id_salt_base_;
 
   // The following fields can only be accessed on the IO thread.
   MediaStreamManager* media_stream_manager_;
diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
index 0647a6d..228ef45 100644
--- a/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/media/media_devices_dispatcher_host_unittest.cc
@@ -375,9 +375,10 @@
     }
   }
 
-  std::pair<std::string, url::Origin> GetSaltAndOrigin(int /* process_id */,
-                                                       int /* frame_id */) {
-    return std::make_pair(browser_context_->GetMediaDeviceIDSalt(), origin_);
+  MediaDeviceSaltAndOrigin GetSaltAndOrigin(int /* process_id */,
+                                            int /* frame_id */) {
+    return MediaDeviceSaltAndOrigin(browser_context_->GetMediaDeviceIDSalt(),
+                                    "fake_group_id_salt", origin_);
   }
 
   // The order of these members is important on teardown:
diff --git a/content/browser/renderer_host/media/media_devices_manager.cc b/content/browser/renderer_host/media/media_devices_manager.cc
index d08a1ced..0ec4dc82 100644
--- a/content/browser/renderer_host/media/media_devices_manager.cc
+++ b/content/browser/renderer_host/media/media_devices_manager.cc
@@ -110,6 +110,11 @@
          !media::AudioDeviceDescription::IsCommunicationsDevice(device_id);
 }
 
+static bool EqualDeviceAndGroupID(const MediaDeviceInfo& lhs,
+                                  const MediaDeviceInfo& rhs) {
+  return lhs == rhs && lhs.group_id == rhs.group_id;
+}
+
 }  // namespace
 
 std::string GuessVideoGroupID(const MediaDeviceInfoArray& audio_infos,
@@ -246,12 +251,10 @@
 MediaDevicesManager::SubscriptionRequest::SubscriptionRequest(
     int render_process_id,
     int render_frame_id,
-    const std::string& group_id_salt_base,
     const BoolDeviceTypes& subscribe_types,
     blink::mojom::MediaDevicesListenerPtr listener)
     : render_process_id(render_process_id),
       render_frame_id(render_frame_id),
-      group_id_salt_base(group_id_salt_base),
       subscribe_types(subscribe_types),
       listener(std::move(listener)) {}
 
@@ -312,7 +315,6 @@
 void MediaDevicesManager::EnumerateDevices(
     int render_process_id,
     int render_frame_id,
-    const std::string& group_id_salt_base,
     const BoolDeviceTypes& requested_types,
     bool request_video_input_capabilities,
     EnumerateDevicesCallback callback) {
@@ -324,14 +326,13 @@
                      render_frame_id),
       base::BindOnce(&MediaDevicesManager::CheckPermissionsForEnumerateDevices,
                      weak_factory_.GetWeakPtr(), render_process_id,
-                     render_frame_id, group_id_salt_base, requested_types,
+                     render_frame_id, requested_types,
                      request_video_input_capabilities, std::move(callback)));
 }
 
 uint32_t MediaDevicesManager::SubscribeDeviceChangeNotifications(
     int render_process_id,
     int render_frame_id,
-    const std::string& group_id_salt_base,
     const BoolDeviceTypes& subscribe_types,
     blink::mojom::MediaDevicesListenerPtr listener) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -342,9 +343,9 @@
       base::BindOnce(&MediaDevicesManager::UnsubscribeDeviceChangeNotifications,
                      weak_factory_.GetWeakPtr(), subscription_id));
   subscriptions_.emplace(
-      subscription_id, SubscriptionRequest(render_process_id, render_frame_id,
-                                           group_id_salt_base, subscribe_types,
-                                           std::move(media_devices_listener)));
+      subscription_id,
+      SubscriptionRequest(render_process_id, render_frame_id, subscribe_types,
+                          std::move(media_devices_listener)));
 
   return subscription_id;
 }
@@ -505,81 +506,70 @@
 void MediaDevicesManager::CheckPermissionsForEnumerateDevices(
     int render_process_id,
     int render_frame_id,
-    const std::string& group_id_salt_base,
     const BoolDeviceTypes& requested_types,
     bool request_video_input_capabilities,
     EnumerateDevicesCallback callback,
-    const std::pair<std::string, url::Origin>& salt_and_origin) {
+    MediaDeviceSaltAndOrigin salt_and_origin) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   permission_checker_->CheckPermissions(
       requested_types, render_process_id, render_frame_id,
       base::BindOnce(&MediaDevicesManager::OnPermissionsCheckDone,
-                     weak_factory_.GetWeakPtr(), group_id_salt_base,
-                     requested_types, request_video_input_capabilities,
-                     std::move(callback), salt_and_origin.first,
-                     salt_and_origin.second));
+                     weak_factory_.GetWeakPtr(), requested_types,
+                     request_video_input_capabilities, std::move(callback),
+                     std::move(salt_and_origin)));
 }
 
 void MediaDevicesManager::OnPermissionsCheckDone(
-    const std::string& group_id_salt_base,
     const MediaDevicesManager::BoolDeviceTypes& requested_types,
     bool request_video_input_capabilities,
     EnumerateDevicesCallback callback,
-    const std::string& device_id_salt,
-    const url::Origin& security_origin,
+    MediaDeviceSaltAndOrigin salt_and_origin,
     const MediaDevicesManager::BoolDeviceTypes& has_permissions) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  // The video-capture subsystem currently does not support group IDs.
+  // If video input devices are requested, also request audio input devices in
+  // order to be able to use an heuristic that guesses group IDs for video
+  // devices by finding matches in audio input devices.
+  // TODO(crbug.com/627793): Remove |internal_requested_types| and use
+  // |requested_types| directly when video capture supports group IDs.
+  BoolDeviceTypes internal_requested_types;
+  internal_requested_types[MEDIA_DEVICE_TYPE_AUDIO_INPUT] =
+      requested_types[MEDIA_DEVICE_TYPE_AUDIO_INPUT] ||
+      requested_types[MEDIA_DEVICE_TYPE_VIDEO_INPUT];
+  internal_requested_types[MEDIA_DEVICE_TYPE_VIDEO_INPUT] =
+      requested_types[MEDIA_DEVICE_TYPE_VIDEO_INPUT];
+  internal_requested_types[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] =
+      requested_types[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT];
+
   EnumerateDevices(
-      requested_types,
+      internal_requested_types,
       base::BindRepeating(&MediaDevicesManager::OnDevicesEnumerated,
-                          weak_factory_.GetWeakPtr(), group_id_salt_base,
-                          requested_types, request_video_input_capabilities,
-                          base::Passed(&callback), device_id_salt,
-                          security_origin, has_permissions));
+                          weak_factory_.GetWeakPtr(), requested_types,
+                          request_video_input_capabilities,
+                          base::Passed(&callback), std::move(salt_and_origin),
+                          has_permissions));
 }
 
 void MediaDevicesManager::OnDevicesEnumerated(
-    const std::string& group_id_salt_base,
     const MediaDevicesManager::BoolDeviceTypes& requested_types,
     bool request_video_input_capabilities,
     EnumerateDevicesCallback callback,
-    const std::string& device_id_salt,
-    const url::Origin& security_origin,
+    const MediaDeviceSaltAndOrigin& salt_and_origin,
     const MediaDevicesManager::BoolDeviceTypes& has_permissions,
     const MediaDeviceEnumeration& enumeration) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  std::string group_id_salt = group_id_salt_base + device_id_salt;
   const bool video_input_capabilities_requested =
       has_permissions[MEDIA_DEVICE_TYPE_VIDEO_INPUT] &&
       request_video_input_capabilities;
 
-  MediaDeviceInfoArray video_device_infos =
-      enumeration[MEDIA_DEVICE_TYPE_VIDEO_INPUT];
-  for (auto& video_device_info : video_device_infos) {
-    video_device_info.group_id = GuessVideoGroupID(
-        enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT], video_device_info);
-  }
-
   std::vector<MediaDeviceInfoArray> result(NUM_MEDIA_DEVICE_TYPES);
   for (size_t i = 0; i < NUM_MEDIA_DEVICE_TYPES; ++i) {
     if (!requested_types[i])
       continue;
 
-    if (i == MEDIA_DEVICE_TYPE_VIDEO_INPUT) {
-      for (const auto& device_info : video_device_infos) {
-        MediaDeviceInfo translated_device_info = TranslateMediaDeviceInfo(
-            has_permissions[i], device_id_salt, group_id_salt, security_origin,
-            device_info);
-        if (video_input_capabilities_requested)
-          translated_device_info.video_facing = device_info.video_facing;
-        result[i].push_back(translated_device_info);
-      }
-    } else {
-      for (const auto& device_info : enumeration[i]) {
-        result[i].push_back(TranslateMediaDeviceInfo(
-            has_permissions[i], device_id_salt, group_id_salt, security_origin,
-            device_info));
-      }
+    for (const auto& device_info : enumeration[i]) {
+      result[i].push_back(TranslateMediaDeviceInfo(
+          has_permissions[i], salt_and_origin, device_info));
     }
   }
 
@@ -698,19 +688,29 @@
 
 void MediaDevicesManager::UpdateSnapshot(
     MediaDeviceType type,
-    const MediaDeviceInfoArray& new_snapshot) {
+    const MediaDeviceInfoArray& new_snapshot,
+    bool ignore_group_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(IsValidMediaDeviceType(type));
 
-  // Only cache the device list when the device list has been changed.
   bool need_update_device_change_subscribers = false;
   MediaDeviceInfoArray& old_snapshot = current_snapshot_[type];
 
+  // Update the cached snapshot and send notifications only if the device list
+  // has changed.
   if (old_snapshot.size() != new_snapshot.size() ||
       !std::equal(new_snapshot.begin(), new_snapshot.end(),
-                  old_snapshot.begin())) {
-    if (type == MEDIA_DEVICE_TYPE_AUDIO_INPUT ||
-        type == MEDIA_DEVICE_TYPE_VIDEO_INPUT) {
+                  old_snapshot.begin(),
+                  ignore_group_id ? operator== : EqualDeviceAndGroupID)) {
+    // Prevent sending notifications until group IDs are updated using
+    // a heuristic in ProcessRequests().
+    // TODO(crbug.com/627793): Remove |is_video_with_group_ids| and the
+    // corresponding checks when the video-capture subsystem supports
+    // group IDs.
+    bool is_video_with_good_group_ids =
+        type == MEDIA_DEVICE_TYPE_VIDEO_INPUT &&
+        (new_snapshot.size() == 0 || !new_snapshot[0].group_id.empty());
+    if (type == MEDIA_DEVICE_TYPE_AUDIO_INPUT || is_video_with_good_group_ids) {
       NotifyMediaStreamManager(type, new_snapshot);
     }
 
@@ -718,7 +718,8 @@
     // result, since it is not due to an actual device change.
     need_update_device_change_subscribers =
         has_seen_result_[type] &&
-        (old_snapshot.size() != 0 || new_snapshot.size() != 0);
+        (old_snapshot.size() != 0 || new_snapshot.size() != 0) &&
+        (type != MEDIA_DEVICE_TYPE_VIDEO_INPUT || is_video_with_good_group_ids);
     current_snapshot_[type] = new_snapshot;
   }
 
@@ -728,6 +729,21 @@
 
 void MediaDevicesManager::ProcessRequests() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  // Populate the group ID field for video devices using a heuristic that looks
+  // for device coincidences with audio input devices.
+  // TODO(crbug.com/627793): Remove this once the video-capture subsystem
+  // supports group IDs.
+  if (has_seen_result_[MEDIA_DEVICE_TYPE_VIDEO_INPUT]) {
+    MediaDeviceInfoArray video_devices =
+        current_snapshot_[MEDIA_DEVICE_TYPE_VIDEO_INPUT];
+    for (auto& video_device_info : video_devices) {
+      video_device_info.group_id = GuessVideoGroupID(
+          current_snapshot_[MEDIA_DEVICE_TYPE_AUDIO_INPUT], video_device_info);
+    }
+    UpdateSnapshot(MEDIA_DEVICE_TYPE_VIDEO_INPUT, video_devices,
+                   false /* ignore_group_id */);
+  }
+
   requests_.erase(std::remove_if(requests_.begin(), requests_.end(),
                                  [this](const EnumerationRequest& request) {
                                    if (IsEnumerationRequestReady(request)) {
@@ -822,22 +838,20 @@
     int render_frame_id,
     MediaDeviceType type,
     const MediaDeviceInfoArray& device_infos,
-    const std::pair<std::string, url::Origin>& salt_and_origin) {
+    MediaDeviceSaltAndOrigin salt_and_origin) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   permission_checker_->CheckPermission(
       type, render_process_id, render_frame_id,
       base::BindOnce(&MediaDevicesManager::NotifyDeviceChange,
                      weak_factory_.GetWeakPtr(), subscription_id, type,
-                     device_infos, salt_and_origin.first,
-                     salt_and_origin.second));
+                     device_infos, std::move(salt_and_origin)));
 }
 
 void MediaDevicesManager::NotifyDeviceChange(
     uint32_t subscription_id,
     MediaDeviceType type,
     const MediaDeviceInfoArray& device_infos,
-    std::string device_id_salt,
-    const url::Origin& security_origin,
+    const MediaDeviceSaltAndOrigin& salt_and_origin,
     bool has_permission) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(IsValidMediaDeviceType(type));
@@ -846,10 +860,8 @@
     return;
 
   const SubscriptionRequest& request = it->second;
-  std::string group_id_salt = request.group_id_salt_base + device_id_salt;
   request.listener->OnDevicesChanged(
-      type, TranslateMediaDeviceInfoArray(has_permission, device_id_salt,
-                                          group_id_salt, security_origin,
+      type, TranslateMediaDeviceInfoArray(has_permission, salt_and_origin,
                                           device_infos));
 }
 
diff --git a/content/browser/renderer_host/media/media_devices_manager.h b/content/browser/renderer_host/media/media_devices_manager.h
index 27eb038b..59fae7ff 100644
--- a/content/browser/renderer_host/media/media_devices_manager.h
+++ b/content/browser/renderer_host/media/media_devices_manager.h
@@ -81,11 +81,9 @@
   // types and reports the results to |callback|. The enumeration results are
   // translated for use by the renderer process and frame identified with
   // |render_process_id| and |render_frame_id|, based on the frame origin's
-  // permissions, an internal media-device salt, and the given
-  // |group_id_salt_base|.
+  // permissions, an internal media-device salts.
   void EnumerateDevices(int render_process_id,
                         int render_frame_id,
-                        const std::string& group_id_salt_base,
                         const BoolDeviceTypes& requested_types,
                         bool request_video_input_capabilities,
                         EnumerateDevicesCallback callback);
@@ -93,7 +91,6 @@
   uint32_t SubscribeDeviceChangeNotifications(
       int render_process_id,
       int render_frame_id,
-      const std::string& group_id_salt_base,
       const BoolDeviceTypes& subscribe_types,
       blink::mojom::MediaDevicesListenerPtr listener);
   void UnsubscribeDeviceChangeNotifications(uint32_t subscription_id);
@@ -146,7 +143,6 @@
   struct SubscriptionRequest {
     SubscriptionRequest(int render_process_id,
                         int render_frame_id,
-                        const std::string& group_id_salt_base,
                         const BoolDeviceTypes& subscribe_types,
                         blink::mojom::MediaDevicesListenerPtr listener);
     SubscriptionRequest(SubscriptionRequest&&);
@@ -156,7 +152,6 @@
 
     int render_process_id;
     int render_frame_id;
-    std::string group_id_salt_base;
     BoolDeviceTypes subscribe_types;
     blink::mojom::MediaDevicesListenerPtr listener;
   };
@@ -179,26 +174,21 @@
   void CheckPermissionsForEnumerateDevices(
       int render_process_id,
       int render_frame_id,
-      const std::string& group_id_salt_base,
       const BoolDeviceTypes& requested_types,
       bool request_video_input_capabilities,
       EnumerateDevicesCallback callback,
-      const std::pair<std::string, url::Origin>& salt_and_origin);
+      MediaDeviceSaltAndOrigin salt_and_origin);
   void OnPermissionsCheckDone(
-      const std::string& group_id_salt_base,
       const MediaDevicesManager::BoolDeviceTypes& requested_types,
       bool request_video_input_capabilities,
       EnumerateDevicesCallback callback,
-      const std::string& device_id_salt,
-      const url::Origin& security_origin,
+      MediaDeviceSaltAndOrigin salt_and_origin,
       const MediaDevicesManager::BoolDeviceTypes& has_permissions);
   void OnDevicesEnumerated(
-      const std::string& group_id_salt_base,
       const MediaDevicesManager::BoolDeviceTypes& requested_types,
       bool request_video_input_capabilities,
       EnumerateDevicesCallback callback,
-      const std::string& device_id_salt,
-      const url::Origin& security_origin,
+      const MediaDeviceSaltAndOrigin& salt_and_origin,
       const MediaDevicesManager::BoolDeviceTypes& has_permissions,
       const MediaDeviceEnumeration& enumeration);
 
@@ -222,7 +212,8 @@
   void DevicesEnumerated(MediaDeviceType type,
                          const MediaDeviceInfoArray& snapshot);
   void UpdateSnapshot(MediaDeviceType type,
-                      const MediaDeviceInfoArray& new_snapshot);
+                      const MediaDeviceInfoArray& new_snapshot,
+                      bool ignore_group_id = true);
   void ProcessRequests();
   bool IsEnumerationRequestReady(const EnumerationRequest& request_info);
 
@@ -232,18 +223,16 @@
                                 const MediaDeviceInfoArray& new_snapshot);
   void NotifyDeviceChangeSubscribers(MediaDeviceType type,
                                      const MediaDeviceInfoArray& snapshot);
-  void CheckPermissionForDeviceChange(
-      uint32_t subscription_id,
-      int render_process_id,
-      int render_frame_id,
-      MediaDeviceType type,
-      const MediaDeviceInfoArray& device_infos,
-      const std::pair<std::string, url::Origin>& salt_and_origin);
+  void CheckPermissionForDeviceChange(uint32_t subscription_id,
+                                      int render_process_id,
+                                      int render_frame_id,
+                                      MediaDeviceType type,
+                                      const MediaDeviceInfoArray& device_infos,
+                                      MediaDeviceSaltAndOrigin salt_and_origin);
   void NotifyDeviceChange(uint32_t subscription_id,
                           MediaDeviceType type,
                           const MediaDeviceInfoArray& device_infos,
-                          std::string device_id_salt,
-                          const url::Origin& security_origin,
+                          const MediaDeviceSaltAndOrigin& salt_and_origin,
                           bool has_permission);
 
 #if defined(OS_MACOSX)
diff --git a/content/browser/renderer_host/media/media_devices_manager_unittest.cc b/content/browser/renderer_host/media/media_devices_manager_unittest.cc
index 79302f2..b447591d 100644
--- a/content/browser/renderer_host/media/media_devices_manager_unittest.cc
+++ b/content/browser/renderer_host/media/media_devices_manager_unittest.cc
@@ -46,10 +46,11 @@
 
 const auto kIgnoreLogMessageCB = base::BindRepeating([](const std::string&) {});
 
-std::pair<std::string, url::Origin> GetSaltAndOrigin(int /* process_id */,
-                                                     int /* frame_id */) {
-  return std::make_pair(std::string("fake_media_device_salt"),
-                        url::Origin::Create(GURL("https://test.com")));
+MediaDeviceSaltAndOrigin GetSaltAndOrigin(int /* process_id */,
+                                          int /* frame_id */) {
+  return MediaDeviceSaltAndOrigin(
+      "fake_media_device_salt", "fake_group_id_salt",
+      url::Origin::Create(GURL("https://test.com")));
 }
 
 // This class mocks the audio manager and overrides some methods to ensure that
@@ -148,6 +149,15 @@
   mojo::BindingSet<blink::mojom::MediaDevicesListener> bindings_;
 };
 
+void VerifyDeviceAndGroupID(const std::vector<MediaDeviceInfoArray>& array) {
+  for (const auto& device_infos : array) {
+    for (const auto& device_info : device_infos) {
+      EXPECT_FALSE(device_info.device_id.empty());
+      EXPECT_FALSE(device_info.group_id.empty());
+    }
+  }
+}
+
 }  // namespace
 
 class MediaDevicesManagerTest : public ::testing::Test {
@@ -161,6 +171,12 @@
 
   void EnumerateCallback(base::RunLoop* run_loop,
                          const MediaDeviceEnumeration& result) {
+    for (int i = 0; i < NUM_MEDIA_DEVICE_TYPES; ++i) {
+      for (const auto& device_info : result[i]) {
+        EXPECT_FALSE(device_info.device_id.empty());
+        EXPECT_FALSE(device_info.group_id.empty());
+      }
+    }
     MockCallback(result);
     run_loop->Quit();
   }
@@ -522,9 +538,7 @@
   audio_input_devices_to_subscribe[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true;
   uint32_t audio_input_subscription_id =
       media_devices_manager_->SubscribeDeviceChangeNotifications(
-          kRenderProcessId, kRenderFrameId,
-          std::string("fake_group_id_salt_base"),
-          audio_input_devices_to_subscribe,
+          kRenderProcessId, kRenderFrameId, audio_input_devices_to_subscribe,
           listener_audio_input.CreateInterfacePtrAndBind());
 
   MockMediaDevicesListener listener_video_input;
@@ -532,9 +546,7 @@
   video_input_devices_to_subscribe[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = true;
   uint32_t video_input_subscription_id =
       media_devices_manager_->SubscribeDeviceChangeNotifications(
-          kRenderProcessId, kRenderFrameId,
-          std::string("fake_group_id_salt_base"),
-          video_input_devices_to_subscribe,
+          kRenderProcessId, kRenderFrameId, video_input_devices_to_subscribe,
           listener_video_input.CreateInterfacePtrAndBind());
 
   MockMediaDevicesListener listener_audio_output;
@@ -542,9 +554,7 @@
   audio_output_devices_to_subscribe[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
   uint32_t audio_output_subscription_id =
       media_devices_manager_->SubscribeDeviceChangeNotifications(
-          kRenderProcessId, kRenderFrameId,
-          std::string("fake_group_id_salt_base"),
-          audio_output_devices_to_subscribe,
+          kRenderProcessId, kRenderFrameId, audio_output_devices_to_subscribe,
           listener_audio_output.CreateInterfacePtrAndBind());
 
   MockMediaDevicesListener listener_all;
@@ -553,8 +563,8 @@
   all_devices_to_subscribe[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = true;
   all_devices_to_subscribe[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
   media_devices_manager_->SubscribeDeviceChangeNotifications(
-      kRenderProcessId, kRenderFrameId, std::string("fake_group_id_salt_base"),
-      all_devices_to_subscribe, listener_all.CreateInterfacePtrAndBind());
+      kRenderProcessId, kRenderFrameId, all_devices_to_subscribe,
+      listener_all.CreateInterfacePtrAndBind());
 
   MediaDeviceInfoArray notification_audio_input;
   MediaDeviceInfoArray notification_video_input;
@@ -602,6 +612,10 @@
   EXPECT_EQ(num_audio_input_devices, notification_all_audio_input.size());
   EXPECT_EQ(num_video_input_devices, notification_all_video_input.size());
   EXPECT_EQ(num_audio_output_devices, notification_all_audio_output.size());
+  VerifyDeviceAndGroupID(
+      {notification_audio_input, notification_video_input,
+       notification_audio_output, notification_all_audio_input,
+       notification_all_video_input, notification_all_audio_output});
 
   media_devices_manager_->UnsubscribeDeviceChangeNotifications(
       audio_input_subscription_id);
@@ -626,6 +640,9 @@
   EXPECT_EQ(num_audio_input_devices, notification_all_audio_input.size());
   EXPECT_EQ(num_video_input_devices, notification_all_video_input.size());
   EXPECT_EQ(num_audio_output_devices, notification_all_audio_output.size());
+  VerifyDeviceAndGroupID({notification_all_audio_input,
+                          notification_all_video_input,
+                          notification_all_audio_output});
 }
 
 TEST_F(MediaDevicesManagerTest, GuessVideoGroupID) {
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
index 17593bdb..9f623c4 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -126,19 +126,18 @@
     const StreamControls& controls,
     bool user_gesture,
     GenerateStreamCallback callback,
-    const std::pair<std::string, url::Origin>& salt_and_origin) {
+    MediaDeviceSaltAndOrigin salt_and_origin) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (!MediaStreamManager::IsOriginAllowed(render_process_id_,
-                                           salt_and_origin.second)) {
+                                           salt_and_origin.origin)) {
     std::move(callback).Run(MEDIA_DEVICE_INVALID_SECURITY_ORIGIN, std::string(),
                             MediaStreamDevices(), MediaStreamDevices());
     return;
   }
 
   media_stream_manager_->GenerateStream(
-      render_process_id_, render_frame_id_, salt_and_origin.first,
-      page_request_id, controls, salt_and_origin.second, user_gesture,
-      std::move(callback),
+      render_process_id_, render_frame_id_, page_request_id, controls,
+      std::move(salt_and_origin), user_gesture, std::move(callback),
       base::BindRepeating(&MediaStreamDispatcherHost::OnDeviceStopped,
                           weak_factory_.GetWeakPtr()));
 }
@@ -178,19 +177,18 @@
     const std::string& device_id,
     MediaStreamType type,
     OpenDeviceCallback callback,
-    const std::pair<std::string, url::Origin>& salt_and_origin) {
+    MediaDeviceSaltAndOrigin salt_and_origin) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (!MediaStreamManager::IsOriginAllowed(render_process_id_,
-                                           salt_and_origin.second)) {
+                                           salt_and_origin.origin)) {
     std::move(callback).Run(false /* success */, std::string(),
                             MediaStreamDevice());
     return;
   }
 
   media_stream_manager_->OpenDevice(
-      render_process_id_, render_frame_id_, salt_and_origin.first,
-      page_request_id, device_id, type, salt_and_origin.second,
-      std::move(callback),
+      render_process_id_, render_frame_id_, page_request_id, device_id, type,
+      std::move(salt_and_origin), std::move(callback),
       base::BindRepeating(&MediaStreamDispatcherHost::OnDeviceStopped,
                           weak_factory_.GetWeakPtr()));
 }
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.h b/content/browser/renderer_host/media/media_stream_dispatcher_host.h
index fecd1b1..1144a33 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.h
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.h
@@ -17,10 +17,6 @@
 #include "content/common/media/media_stream_controls.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
 
-namespace url {
-class Origin;
-}
-
 namespace content {
 
 class MediaStreamManager;
@@ -72,17 +68,16 @@
                                bool is_secure) override;
   void OnStreamStarted(const std::string& label) override;
 
-  void DoGenerateStream(
-      int32_t request_id,
-      const StreamControls& controls,
-      bool user_gesture,
-      GenerateStreamCallback callback,
-      const std::pair<std::string, url::Origin>& salt_and_origin);
+  void DoGenerateStream(int32_t request_id,
+                        const StreamControls& controls,
+                        bool user_gesture,
+                        GenerateStreamCallback callback,
+                        MediaDeviceSaltAndOrigin salt_and_origin);
   void DoOpenDevice(int32_t request_id,
                     const std::string& device_id,
                     MediaStreamType type,
                     OpenDeviceCallback callback,
-                    const std::pair<std::string, url::Origin>& salt_and_origin);
+                    MediaDeviceSaltAndOrigin salt_and_origin);
 
   void OnDeviceStopped(const std::string& label,
                        const MediaStreamDevice& device);
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
index eeccf1f..688ce18 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -307,9 +307,10 @@
 
   void TearDown() override { host_.reset(); }
 
-  std::pair<std::string, url::Origin> GetSaltAndOrigin(int /* process_id */,
-                                                       int /* frame_id */) {
-    return std::make_pair(browser_context_->GetMediaDeviceIDSalt(), origin_);
+  MediaDeviceSaltAndOrigin GetSaltAndOrigin(int /* process_id */,
+                                            int /* frame_id */) {
+    return MediaDeviceSaltAndOrigin(browser_context_->GetMediaDeviceIDSalt(),
+                                    "fake_group_id_salt", origin_);
   }
 
  protected:
@@ -350,12 +351,11 @@
       int page_request_id,
       const StreamControls& controls,
       MediaStreamRequestResult expected_result) {
-      base::RunLoop run_loop;
-      EXPECT_CALL(*host_,
-                  OnStreamGenerationFailure(page_request_id, expected_result));
-      host_->OnGenerateStream(page_request_id, controls,
-                              run_loop.QuitClosure());
-      run_loop.Run();
+    base::RunLoop run_loop;
+    EXPECT_CALL(*host_,
+                OnStreamGenerationFailure(page_request_id, expected_result));
+    host_->OnGenerateStream(page_request_id, controls, run_loop.QuitClosure());
+    run_loop.Run();
   }
 
   void OpenVideoDeviceAndWaitForResult(int page_request_id,
@@ -696,8 +696,9 @@
 
   std::string stream_request_label = host_->label_;
   MediaStreamDevice video_device = host_->video_devices_.front();
-  ASSERT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
-      stream_request_label).size());
+  ASSERT_EQ(
+      1u, media_stream_manager_->GetDevicesOpenedByRequest(stream_request_label)
+              .size());
 
   // Open the same device by Pepper.
   OpenVideoDeviceAndWaitForResult(kPageRequestId, video_device.id);
@@ -706,10 +707,12 @@
   // Stop the device in the MediaStream.
   host_->OnStopStreamDevice(video_device.id, video_device.session_id);
 
-  EXPECT_EQ(0u, media_stream_manager_->GetDevicesOpenedByRequest(
-      stream_request_label).size());
-  EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
-      open_device_request_label).size());
+  EXPECT_EQ(
+      0u, media_stream_manager_->GetDevicesOpenedByRequest(stream_request_label)
+              .size());
+  EXPECT_EQ(1u, media_stream_manager_
+                    ->GetDevicesOpenedByRequest(open_device_request_label)
+                    .size());
 }
 
 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
@@ -721,12 +724,14 @@
   std::string request_label1 = host_->label_;
   MediaStreamDevice video_device = host_->video_devices_.front();
   // Expect that 1 audio and 1 video device has been opened.
-  EXPECT_EQ(2u, media_stream_manager_->GetDevicesOpenedByRequest(
-      request_label1).size());
+  EXPECT_EQ(
+      2u,
+      media_stream_manager_->GetDevicesOpenedByRequest(request_label1).size());
 
   host_->OnStopStreamDevice(video_device.id, video_device.session_id);
-  EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
-      request_label1).size());
+  EXPECT_EQ(
+      1u,
+      media_stream_manager_->GetDevicesOpenedByRequest(request_label1).size());
 
   GenerateStreamAndWaitForResult(kPageRequestId, controls);
   std::string request_label2 = host_->label_;
@@ -856,14 +861,21 @@
   EXPECT_EQ(host_->video_devices_.size(), 1u);
   const std::string label1 = host_->label_;
   const std::string device_id1 = host_->video_devices_.front().id;
+  EXPECT_TRUE(host_->video_devices_.front().group_id.has_value());
+  const std::string group_id1 = *host_->video_devices_.front().group_id;
+  EXPECT_FALSE(group_id1.empty());
   const int session_id1 = host_->video_devices_.front().session_id;
 
   // Generate second stream.
   OpenVideoDeviceAndWaitForResult(kPageRequestId, device_id1);
   const std::string device_id2 = host_->opened_device_.id;
+  EXPECT_TRUE(host_->opened_device_.group_id.has_value());
+  const std::string group_id2 = *host_->opened_device_.group_id;
+  EXPECT_FALSE(group_id2.empty());
   const int session_id2 = host_->opened_device_.session_id;
   const std::string label2 = host_->label_;
   EXPECT_EQ(device_id1, device_id2);
+  EXPECT_EQ(group_id1, group_id2);
   EXPECT_NE(session_id1, session_id2);
   EXPECT_NE(label1, label2);
 
@@ -874,6 +886,7 @@
   // Last open device ID and session are from the second stream.
   EXPECT_EQ(session_id2, host_->opened_device_.session_id);
   EXPECT_EQ(device_id2, host_->opened_device_.id);
+  EXPECT_EQ(group_id2, host_->opened_device_.group_id);
 }
 
 };  // namespace content
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index 9d3ed22..c45c089 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -81,7 +81,8 @@
   // U+007E. That causes problems with searching for labels in bots, so we use a
   // safe alphanumeric subset |kAlphabet|.
   // [1] http://dev.w3.org/2011/webrtc/editor/webrtc.html
-  static const char kAlphabet[] = "0123456789"
+  static const char kAlphabet[] =
+      "0123456789"
       "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
   static const size_t kRfc4122LengthLabel = 36u;
@@ -140,19 +141,19 @@
           switches::kDisableAudioSupportForDesktopShare);
   if (controls.audio.requested) {
     if (!controls.audio.stream_source.empty()) {
-       // This is tab or screen capture.
-       if (controls.audio.stream_source == kMediaStreamSourceTab) {
-         *audio_type = MEDIA_TAB_AUDIO_CAPTURE;
-       } else if (controls.audio.stream_source == kMediaStreamSourceSystem) {
-         *audio_type = MEDIA_DESKTOP_AUDIO_CAPTURE;
-       } else if (audio_support_flag_for_desktop_share &&
-                  controls.audio.stream_source == kMediaStreamSourceDesktop) {
-         *audio_type = MEDIA_DESKTOP_AUDIO_CAPTURE;
-       }
-     } else {
-       // This is normal audio device capture.
-       *audio_type = MEDIA_DEVICE_AUDIO_CAPTURE;
-     }
+      // This is tab or screen capture.
+      if (controls.audio.stream_source == kMediaStreamSourceTab) {
+        *audio_type = MEDIA_TAB_AUDIO_CAPTURE;
+      } else if (controls.audio.stream_source == kMediaStreamSourceSystem) {
+        *audio_type = MEDIA_DESKTOP_AUDIO_CAPTURE;
+      } else if (audio_support_flag_for_desktop_share &&
+                 controls.audio.stream_source == kMediaStreamSourceDesktop) {
+        *audio_type = MEDIA_DESKTOP_AUDIO_CAPTURE;
+      }
+    } else {
+      // This is normal audio device capture.
+      *audio_type = MEDIA_DEVICE_AUDIO_CAPTURE;
+    }
   }
   if (controls.video.requested) {
     if (!controls.video.stream_source.empty()) {
@@ -255,7 +256,6 @@
 
 }  // namespace
 
-
 // MediaStreamManager::DeviceRequest represents a request to either enumerate
 // available devices or open one or more devices.
 // TODO(perkj): MediaStreamManager still needs refactoring. I propose we create
@@ -268,20 +268,18 @@
       int requesting_process_id,
       int requesting_frame_id,
       int page_request_id,
-      const url::Origin& security_origin,
       bool user_gesture,
       MediaStreamRequestType request_type,
       const StreamControls& controls,
-      const std::string& salt,
+      MediaDeviceSaltAndOrigin salt_and_origin,
       DeviceStoppedCallback device_stopped_cb = DeviceStoppedCallback())
       : requesting_process_id(requesting_process_id),
         requesting_frame_id(requesting_frame_id),
         page_request_id(page_request_id),
-        security_origin(security_origin),
         user_gesture(user_gesture),
         request_type(request_type),
         controls(controls),
-        salt(salt),
+        salt_and_origin(std::move(salt_and_origin)),
         device_stopped_cb(std::move(device_stopped_cb)),
         state_(NUM_MEDIA_TYPES, MEDIA_REQUEST_STATE_NOT_REQUESTED),
         audio_type_(MEDIA_NO_SERVICE),
@@ -292,8 +290,7 @@
   ~DeviceRequest() { RunMojoCallbacks(); }
 
   void SetAudioType(MediaStreamType audio_type) {
-    DCHECK(IsAudioInputMediaType(audio_type) ||
-           audio_type == MEDIA_NO_SERVICE);
+    DCHECK(IsAudioInputMediaType(audio_type) || audio_type == MEDIA_NO_SERVICE);
     audio_type_ = audio_type;
   }
 
@@ -315,7 +312,7 @@
     target_frame_id_ = requesting_frame_id;
     ui_request_.reset(new MediaStreamRequest(
         requesting_process_id, requesting_frame_id, page_request_id,
-        security_origin.GetURL(), user_gesture, request_type,
+        salt_and_origin.origin.GetURL(), user_gesture, request_type,
         requested_audio_device_id, requested_video_device_id, audio_type_,
         video_type_, controls.disable_local_echo));
   }
@@ -329,7 +326,7 @@
     target_frame_id_ = target_render_frame_id;
     ui_request_.reset(new MediaStreamRequest(
         target_render_process_id, target_render_frame_id, page_request_id,
-        security_origin.GetURL(), user_gesture, request_type, "", "",
+        salt_and_origin.origin.GetURL(), user_gesture, request_type, "", "",
         audio_type_, video_type_, controls.disable_local_echo));
   }
 
@@ -357,13 +354,13 @@
       for (int i = MEDIA_NO_SERVICE + 1; i < NUM_MEDIA_TYPES; ++i) {
         media_observer->OnMediaRequestStateChanged(
             target_process_id_, target_frame_id_, page_request_id,
-            security_origin.GetURL(), static_cast<MediaStreamType>(i),
+            salt_and_origin.origin.GetURL(), static_cast<MediaStreamType>(i),
             new_state);
       }
     } else {
       media_observer->OnMediaRequestStateChanged(
           target_process_id_, target_frame_id_, page_request_id,
-          security_origin.GetURL(), stream_type, new_state);
+          salt_and_origin.origin.GetURL(), stream_type, new_state);
     }
   }
 
@@ -410,15 +407,13 @@
   // An ID the render frame provided to identify this request.
   const int page_request_id;
 
-  const url::Origin security_origin;
-
   const bool user_gesture;
 
   const MediaStreamRequestType request_type;
 
   const StreamControls controls;
 
-  const std::string salt;
+  const MediaDeviceSaltAndOrigin salt_and_origin;
 
   MediaStreamDevices devices;
 
@@ -588,9 +583,11 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   DeviceRequest* request = new DeviceRequest(
-      render_process_id, render_frame_id, page_request_id, security_origin,
-      false,  // user gesture
-      MEDIA_DEVICE_ACCESS, controls, std::string());
+      render_process_id, render_frame_id, page_request_id,
+      false /* user gesture */, MEDIA_DEVICE_ACCESS, controls,
+      MediaDeviceSaltAndOrigin{std::string() /* salt */,
+                               std::string() /* group_id_salt */,
+                               security_origin});
 
   const std::string& label = AddRequest(request);
 
@@ -609,20 +606,19 @@
 void MediaStreamManager::GenerateStream(
     int render_process_id,
     int render_frame_id,
-    const std::string& salt,
     int page_request_id,
     const StreamControls& controls,
-    const url::Origin& security_origin,
+    MediaDeviceSaltAndOrigin salt_and_origin,
     bool user_gesture,
     GenerateStreamCallback generate_stream_cb,
     DeviceStoppedCallback device_stopped_cb) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DVLOG(1) << "GenerateStream()";
 
-  DeviceRequest* request =
-      new DeviceRequest(render_process_id, render_frame_id, page_request_id,
-                        security_origin, user_gesture, MEDIA_GENERATE_STREAM,
-                        controls, salt, std::move(device_stopped_cb));
+  DeviceRequest* request = new DeviceRequest(
+      render_process_id, render_frame_id, page_request_id, user_gesture,
+      MEDIA_GENERATE_STREAM, controls, std::move(salt_and_origin),
+      std::move(device_stopped_cb));
 
   const std::string& label = AddRequest(request);
 
@@ -667,11 +663,11 @@
 
 void MediaStreamManager::CancelRequest(const std::string& label) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  DVLOG(1) << "CancelRequest({label = " << label <<  "})";
+  DVLOG(1) << "CancelRequest({label = " << label << "})";
   DeviceRequest* request = FindRequest(label);
   if (!request) {
     // The request does not exist.
-    LOG(ERROR) << "The request with label = " << label  << " does not exist.";
+    LOG(ERROR) << "The request with label = " << label << " does not exist.";
     return;
   }
 
@@ -790,7 +786,7 @@
 
 void MediaStreamManager::CloseDevice(MediaStreamType type, int session_id) {
   DVLOG(1) << "CloseDevice("
-           << "{type = " << type <<  "} "
+           << "{type = " << type << "} "
            << "{session_id = " << session_id << "})";
   GetDeviceManager(type)->Close(session_id);
 
@@ -808,17 +804,16 @@
 
 void MediaStreamManager::OpenDevice(int render_process_id,
                                     int render_frame_id,
-                                    const std::string& salt,
                                     int page_request_id,
                                     const std::string& device_id,
                                     MediaStreamType type,
-                                    const url::Origin& security_origin,
+                                    MediaDeviceSaltAndOrigin salt_and_origin,
                                     OpenDeviceCallback open_device_cb,
                                     DeviceStoppedCallback device_stopped_cb) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE ||
          type == MEDIA_DEVICE_VIDEO_CAPTURE);
-  DVLOG(1) << "OpenDevice ({page_request_id = " << page_request_id <<  "})";
+  DVLOG(1) << "OpenDevice ({page_request_id = " << page_request_id << "})";
   StreamControls controls;
   if (IsAudioInputMediaType(type)) {
     controls.audio.requested = true;
@@ -830,10 +825,9 @@
     NOTREACHED();
   }
   DeviceRequest* request = new DeviceRequest(
-      render_process_id, render_frame_id, page_request_id, security_origin,
-      false,  // user gesture
-      MEDIA_OPEN_DEVICE_PEPPER_ONLY, controls, salt,
-      std::move(device_stopped_cb));
+      render_process_id, render_frame_id, page_request_id,
+      false /* user gesture */, MEDIA_OPEN_DEVICE_PEPPER_ONLY, controls,
+      std::move(salt_and_origin), std::move(device_stopped_cb));
 
   const std::string& label = AddRequest(request);
 
@@ -887,7 +881,8 @@
     const DeviceRequest* request = labeled_request.second;
     for (const MediaStreamDevice& device : request->devices) {
       const std::string source_id = GetHMACForMediaDeviceID(
-          request->salt, request->security_origin, media_device_info.device_id);
+          request->salt_and_origin.device_id_salt,
+          request->salt_and_origin.origin, media_device_info.device_id);
       if (device.id == source_id && device.type == stream_type) {
         session_ids.push_back(device.session_id);
         if (request->device_stopped_cb) {
@@ -907,15 +902,16 @@
           .c_str());
 }
 
-bool MediaStreamManager::PickDeviceId(const std::string& salt,
-                                      const url::Origin& security_origin,
-                                      const TrackControls& controls,
-                                      const MediaDeviceInfoArray& devices,
-                                      std::string* device_id) const {
+bool MediaStreamManager::PickDeviceId(
+    const MediaDeviceSaltAndOrigin& salt_and_origin,
+    const TrackControls& controls,
+    const MediaDeviceInfoArray& devices,
+    std::string* device_id) const {
   if (controls.device_id.empty())
     return true;
 
-  if (!GetDeviceIDFromHMAC(salt, security_origin, controls.device_id, devices,
+  if (!GetDeviceIDFromHMAC(salt_and_origin.device_id_salt,
+                           salt_and_origin.origin, controls.device_id, devices,
                            device_id)) {
     LOG(WARNING) << "Invalid device ID = " << controls.device_id;
     return false;
@@ -929,11 +925,11 @@
     const MediaDeviceInfoArray& devices,
     std::string* device_id) const {
   if (type == MEDIA_DEVICE_AUDIO_CAPTURE) {
-    return PickDeviceId(request->salt, request->security_origin,
-                        request->controls.audio, devices, device_id);
+    return PickDeviceId(request->salt_and_origin, request->controls.audio,
+                        devices, device_id);
   } else if (type == MEDIA_DEVICE_VIDEO_CAPTURE) {
-    return PickDeviceId(request->salt, request->security_origin,
-                        request->controls.video, devices, device_id);
+    return PickDeviceId(request->salt_and_origin, request->controls.video,
+                        devices, device_id);
   } else {
     NOTREACHED();
   }
@@ -945,8 +941,14 @@
     MediaStreamDevice* device) {
   if (request->audio_type() == MEDIA_DEVICE_AUDIO_CAPTURE ||
       request->video_type() == MEDIA_DEVICE_VIDEO_CAPTURE) {
-    device->id = GetHMACForMediaDeviceID(request->salt,
-                                         request->security_origin, device->id);
+    device->id =
+        GetHMACForMediaDeviceID(request->salt_and_origin.device_id_salt,
+                                request->salt_and_origin.origin, device->id);
+    if (device->group_id) {
+      device->group_id = GetHMACForMediaDeviceID(
+          request->salt_and_origin.group_id_salt,
+          request->salt_and_origin.origin, *device->group_id);
+    }
   }
 }
 
@@ -992,8 +994,8 @@
   return unique_label;
 }
 
-MediaStreamManager::DeviceRequest*
-MediaStreamManager::FindRequest(const std::string& label) const {
+MediaStreamManager::DeviceRequest* MediaStreamManager::FindRequest(
+    const std::string& label) const {
   for (const LabeledDeviceRequest& labeled_request : requests_) {
     if (labeled_request.first == label)
       return labeled_request.second;
@@ -1101,17 +1103,13 @@
   const bool is_web_contents_capture = audio_type == MEDIA_TAB_AUDIO_CAPTURE ||
                                        video_type == MEDIA_TAB_VIDEO_CAPTURE;
   if (is_web_contents_capture && !SetupTabCaptureRequest(request)) {
-    FinalizeRequestFailed(label,
-                          request,
-                          MEDIA_DEVICE_TAB_CAPTURE_FAILURE);
+    FinalizeRequestFailed(label, request, MEDIA_DEVICE_TAB_CAPTURE_FAILURE);
     return;
   }
 
   const bool is_screen_capture = video_type == MEDIA_DESKTOP_VIDEO_CAPTURE;
   if (is_screen_capture && !SetupScreenCaptureRequest(request)) {
-    FinalizeRequestFailed(label,
-                          request,
-                          MEDIA_DEVICE_SCREEN_CAPTURE_FAILURE);
+    FinalizeRequestFailed(label, request, MEDIA_DEVICE_SCREEN_CAPTURE_FAILURE);
     return;
   }
 
@@ -1251,7 +1249,8 @@
   DCHECK(existing_request_state);
 
   std::string source_id = GetHMACForMediaDeviceID(
-      new_request.salt, new_request.security_origin, new_device.id);
+      new_request.salt_and_origin.device_id_salt,
+      new_request.salt_and_origin.origin, new_device.id);
 
   for (const LabeledDeviceRequest& labeled_request : requests_) {
     const DeviceRequest* request = labeled_request.second;
@@ -1393,7 +1392,7 @@
 void MediaStreamManager::Opened(MediaStreamType stream_type,
                                 int capture_session_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  DVLOG(1) << "Opened({stream_type = " << stream_type <<  "} "
+  DVLOG(1) << "Opened({stream_type = " << stream_type << "} "
            << "{capture_session_id = " << capture_session_id << "})";
 
   // Find the request(s) containing this device and mark it as used.
@@ -1441,7 +1440,7 @@
                                            DeviceRequest* request) {
   DCHECK(RequestDone(*request));
   DVLOG(1) << "HandleRequestDone("
-           << ", {label = " << label <<  "})";
+           << ", {label = " << label << "})";
 
   switch (request->request_type) {
     case MEDIA_OPEN_DEVICE_PEPPER_ONLY:
@@ -1497,7 +1496,7 @@
 void MediaStreamManager::Aborted(MediaStreamType stream_type,
                                  int capture_session_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  DVLOG(1) << "Aborted({stream_type = " << stream_type <<  "} "
+  DVLOG(1) << "Aborted({stream_type = " << stream_type << "} "
            << "{capture_session_id = " << capture_session_id << "})";
   StopDevice(stream_type, capture_session_id);
 }
@@ -1556,7 +1555,7 @@
     MediaStreamRequestResult result) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DVLOG(1) << "HandleAccessRequestResponse("
-           << ", {label = " << label <<  "})";
+           << ", {label = " << label << "})";
 
   DeviceRequest* request = FindRequest(label);
   if (!request) {
@@ -1863,9 +1862,10 @@
     MediaStreamType stream_type,
     const MediaDeviceInfoArray& device_infos) {
   MediaStreamDevices devices;
-  for (const auto& info : device_infos)
+  for (const auto& info : device_infos) {
     devices.emplace_back(stream_type, info.device_id, info.label,
-                         info.video_facing);
+                         info.video_facing, info.group_id);
+  }
 
   if (stream_type != MEDIA_DEVICE_VIDEO_CAPTURE)
     return devices;
diff --git a/content/browser/renderer_host/media/media_stream_manager.h b/content/browser/renderer_host/media/media_stream_manager.h
index ef6e727c..4199262 100644
--- a/content/browser/renderer_host/media/media_stream_manager.h
+++ b/content/browser/renderer_host/media/media_stream_manager.h
@@ -42,6 +42,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/threading/thread.h"
 #include "build/build_config.h"
+#include "content/browser/media/media_devices_util.h"
 #include "content/browser/renderer_host/media/media_devices_manager.h"
 #include "content/browser/renderer_host/media/media_stream_provider.h"
 #include "content/common/content_export.h"
@@ -159,10 +160,9 @@
   // is set to receive device stopped notifications.
   void GenerateStream(int render_process_id,
                       int render_frame_id,
-                      const std::string& salt,
                       int page_request_id,
                       const StreamControls& controls,
-                      const url::Origin& security_origin,
+                      MediaDeviceSaltAndOrigin salt_and_origin,
                       bool user_gesture,
                       GenerateStreamCallback generate_stream_cb,
                       DeviceStoppedCallback device_stopped_cb);
@@ -191,11 +191,10 @@
   // request is identified using string returned to the caller.
   void OpenDevice(int render_process_id,
                   int render_frame_id,
-                  const std::string& salt,
                   int page_request_id,
                   const std::string& device_id,
                   MediaStreamType type,
-                  const url::Origin& security_origin,
+                  MediaDeviceSaltAndOrigin salt_and_origin,
                   OpenDeviceCallback open_device_cb,
                   DeviceStoppedCallback device_stopped_cb);
 
@@ -322,8 +321,7 @@
   // Helpers.
   // Checks if all devices that was requested in the request identififed by
   // |label| has been opened and set the request state accordingly.
-  void HandleRequestDone(const std::string& label,
-                         DeviceRequest* request);
+  void HandleRequestDone(const std::string& label, DeviceRequest* request);
   // Stop the use of the device associated with |session_id| of type |type| in
   // all |requests_|. The device is removed from the request. If a request
   /// doesn't use any devices as a consequence, the request is deleted.
@@ -394,8 +392,7 @@
   // valid alternate device ID.
   // Returns false if the required device ID is present and invalid.
   // Otherwise, if no valid device is found, device_id is unchanged.
-  bool PickDeviceId(const std::string& salt,
-                    const url::Origin& security_origin,
+  bool PickDeviceId(const MediaDeviceSaltAndOrigin& salt_and_origin,
                     const TrackControls& controls,
                     const MediaDeviceInfoArray& devices,
                     std::string* device_id) const;
@@ -417,7 +414,8 @@
                                gfx::NativeViewId window_id);
 
   // Runs on the IO thread and does the actual [un]registration of callbacks.
-  void DoNativeLogCallbackRegistration(int renderer_host_id,
+  void DoNativeLogCallbackRegistration(
+      int renderer_host_id,
       const base::Callback<void(const std::string&)>& callback);
   void DoNativeLogCallbackUnregistration(int renderer_host_id);
 
diff --git a/content/browser/renderer_host/media/video_capture_browsertest.cc b/content/browser/renderer_host/media/video_capture_browsertest.cc
index d349b879..3459db6 100644
--- a/content/browser/renderer_host/media/video_capture_browsertest.cc
+++ b/content/browser/renderer_host/media/video_capture_browsertest.cc
@@ -40,10 +40,6 @@
                     media::mojom::VideoBufferHandlePtr* buffer_handle,
                     int length,
                     int buffer_id));
-  MOCK_METHOD3(DoOnNewMailboxHolderBufferHandle,
-               void(VideoCaptureControllerID id,
-                    int buffer_id,
-                    media::mojom::MailboxVideoFrameDataPtr* texture_handles));
   MOCK_METHOD2(OnBufferDestroyed,
                void(VideoCaptureControllerID, int buffer_id));
   MOCK_METHOD3(OnBufferReady,
diff --git a/content/browser/renderer_host/media/video_capture_unittest.cc b/content/browser/renderer_host/media/video_capture_unittest.cc
index a909dd3..6cebba5 100644
--- a/content/browser/renderer_host/media/video_capture_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_unittest.cc
@@ -153,10 +153,11 @@
     {
       base::RunLoop run_loop;
       media_stream_manager_->OpenDevice(
-          render_process_id, render_frame_id,
-          browser_context_.GetMediaDeviceIDSalt(), page_request_id,
+          render_process_id, render_frame_id, page_request_id,
           video_devices[0].device_id, MEDIA_DEVICE_VIDEO_CAPTURE,
-          security_origin,
+          MediaDeviceSaltAndOrigin{browser_context_.GetMediaDeviceIDSalt(),
+                                   browser_context_.GetMediaDeviceIDSalt(),
+                                   security_origin},
           base::BindOnce(&VideoCaptureTest::OnDeviceOpened,
                          base::Unretained(this), run_loop.QuitClosure()),
           MediaStreamManager::DeviceStoppedCallback());
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
index fc9228f..7f78f8e3 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.cc
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
@@ -956,6 +956,19 @@
 
 InputEventAckState RenderWidgetHostViewChildFrame::FilterInputEvent(
     const blink::WebInputEvent& input_event) {
+  // A child renderer should not receive touchscreen pinch events. Ideally, we
+  // would DCHECK this, but since touchscreen pinch events may be targeted to
+  // a child in order to have the child's TouchActionFilter filter them, we
+  // may encounter https://crbug.com/771330 which would let the pinch events
+  // through.
+  if (blink::WebInputEvent::IsPinchGestureEventType(input_event.GetType())) {
+    const blink::WebGestureEvent& gesture_event =
+        static_cast<const blink::WebGestureEvent&>(input_event);
+    if (gesture_event.SourceDevice() == blink::kWebGestureDeviceTouchscreen) {
+      return INPUT_EVENT_ACK_STATE_CONSUMED;
+    }
+  }
+
   if (input_event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
     const blink::WebGestureEvent& gesture_event =
         static_cast<const blink::WebGestureEvent&>(input_event);
diff --git a/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
index 7e9fab6..e9bef08 100644
--- a/content/browser/renderer_host/render_widget_host_view_event_handler.cc
+++ b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
@@ -437,9 +437,10 @@
     gesture_event.SetPositionInWidget(event->location_f());
     blink::WebMouseWheelEvent mouse_wheel_event = ui::MakeWebMouseWheelEvent(
         *event, base::Bind(&GetScreenLocationFromEvent));
-    if (host_view_->wheel_scroll_latching_enabled())
+    if (host_view_->wheel_scroll_latching_enabled()) {
       mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
           mouse_wheel_event, should_route_event);
+    }
     if (should_route_event) {
       host_->delegate()->GetInputEventRouter()->RouteGestureEvent(
           host_view_, &gesture_event,
@@ -563,7 +564,6 @@
 
   if (gesture.GetType() != blink::WebInputEvent::kUndefined) {
     if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN) {
-      RecordAction(base::UserMetricsAction("TouchscreenScroll"));
       // If there is a current scroll going on and a new scroll that isn't
       // wheel based send a synthetic wheel event with kPhaseEnded to cancel
       // the current scroll.
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc
index 0402edb..27ab30f 100644
--- a/content/browser/site_per_process_hit_test_browsertest.cc
+++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -3024,6 +3024,12 @@
 
 IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
                        InputEventRouterTouchpadGestureTargetTest) {
+  // TODO(838835): Flaky with viz hit testing
+  if (features::IsVizHitTestingEnabled()) {
+    LOG(INFO) << "Skipping test due to https://crbug.com/838835";
+    return;
+  }
+
   GURL main_url(embedded_test_server()->GetURL(
       "/frame_tree/page_with_positioned_nested_frames.html"));
   EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -3570,6 +3576,7 @@
         ui::ET_GESTURE_SCROLL_BEGIN);
     gesture_scroll_begin_details.set_device_type(
         ui::GestureDeviceType::DEVICE_TOUCHSCREEN);
+    gesture_scroll_begin_details.set_touch_points(2);
     ui::GestureEvent gesture_scroll_begin(
         position.x(), position.y(), 0, ui::EventTimeForNow(),
         gesture_scroll_begin_details, touch_pressed.unique_event_id());
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 4e33ec3f..78cd421 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -517,6 +517,8 @@
           BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode()),
       audio_stream_monitor_(this),
       bluetooth_connected_device_count_(0),
+      media_device_group_id_salt_base_(
+          BrowserContext::CreateRandomMediaDeviceIDSalt()),
 #if !defined(OS_ANDROID)
       page_scale_factor_is_one_(true),
 #endif  // !defined(OS_ANDROID)
@@ -1247,6 +1249,10 @@
   return page_importance_signals_;
 }
 
+const std::string& WebContentsImpl::GetMediaDeviceGroupIDSaltBase() const {
+  return media_device_group_id_salt_base_;
+}
+
 const base::string16& WebContentsImpl::GetTitle() const {
   // Transient entries take precedence. They are used for interstitial pages
   // that are shown on top of existing pages.
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index c67cef50..cedc6d0 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -945,6 +945,10 @@
                                  const gfx::RectF& active_rect);
 #endif
 
+  // Returns a base salt used to generate group IDs for media-device
+  // enumerations.
+  const std::string& GetMediaDeviceGroupIDSaltBase() const;
+
  private:
   friend class WebContentsObserver;
   friend class WebContents;  // To implement factory methods.
@@ -1671,6 +1675,8 @@
 
   PageImportanceSignals page_importance_signals_;
 
+  std::string media_device_group_id_salt_base_;
+
 #if !defined(OS_ANDROID)
   bool page_scale_factor_is_one_;
 #endif  // !defined(OS_ANDROID)
diff --git a/content/common/media/media_devices.cc b/content/common/media/media_devices.cc
index 90488d0..b2ed9e4 100644
--- a/content/common/media/media_devices.cc
+++ b/content/common/media/media_devices.cc
@@ -17,11 +17,12 @@
 
 MediaDeviceInfo::MediaDeviceInfo(const std::string& device_id,
                                  const std::string& label,
-                                 const std::string& group_id)
+                                 const std::string& group_id,
+                                 media::VideoFacingMode video_facing)
     : device_id(device_id),
       label(label),
       group_id(group_id),
-      video_facing(media::VideoFacingMode::MEDIA_VIDEO_FACING_NONE) {}
+      video_facing(video_facing) {}
 
 MediaDeviceInfo::MediaDeviceInfo(
     const media::AudioDeviceDescription& device_description)
@@ -44,9 +45,11 @@
 MediaDeviceInfo& MediaDeviceInfo::operator=(MediaDeviceInfo&& other) = default;
 
 bool operator==(const MediaDeviceInfo& first, const MediaDeviceInfo& second) {
-  return first.device_id == second.device_id && first.label == second.label &&
-         first.group_id == second.group_id &&
-         first.video_facing == second.video_facing;
+  // Do not use the |group_id| and |video_facing| fields for equality comparison
+  // since they are currently not fully supported by the video-capture layer.
+  // The modification of those fields by heuristics in upper layers does not
+  // result in a different device.
+  return first.device_id == second.device_id && first.label == second.label;
 }
 
 }  // namespace content
diff --git a/content/common/media/media_devices.h b/content/common/media/media_devices.h
index c0cd354..0e3de71 100644
--- a/content/common/media/media_devices.h
+++ b/content/common/media/media_devices.h
@@ -14,7 +14,7 @@
 namespace media {
 struct AudioDeviceDescription;
 struct VideoCaptureDeviceDescriptor;
-}
+}  // namespace media
 
 namespace content {
 
@@ -29,9 +29,11 @@
   MediaDeviceInfo();
   MediaDeviceInfo(const MediaDeviceInfo& other);
   MediaDeviceInfo(MediaDeviceInfo&& other);
-  MediaDeviceInfo(const std::string& device_id,
-                  const std::string& label,
-                  const std::string& group_id);
+  MediaDeviceInfo(
+      const std::string& device_id,
+      const std::string& label,
+      const std::string& group_id,
+      media::VideoFacingMode video_facing = media::MEDIA_VIDEO_FACING_NONE);
   explicit MediaDeviceInfo(const media::AudioDeviceDescription& description);
   explicit MediaDeviceInfo(
       const media::VideoCaptureDeviceDescriptor& descriptor);
diff --git a/content/common/media/media_stream_param_traits.h b/content/common/media/media_stream_param_traits.h
index 146f5cec..3b58a31 100644
--- a/content/common/media/media_stream_param_traits.h
+++ b/content/common/media/media_stream_param_traits.h
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 // IPC messages for the media streaming.
-// Multiply-included message file, hence no include guard.
+// no-include-guard-because-multiply-included
 
 #include "content/common/content_export.h"
 #include "content/public/common/media_stream_request.h"
@@ -23,6 +23,7 @@
 IPC_STRUCT_TRAITS_BEGIN(content::MediaStreamDevice)
   IPC_STRUCT_TRAITS_MEMBER(type)
   IPC_STRUCT_TRAITS_MEMBER(id)
+  IPC_STRUCT_TRAITS_MEMBER(group_id)
   IPC_STRUCT_TRAITS_MEMBER(video_facing)
   IPC_STRUCT_TRAITS_MEMBER(matched_output_device_id)
   IPC_STRUCT_TRAITS_MEMBER(name)
diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h
index 4fac6fa..b927be06 100644
--- a/content/public/browser/storage_partition.h
+++ b/content/public/browser/storage_partition.h
@@ -76,7 +76,12 @@
   virtual base::FilePath GetPath() = 0;
   virtual net::URLRequestContextGetter* GetURLRequestContext() = 0;
   virtual net::URLRequestContextGetter* GetMediaURLRequestContext() = 0;
+
+  // Returns a raw mojom::NetworkContext pointer. When network service crashes
+  // or restarts, the raw pointer will not be valid or safe to use. Therefore,
+  // caller should not hold onto this pointer beyond the same message loop task.
   virtual network::mojom::NetworkContext* GetNetworkContext() = 0;
+
   // Returns a pointer/info to a URLLoaderFactory/CookieManager owned by
   // the storage partition. Prefer to use this instead of creating a new
   // URLLoaderFactory when issuing requests from the Browser process, to
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index ae27ecd..df0ee20 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -313,7 +313,7 @@
 
 // Loading Dispatcher v0 support with ResourceLoadScheduler (crbug.com/729954).
 const base::Feature kResourceLoadScheduler{"ResourceLoadScheduler",
-                                           base::FEATURE_ENABLED_BY_DEFAULT};
+                                           base::FEATURE_DISABLED_BY_DEFAULT};
 
 // Use common overflow scroll mechanism for frames. See http://crbug.com/417782.
 const base::Feature kRootLayerScrolling{"RootLayerScrolling",
diff --git a/content/public/common/media_stream_request.cc b/content/public/common/media_stream_request.cc
index 032525de..2b666452 100644
--- a/content/public/common/media_stream_request.cc
+++ b/content/public/common/media_stream_request.cc
@@ -41,11 +41,17 @@
       video_facing(media::MEDIA_VIDEO_FACING_NONE),
       name(name) {}
 
-MediaStreamDevice::MediaStreamDevice(MediaStreamType type,
-                                     const std::string& id,
-                                     const std::string& name,
-                                     media::VideoFacingMode facing)
-    : type(type), id(id), video_facing(facing), name(name) {}
+MediaStreamDevice::MediaStreamDevice(
+    MediaStreamType type,
+    const std::string& id,
+    const std::string& name,
+    media::VideoFacingMode facing,
+    const base::Optional<std::string>& group_id)
+    : type(type),
+      id(id),
+      video_facing(facing),
+      group_id(group_id),
+      name(name) {}
 
 MediaStreamDevice::MediaStreamDevice(MediaStreamType type,
                                      const std::string& id,
diff --git a/content/public/common/media_stream_request.h b/content/public/common/media_stream_request.h
index fedfe072..9ea6103 100644
--- a/content/public/common/media_stream_request.h
+++ b/content/public/common/media_stream_request.h
@@ -91,10 +91,12 @@
                     const std::string& id,
                     const std::string& name);
 
-  MediaStreamDevice(MediaStreamType type,
-                    const std::string& id,
-                    const std::string& name,
-                    media::VideoFacingMode facing);
+  MediaStreamDevice(
+      MediaStreamType type,
+      const std::string& id,
+      const std::string& name,
+      media::VideoFacingMode facing,
+      const base::Optional<std::string>& group_id = base::nullopt);
 
   MediaStreamDevice(MediaStreamType type,
                     const std::string& id,
@@ -118,6 +120,9 @@
   // The facing mode for video capture device.
   media::VideoFacingMode video_facing;
 
+  // The device's group ID.
+  base::Optional<std::string> group_id;
+
   // The device id of a matched output device if any (otherwise empty).
   // Only applicable to audio devices.
   base::Optional<std::string> matched_output_device_id;
diff --git a/content/public/common/page_state.h b/content/public/common/page_state.h
index 6cf6c091..c630e6b 100644
--- a/content/public/common/page_state.h
+++ b/content/public/common/page_state.h
@@ -53,20 +53,18 @@
   PageState RemoveScrollOffset() const;
   PageState RemoveReferrer() const;
 
+  // Support DCHECK_EQ(a, b), etc.
+  bool operator==(const PageState& other) const { return this->Equals(other); }
+  bool operator!=(const PageState& other) const {
+    return !(this->Equals(other));
+  }
+
  private:
   PageState(const std::string& data);
 
   std::string data_;
 };
 
-// Support DCHECK_EQ(a, b), etc.
-inline bool operator==(const PageState& a, const PageState& b) {
-  return a.Equals(b);
-}
-inline bool operator!=(const PageState& a, const PageState& b) {
-  return !(a == b);
-}
-
 }  // namespace content
 
 #endif  // CONTENT_PUBLIC_COMMON_PAGE_STATE_H_
diff --git a/content/renderer/media/stream/media_stream_audio_source.cc b/content/renderer/media/stream/media_stream_audio_source.cc
index b11dd24..8ceda6c 100644
--- a/content/renderer/media/stream/media_stream_audio_source.cc
+++ b/content/renderer/media/stream/media_stream_audio_source.cc
@@ -168,4 +168,8 @@
                                         GetWeakPtr(), muted_state));
 }
 
+base::SingleThreadTaskRunner* MediaStreamAudioSource::GetTaskRunner() const {
+  return task_runner_.get();
+}
+
 }  // namespace content
diff --git a/content/renderer/media/stream/media_stream_audio_source.h b/content/renderer/media/stream/media_stream_audio_source.h
index c8f1a87..cc55c32 100644
--- a/content/renderer/media/stream/media_stream_audio_source.h
+++ b/content/renderer/media/stream/media_stream_audio_source.h
@@ -142,6 +142,9 @@
   // Sets muted state and notifies it to all registered tracks.
   void SetMutedState(bool state);
 
+  // Gets the TaskRunner for the main thread, for subclasses that need it.
+  base::SingleThreadTaskRunner* GetTaskRunner() const;
+
  private:
   // MediaStreamSource override.
   void DoStopSource() final;
diff --git a/content/renderer/media/stream/processed_local_audio_source.cc b/content/renderer/media/stream/processed_local_audio_source.cc
index c289f62..5496f9a 100644
--- a/content/renderer/media/stream/processed_local_audio_source.cc
+++ b/content/renderer/media/stream/processed_local_audio_source.cc
@@ -46,7 +46,8 @@
       audio_processing_properties_(audio_processing_properties),
       started_callback_(started_callback),
       volume_(0),
-      allow_invalid_render_frame_id_for_testing_(false) {
+      allow_invalid_render_frame_id_for_testing_(false),
+      weak_factory_(this) {
   DCHECK(pc_factory_);
   DVLOG(1) << "ProcessedLocalAudioSource::ProcessedLocalAudioSource()";
   SetDevice(device);
@@ -71,13 +72,10 @@
 }
 
 bool ProcessedLocalAudioSource::EnsureSourceIsStarted() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
 
-  {
-    base::AutoLock auto_lock(source_lock_);
-    if (source_)
-      return true;
-  }
+  if (source_)
+    return true;
 
   // Sanity-check that the consuming RenderFrame still exists. This is required
   // to initialize the audio source.
@@ -206,10 +204,7 @@
   new_source->Initialize(params, this);
   // We need to set the AGC control before starting the stream.
   new_source->SetAutomaticGainControl(true);
-  {
-    base::AutoLock auto_lock(source_lock_);
-    source_ = std::move(new_source);
-  }
+  source_ = std::move(new_source);
   source_->Start();
 
   // Register this source with the WebRtcAudioDeviceImpl.
@@ -219,15 +214,12 @@
 }
 
 void ProcessedLocalAudioSource::EnsureSourceIsStopped() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
 
-  scoped_refptr<media::AudioCapturerSource> source_to_stop;
-  {
-    base::AutoLock auto_lock(source_lock_);
-    if (!source_)
-      return;
-    source_to_stop = std::move(source_);
-  }
+  if (!source_)
+    return;
+
+  scoped_refptr<media::AudioCapturerSource> source_to_stop(std::move(source_));
 
   if (WebRtcAudioDeviceImpl* rtc_audio_device =
       pc_factory_->GetWebRtcAudioDevice()) {
@@ -246,21 +238,9 @@
 void ProcessedLocalAudioSource::SetVolume(int volume) {
   DVLOG(1) << "ProcessedLocalAudioSource::SetVolume()";
   DCHECK_LE(volume, MaxVolume());
-
   const double normalized_volume = static_cast<double>(volume) / MaxVolume();
-
-  // Hold a strong reference to |source_| while its SetVolume() method is
-  // called. This will prevent the object from being destroyed on another thread
-  // in the meantime. It's possible the |source_| will be stopped on another
-  // thread while calling SetVolume() here; but this is safe: The operation will
-  // simply be ignored.
-  scoped_refptr<media::AudioCapturerSource> maybe_source;
-  {
-    base::AutoLock auto_lock(source_lock_);
-    maybe_source = source_;
-  }
-  if (maybe_source)
-    maybe_source->SetVolume(normalized_volume);
+  if (source_)
+    source_->SetVolume(normalized_volume);
 }
 
 int ProcessedLocalAudioSource::Volume() const {
@@ -346,8 +326,9 @@
                         reference_clock_snapshot - processed_data_audio_delay);
 
     if (new_volume) {
-      SetVolume(new_volume);
-
+      GetTaskRunner()->PostTask(
+          FROM_HERE, base::BindOnce(&ProcessedLocalAudioSource::SetVolume,
+                                    weak_factory_.GetWeakPtr(), new_volume));
       // Update the |current_volume| to avoid passing the old volume to AGC.
       current_volume = new_volume;
     }
@@ -369,7 +350,7 @@
 }
 
 int ProcessedLocalAudioSource::GetBufferSize(int sample_rate) const {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK(GetTaskRunner()->BelongsToCurrentThread());
 #if defined(OS_ANDROID)
   // TODO(henrika): Re-evaluate whether to use same logic as other platforms.
   // http://crbug.com/638081
diff --git a/content/renderer/media/stream/processed_local_audio_source.h b/content/renderer/media/stream/processed_local_audio_source.h
index 149c1d7d..608179a 100644
--- a/content/renderer/media/stream/processed_local_audio_source.h
+++ b/content/renderer/media/stream/processed_local_audio_source.h
@@ -110,10 +110,6 @@
 
   PeerConnectionDependencyFactory* const pc_factory_;
 
-  // In debug builds, check that all methods that could cause object graph
-  // or data flow changes are being called on the main thread.
-  base::ThreadChecker thread_checker_;
-
   AudioProcessingProperties audio_processing_properties_;
 
   // Callback that's called when the audio source has been initialized.
@@ -126,9 +122,6 @@
   // The device created by the AudioDeviceFactory in EnsureSourceIsStarted().
   scoped_refptr<media::AudioCapturerSource> source_;
 
-  // Lock used to ensure thread-safe access to |source_| by SetVolume().
-  mutable base::Lock source_lock_;
-
   // Stores latest microphone volume received in a CaptureData() callback.
   // Range is [0, 255].
   base::subtle::Atomic32 volume_;
@@ -138,6 +131,9 @@
 
   bool allow_invalid_render_frame_id_for_testing_;
 
+  // Provides weak pointers for tasks posted by this instance.
+  base::WeakPtrFactory<ProcessedLocalAudioSource> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(ProcessedLocalAudioSource);
 };
 
diff --git a/content/renderer/media/stream/user_media_processor.cc b/content/renderer/media/stream/user_media_processor.cc
index 2a5c2ad..cc173a1 100644
--- a/content/renderer/media/stream/user_media_processor.cc
+++ b/content/renderer/media/stream/user_media_processor.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <algorithm>
+#include <map>
 #include <utility>
 
 #include "base/location.h"
@@ -1158,6 +1159,8 @@
   source.Initialize(blink::WebString::FromUTF8(device.id), type,
                     blink::WebString::FromUTF8(device.name),
                     false /* remote */);
+  if (device.group_id)
+    source.SetGroupId(blink::WebString::FromUTF8(*device.group_id));
 
   DVLOG(1) << "Initialize source object :"
            << "id = " << source.Id().Utf8()
diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc
index 7232a078..d5c5d83 100644
--- a/content/renderer/media/video_capture_impl.cc
+++ b/content/renderer/media/video_capture_impl.cc
@@ -77,10 +77,10 @@
   }
 
   void InitializeFromMailbox(
-      media::mojom::MailboxVideoFrameDataPtr mailbox_data) {
+      media::mojom::MailboxBufferHandleSetPtr mailbox_handles) {
     DCHECK_EQ(media::VideoFrame::kMaxPlanes,
-              mailbox_data->mailbox_holder.size());
-    mailbox_holders_ = std::move(mailbox_data->mailbox_holder);
+              mailbox_handles->mailbox_holder.size());
+    mailbox_holders_ = std::move(mailbox_handles->mailbox_holder);
   }
 
   friend class base::RefCountedThreadSafe<BufferContext>;
diff --git a/content/test/data/navigation_controller/reload-with-url-anchor.html b/content/test/data/navigation_controller/reload-with-url-anchor.html
index 36bcaec8..9335bac 100644
--- a/content/test/data/navigation_controller/reload-with-url-anchor.html
+++ b/content/test/data/navigation_controller/reload-with-url-anchor.html
@@ -1,18 +1,19 @@
 <!DOCTYPE html>
 
 <style>
-div {
-  height: 100px;
-}
-
-#div {
-  overflow-y: scroll;
-}
+  body {
+    margin:0;
+  }
+  .big_space {
+    height: 2000px;
+    background-color:gray;
+  }
 </style>
 
-<div id='div'>
-  <div>d1</div>
-  <div id='d2'>d2</div>
+<div class="big_space"></div>
+
+<div id='center-element'>
+  The 'center-element'.
 </div>
 
-<p style="position: absolute; top: 2000px">End of page.</p>
+<div class="big_space"></div>
diff --git a/extensions/common/api/declarative_net_request/test_utils.cc b/extensions/common/api/declarative_net_request/test_utils.cc
index be77366..77b7606 100644
--- a/extensions/common/api/declarative_net_request/test_utils.cc
+++ b/extensions/common/api/declarative_net_request/test_utils.cc
@@ -156,9 +156,9 @@
   JSONFileValueSerializer(extension_dir.Append(json_rules_filepath))
       .Serialize(rules);
 
-  // Persists a background script if needed.
+  // Persists an empty background script if needed.
   if (has_background_script) {
-    std::string content = "chrome.test.sendMessage('ready');";
+    std::string content;
     CHECK_EQ(static_cast<int>(content.length()),
              base::WriteFile(extension_dir.Append(kBackgroundScriptFilepath),
                              content.c_str(), content.length()));
diff --git a/extensions/common/api/declarative_net_request/test_utils.h b/extensions/common/api/declarative_net_request/test_utils.h
index 877e086..46610ca 100644
--- a/extensions/common/api/declarative_net_request/test_utils.h
+++ b/extensions/common/api/declarative_net_request/test_utils.h
@@ -84,10 +84,8 @@
 
 // Writes the declarative |rules| in the given |extension_dir| together with the
 // manifest file. |hosts| specifies the host permissions, the extensions should
-// have. If |has_background_script| is true, a background script
-// ("background.js") will also be persisted for the extension. Clients can
-// listen in to the "ready" message from the background page to detect its
-// loading.
+// have. If |has_background_script| is true, an empty background script
+// ("background.js") will also be persisted for the extension.
 void WriteManifestAndRuleset(
     const base::FilePath& extension_dir,
     const base::FilePath::CharType* json_rules_filepath,
diff --git a/extensions/shell/browser/shell_content_browser_client.cc b/extensions/shell/browser/shell_content_browser_client.cc
index 99222f8..62cc188 100644
--- a/extensions/shell/browser/shell_content_browser_client.cc
+++ b/extensions/shell/browser/shell_content_browser_client.cc
@@ -109,10 +109,8 @@
   // the concept of disabled plugins.
 #if BUILDFLAG(ENABLE_NACL)
   host->AddFilter(new nacl::NaClHostMessageFilter(
-      render_process_id,
-      browser_context->IsOffTheRecord(),
-      browser_context->GetPath(),
-      host->GetStoragePartition()->GetURLRequestContext()));
+      render_process_id, browser_context->IsOffTheRecord(),
+      browser_context->GetPath()));
 #endif
 }
 
diff --git a/extensions/test/extension_test_message_listener.cc b/extensions/test/extension_test_message_listener.cc
index 20167d5..6119574 100644
--- a/extensions/test/extension_test_message_listener.cc
+++ b/extensions/test/extension_test_message_listener.cc
@@ -76,7 +76,6 @@
   satisfied_ = false;
   failed_ = false;
   message_.clear();
-  extension_id_for_message_.clear();
   replied_ = false;
 }
 
@@ -90,19 +89,13 @@
   // extension.
   extensions::TestSendMessageFunction* function =
       content::Source<extensions::TestSendMessageFunction>(source).ptr();
-
-  std::string sender_extension_id;
-  if (function->extension())
-    sender_extension_id = function->extension_id();
-
   if (satisfied_ ||
-      (!extension_id_.empty() && sender_extension_id != extension_id_)) {
+      (!extension_id_.empty() && function->extension_id() != extension_id_)) {
     return;
   }
 
   // We should have an empty message if we're not already satisfied.
   CHECK(message_.empty());
-  CHECK(extension_id_for_message_.empty());
 
   std::pair<std::string, bool*>* message_details =
       content::Details<std::pair<std::string, bool*>>(details).ptr();
@@ -113,7 +106,6 @@
     // empty string.
     *message_details->second = true;
     message_ = message;
-    extension_id_for_message_ = sender_extension_id;
     satisfied_ = true;
     failed_ = (message_ == failure_message_);
 
diff --git a/extensions/test/extension_test_message_listener.h b/extensions/test/extension_test_message_listener.h
index 4a72800..596632b9 100644
--- a/extensions/test/extension_test_message_listener.h
+++ b/extensions/test/extension_test_message_listener.h
@@ -11,7 +11,6 @@
 #include "base/memory/ref_counted.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "extensions/common/extension_id.h"
 
 namespace extensions {
 class TestSendMessageFunction;
@@ -95,8 +94,7 @@
   ~ExtensionTestMessageListener() override;
 
   // This returns true immediately if we've already gotten the expected
-  // message, or waits until it arrives. Once this returns true, message() and
-  // extension_id_for_message() accessors can be used.
+  // message, or waits until it arrives.
   // Returns false if the wait is interrupted and we still haven't gotten the
   // message, or if the message was equal to |failure_message_|.
   bool WaitUntilSatisfied() WARN_UNUSED_RESULT;
@@ -129,10 +127,6 @@
 
   const std::string& message() const { return message_; }
 
-  const extensions::ExtensionId& extension_id_for_message() const {
-    return extension_id_for_message_;
-  }
-
  private:
   // Implements the content::NotificationObserver interface.
   void Observe(int type,
@@ -173,9 +167,6 @@
   // If we received a message that was the failure message.
   bool failed_;
 
-  // The extension id from which |message_| was received.
-  extensions::ExtensionId extension_id_for_message_;
-
   // The function we need to reply to.
   scoped_refptr<extensions::TestSendMessageFunction> function_;
 };
diff --git a/headless/OWNERS b/headless/OWNERS
index 1511b85..ad64e8d 100644
--- a/headless/OWNERS
+++ b/headless/OWNERS
@@ -1,9 +1,9 @@
 skyostil@chromium.org
 alexclarke@chromium.org
-altimin@chromium.org
 eseckler@chromium.org
 
 # Emeritus:
+altimin@chromium.org
 dvallet@chromium.org
 irisu@chromium.org
 jzfeng@chromium.org
diff --git a/ios/chrome/browser/signin/ios_chrome_signin_client.mm b/ios/chrome/browser/signin/ios_chrome_signin_client.mm
index 0b70b05..682a6ea 100644
--- a/ios/chrome/browser/signin/ios_chrome_signin_client.mm
+++ b/ios/chrome/browser/signin/ios_chrome_signin_client.mm
@@ -6,8 +6,8 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "components/metrics/metrics_service.h"
+#include "components/signin/core/browser/cookie_settings_util.h"
 #include "components/signin/core/browser/signin_cookie_change_subscription.h"
-#include "components/signin/core/browser/signin_header_helper.h"
 #include "components/signin/ios/browser/account_consistency_service.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/browser_state/browser_state_info_cache.h"
diff --git a/ios/chrome/browser/ui/authentication/BUILD.gn b/ios/chrome/browser/ui/authentication/BUILD.gn
index 6633094b..f14f7c1 100644
--- a/ios/chrome/browser/ui/authentication/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/BUILD.gn
@@ -16,8 +16,6 @@
     "authentication_ui_util.mm",
     "chrome_signin_view_controller.h",
     "chrome_signin_view_controller.mm",
-    "identity_picker_view.h",
-    "identity_picker_view.mm",
     "re_signin_infobar_delegate.h",
     "re_signin_infobar_delegate.mm",
     "resized_avatar_cache.h",
@@ -30,18 +28,12 @@
     "signin_confirmation_view_controller.mm",
     "signin_promo_view_mediator.h",
     "signin_promo_view_mediator.mm",
-    "unified_consent_coordinator.h",
-    "unified_consent_coordinator.mm",
-    "unified_consent_mediator.h",
-    "unified_consent_mediator.mm",
-    "unified_consent_view_controller.h",
-    "unified_consent_view_controller.mm",
   ]
   deps = [
     ":authentication_ui",
-    "resources:identity_picker_view_arrow_down",
     "resources:signin_confirmation_more",
     "resources:signin_promo_close_gray",
+    "unified_consent",
     "//base",
     "//components/consent_auditor",
     "//components/google/core/browser",
@@ -52,10 +44,8 @@
     "//components/strings",
     "//google_apis",
     "//ios/chrome/app/strings",
-    "//ios/chrome/app/theme",
     "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state",
-    "//ios/chrome/browser/browsing_data",
     "//ios/chrome/browser/consent_auditor",
     "//ios/chrome/browser/infobars",
     "//ios/chrome/browser/signin",
@@ -73,7 +63,6 @@
     "//ios/public/provider/chrome/browser/images",
     "//ios/public/provider/chrome/browser/signin",
     "//ios/third_party/material_components_ios",
-    "//ios/third_party/material_roboto_font_loader_ios",
     "//ui/base",
     "//ui/gfx",
     "//url",
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
index 97856315..23226f6 100644
--- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
@@ -37,7 +37,7 @@
 #import "ios/chrome/browser/ui/authentication/authentication_ui_util.h"
 #include "ios/chrome/browser/ui/authentication/signin_account_selector_view_controller.h"
 #include "ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.h"
-#include "ios/chrome/browser/ui/authentication/unified_consent_coordinator.h"
+#include "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/rtl_geometry.h"
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller_unittest.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller_unittest.mm
index ff8e2ee..9d4dcc1f 100644
--- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller_unittest.mm
@@ -4,6 +4,7 @@
 
 #include "ios/chrome/browser/ui/authentication/chrome_signin_view_controller.h"
 
+#include "base/mac/foundation_util.h"
 #include "base/memory/ptr_util.h"
 #import "base/strings/sys_string_conversions.h"
 #import "base/test/ios/wait_util.h"
@@ -308,44 +309,80 @@
     return IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OPEN_SETTINGS;
   }
 
-  bool IsMoreButtonVisible() {
-    UIButton* primary_button = vc_.primaryButton;
-    NSString* primary_title = primary_button.currentTitle;
-    BOOL is_more_button =
-        [primary_title
-            caseInsensitiveCompare:
-                l10n_util::GetNSString(
-                    IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_SCROLL_BUTTON)] ==
-        NSOrderedSame;
-    return !primary_button.isHidden && is_more_button;
+  // Returns true if the primary button is visible and its tile is equal the
+  // |string_id| (case insensitive).
+  bool IsPrimaryButtonVisibleWithTitle(int string_id) {
+    if (vc_.primaryButton.isHidden)
+      return false;
+    NSString* primary_title = vc_.primaryButton.currentTitle;
+    return [primary_title
+               caseInsensitiveCompare:l10n_util::GetNSString(string_id)] ==
+           NSOrderedSame;
+  }
+
+  // Returns |view| if it is kind of UIScrollView or returns the UIScrollView-
+  // kind in the subviews (recursive search). At most one UIScrollView is
+  // expected.
+  UIScrollView* FindConsentScrollView(UIView* view) {
+    if ([view isKindOfClass:[UIScrollView class]])
+      return base::mac::ObjCCastStrict<UIScrollView>(view);
+    UIScrollView* found_scroll_view = nil;
+    for (UIView* subview in view.subviews) {
+      UIScrollView* scroll_view_from_subview = FindConsentScrollView(subview);
+      if (scroll_view_from_subview) {
+        EXPECT_EQ(nil, found_scroll_view);
+        found_scroll_view = scroll_view_from_subview;
+      }
+    }
+    return found_scroll_view;
+  }
+
+  // Scrolls to the bottom if needed and returns once the primary button is
+  // found with the confirmation title (based on ConfirmationStringId()).
+  // The scroll is done without animation. Otherwise, the scroll view doesn't
+  // scroll correctly inside testing::WaitUntilConditionOrTimeout().
+  void ScrollConsentViewToBottom() {
+    ConditionBlock condition = ^bool() {
+      if (IsPrimaryButtonVisibleWithTitle(
+              IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_SCROLL_BUTTON)) {
+        UIScrollView* consent_scroll_view = FindConsentScrollView(vc_.view);
+        CGPoint bottom_offset =
+            CGPointMake(0, consent_scroll_view.contentSize.height -
+                               consent_scroll_view.bounds.size.height +
+                               consent_scroll_view.contentInset.bottom);
+        [consent_scroll_view setContentOffset:bottom_offset animated:NO];
+      }
+      return IsPrimaryButtonVisibleWithTitle(ConfirmationStringId());
+    };
+    bool condition_met = testing::WaitUntilConditionOrTimeout(10, condition);
+    EXPECT_TRUE(condition_met);
   }
 
   // Waits until all expected strings are on the screen.
   void WaitAndExpectAllStringsOnScreen() {
-    __block NSSet<NSString*>* notFoundStrings = nil;
-    __block NSSet<NSString*>* notExpectedStrings = nil;
+    __block NSSet<NSString*>* not_found_strings = nil;
+    __block NSSet<NSString*>* not_expected_strings = nil;
+    // Make sure the consent view is scrolled to the button to show the
+    // confirmation button (instead of the "more" button).
+    ScrollConsentViewToBottom();
     ConditionBlock condition = ^bool() {
-      if (IsMoreButtonVisible()) {
-        [vc_.primaryButton
-            sendActionsForControlEvents:UIControlEventTouchUpInside];
-      }
-      NSSet<NSString*>* foundStrings = LocalizedStringOnScreen();
-      NSSet<NSString*>* expectedStrings = LocalizedExpectedStringsOnScreen();
-      notFoundStrings = [expectedStrings
+      NSSet<NSString*>* found_strings = LocalizedStringOnScreen();
+      NSSet<NSString*>* expected_strings = LocalizedExpectedStringsOnScreen();
+      not_found_strings = [expected_strings
           objectsPassingTest:^BOOL(NSString* string, BOOL* stop) {
-            return ![foundStrings containsObject:string];
+            return ![found_strings containsObject:string];
           }];
-      notExpectedStrings =
-          [foundStrings objectsPassingTest:^BOOL(NSString* string, BOOL* stop) {
-            return ![expectedStrings containsObject:string];
+      not_expected_strings = [found_strings
+          objectsPassingTest:^BOOL(NSString* string, BOOL* stop) {
+            return ![expected_strings containsObject:string];
           }];
-      return [foundStrings isEqual:expectedStrings];
+      return [found_strings isEqual:expected_strings];
     };
-    bool conditionMet = testing::WaitUntilConditionOrTimeout(10, condition);
+    bool condition_met = testing::WaitUntilConditionOrTimeout(10, condition);
     NSString* failureExplaination = [NSString
         stringWithFormat:@"Strings not found: %@, Strings not expected: %@",
-                         notFoundStrings, notExpectedStrings];
-    EXPECT_TRUE(conditionMet) << base::SysNSStringToUTF8(failureExplaination);
+                         not_found_strings, not_expected_strings];
+    EXPECT_TRUE(condition_met) << base::SysNSStringToUTF8(failureExplaination);
   }
 
   bool unified_consent_enabled_;
@@ -369,15 +406,13 @@
 // list defined in FakeConsentAuditor::ExpectedConsentStringIds()), or are part
 // of the white list strings defined in
 // FakeConsentAuditor::WhiteListLocalizedStrings().
-// TODO(crbug.com/839001): Reenable this test.
-TEST_F(ChromeSigninViewControllerTest, DISABLED_TestAllStrings) {
+TEST_P(ChromeSigninViewControllerTest, TestAllStrings) {
   WaitAndExpectAllStringsOnScreen();
 }
 
 // Tests when the user taps on "OK GOT IT", that RecordGaiaConsent() is called
 // with the expected list of string ids, and confirmation string id.
-// TODO(crbug.com/839001): Reenable this test.
-TEST_F(ChromeSigninViewControllerTest, DISABLED_TestConsentWithOKGOTIT) {
+TEST_P(ChromeSigninViewControllerTest, TestConsentWithOKGOTIT) {
   WaitAndExpectAllStringsOnScreen();
   [vc_.primaryButton sendActionsForControlEvents:UIControlEventTouchUpInside];
   ConditionBlock condition = ^bool() {
@@ -399,8 +434,7 @@
 }
 
 // Tests that RecordGaiaConsent() is not called when the user taps on UNDO.
-// TODO(crbug.com/839001): Reenable this test.
-TEST_F(ChromeSigninViewControllerTest, DISABLED_TestRefusingConsent) {
+TEST_P(ChromeSigninViewControllerTest, TestRefusingConsent) {
   WaitAndExpectAllStringsOnScreen();
   [vc_.secondaryButton sendActionsForControlEvents:UIControlEventTouchUpInside];
   const std::vector<int>& recorded_ids = fake_consent_auditor_->recorded_ids();
@@ -410,8 +444,7 @@
 
 // Tests that RecordGaiaConsent() is called with the expected list of string
 // ids, and settings confirmation string id.
-// TODO(crbug.com/839001): Reenable this test.
-TEST_F(ChromeSigninViewControllerTest, DISABLED_TestConsentWithSettings) {
+TEST_P(ChromeSigninViewControllerTest, TestConsentWithSettings) {
   WaitAndExpectAllStringsOnScreen();
   [vc_ signinConfirmationControllerDidTapSettingsLink:vc_.confirmationVC];
   const std::vector<int>& recorded_ids = fake_consent_auditor_->recorded_ids();
diff --git a/ios/chrome/browser/ui/authentication/resources/BUILD.gn b/ios/chrome/browser/ui/authentication/resources/BUILD.gn
index b5c7d333..02a9899 100644
--- a/ios/chrome/browser/ui/authentication/resources/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/resources/BUILD.gn
@@ -4,14 +4,6 @@
 
 import("//build/config/ios/asset_catalog.gni")
 
-imageset("identity_picker_view_arrow_down") {
-  sources = [
-    "identity_picker_view_arrow_down.imageset/Contents.json",
-    "identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down.png",
-    "identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@2x.png",
-    "identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@3x.png",
-  ]
-}
 imageset("signin_confirmation_more") {
   sources = [
     "signin_confirmation_more.imageset/Contents.json",
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/BUILD.gn b/ios/chrome/browser/ui/authentication/unified_consent/BUILD.gn
new file mode 100644
index 0000000..3179a17
--- /dev/null
+++ b/ios/chrome/browser/ui/authentication/unified_consent/BUILD.gn
@@ -0,0 +1,46 @@
+# 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("//build/config/chrome_build.gni")
+
+source_set("unified_consent") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [
+    "unified_consent_coordinator.h",
+    "unified_consent_coordinator.mm",
+    "unified_consent_mediator.h",
+    "unified_consent_mediator.mm",
+  ]
+  deps = [
+    ":unified_consent_ui",
+    "//base",
+    "//ios/chrome/browser",
+    "//ios/chrome/browser/signin",
+    "//ios/public/provider/chrome/browser/signin",
+  ]
+}
+
+source_set("unified_consent_ui") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [
+    "identity_picker_view.h",
+    "identity_picker_view.mm",
+    "unified_consent_view_controller.h",
+    "unified_consent_view_controller.mm",
+  ]
+  deps = [
+    "resources:identity_picker_view_arrow_down",
+    "//base",
+    "//components/google/core/browser",
+    "//ios/chrome/app/strings",
+    "//ios/chrome/browser",
+    "//ios/chrome/browser/ui:ui_util",
+    "//ios/chrome/browser/ui/colors",
+    "//ios/chrome/browser/ui/util",
+    "//ios/chrome/browser/ui/util:constraints_ui",
+    "//ios/chrome/common",
+    "//ios/third_party/material_components_ios",
+    "//ui/base",
+  ]
+}
diff --git a/ios/chrome/browser/ui/authentication/identity_picker_view.h b/ios/chrome/browser/ui/authentication/unified_consent/identity_picker_view.h
similarity index 79%
rename from ios/chrome/browser/ui/authentication/identity_picker_view.h
rename to ios/chrome/browser/ui/authentication/unified_consent/identity_picker_view.h
index e28f89b..9dda7ef 100644
--- a/ios/chrome/browser/ui/authentication/identity_picker_view.h
+++ b/ios/chrome/browser/ui/authentication/unified_consent/identity_picker_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 IOS_CHROME_BROWSER_UI_AUTHENTICATION_IDENTITY_PICKER_VIEW_H_
-#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_IDENTITY_PICKER_VIEW_H_
+#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_IDENTITY_PICKER_VIEW_H_
+#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_IDENTITY_PICKER_VIEW_H_
 
 #import <UIKit/UIKit.h>
 
@@ -28,4 +28,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_IDENTITY_PICKER_VIEW_H_
+#endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_IDENTITY_PICKER_VIEW_H_
diff --git a/ios/chrome/browser/ui/authentication/identity_picker_view.mm b/ios/chrome/browser/ui/authentication/unified_consent/identity_picker_view.mm
similarity index 98%
rename from ios/chrome/browser/ui/authentication/identity_picker_view.mm
rename to ios/chrome/browser/ui/authentication/unified_consent/identity_picker_view.mm
index c78c2e2..9e83887 100644
--- a/ios/chrome/browser/ui/authentication/identity_picker_view.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/identity_picker_view.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/authentication/identity_picker_view.h"
+#import "ios/chrome/browser/ui/authentication/unified_consent/identity_picker_view.h"
 
 #include "base/logging.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
diff --git a/ios/chrome/browser/ui/authentication/unified_consent/resources/BUILD.gn b/ios/chrome/browser/ui/authentication/unified_consent/resources/BUILD.gn
new file mode 100644
index 0000000..c5475c1
--- /dev/null
+++ b/ios/chrome/browser/ui/authentication/unified_consent/resources/BUILD.gn
@@ -0,0 +1,14 @@
+# 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("//build/config/ios/asset_catalog.gni")
+
+imageset("identity_picker_view_arrow_down") {
+  sources = [
+    "identity_picker_view_arrow_down.imageset/Contents.json",
+    "identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down.png",
+    "identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@2x.png",
+    "identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@3x.png",
+  ]
+}
diff --git a/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/Contents.json b/ios/chrome/browser/ui/authentication/unified_consent/resources/identity_picker_view_arrow_down.imageset/Contents.json
similarity index 100%
rename from ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/Contents.json
rename to ios/chrome/browser/ui/authentication/unified_consent/resources/identity_picker_view_arrow_down.imageset/Contents.json
diff --git a/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down.png b/ios/chrome/browser/ui/authentication/unified_consent/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down.png
similarity index 100%
rename from ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down.png
rename to ios/chrome/browser/ui/authentication/unified_consent/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down.png
Binary files differ
diff --git a/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@2x.png b/ios/chrome/browser/ui/authentication/unified_consent/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@2x.png
similarity index 100%
rename from ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@2x.png
rename to ios/chrome/browser/ui/authentication/unified_consent/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@3x.png b/ios/chrome/browser/ui/authentication/unified_consent/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@3x.png
similarity index 100%
rename from ios/chrome/browser/ui/authentication/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@3x.png
rename to ios/chrome/browser/ui/authentication/unified_consent/resources/identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/authentication/unified_consent_coordinator.h b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.h
similarity index 91%
rename from ios/chrome/browser/ui/authentication/unified_consent_coordinator.h
rename to ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.h
index 03ad87094..c11c1cf 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent_coordinator.h
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.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 IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_COORDINATOR_H_
-#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_COORDINATOR_H_
+#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_UNIFIED_CONSENT_COORDINATOR_H_
+#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_UNIFIED_CONSENT_COORDINATOR_H_
 
 #import <UIKit/UIKit.h>
 
@@ -60,4 +60,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_COORDINATOR_H_
+#endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_UNIFIED_CONSENT_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/authentication/unified_consent_coordinator.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.mm
similarity index 90%
rename from ios/chrome/browser/ui/authentication/unified_consent_coordinator.mm
rename to ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.mm
index 977ae48..1ea36a2 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent_coordinator.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.mm
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ios/chrome/browser/ui/authentication/unified_consent_coordinator.h"
+#include "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_coordinator.h"
 
 #include "base/logging.h"
-#import "ios/chrome/browser/ui/authentication/unified_consent_mediator.h"
-#import "ios/chrome/browser/ui/authentication/unified_consent_view_controller.h"
+#import "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.h"
+#import "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/chrome/browser/ui/authentication/unified_consent_mediator.h b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.h
similarity index 83%
rename from ios/chrome/browser/ui/authentication/unified_consent_mediator.h
rename to ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.h
index 24eb74c9..0df0ad61 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent_mediator.h
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.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 IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_MEDIATOR_H_
-#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_MEDIATOR_H_
+#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_UNIFIED_CONSENT_MEDIATOR_H_
+#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_UNIFIED_CONSENT_MEDIATOR_H_
 
 #import <Foundation/Foundation.h>
 
@@ -29,4 +29,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_MEDIATOR_H_
+#endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_UNIFIED_CONSENT_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/authentication/unified_consent_mediator.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm
similarity index 96%
rename from ios/chrome/browser/ui/authentication/unified_consent_mediator.mm
rename to ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm
index 40aea00..03a2644 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.mm
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ios/chrome/browser/ui/authentication/unified_consent_mediator.h"
+#include "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_mediator.h"
 
 #include "base/logging.h"
 #import "ios/chrome/browser/chrome_browser_provider_observer_bridge.h"
 #import "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h"
-#include "ios/chrome/browser/ui/authentication/unified_consent_view_controller.h"
+#include "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.h"
 #import "ios/public/provider/chrome/browser/signin/chrome_identity.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/authentication/unified_consent_view_controller.h b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.h
similarity index 91%
rename from ios/chrome/browser/ui/authentication/unified_consent_view_controller.h
rename to ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.h
index b5291932..6d1816b 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent_view_controller.h
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.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 IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_VIEW_CONTROLLER_H_
-#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_VIEW_CONTROLLER_H_
+#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_UNIFIED_CONSENT_VIEW_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_UNIFIED_CONSENT_VIEW_CONTROLLER_H_
 
 #import <UIKit/UIKit.h>
 
@@ -66,4 +66,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_VIEW_CONTROLLER_H_
+#endif  // IOS_CHROME_BROWSER_UI_AUTHENTICATION_UNIFIED_CONSENT_UNIFIED_CONSENT_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/authentication/unified_consent_view_controller.mm b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm
similarity index 98%
rename from ios/chrome/browser/ui/authentication/unified_consent_view_controller.mm
rename to ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm
index d2b5f58..6dba93a2 100644
--- a/ios/chrome/browser/ui/authentication/unified_consent_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.mm
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/ui/authentication/unified_consent_view_controller.h"
+#import "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_view_controller.h"
 
 #include "base/logging.h"
 #include "components/google/core/browser/google_util.h"
 #include "ios/chrome/browser/application_context.h"
-#import "ios/chrome/browser/ui/authentication/identity_picker_view.h"
+#import "ios/chrome/browser/ui/authentication/unified_consent/identity_picker_view.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/util/constraints_ui_util.h"
diff --git a/ios/third_party/material_components_ios/README.chromium b/ios/third_party/material_components_ios/README.chromium
index 33653483..5ad7ace 100644
--- a/ios/third_party/material_components_ios/README.chromium
+++ b/ios/third_party/material_components_ios/README.chromium
@@ -1,7 +1,7 @@
 Name: Material Components for iOS
 URL: https://github.com/material-components/material-components-ios
 Version: 0
-Revision: d7b1f39ad946be67cd6a83b6f9cd36b41f29a619
+Revision: 942163f2be5c76ca5c67f6449941a777f839c15a
 License: Apache 2.0
 License File: LICENSE
 Security Critical: yes
diff --git a/ios/web_view/internal/signin/ios_web_view_signin_client.mm b/ios/web_view/internal/signin/ios_web_view_signin_client.mm
index a847a6c..cd4db3b 100644
--- a/ios/web_view/internal/signin/ios_web_view_signin_client.mm
+++ b/ios/web_view/internal/signin/ios_web_view_signin_client.mm
@@ -4,8 +4,8 @@
 
 #include "ios/web_view/internal/signin/ios_web_view_signin_client.h"
 
+#include "components/signin/core/browser/cookie_settings_util.h"
 #include "components/signin/core/browser/signin_cookie_change_subscription.h"
-#include "components/signin/core/browser/signin_header_helper.h"
 #include "google_apis/gaia/gaia_auth_fetcher.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc
index 6b76f16..c46b9dd 100644
--- a/media/audio/mac/audio_manager_mac.cc
+++ b/media/audio/mac/audio_manager_mac.cc
@@ -144,6 +144,11 @@
     if (!label)
       continue;
 
+    // Filter out aggregate devices, e.g. those that get created by using
+    // kAudioUnitSubType_VoiceProcessingIO.
+    if (core_audio_mac::IsPrivateAggregateDevice(device_id))
+      continue;
+
     device_names->emplace_back(std::move(*label), std::move(*unique_id));
   }
 
@@ -639,9 +644,16 @@
     params.set_effects(AudioParameters::NOISE_SUPPRESSION);
   }
 
+  // VoiceProcessingIO is only supported on MacOS 10.12 and cannot be used on
+  // aggregate devices, since it creates an aggregate device itself.  It also
+  // only runs in mono, but we allow upmixing to stereo since we can't claim a
+  // device works either in stereo without echo cancellation or mono with echo
+  // cancellation.
   if (base::mac::IsAtLeastOS10_12() &&
       (params.channel_layout() == CHANNEL_LAYOUT_MONO ||
-       params.channel_layout() == CHANNEL_LAYOUT_STEREO)) {
+       params.channel_layout() == CHANNEL_LAYOUT_STEREO) &&
+      core_audio_mac::GetDeviceTransportType(device) !=
+          kAudioDeviceTransportTypeAggregate) {
     params.set_effects(params.effects() |
                        AudioParameters::EXPERIMENTAL_ECHO_CANCELLER);
   }
diff --git a/media/audio/mac/core_audio_util_mac.cc b/media/audio/mac/core_audio_util_mac.cc
index 52bfbfd1..249ea67 100644
--- a/media/audio/mac/core_audio_util_mac.cc
+++ b/media/audio/mac/core_audio_util_mac.cc
@@ -134,11 +134,6 @@
   return GetDeviceStringProperty(device_id, kAudioDevicePropertyModelUID);
 }
 
-base::Optional<uint32_t> GetDeviceTransportType(AudioObjectID device_id) {
-  return GetDeviceUint32Property(device_id, kAudioDevicePropertyTransportType,
-                                 kAudioObjectPropertyScopeGlobal);
-}
-
 bool ModelContainsVidPid(const std::string& model) {
   return model.size() > 10 && model[model.size() - 5] == ':' &&
          model[model.size() - 10] == ':';
@@ -273,5 +268,49 @@
                                  InputOutputScope(is_input));
 }
 
+base::Optional<uint32_t> GetDeviceTransportType(AudioObjectID device_id) {
+  return GetDeviceUint32Property(device_id, kAudioDevicePropertyTransportType,
+                                 kAudioObjectPropertyScopeGlobal);
+}
+
+bool IsPrivateAggregateDevice(AudioObjectID device_id) {
+  // Don't try to access aggregate device properties unless |device_id| is
+  // really an aggregate device.
+  if (GetDeviceTransportType(device_id) != kAudioDeviceTransportTypeAggregate)
+    return false;
+
+  const AudioObjectPropertyAddress property_address = {
+      kAudioAggregateDevicePropertyComposition, kAudioObjectPropertyScopeGlobal,
+      kAudioObjectPropertyElementMaster};
+  CFDictionaryRef dictionary = nullptr;
+  UInt32 size = sizeof(dictionary);
+  OSStatus result = AudioObjectGetPropertyData(
+      device_id, &property_address, 0 /* inQualifierDataSize */,
+      nullptr /* inQualifierData */, &size, &dictionary);
+
+  if (result != noErr) {
+    OSSTATUS_LOG(WARNING, result) << "Failed to read property "
+                                  << kAudioAggregateDevicePropertyComposition
+                                  << " for device " << device_id;
+    return false;
+  }
+
+  DCHECK_EQ(CFGetTypeID(dictionary), CFDictionaryGetTypeID());
+  bool is_private = false;
+  CFTypeRef value = CFDictionaryGetValue(
+      dictionary, CFSTR(kAudioAggregateDeviceIsPrivateKey));
+
+  if (value && CFGetTypeID(value) == CFNumberGetTypeID()) {
+    int number = 0;
+    if (CFNumberGetValue(reinterpret_cast<CFNumberRef>(value), kCFNumberIntType,
+                         &number)) {
+      is_private = number != 0;
+    }
+  }
+  CFRelease(dictionary);
+
+  return is_private;
+}
+
 }  // namespace core_audio_mac
 }  // namespace media
diff --git a/media/audio/mac/core_audio_util_mac.h b/media/audio/mac/core_audio_util_mac.h
index 7c728b3..39c3756 100644
--- a/media/audio/mac/core_audio_util_mac.h
+++ b/media/audio/mac/core_audio_util_mac.h
@@ -43,6 +43,15 @@
 base::Optional<uint32_t> GetDeviceSource(AudioObjectID device_id,
                                          bool is_input);
 
+// Returns the transport type of the given |device_id|, or no value if
+// |device_id| has no source or if there is an error.
+base::Optional<uint32_t> GetDeviceTransportType(AudioObjectID device_id);
+
+// Returns whether or not the |device_id| corresponds to a private, aggregate
+// device. Such a device gets created by instantiating a VoiceProcessingIO
+// AudioUnit.
+bool IsPrivateAggregateDevice(AudioObjectID device_id);
+
 }  // namespace core_audio_mac
 }  // namespace media
 
diff --git a/media/capture/mojom/BUILD.gn b/media/capture/mojom/BUILD.gn
index 93828b66..6fc162b 100644
--- a/media/capture/mojom/BUILD.gn
+++ b/media/capture/mojom/BUILD.gn
@@ -11,7 +11,7 @@
   ]
 
   public_deps = [
-    "//media/mojo/interfaces",
+    "//gpu/ipc/common:interfaces",
     "//mojo/public/mojom/base",
     "//ui/gfx/geometry/mojo",
   ]
diff --git a/media/capture/mojom/video_capture.mojom b/media/capture/mojom/video_capture.mojom
index 4ed732c..6926112 100644
--- a/media/capture/mojom/video_capture.mojom
+++ b/media/capture/mojom/video_capture.mojom
@@ -4,7 +4,6 @@
 
 module media.mojom;
 
-import "media/mojo/interfaces/media_types.mojom";
 import "media/capture/mojom/video_capture_types.mojom";
 import "ui/gfx/geometry/mojo/geometry.mojom";
 
diff --git a/media/capture/mojom/video_capture_types.mojom b/media/capture/mojom/video_capture_types.mojom
index 9c02d7699..039fdac 100644
--- a/media/capture/mojom/video_capture_types.mojom
+++ b/media/capture/mojom/video_capture_types.mojom
@@ -4,11 +4,16 @@
 
 module media.mojom;
 
-import "media/mojo/interfaces/media_types.mojom";
+import "gpu/ipc/common/mailbox_holder.mojom";
 import "mojo/public/mojom/base/time.mojom";
 import "mojo/public/mojom/base/values.mojom";
 import "ui/gfx/geometry/mojo/geometry.mojom";
 
+enum VideoCapturePixelFormat {
+  I420,
+  Y16
+};
+
 enum ResolutionChangePolicy {
   FIXED_RESOLUTION,
   FIXED_ASPECT_RATIO,
@@ -41,15 +46,10 @@
   OTHER_TRANSPORT
 };
 
-union VideoBufferHandle {
-  handle<shared_buffer> shared_buffer_handle;
-  media.mojom.MailboxVideoFrameData mailbox_handles;
-};
-
 struct VideoCaptureFormat {
   gfx.mojom.Size frame_size;
   float frame_rate;
-  VideoPixelFormat pixel_format;
+  VideoCapturePixelFormat pixel_format;
 };
 
 struct VideoCaptureParams {
@@ -61,7 +61,7 @@
 struct VideoFrameInfo{
   mojo_base.mojom.TimeDelta timestamp;
   mojo_base.mojom.DictionaryValue metadata;
-  VideoPixelFormat pixel_format;
+  VideoCapturePixelFormat pixel_format;
   gfx.mojom.Size coded_size;
   gfx.mojom.Rect visible_rect;
 };
@@ -86,3 +86,14 @@
   VideoCaptureDeviceDescriptor descriptor;
   array<VideoCaptureFormat> supported_formats;
 };
+
+struct MailboxBufferHandleSet {
+  // Size must be kept in sync with media::VideoFrame::kMaxPlanes.
+  array<gpu.mojom.MailboxHolder, 4> mailbox_holder;
+};
+
+union VideoBufferHandle {
+  handle<shared_buffer> shared_buffer_handle;
+  MailboxBufferHandleSet mailbox_handles;
+};
+
diff --git a/media/capture/mojom/video_capture_types.typemap b/media/capture/mojom/video_capture_types.typemap
index 0a5d9f0..27b8599 100644
--- a/media/capture/mojom/video_capture_types.typemap
+++ b/media/capture/mojom/video_capture_types.typemap
@@ -32,6 +32,7 @@
 type_mappings = [
   "media.mojom.ResolutionChangePolicy=media::ResolutionChangePolicy",
   "media.mojom.PowerLineFrequency=media::PowerLineFrequency",
+  "media.mojom.VideoCapturePixelFormat=media::VideoPixelFormat",
   "media.mojom.VideoCaptureFormat=media::VideoCaptureFormat",
   "media.mojom.VideoCaptureParams=media::VideoCaptureParams",
   "media.mojom.VideoCaptureDeviceDescriptorCameraCalibration=media::VideoCaptureDeviceDescriptor::CameraCalibration",
diff --git a/media/capture/mojom/video_capture_types_mojom_traits.cc b/media/capture/mojom/video_capture_types_mojom_traits.cc
index 71b2bb6..04e6cb0 100644
--- a/media/capture/mojom/video_capture_types_mojom_traits.cc
+++ b/media/capture/mojom/video_capture_types_mojom_traits.cc
@@ -83,6 +83,65 @@
 }
 
 // static
+media::mojom::VideoCapturePixelFormat
+EnumTraits<media::mojom::VideoCapturePixelFormat,
+           media::VideoPixelFormat>::ToMojom(media::VideoPixelFormat input) {
+  switch (input) {
+    case media::VideoPixelFormat::PIXEL_FORMAT_I420:
+      return media::mojom::VideoCapturePixelFormat::I420;
+    case media::VideoPixelFormat::PIXEL_FORMAT_Y16:
+      return media::mojom::VideoCapturePixelFormat::Y16;
+    case media::VideoPixelFormat::PIXEL_FORMAT_UNKNOWN:
+    case media::VideoPixelFormat::PIXEL_FORMAT_YV12:
+    case media::VideoPixelFormat::PIXEL_FORMAT_I422:
+    case media::VideoPixelFormat::PIXEL_FORMAT_I420A:
+    case media::VideoPixelFormat::PIXEL_FORMAT_I444:
+    case media::VideoPixelFormat::PIXEL_FORMAT_NV12:
+    case media::VideoPixelFormat::PIXEL_FORMAT_NV21:
+    case media::VideoPixelFormat::PIXEL_FORMAT_UYVY:
+    case media::VideoPixelFormat::PIXEL_FORMAT_YUY2:
+    case media::VideoPixelFormat::PIXEL_FORMAT_ARGB:
+    case media::VideoPixelFormat::PIXEL_FORMAT_XRGB:
+    case media::VideoPixelFormat::PIXEL_FORMAT_RGB24:
+    case media::VideoPixelFormat::PIXEL_FORMAT_RGB32:
+    case media::VideoPixelFormat::PIXEL_FORMAT_MJPEG:
+    case media::VideoPixelFormat::PIXEL_FORMAT_MT21:
+    case media::VideoPixelFormat::PIXEL_FORMAT_YUV420P9:
+    case media::VideoPixelFormat::PIXEL_FORMAT_YUV420P10:
+    case media::VideoPixelFormat::PIXEL_FORMAT_YUV422P9:
+    case media::VideoPixelFormat::PIXEL_FORMAT_YUV422P10:
+    case media::VideoPixelFormat::PIXEL_FORMAT_YUV444P9:
+    case media::VideoPixelFormat::PIXEL_FORMAT_YUV444P10:
+    case media::VideoPixelFormat::PIXEL_FORMAT_YUV420P12:
+    case media::VideoPixelFormat::PIXEL_FORMAT_YUV422P12:
+    case media::VideoPixelFormat::PIXEL_FORMAT_YUV444P12:
+      // Any pixel format requested via a media::VideoPixelFormat that is not
+      // supported by the video capture service is interpreted as requesting
+      // I420.
+      return media::mojom::VideoCapturePixelFormat::I420;
+  }
+  NOTREACHED();
+  return media::mojom::VideoCapturePixelFormat::I420;
+}
+
+// static
+bool EnumTraits<media::mojom::VideoCapturePixelFormat,
+                media::VideoPixelFormat>::
+    FromMojom(media::mojom::VideoCapturePixelFormat input,
+              media::VideoPixelFormat* output) {
+  switch (input) {
+    case media::mojom::VideoCapturePixelFormat::I420:
+      *output = media::VideoPixelFormat::PIXEL_FORMAT_I420;
+      return true;
+    case media::mojom::VideoCapturePixelFormat::Y16:
+      *output = media::VideoPixelFormat::PIXEL_FORMAT_Y16;
+      return true;
+  }
+  NOTREACHED();
+  return false;
+}
+
+// static
 media::mojom::VideoCaptureApi
 EnumTraits<media::mojom::VideoCaptureApi, media::VideoCaptureApi>::ToMojom(
     media::VideoCaptureApi input) {
diff --git a/media/capture/mojom/video_capture_types_mojom_traits.h b/media/capture/mojom/video_capture_types_mojom_traits.h
index 8c0c21e7..4c9283c4 100644
--- a/media/capture/mojom/video_capture_types_mojom_traits.h
+++ b/media/capture/mojom/video_capture_types_mojom_traits.h
@@ -32,6 +32,15 @@
 };
 
 template <>
+struct EnumTraits<media::mojom::VideoCapturePixelFormat,
+                  media::VideoPixelFormat> {
+  static media::mojom::VideoCapturePixelFormat ToMojom(
+      media::VideoPixelFormat input);
+  static bool FromMojom(media::mojom::VideoCapturePixelFormat input,
+                        media::VideoPixelFormat* output);
+};
+
+template <>
 struct EnumTraits<media::mojom::VideoCaptureApi, media::VideoCaptureApi> {
   static media::mojom::VideoCaptureApi ToMojom(media::VideoCaptureApi input);
   static bool FromMojom(media::mojom::VideoCaptureApi input,
diff --git a/media/media_options.gni b/media/media_options.gni
index 2d2761d..d3244b1 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -71,7 +71,7 @@
   # which are encoded using HEVC require |enable_hevc_demuxing| to be enabled.
   enable_dolby_vision_demuxing = proprietary_codecs && is_chromecast
 
-  enable_webrtc = !is_cast_audio_only
+  enable_webrtc = true
 
   # Enable HLS with SAMPLE-AES decryption.
   enable_hls_sample_aes = proprietary_codecs && is_chromecast
diff --git a/media/mojo/clients/mojo_decryptor_unittest.cc b/media/mojo/clients/mojo_decryptor_unittest.cc
index 007e01a..38f6ab3 100644
--- a/media/mojo/clients/mojo_decryptor_unittest.cc
+++ b/media/mojo/clients/mojo_decryptor_unittest.cc
@@ -20,6 +20,7 @@
 #include "media/mojo/common/mojo_shared_buffer_video_frame.h"
 #include "media/mojo/interfaces/decryptor.mojom.h"
 #include "media/mojo/services/mojo_decryptor_service.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -44,10 +45,11 @@
     decryptor_.reset(new StrictMock<MockDecryptor>());
 
     mojom::DecryptorPtr remote_decryptor;
-    mojo_decryptor_service_.reset(new MojoDecryptorService(
-        decryptor_.get(), mojo::MakeRequest(&remote_decryptor),
-        base::Bind(&MojoDecryptorTest::OnConnectionClosed,
-                   base::Unretained(this))));
+    mojo_decryptor_service_.reset(new MojoDecryptorService(decryptor_.get()));
+    binding_ = std::make_unique<mojo::Binding<mojom::Decryptor>>(
+        mojo_decryptor_service_.get(), MakeRequest(&remote_decryptor));
+    binding_->set_connection_error_handler(base::BindOnce(
+        &MojoDecryptorTest::OnConnectionClosed, base::Unretained(this)));
 
     mojo_decryptor_.reset(
         new MojoDecryptor(std::move(remote_decryptor), writer_capacity_));
@@ -61,6 +63,7 @@
   void DestroyService() {
     // MojoDecryptor has no way to notify callers that the connection is closed.
     // TODO(jrummell): Determine if notification is needed.
+    binding_.reset();
     mojo_decryptor_service_.reset();
   }
 
@@ -119,6 +122,7 @@
 
   // The matching MojoDecryptorService for |mojo_decryptor_|.
   std::unique_ptr<MojoDecryptorService> mojo_decryptor_service_;
+  std::unique_ptr<mojo::Binding<mojom::Decryptor>> binding_;
 
   // The actual Decryptor object used by |mojo_decryptor_service_|.
   std::unique_ptr<StrictMock<MockDecryptor>> decryptor_;
diff --git a/media/mojo/services/interface_factory_impl.cc b/media/mojo/services/interface_factory_impl.cc
index 37bd49b..0caf1c6 100644
--- a/media/mojo/services/interface_factory_impl.cc
+++ b/media/mojo/services/interface_factory_impl.cc
@@ -58,6 +58,8 @@
       mojo_media_client_(mojo_media_client) {
   DVLOG(1) << __func__;
   DCHECK(mojo_media_client_);
+
+  SetBindingConnectionErrorHandler();
 }
 
 InterfaceFactoryImpl::~InterfaceFactoryImpl() {
@@ -187,6 +189,77 @@
 #endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
 }
 
+void InterfaceFactoryImpl::OnDestroyPending(base::OnceClosure destroy_cb) {
+  DVLOG(1) << __func__;
+  destroy_cb_ = std::move(destroy_cb);
+  if (IsEmpty())
+    std::move(destroy_cb_).Run();
+  // else the callback will be called when IsEmpty() becomes true.
+}
+
+bool InterfaceFactoryImpl::IsEmpty() {
+#if BUILDFLAG(ENABLE_MOJO_AUDIO_DECODER)
+  if (!audio_decoder_bindings_.empty())
+    return false;
+#endif  // BUILDFLAG(ENABLE_MOJO_AUDIO_DECODER)
+
+#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
+  if (!video_decoder_bindings_.empty())
+    return false;
+#endif  // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
+
+#if BUILDFLAG(ENABLE_MOJO_RENDERER)
+  if (!renderer_bindings_.empty())
+    return false;
+#endif  // BUILDFLAG(ENABLE_MOJO_RENDERER)
+
+#if BUILDFLAG(ENABLE_MOJO_CDM)
+  if (!cdm_bindings_.empty())
+    return false;
+#endif  // BUILDFLAG(ENABLE_MOJO_CDM)
+
+#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
+  if (!cdm_proxy_bindings_.empty())
+    return false;
+#endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
+
+  return true;
+}
+
+void InterfaceFactoryImpl::SetBindingConnectionErrorHandler() {
+  // base::Unretained is safe because all bindings are owned by |this|. If
+  // |this| is destructed, the bindings will be destructed as well and the
+  // connection error handler should never be called.
+  auto connection_error_cb = base::BindRepeating(
+      &InterfaceFactoryImpl::OnBindingConnectionError, base::Unretained(this));
+
+#if BUILDFLAG(ENABLE_MOJO_AUDIO_DECODER)
+  audio_decoder_bindings_.set_connection_error_handler(connection_error_cb);
+#endif  // BUILDFLAG(ENABLE_MOJO_AUDIO_DECODER)
+
+#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
+  video_decoder_bindings_.set_connection_error_handler(connection_error_cb);
+#endif  // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
+
+#if BUILDFLAG(ENABLE_MOJO_RENDERER)
+  renderer_bindings_.set_connection_error_handler(connection_error_cb);
+#endif  // BUILDFLAG(ENABLE_MOJO_RENDERER)
+
+#if BUILDFLAG(ENABLE_MOJO_CDM)
+  cdm_bindings_.set_connection_error_handler(connection_error_cb);
+#endif  // BUILDFLAG(ENABLE_MOJO_CDM)
+
+#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
+  cdm_proxy_bindings_.set_connection_error_handler(connection_error_cb);
+#endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
+}
+
+void InterfaceFactoryImpl::OnBindingConnectionError() {
+  DVLOG(2) << __func__;
+  if (destroy_cb_ && IsEmpty())
+    std::move(destroy_cb_).Run();
+}
+
 #if BUILDFLAG(ENABLE_MOJO_RENDERER)
 RendererFactory* InterfaceFactoryImpl::GetRendererFactory() {
   if (!renderer_factory_) {
diff --git a/media/mojo/services/interface_factory_impl.h b/media/mojo/services/interface_factory_impl.h
index 7797ca1..05ed491 100644
--- a/media/mojo/services/interface_factory_impl.h
+++ b/media/mojo/services/interface_factory_impl.h
@@ -10,6 +10,7 @@
 #include "base/macros.h"
 #include "media/mojo/buildflags.h"
 #include "media/mojo/interfaces/interface_factory.mojom.h"
+#include "media/mojo/services/deferred_destroy_strong_binding_set.h"
 #include "media/mojo/services/mojo_cdm_service_context.h"
 #include "mojo/public/cpp/bindings/strong_binding_set.h"
 #include "services/service_manager/public/cpp/connector.h"
@@ -22,7 +23,7 @@
 class MojoMediaClient;
 class RendererFactory;
 
-class InterfaceFactoryImpl : public mojom::InterfaceFactory {
+class InterfaceFactoryImpl : public DeferredDestroy<mojom::InterfaceFactory> {
  public:
   InterfaceFactoryImpl(
       service_manager::mojom::InterfaceProviderPtr interfaces,
@@ -42,7 +43,17 @@
   void CreateCdmProxy(const std::string& cdm_guid,
                       mojom::CdmProxyRequest request) final;
 
+  // DeferredDestroy<mojom::InterfaceFactory> implemenation.
+  void OnDestroyPending(base::OnceClosure destroy_cb) final;
+
  private:
+  // Returns true when there is no media component (audio/video decoder,
+  // renderer, cdm and cdm proxy) bindings exist.
+  bool IsEmpty();
+
+  void SetBindingConnectionErrorHandler();
+  void OnBindingConnectionError();
+
 #if BUILDFLAG(ENABLE_MOJO_RENDERER)
   RendererFactory* GetRendererFactory();
 #endif  // BUILDFLAG(ENABLE_MOJO_RENDERER)
@@ -82,6 +93,7 @@
 
   std::unique_ptr<service_manager::ServiceContextRef> connection_ref_;
   MojoMediaClient* mojo_media_client_;
+  base::OnceClosure destroy_cb_;
 
   DISALLOW_COPY_AND_ASSIGN(InterfaceFactoryImpl);
 };
diff --git a/media/mojo/services/media_service.h b/media/mojo/services/media_service.h
index 5219eb2..0e4dc375 100644
--- a/media/mojo/services/media_service.h
+++ b/media/mojo/services/media_service.h
@@ -11,9 +11,9 @@
 #include "media/base/media_log.h"
 #include "media/mojo/interfaces/interface_factory.mojom.h"
 #include "media/mojo/interfaces/media_service.mojom.h"
+#include "media/mojo/services/deferred_destroy_strong_binding_set.h"
 #include "media/mojo/services/media_mojo_export.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
-#include "mojo/public/cpp/bindings/strong_binding_set.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
 #include "services/service_manager/public/cpp/service.h"
 #include "services/service_manager/public/cpp/service_context.h"
@@ -56,7 +56,8 @@
 
   // Note: Since |&media_log_| is passed to bindings, the bindings must be
   // destructed first.
-  mojo::StrongBindingSet<mojom::InterfaceFactory> interface_factory_bindings_;
+  DeferredDestroyStrongBindingSet<mojom::InterfaceFactory>
+      interface_factory_bindings_;
 
   service_manager::BinderRegistry registry_;
   mojo::BindingSet<mojom::MediaService> bindings_;
diff --git a/media/mojo/services/media_service_unittest.cc b/media/mojo/services/media_service_unittest.cc
index 2f4a862..6aa13a1 100644
--- a/media/mojo/services/media_service_unittest.cc
+++ b/media/mojo/services/media_service_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/run_loop.h"
+#include "base/task_scheduler/post_task.h"
 #include "build/build_config.h"
 #include "media/base/cdm_config.h"
 #include "media/base/mock_filters.h"
@@ -46,6 +47,7 @@
 using testing::InvokeWithoutArgs;
 using testing::NiceMock;
 using testing::StrictMock;
+using testing::WithoutArgs;
 
 MATCHER_P(MatchesResult, success, "") {
   return arg->success == success;
@@ -96,6 +98,15 @@
   DISALLOW_COPY_AND_ASSIGN(MockRendererClient);
 };
 
+ACTION_P(QuitLoop, run_loop) {
+  base::PostTask(FROM_HERE, run_loop->QuitClosure());
+}
+
+// Tests MediaService built into a standalone mojo service binary (see
+// ServiceMain() in main.cc) where MediaService uses TestMojoMediaClient.
+// TestMojoMediaClient supports CDM creation using DefaultCdmFactory (only
+// supports Clear Key key system), and Renderer creation using
+// DefaultRendererFactory that always create media::RendererImpl.
 class MediaServiceTest : public service_manager::test::ServiceTest {
  public:
   MediaServiceTest()
@@ -116,27 +127,31 @@
         mojo::MakeRequest(&interfaces));
     media_service->CreateInterfaceFactory(
         mojo::MakeRequest(&interface_factory_), std::move(interfaces));
-
-    run_loop_.reset(new base::RunLoop());
   }
 
   MOCK_METHOD3(OnCdmInitialized,
                void(mojom::CdmPromiseResultPtr result,
                     int cdm_id,
                     mojom::DecryptorPtr decryptor));
+  MOCK_METHOD0(OnCdmConnectionError, void());
 
   void InitializeCdm(const std::string& key_system,
                      bool expected_result,
                      int cdm_id) {
+    base::RunLoop run_loop;
     interface_factory_->CreateCdm(key_system, mojo::MakeRequest(&cdm_));
+    cdm_.set_connection_error_handler(base::BindRepeating(
+        &MediaServiceTest::OnCdmConnectionError, base::Unretained(this)));
 
+    // Have to use WithoutArgs since move-only types do not work with actions.
     EXPECT_CALL(*this,
                 OnCdmInitialized(MatchesResult(expected_result), cdm_id, _))
-        .WillOnce(InvokeWithoutArgs(run_loop_.get(), &base::RunLoop::Quit));
+        .WillOnce(WithoutArgs(QuitLoop(&run_loop)));
     cdm_->Initialize(key_system, url::Origin::Create(GURL(kSecurityOrigin)),
                      CdmConfig(),
                      base::BindOnce(&MediaServiceTest::OnCdmInitialized,
                                     base::Unretained(this)));
+    run_loop.Run();
   }
 
   MOCK_METHOD4(OnCdmProxyInitialized,
@@ -146,23 +161,26 @@
                     int cdm_id));
 
   void InitializeCdmProxy(const std::string& cdm_guid) {
+    base::RunLoop run_loop;
     interface_factory_->CreateCdmProxy(cdm_guid,
                                        mojo::MakeRequest(&cdm_proxy_));
 
     EXPECT_CALL(*this, OnCdmProxyInitialized(CdmProxy::Status::kOk, _, _, _))
-        .WillOnce(InvokeWithoutArgs(run_loop_.get(), &base::RunLoop::Quit));
+        .WillOnce(QuitLoop(&run_loop));
     mojom::CdmProxyClientAssociatedPtrInfo client_ptr_info;
     cdm_proxy_client_binding_.Bind(mojo::MakeRequest(&client_ptr_info));
     cdm_proxy_->Initialize(
         std::move(client_ptr_info),
         base::BindOnce(&MediaServiceTest::OnCdmProxyInitialized,
                        base::Unretained(this)));
+    run_loop.Run();
   }
 
   MOCK_METHOD1(OnRendererInitialized, void(bool));
 
   void InitializeRenderer(const VideoDecoderConfig& video_config,
                           bool expected_result) {
+    base::RunLoop run_loop;
     interface_factory_->CreateRenderer(
         media::mojom::HostedRendererType::kDefault, std::string(),
         mojo::MakeRequest(&renderer_));
@@ -177,7 +195,7 @@
     renderer_client_binding_.Bind(mojo::MakeRequest(&client_ptr_info));
 
     EXPECT_CALL(*this, OnRendererInitialized(expected_result))
-        .WillOnce(InvokeWithoutArgs(run_loop_.get(), &base::RunLoop::Quit));
+        .WillOnce(QuitLoop(&run_loop));
     std::vector<mojom::DemuxerStreamPtrInfo> streams;
     streams.push_back(std::move(video_stream_proxy_info));
     renderer_->Initialize(
@@ -185,13 +203,12 @@
         base::nullopt,
         base::BindOnce(&MediaServiceTest::OnRendererInitialized,
                        base::Unretained(this)));
+    run_loop.Run();
   }
 
-  MOCK_METHOD0(ConnectionClosed, void());
+  MOCK_METHOD0(MediaServiceConnectionClosed, void());
 
  protected:
-  std::unique_ptr<base::RunLoop> run_loop_;
-
   mojom::InterfaceFactoryPtr interface_factory_;
   mojom::ContentDecryptionModulePtr cdm_;
   mojom::CdmProxyPtr cdm_proxy_;
@@ -214,54 +231,105 @@
 
 // Note: base::RunLoop::RunUntilIdle() does not work well in these tests because
 // even when the loop is idle, we may still have pending events in the pipe.
+// - If you have an InterfacePtr hosted by the service in the service process,
+//   you can use InterfacePtr::FlushForTesting().
+// - If you expect a callback on an InterfacePtr call or connection error, use
+//   base::RunLoop::Run() and QuitLoop().
 
 // TODO(crbug.com/829233): Enable these tests on Android.
 #if BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)
 TEST_F(MediaServiceTest, InitializeCdm_Success) {
   InitializeCdm(kClearKeyKeySystem, true, 1);
-  run_loop_->Run();
 }
 
 TEST_F(MediaServiceTest, InitializeCdm_InvalidKeySystem) {
   InitializeCdm(kInvalidKeySystem, false, 0);
-  run_loop_->Run();
 }
 #endif  // BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)
 
 #if BUILDFLAG(ENABLE_MOJO_RENDERER)
 TEST_F(MediaServiceTest, InitializeRenderer) {
   InitializeRenderer(TestVideoConfig::Normal(), true);
-  run_loop_->Run();
 }
 #endif  // BUILDFLAG(ENABLE_MOJO_RENDERER)
 
 #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
 TEST_F(MediaServiceTest, CdmProxy) {
   InitializeCdmProxy(kClearKeyCdmGuid);
-  run_loop_->Run();
 }
 #endif  // BUILDFLAG(ENABLE_LIBRARY_CDMS)
 
 TEST_F(MediaServiceTest, Lifetime) {
   // The lifetime of the media service is controlled by the number of
-  // live InterfaceFactory impls, not MediaService impls, so this pipe should
-  // be closed when the last InterfaceFactory is destroyed.
+  // live InterfaceFactory impls, which are then deferred destroyed until no
+  // media components (CDM or Renderer) are hosted.
   media::mojom::MediaServicePtr media_service;
   connector()->BindInterface(media::mojom::kMediaServiceName, &media_service);
-  media_service.set_connection_error_handler(
-      base::Bind(&MediaServiceTest::ConnectionClosed, base::Unretained(this)));
+  media_service.set_connection_error_handler(base::BindRepeating(
+      &MediaServiceTest::MediaServiceConnectionClosed, base::Unretained(this)));
 
-  // Disconnecting CDM and Renderer services doesn't terminate the app.
+#if BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)
+  InitializeCdm(kClearKeyKeySystem, true, 1);
+#endif
+
+#if BUILDFLAG(ENABLE_MOJO_RENDERER)
+  InitializeRenderer(TestVideoConfig::Normal(), true);
+#endif
+
+  // Disconnecting CDM and Renderer services doesn't terminate MediaService
+  // since |interface_factory_| is still alive.
   cdm_.reset();
   renderer_.reset();
+  interface_factory_.FlushForTesting();
 
-  // Disconnecting InterfaceFactory service should terminate the app, which will
-  // close the connection.
-  EXPECT_CALL(*this, ConnectionClosed())
-      .WillOnce(Invoke(run_loop_.get(), &base::RunLoop::Quit));
+  // Disconnecting InterfaceFactory will now terminate the MediaService.
+  base::RunLoop run_loop;
+  EXPECT_CALL(*this, MediaServiceConnectionClosed())
+      .WillOnce(QuitLoop(&run_loop));
   interface_factory_.reset();
-
-  run_loop_->Run();
+  run_loop.Run();
 }
 
+#if (BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)) || \
+    BUILDFLAG(ENABLE_MOJO_RENDERER)
+TEST_F(MediaServiceTest, DeferredDestruction) {
+  // The lifetime of the media service is controlled by the number of
+  // live InterfaceFactory impls, which are then deferred destroyed until no
+  // media components (CDM or Renderer) are hosted.
+  media::mojom::MediaServicePtr media_service;
+  connector()->BindInterface(media::mojom::kMediaServiceName, &media_service);
+  media_service.set_connection_error_handler(base::BindRepeating(
+      &MediaServiceTest::MediaServiceConnectionClosed, base::Unretained(this)));
+
+#if BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)
+  InitializeCdm(kClearKeyKeySystem, true, 1);
+#endif
+
+#if BUILDFLAG(ENABLE_MOJO_RENDERER)
+  InitializeRenderer(TestVideoConfig::Normal(), true);
+#endif
+
+  ASSERT_TRUE(cdm_ || renderer_);
+
+  // Disconnecting InterfaceFactory should not terminate the MediaService since
+  // there are still media components (CDM or Renderer) hosted.
+  interface_factory_.reset();
+  if (cdm_)
+    cdm_.FlushForTesting();
+  else if (renderer_)
+    renderer_.FlushForTesting();
+  else
+    NOTREACHED();
+
+  // Disconnecting CDM and Renderer will now terminate the MediaService.
+  base::RunLoop run_loop;
+  cdm_.reset();
+  renderer_.reset();
+  EXPECT_CALL(*this, MediaServiceConnectionClosed())
+      .WillOnce(QuitLoop(&run_loop));
+  run_loop.Run();
+}
+#endif  // (BUILDFLAG(ENABLE_MOJO_CDM) && !defined(OS_ANDROID)) ||
+        //  BUILDFLAG(ENABLE_MOJO_RENDERER)
+
 }  // namespace media
diff --git a/media/mojo/services/mojo_cdm_service.cc b/media/mojo/services/mojo_cdm_service.cc
index 5c39b20..c38b6e8 100644
--- a/media/mojo/services/mojo_cdm_service.cc
+++ b/media/mojo/services/mojo_cdm_service.cc
@@ -166,12 +166,14 @@
 
   // If |cdm| has a decryptor, create the MojoDecryptorService
   // and pass the connection back to the client.
-  mojom::DecryptorPtr decryptor_service;
+  mojom::DecryptorPtr decryptor_ptr;
   CdmContext* const cdm_context = cdm_->GetCdmContext();
   if (cdm_context && cdm_context->GetDecryptor()) {
-    decryptor_.reset(new MojoDecryptorService(
-        cdm_context->GetDecryptor(), MakeRequest(&decryptor_service),
-        base::Bind(&MojoCdmService::OnDecryptorConnectionError, weak_this_)));
+    decryptor_.reset(new MojoDecryptorService(cdm_context->GetDecryptor()));
+    decryptor_binding_ = std::make_unique<mojo::Binding<mojom::Decryptor>>(
+        decryptor_.get(), MakeRequest(&decryptor_ptr));
+    decryptor_binding_->set_connection_error_handler(base::BindOnce(
+        &MojoCdmService::OnDecryptorConnectionError, weak_this_));
   }
 
   // If the |context_| is not null, we should support connecting the |cdm| with
@@ -184,7 +186,7 @@
 
   cdm_promise_result->success = true;
   std::move(callback).Run(std::move(cdm_promise_result), cdm_id,
-                          std::move(decryptor_service));
+                          std::move(decryptor_ptr));
 }
 
 void MojoCdmService::OnSessionMessage(const std::string& session_id,
diff --git a/media/mojo/services/mojo_cdm_service.h b/media/mojo/services/mojo_cdm_service.h
index 051d46d..716620b9 100644
--- a/media/mojo/services/mojo_cdm_service.h
+++ b/media/mojo/services/mojo_cdm_service.h
@@ -21,6 +21,7 @@
 #include "media/mojo/services/mojo_cdm_promise.h"
 #include "media/mojo/services/mojo_cdm_service_context.h"
 #include "media/mojo/services/mojo_decryptor_service.h"
+#include "mojo/public/cpp/bindings/binding.h"
 
 namespace media {
 
@@ -106,6 +107,7 @@
   // MojoDecryptorService is passed the Decryptor from |cdm_|, so
   // |decryptor_| must not outlive |cdm_|.
   std::unique_ptr<MojoDecryptorService> decryptor_;
+  std::unique_ptr<mojo::Binding<mojom::Decryptor>> decryptor_binding_;
 
   // Set to a valid CDM ID if the |cdm_| is successfully created.
   int cdm_id_;
diff --git a/media/mojo/services/mojo_decryptor_service.cc b/media/mojo/services/mojo_decryptor_service.cc
index 99307ad6..5cc3335 100644
--- a/media/mojo/services/mojo_decryptor_service.cc
+++ b/media/mojo/services/mojo_decryptor_service.cc
@@ -45,17 +45,11 @@
 
 }  // namespace
 
-MojoDecryptorService::MojoDecryptorService(
-    media::Decryptor* decryptor,
-    mojo::InterfaceRequest<mojom::Decryptor> request,
-    const base::Closure& error_handler)
-    : binding_(this, std::move(request)),
-      decryptor_(decryptor),
-      weak_factory_(this) {
+MojoDecryptorService::MojoDecryptorService(media::Decryptor* decryptor)
+    : decryptor_(decryptor), weak_factory_(this) {
   DVLOG(1) << __func__;
   DCHECK(decryptor_);
   weak_this_ = weak_factory_.GetWeakPtr();
-  binding_.set_connection_error_handler(error_handler);
 }
 
 MojoDecryptorService::~MojoDecryptorService() {
diff --git a/media/mojo/services/mojo_decryptor_service.h b/media/mojo/services/mojo_decryptor_service.h
index 879456b1..5d37637 100644
--- a/media/mojo/services/mojo_decryptor_service.h
+++ b/media/mojo/services/mojo_decryptor_service.h
@@ -16,7 +16,6 @@
 #include "media/base/decryptor.h"
 #include "media/mojo/interfaces/decryptor.mojom.h"
 #include "media/mojo/services/media_mojo_export.h"
-#include "mojo/public/cpp/bindings/binding.h"
 
 namespace media {
 
@@ -24,19 +23,15 @@
 class MojoDecoderBufferReader;
 class MojoDecoderBufferWriter;
 
-// A mojom::Decryptor implementation. This object is owned by the creator,
-// and uses a weak binding across the mojo interface.
+// A mojom::Decryptor implementation that proxies decryptor calls to a
+// media::Decryptor.
 class MEDIA_MOJO_EXPORT MojoDecryptorService : public mojom::Decryptor {
  public:
   using StreamType = media::Decryptor::StreamType;
   using Status = media::Decryptor::Status;
 
-  // Constructs a MojoDecryptorService and binds it to the |request|.
-  // |error_handler| will be called if a connection error occurs.
   // Caller must ensure that |decryptor| outlives |this|.
-  MojoDecryptorService(media::Decryptor* decryptor,
-                       mojo::InterfaceRequest<mojom::Decryptor> request,
-                       const base::Closure& error_handler);
+  explicit MojoDecryptorService(media::Decryptor* decryptor);
 
   ~MojoDecryptorService() final;
 
@@ -93,9 +88,6 @@
   // Returns audio/video buffer reader according to the |stream_type|.
   MojoDecoderBufferReader* GetBufferReader(StreamType stream_type) const;
 
-  // A weak binding is used to connect to the MojoDecryptor.
-  mojo::Binding<mojom::Decryptor> binding_;
-
   // Helper classes to receive encrypted DecoderBuffer from the client.
   std::unique_ptr<MojoDecoderBufferReader> audio_buffer_reader_;
   std::unique_ptr<MojoDecoderBufferReader> video_buffer_reader_;
diff --git a/media/test/pipeline_integration_test_base.cc b/media/test/pipeline_integration_test_base.cc
index 1cc290d..de84694 100644
--- a/media/test/pipeline_integration_test_base.cc
+++ b/media/test/pipeline_integration_test_base.cc
@@ -203,20 +203,17 @@
 }
 
 bool PipelineIntegrationTestBase::WaitUntilOnEnded() {
-  if (!ended_) {
-    base::RunLoop run_loop;
-    RunUntilIdleOrEnded(&run_loop);
-    EXPECT_TRUE(ended_);
-  } else {
-    scoped_task_environment_.RunUntilIdle();
-  }
-  return ended_ && (pipeline_status_ == PIPELINE_OK);
+  EXPECT_EQ(pipeline_status_, PIPELINE_OK);
+  PipelineStatus status = WaitUntilEndedOrError();
+  EXPECT_TRUE(ended_);
+  EXPECT_EQ(pipeline_status_, PIPELINE_OK);
+  return ended_ && (status == PIPELINE_OK);
 }
 
 PipelineStatus PipelineIntegrationTestBase::WaitUntilEndedOrError() {
   if (!ended_ && pipeline_status_ == PIPELINE_OK) {
     base::RunLoop run_loop;
-    RunUntilIdleOrEndedOrError(&run_loop);
+    RunUntilQuitOrEndedOrError(&run_loop);
   } else {
     scoped_task_environment_.RunUntilIdle();
   }
@@ -293,7 +290,7 @@
       this,
       base::Bind(&PipelineIntegrationTestBase::OnStatusCallback,
                  base::Unretained(this), run_loop.QuitWhenIdleClosure()));
-  RunUntilIdleOrEndedOrError(&run_loop);
+  RunUntilQuitOrEndedOrError(&run_loop);
   return pipeline_status_;
 }
 
@@ -361,7 +358,7 @@
 
   pipeline_->Seek(seek_time, base::Bind(&PipelineIntegrationTestBase::OnSeeked,
                                         base::Unretained(this), seek_time));
-  RunUntilIdle(&run_loop);
+  RunUntilQuit(&run_loop);
   return (pipeline_status_ == PIPELINE_OK);
 }
 
@@ -370,7 +367,7 @@
   pipeline_->Suspend(base::Bind(&PipelineIntegrationTestBase::OnStatusCallback,
                                 base::Unretained(this),
                                 run_loop.QuitWhenIdleClosure()));
-  RunUntilIdle(&run_loop);
+  RunUntilQuit(&run_loop);
   return (pipeline_status_ == PIPELINE_OK);
 }
 
@@ -385,7 +382,7 @@
                     seek_time,
                     base::Bind(&PipelineIntegrationTestBase::OnSeeked,
                                base::Unretained(this), seek_time));
-  RunUntilIdle(&run_loop);
+  RunUntilQuit(&run_loop);
   return (pipeline_status_ == PIPELINE_OK);
 }
 
@@ -431,7 +428,7 @@
                      run_loop.QuitWhenIdleClosure()),
       base::TimeDelta::FromMilliseconds(10));
 
-  RunUntilIdleOrEndedOrError(&run_loop);
+  RunUntilQuitOrEndedOrError(&run_loop);
 
   return (pipeline_status_ == PIPELINE_OK);
 }
@@ -649,7 +646,7 @@
                    base::Unretained(encrypted_media)));
   }
 
-  RunUntilIdleOrEndedOrError(&run_loop);
+  RunUntilQuitOrEndedOrError(&run_loop);
 
   for (auto* stream : demuxer_->GetAllStreams()) {
     EXPECT_TRUE(stream->SupportsConfigChanges());
@@ -658,35 +655,21 @@
   return pipeline_status_;
 }
 
-void PipelineIntegrationTestBase::RunUntilIdle(base::RunLoop* run_loop) {
-  RunUntilIdleEndedOrErrorInternal(run_loop, false, false);
+void PipelineIntegrationTestBase::RunUntilQuit(base::RunLoop* run_loop) {
+  run_loop->Run();
+  on_ended_closure_ = base::OnceClosure();
+  on_error_closure_ = base::OnceClosure();
+  scoped_task_environment_.RunUntilIdle();
 }
 
-void PipelineIntegrationTestBase::RunUntilIdleOrEnded(base::RunLoop* run_loop) {
-  RunUntilIdleEndedOrErrorInternal(run_loop, true, false);
-}
-
-void PipelineIntegrationTestBase::RunUntilIdleOrEndedOrError(
+void PipelineIntegrationTestBase::RunUntilQuitOrEndedOrError(
     base::RunLoop* run_loop) {
-  RunUntilIdleEndedOrErrorInternal(run_loop, true, true);
-}
-
-void PipelineIntegrationTestBase::RunUntilIdleEndedOrErrorInternal(
-    base::RunLoop* run_loop,
-    bool run_until_ended,
-    bool run_until_error) {
   DCHECK(on_ended_closure_.is_null());
   DCHECK(on_error_closure_.is_null());
 
-  if (run_until_ended)
-    on_ended_closure_ = run_loop->QuitWhenIdleClosure();
-  if (run_until_error)
-    on_error_closure_ = run_loop->QuitWhenIdleClosure();
-  run_loop->Run();
-  on_ended_closure_ = base::Closure();
-  on_error_closure_ = base::Closure();
-
-  scoped_task_environment_.RunUntilIdle();
+  on_ended_closure_ = run_loop->QuitWhenIdleClosure();
+  on_error_closure_ = run_loop->QuitWhenIdleClosure();
+  RunUntilQuit(run_loop);
 }
 
 base::TimeTicks DummyTickClock::NowTicks() const {
diff --git a/media/test/pipeline_integration_test_base.h b/media/test/pipeline_integration_test_base.h
index 65c54f6..aa27784 100644
--- a/media/test/pipeline_integration_test_base.h
+++ b/media/test/pipeline_integration_test_base.h
@@ -252,19 +252,16 @@
   MOCK_METHOD1(OnVideoDecoderChange, void(const std::string&));
 
  private:
-  // Helpers that run |*run_loop|, where OnEnded() or OnError() are each
-  // conditionally setup to quit |*run_loop| when it becomes idle. Once
-  // |*run_loop|'s Run() Quits, these helpers also run
-  // |scoped_task_environment_| until Idle.
-  void RunUntilIdle(base::RunLoop* run_loop);
-  void RunUntilIdleOrEnded(base::RunLoop* run_loop);
-  void RunUntilIdleOrEndedOrError(base::RunLoop* run_loop);
-  void RunUntilIdleEndedOrErrorInternal(base::RunLoop* run_loop,
-                                        bool run_until_ended,
-                                        bool run_until_error);
+  // Runs |run_loop| until it is explicitly Quit() by some part of the calling
+  // test fixture. The |scoped_task_environment_| is RunUntilIdle() after the
+  // RunLoop finishes running, before returning to the caller.
+  void RunUntilQuit(base::RunLoop* run_loop);
+  // Configures |on_ended_closure_| and |on_error_closure_| to quit |run_loop|
+  // and then calls RunUntilQuit() on it.
+  void RunUntilQuitOrEndedOrError(base::RunLoop* run_loop);
 
-  base::Closure on_ended_closure_;
-  base::Closure on_error_closure_;
+  base::OnceClosure on_ended_closure_;
+  base::OnceClosure on_error_closure_;
 
   DISALLOW_COPY_AND_ASSIGN(PipelineIntegrationTestBase);
 };
diff --git a/net/proxy_resolution/proxy_resolution_service.h b/net/proxy_resolution/proxy_resolution_service.h
index de6bd2a9..61b748a 100644
--- a/net/proxy_resolution/proxy_resolution_service.h
+++ b/net/proxy_resolution/proxy_resolution_service.h
@@ -298,10 +298,14 @@
   void set_quick_check_enabled(bool value) {
     quick_check_enabled_ = value;
   }
+  bool quick_check_enabled_for_testing() const { return quick_check_enabled_; }
 
   void set_sanitize_url_policy(SanitizeUrlPolicy policy) {
     sanitize_url_policy_ = policy;
   }
+  SanitizeUrlPolicy sanitize_url_policy_for_testing() const {
+    return sanitize_url_policy_;
+  }
 
  private:
   FRIEND_TEST_ALL_PREFIXES(ProxyResolutionServiceTest,
diff --git a/net/reporting/reporting_cache.cc b/net/reporting/reporting_cache.cc
index 3a85b4b..0df7956 100644
--- a/net/reporting/reporting_cache.cc
+++ b/net/reporting/reporting_cache.cc
@@ -335,11 +335,14 @@
         std::vector<base::Value> endpoint_list;
         for (const ReportingClient* client : clients) {
           base::Value endpoint_dict(base::Value::Type::DICTIONARY);
-          // Reporting defines the group as a whole to have an expiration time,
-          // not the individual endpoints within the group.
+          // Reporting defines the group as a whole to have an expiration time
+          // and subdomains flag, not the individual endpoints within the group.
           group_dict.SetKey(
               "expires",
               base::Value(NetLog::TickCountToString(client->expires)));
+          group_dict.SetKey("includeSubdomains",
+                            base::Value(client->subdomains ==
+                                        ReportingClient::Subdomains::INCLUDE));
           endpoint_dict.SetKey("url", base::Value(client->endpoint.spec()));
           endpoint_dict.SetKey("priority", base::Value(client->priority));
           endpoint_dict.SetKey("weight", base::Value(client->weight));
diff --git a/net/reporting/reporting_cache_unittest.cc b/net/reporting/reporting_cache_unittest.cc
index fbd6e92..a2fbb9e 100644
--- a/net/reporting/reporting_cache_unittest.cc
+++ b/net/reporting/reporting_cache_unittest.cc
@@ -409,7 +409,7 @@
   const base::TimeTicks expires =
       base::TimeTicks() + base::TimeDelta::FromDays(7);
   SetClient(kOrigin1_, kEndpoint1_, false, kGroup1_, expires);
-  SetClient(kOrigin2_, kEndpoint2_, false, kGroup1_, expires);
+  SetClient(kOrigin2_, kEndpoint2_, true, kGroup1_, expires);
 
   // Add some reports so that we can test the upload counts.
   const ReportingReport* report1a = AddAndReturnReport(
@@ -433,6 +433,7 @@
             {
               "name": "group1",
               "expires": "604800000",
+              "includeSubdomains": false,
               "endpoints": [
                 {"url": "https://endpoint1/", "priority": 0, "weight": 1,
                  "successful": {"uploads": 1, "reports": 2},
@@ -447,6 +448,7 @@
             {
               "name": "group1",
               "expires": "604800000",
+              "includeSubdomains": true,
               "endpoints": [
                 {"url": "https://endpoint2/", "priority": 0, "weight": 1,
                  "successful": {"uploads": 0, "reports": 0},
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index a0a2ee2..47f79b9 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -431,6 +431,12 @@
       std::move(network_context_params->proxy_config_client_request),
       std::move(network_context_params->initial_proxy_config),
       std::move(network_context_params->proxy_config_poller_client)));
+  builder->set_pac_quick_check_enabled(
+      network_context_params->pac_quick_check_enabled);
+  builder->set_pac_sanitize_url_policy(
+      network_context_params->dangerously_allow_pac_access_to_secure_urls
+          ? net::ProxyResolutionService::SanitizeUrlPolicy::UNSAFE
+          : net::ProxyResolutionService::SanitizeUrlPolicy::SAFE);
 
   std::unique_ptr<PrefService> pref_service;
   if (network_context_params->http_server_properties_path) {
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc
index 39d1d99..a193fed4 100644
--- a/services/network/network_context_unittest.cc
+++ b/services/network/network_context_unittest.cc
@@ -1158,6 +1158,59 @@
   EXPECT_EQ("foopy", proxy_info.proxy_server().host_port_pair().host());
 }
 
+TEST_F(NetworkContextTest, PacQuickCheck) {
+  // Check the default value.
+  std::unique_ptr<NetworkContext> network_context =
+      CreateContextWithParams(CreateContextParams());
+  EXPECT_TRUE(network_context->url_request_context()
+                  ->proxy_resolution_service()
+                  ->quick_check_enabled_for_testing());
+
+  // Explicitly enable.
+  mojom::NetworkContextParamsPtr context_params = CreateContextParams();
+  context_params->pac_quick_check_enabled = true;
+  network_context = CreateContextWithParams(std::move(context_params));
+  EXPECT_TRUE(network_context->url_request_context()
+                  ->proxy_resolution_service()
+                  ->quick_check_enabled_for_testing());
+
+  // Explicitly disable.
+  context_params = CreateContextParams();
+  context_params->pac_quick_check_enabled = false;
+  network_context = CreateContextWithParams(std::move(context_params));
+  EXPECT_FALSE(network_context->url_request_context()
+                   ->proxy_resolution_service()
+                   ->quick_check_enabled_for_testing());
+}
+
+TEST_F(NetworkContextTest, DangerouslyAllowPacAccessToSecureURLs) {
+  // Check the default value.
+  std::unique_ptr<NetworkContext> network_context =
+      CreateContextWithParams(CreateContextParams());
+  EXPECT_EQ(net::ProxyResolutionService::SanitizeUrlPolicy::SAFE,
+            network_context->url_request_context()
+                ->proxy_resolution_service()
+                ->sanitize_url_policy_for_testing());
+
+  // Explicitly disable.
+  mojom::NetworkContextParamsPtr context_params = CreateContextParams();
+  context_params->dangerously_allow_pac_access_to_secure_urls = false;
+  network_context = CreateContextWithParams(std::move(context_params));
+  EXPECT_EQ(net::ProxyResolutionService::SanitizeUrlPolicy::SAFE,
+            network_context->url_request_context()
+                ->proxy_resolution_service()
+                ->sanitize_url_policy_for_testing());
+
+  // Explicitly enable.
+  context_params = CreateContextParams();
+  context_params->dangerously_allow_pac_access_to_secure_urls = true;
+  network_context = CreateContextWithParams(std::move(context_params));
+  EXPECT_EQ(net::ProxyResolutionService::SanitizeUrlPolicy::UNSAFE,
+            network_context->url_request_context()
+                ->proxy_resolution_service()
+                ->sanitize_url_policy_for_testing());
+}
+
 class TestProxyConfigLazyPoller : public mojom::ProxyConfigPollerClient {
  public:
   TestProxyConfigLazyPoller() : binding_(this) {}
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom
index 4739dc1..7f1e32445 100644
--- a/services/network/public/mojom/network_service.mojom
+++ b/services/network/public/mojom/network_service.mojom
@@ -110,6 +110,17 @@
   // ProxyConfigServices be modified not to need this notification?
   ProxyConfigPollerClient? proxy_config_poller_client;
 
+  // When PAC quick checking is enabled, DNS lookups for PAC script's host are
+  // timed out aggressively. This prevents hanging all network request on DNS
+  // lookups that are slow or are blockholed, at the cost of making it more
+  // likely that the network service erroneously fails to fetch a PAC file.
+  bool pac_quick_check_enabled = true;
+
+  // When enabled, exposes full URLs to PAC scripts. This setting will be
+  // removed in the future.
+  // See https://crbug.com/619087
+  bool dangerously_allow_pac_access_to_secure_urls = false;
+
   // Only used on OS_CHROMEOS platform.
   bool allow_gssapi_library_load = false;
 
diff --git a/services/resource_coordinator/public/cpp/system_resource_coordinator.cc b/services/resource_coordinator/public/cpp/system_resource_coordinator.cc
index 2acd815..fffdcd5 100644
--- a/services/resource_coordinator/public/cpp/system_resource_coordinator.cc
+++ b/services/resource_coordinator/public/cpp/system_resource_coordinator.cc
@@ -15,10 +15,11 @@
 
 SystemResourceCoordinator::~SystemResourceCoordinator() = default;
 
-void SystemResourceCoordinator::OnProcessCPUUsageReady() {
+void SystemResourceCoordinator::DistributeMeasurementBatch(
+    mojom::ProcessResourceMeasurementBatchPtr batch) {
   if (!service_)
     return;
-  service_->OnProcessCPUUsageReady();
+  service_->DistributeMeasurementBatch(std::move(batch));
 }
 
 void SystemResourceCoordinator::ConnectToService(
diff --git a/services/resource_coordinator/public/cpp/system_resource_coordinator.h b/services/resource_coordinator/public/cpp/system_resource_coordinator.h
index 5db99a2..3f205ff 100644
--- a/services/resource_coordinator/public/cpp/system_resource_coordinator.h
+++ b/services/resource_coordinator/public/cpp/system_resource_coordinator.h
@@ -18,7 +18,8 @@
   SystemResourceCoordinator(service_manager::Connector* connector);
   ~SystemResourceCoordinator() override;
 
-  void OnProcessCPUUsageReady();
+  void DistributeMeasurementBatch(
+      mojom::ProcessResourceMeasurementBatchPtr batch);
 
  private:
   void ConnectToService(mojom::CoordinationUnitProviderPtr& provider,
diff --git a/services/video_capture/public/mojom/producer.mojom b/services/video_capture/public/mojom/producer.mojom
index 6f927aa..8db6d95 100644
--- a/services/video_capture/public/mojom/producer.mojom
+++ b/services/video_capture/public/mojom/producer.mojom
@@ -4,8 +4,6 @@
 
 module video_capture.mojom;
 
-import "media/mojo/interfaces/media_types.mojom";
-
 // An interface for providing buffer info updates to the producer of
 // video frames for the associated |VirtualDevice| interface.
 interface Producer {
diff --git a/services/video_capture/public/mojom/receiver.mojom b/services/video_capture/public/mojom/receiver.mojom
index 7ac3f612..abcd62d5 100644
--- a/services/video_capture/public/mojom/receiver.mojom
+++ b/services/video_capture/public/mojom/receiver.mojom
@@ -5,7 +5,6 @@
 module video_capture.mojom;
 
 import "media/capture/mojom/video_capture_types.mojom";
-import "media/mojo/interfaces/media_types.mojom";
 
 // Empty interface for encapsulating scoped access permission to a Buffer.
 interface ScopedAccessPermission {};
diff --git a/services/video_capture/public/mojom/virtual_device.mojom b/services/video_capture/public/mojom/virtual_device.mojom
index 677741c9..bc474a2 100644
--- a/services/video_capture/public/mojom/virtual_device.mojom
+++ b/services/video_capture/public/mojom/virtual_device.mojom
@@ -5,7 +5,6 @@
 module video_capture.mojom;
 
 import "media/capture/mojom/video_capture_types.mojom";
-import "media/mojo/interfaces/media_types.mojom";
 import "services/video_capture/public/mojom/producer.mojom";
 import "ui/gfx/geometry/mojo/geometry.mojom";
 
@@ -35,7 +34,7 @@
   // |Producer.OnNewBufferHandle| and/or |Producer.OnBufferRetired|
   // will be invoked.
   RequestFrameBuffer(gfx.mojom.Size dimension,
-                 media.mojom.VideoPixelFormat pixel_format)
+                 media.mojom.VideoCapturePixelFormat pixel_format)
       => (int32 buffer_id);
 
   // Called to indicate that a video frame is ready in the given buffer
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index c1c1e2e8..1cca5c9 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -75,9 +75,6 @@
     ]
   }
 
-  defines += [ "SK_USE_SKCMS" ]
-  include_dirs += [ "//third_party/skia/third_party/skcms" ]
-
   if (skia_support_gpu) {
     include_dirs += [
       "//third_party/skia/src/gpu",
@@ -147,7 +144,7 @@
   # TODO: remove after Skia shader relocation (https://skia-review.googlesource.com/c/17927)
   include_dirs += [ "//third_party/skia/src/effects/gradients" ]
 
-  defines = []
+  defines = [ "SK_USE_SKCMS" ]
 
   if (!is_ios && !use_system_freetype) {
     defines += [ "SK_FREETYPE_MINIMUM_RUNTIME_VERSION=(((FREETYPE_MAJOR) * 0x01000000) | ((FREETYPE_MINOR) * 0x00010000) | ((FREETYPE_PATCH) * 0x00000100))" ]
@@ -348,12 +345,6 @@
     sources += [ "//third_party/skia/src/core/SkUtilsArm.cpp" ]
   }
 
-  # skcms
-  sources += [
-    "//third_party/skia/src/core/SkColorSpaceXform_skcms.cpp",
-    "//third_party/skia/third_party/skcms/skcms.c",
-  ]
-
   # GPU
   if (skia_support_gpu) {
     sources += skia_gpu_sources
@@ -560,6 +551,10 @@
   if (is_fuchsia) {
     deps += [ "//third_party/expat" ]
   }
+
+  # skcms
+  deps += [ "//third_party/skia/third_party/skcms" ]
+  sources += [ "//third_party/skia/src/core/SkColorSpaceXform_skcms.cpp" ]
 }
 
 # Template for things that are logically part of :skia, but need to be split out
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index d3f753d..92254d8 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -443,6 +443,20 @@
     "gtest_tests": [
       {
         "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.base_unittests.filter"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1"
+            }
+          ]
+        },
+        "test": "base_unittests"
+      },
+      {
+        "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter"
         ],
         "swarming": {
diff --git a/testing/buildbot/filters/mac_window_server_killers.browser_tests.filter b/testing/buildbot/filters/mac_window_server_killers.browser_tests.filter
index 29ca61d..5de800a8 100644
--- a/testing/buildbot/filters/mac_window_server_killers.browser_tests.filter
+++ b/testing/buildbot/filters/mac_window_server_killers.browser_tests.filter
@@ -37,8 +37,8 @@
 # -DownloadTest.*
 # -PolicyTest.*
 # -SessionRestoreTest.*
--InstallableManagerBrowserTest.*
--ContextMenuBrowserTest.*
--ChromeSitePerProcessTest.*
--InterstitialUITest.*
+# -InstallableManagerBrowserTest.*
+# -ContextMenuBrowserTest.*
+# -ChromeSitePerProcessTest.*
+# -InterstitialUITest.*
 -ConstrainedWebDialogBrowserTest.*
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 6052459..3866e1e1 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -84,10 +84,6 @@
     ],
   },
   'base_unittests': {
-    'remove_from': [
-      # chromium.linux
-      'Fuchsia x64',
-    ],
     'modifications': {
       # chromium.android
       'KitKat Tablet Tester': {
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index f78bf07..97dcf8a3 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -57,7 +57,7 @@
 crbug.com/714962 accessibility/bounds-calc.html [ Failure ]
 crbug.com/591099 accessibility/canvas-fallback-content-2.html [ Timeout ]
 crbug.com/591099 accessibility/computed-name.html [ Timeout ]
-crbug.com/591099 accessibility/computed-role.html [ Timeout ]
+crbug.com/591099 accessibility/computed-role.html [ Pass Timeout ]
 crbug.com/714962 accessibility/css-first-letter-children.html [ Failure ]
 crbug.com/591099 accessibility/css-generated-content.html [ Failure ]
 crbug.com/591099 accessibility/css-styles.html [ Failure ]
@@ -701,7 +701,7 @@
 crbug.com/591099 external/wpt/editing/run/removeformat.html [ Timeout ]
 crbug.com/591099 external/wpt/editing/run/strikethrough.html [ Timeout ]
 crbug.com/591099 external/wpt/editing/run/subscript.html [ Timeout ]
-crbug.com/591099 external/wpt/editing/run/superscript.html [ Timeout ]
+crbug.com/591099 external/wpt/editing/run/superscript.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/editing/run/underline.html [ Failure Timeout ]
 crbug.com/591099 external/wpt/encoding/api-invalid-label.html [ Timeout ]
 crbug.com/591099 external/wpt/encoding/legacy-mb-japanese/euc-jp/eucjp-decode-cseucpkdfmtjapanese.html [ Timeout ]
@@ -899,7 +899,7 @@
 crbug.com/591099 external/wpt/svg/linking/reftests/href-filter-element.html [ Failure ]
 crbug.com/591099 external/wpt/url/a-element-xhtml.xhtml [ Failure Pass ]
 crbug.com/591099 external/wpt/url/interfaces.any.html [ Failure Pass ]
-crbug.com/591099 external/wpt/url/url-setters.html [ Timeout ]
+crbug.com/591099 external/wpt/url/url-setters.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/wasm/wasm_local_iframe_test.html [ Failure ]
 crbug.com/591099 external/wpt/web-animations/animation-model/animation-types/addition-per-property.html [ Failure Pass ]
 crbug.com/591099 external/wpt/web-animations/animation-model/animation-types/interpolation-per-property.html [ Timeout ]
@@ -1021,7 +1021,7 @@
 crbug.com/591099 fast/css-grid-layout/grid-baseline-margins.html [ Pass ]
 crbug.com/591099 fast/css-grid-layout/grid-columns-rows-get-set-multiple.html [ Timeout ]
 crbug.com/591099 fast/css-grid-layout/grid-columns-rows-get-set.html [ Timeout ]
-crbug.com/591099 fast/css-grid-layout/grid-item-column-row-get-set.html [ 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-item-overflow.html [ Failure ]
 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 ]
@@ -1158,7 +1158,7 @@
 crbug.com/714962 fast/events/event-on-culled_inline.html [ Failure ]
 crbug.com/591099 fast/events/keyboardevent-getModifierState.html [ Timeout ]
 crbug.com/714962 fast/events/middleClickAutoscroll-latching.html [ Pass Timeout ]
-crbug.com/714962 fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure ]
+crbug.com/714962 fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure Pass ]
 crbug.com/591099 fast/events/mouse-event-buttons-attribute.html [ Timeout ]
 crbug.com/591099 fast/events/mouse-relative-position.html [ Failure ]
 crbug.com/591099 fast/events/mouseevent-getModifierState.html [ Timeout ]
@@ -1418,7 +1418,7 @@
 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-auto-content-in-cell.html [ Failure Pass ]
 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 ]
@@ -1540,6 +1540,7 @@
 crbug.com/591099 fast/text/selection/selection-rect-rounding.html [ Failure ]
 crbug.com/591099 fast/text/selection/selection-with-inline-padding.html [ Failure ]
 crbug.com/714962 fast/text/selection/shaping-selection-rect.html [ Failure ]
+crbug.com/591099 fast/text/text-combine-first-line-crash.html [ Crash ]
 crbug.com/714962 fast/text/transform-text-first-line-capitalize.html [ Failure ]
 crbug.com/714962 fast/text/transform-text-first-line-lowercase.html [ Failure ]
 crbug.com/714962 fast/text/transform-text-first-line.html [ Failure ]
@@ -2060,7 +2061,7 @@
 crbug.com/591099 virtual/layout_ng/ [ Skip ]
 crbug.com/824918 virtual/layout_ng_experimental/ [ Skip ]
 crbug.com/836297 virtual/layout_ng_experimental/printing/webgl-oversized-printing.html [ Pass Timeout ]
-crbug.com/591099 virtual/modern-media-controls/media/controls/modern/tap-to-hide-controls.html [ Failure ]
+crbug.com/591099 media/controls/modern/tap-to-hide-controls.html [ Failure ]
 crbug.com/714962 virtual/mouseevent_fractional/fast/events/drag-in-frames.html [ Failure ]
 crbug.com/714962 virtual/mouseevent_fractional/fast/events/event-on-culled_inline.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/hr-timestamp/input-events.html [ Failure Pass ]
@@ -2095,6 +2096,16 @@
 crbug.com/591099 virtual/spv2/paint/invalidation/box/margin.html [ Failure Pass ]
 crbug.com/591099 virtual/stable/ [ Skip ]
 crbug.com/591099 virtual/threaded/ [ Skip ]
+crbug.com/591099 virtual/video-surface-layer/media/audio-controls-rendering.html [ Failure ]
+crbug.com/591099 virtual/video-surface-layer/media/media-document-audio-repaint.html [ Failure ]
+crbug.com/591099 virtual/video-surface-layer/media/video-aspect-ratio.html [ Failure ]
+crbug.com/591099 virtual/video-surface-layer/media/video-colorspace-yuv420.html [ Failure ]
+crbug.com/591099 virtual/video-surface-layer/media/video-colorspace-yuv422.html [ Failure ]
+crbug.com/591099 virtual/video-surface-layer/media/video-display-toggle.html [ Failure ]
+crbug.com/591099 virtual/video-surface-layer/media/video-layer-crash.html [ Failure ]
+crbug.com/591099 virtual/video-surface-layer/media/video-poster-scale.html [ Failure ]
+crbug.com/591099 virtual/video-surface-layer/media/video-replaces-poster.html [ Failure ]
+crbug.com/591099 virtual/video-surface-layer/media/video-zoom.html [ Failure ]
 crbug.com/591099 virtual/wheelscrolllatching/ [ Skip ]
 crbug.com/591099 webaudio/BiquadFilter/tail-time-lowpass.html [ Timeout ]
 crbug.com/591099 webexposed/element-instance-property-listing.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees
index a3c7c720..8efc6b30 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees
@@ -99,7 +99,6 @@
 Bug(none) virtual/longtask-v2/ [ Skip ]
 Bug(none) virtual/mac-antialiasedtext/ [ Skip ]
 Bug(none) virtual/media-gpu-accelerated/ [ Skip ]
-Bug(none) virtual/modern-media-controls/ [ Skip ]
 Bug(none) virtual/mojo-notifications/ [ Skip ]
 Bug(none) virtual/mouseevent_fractional/ [ Skip ]
 Bug(none) virtual/mse-1mb-buffers/ [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
index d359385..95f2bc7 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -5,6 +5,7 @@
 Bug(none) external/wpt/clear-site-data/navigation.https.html [ Timeout ]
 Bug(none) external/wpt/content-security-policy/generic/filesystem-urls-match-filesystem.sub.html [ Failure ]
 Bug(none) external/wpt/content-security-policy/inside-worker/dedicated-script.html [ Failure Timeout ]
+Bug(none) external/wpt/content-security-policy/inside-worker/dedicated-inheritance.html [ Failure ]
 Bug(none) external/wpt/html/browsers/offline/appcache/workers/appcache-worker.html [ Timeout ]
 crbug.com/829417 external/wpt/html/browsers/offline/appcache/workers/appcache-worker.https.html [ Timeout ]
 Bug(none) external/wpt/service-workers/service-worker/clients-get-client-types.https.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/NeverFixTests b/third_party/WebKit/LayoutTests/NeverFixTests
index c78f6dd..527ef2ff 100644
--- a/third_party/WebKit/LayoutTests/NeverFixTests
+++ b/third_party/WebKit/LayoutTests/NeverFixTests
@@ -1863,7 +1863,3 @@
 # in testing, whereas otherwise we do not do so if the composited layer has a
 # direct compositing reason (for performance). Only applies to SPv1.
 paint/invalidation/compositing/subpixel-offset-scaled-transform-composited.html [ WontFix ]
-
-# These tests should always fail because the modern media controls are not yet enabled
-crbug.com/761305 media/controls/modern/ [ WontFix ]
-crbug.com/761306 virtual/new-remote-playback-pipeline/media/controls/modern/ [ WontFix ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests
index a71f237..d17c8a3c 100644
--- a/third_party/WebKit/LayoutTests/SlowTests
+++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -456,7 +456,7 @@
 crbug.com/779956 [ Linux ] external/wpt/offscreen-canvas/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.worker.html [ Slow ]
 crbug.com/779956 [ Linux ] external/wpt/offscreen-canvas/drawing-images-to-the-canvas/2d.drawImage.zerosource.worker.html [ Slow ]
 
-crbug.com/793771 virtual/modern-media-controls/media/controls/modern/scrubbing.html [ Slow ]
+crbug.com/793771 media/controls/modern/scrubbing.html [ Slow ]
 crbug.com/793771 virtual/video-surface-layer/media/controls/modern/scrubbing.html [ Slow ]
 
 # These tests need to do many iterations and so can't be fast.
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 43a3250..7591d14 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1769,6 +1769,7 @@
 crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/redirected-response.https.html [ Crash ]
 crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/referer.https.html [ Crash ]
 crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/referrer-policy-header.https.html [ Crash ]
+crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/redirect-cross-origin-post.html [ Timeout Crash ]
 
 crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/upload-onload-event.html [ Crash ]
 crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/upload-onloadend-event-after-abort.html [ Crash ]
@@ -1795,7 +1796,6 @@
 crbug.com/626703 virtual/outofblink-cors/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ]
 crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https.html [ Timeout ]
 crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/cross-origin-unsupported-url.html [ Timeout ]
-crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/redirect-cross-origin-post.html [ Timeout ]
 crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/simple-cross-origin-denied-events-post.html [ Timeout ]
 crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url.html [ Timeout ]
 
@@ -1883,6 +1883,7 @@
 crbug.com/280342 [ Mac Linux Win ] http/tests/media/progress-events-generated-correctly.html [ Failure Pass ]
 
 crbug.com/520736 [ Win7 ] media/W3C/video/networkState/networkState_during_progress.html [ Failure Pass ]
+crbug.com/520736 [ Win7 ] virtual/video-surface-layer/media/W3C/video/networkState/networkState_during_progress.html [ Failure Pass ]
 
 # gpuBenchmarking.pinchBy is busted on desktops
 crbug.com/787615 [ Mac Win Linux Fuchsia ] synthetic_gestures/synthetic-pinch-zoom-gesture.html [ Failure Pass ]
@@ -2402,10 +2403,12 @@
 crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/pointerevents/pointer-event-in-slop-region.html [ Skip ]
 crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/synthetic-events/tap-on-scaled-screen.html  [ Skip ]
 crbug.com/613672 [ Mac ] virtual/scroll_customization/fast/scroll-behavior/scroll-customization/scroll-customization-property.html [ Skip ]
-crbug.com/613672 [ Mac ] virtual/modern-media-controls/media/controls/modern/tap-to-hide-controls.html [ Skip ]
+crbug.com/613672 [ Mac ] media/controls/modern/tap-to-hide-controls.html [ Skip ]
 crbug.com/613672 [ Mac ] virtual/video-surface-layer/media/controls/modern/tap-to-hide-controls.html [ Skip ]
-crbug.com/613672 [ Mac ] virtual/modern-media-controls/media/controls/modern/singletouch-on-play-button.html [ Skip ]
+crbug.com/613672 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/tap-to-hide-controls.html [ Skip ]
+crbug.com/613672 [ Mac ] media/controls/modern/singletouch-on-play-button.html [ Skip ]
 crbug.com/613672 [ Mac ] virtual/video-surface-layer/media/controls/modern/singletouch-on-play-button.html [ Skip ]
+crbug.com/613672 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/singletouch-on-play-button.html [ Skip ]
 
 # We should send PointerLeave events for stylus devices.
 crbug.com/583413 external/wpt/pointerevents/pointerevent_pointerleave_pen-manual.html  [ Failure ]
@@ -4387,20 +4390,27 @@
 
 # Double tap on modern media controls is a bit more complicated on Mac but
 # since we are not targeting Mac yet we can come back and fix this later.
-crbug.com/783154 [ Mac ] virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-backwards.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-forwards.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/modern-media-controls/media/controls/modern/doubletap-on-play-button.html [ Skip ]
-crbug.com/783154 [ Mac ] virtual/modern-media-controls/media/controls/modern/doubletap-to-toggle-fullscreen.html [ Skip ]
+crbug.com/783154 [ Mac ] media/controls/modern/doubletap-to-jump-backwards.html [ Skip ]
+crbug.com/783154 [ Mac ] media/controls/modern/doubletap-to-jump-forwards.html [ Skip ]
+crbug.com/783154 [ Mac ] media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Skip ]
+crbug.com/783154 [ Mac ] media/controls/modern/doubletap-on-play-button.html [ Skip ]
+crbug.com/783154 [ Mac ] media/controls/modern/doubletap-to-toggle-fullscreen.html [ Skip ]
 crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/modern/doubletap-to-jump-backwards.html [ Skip ]
 crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/modern/doubletap-to-jump-forwards.html [ Skip ]
 crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Skip ]
 crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/modern/doubletap-on-play-button.html [ Skip ]
 crbug.com/783154 [ Mac ] virtual/video-surface-layer/media/controls/modern/doubletap-to-toggle-fullscreen.html [ Skip ]
+crbug.com/783154 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-to-jump-backwards.html [ Skip ]
+crbug.com/783154 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-to-jump-forwards.html [ Skip ]
+crbug.com/783154 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Skip ]
+crbug.com/783154 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-on-play-button.html [ Skip ]
+crbug.com/783154 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-to-toggle-fullscreen.html [ Skip ]
 
 # Seen flaky on Linux, suppressing on Windows as well
-crbug.com/831720 [ Win Linux ] virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
-crbug.com/831720 [ Win Linux ] virtual/modern-media-controls/media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
+crbug.com/831720 [ Win Linux ] media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
+crbug.com/831720 [ Win Linux ] virtual/new-remote-playback-pipeline/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Pass Failure ]
+crbug.com/831720 [ Win Linux ] media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
+crbug.com/831720 [ Win Linux ] virtual/new-remote-playback-pipeline/media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
 crbug.com/831720 [ Win Linux ] virtual/video-surface-layer/media/controls/modern/tap-to-hide-controls.html [ Pass Failure ]
 
 crbug.com/802915 css3/blending/isolation-should-include-non-local-background.html [ Failure ]
@@ -4419,7 +4429,8 @@
 crbug.com/798572 virtual/enable_wasm/external/wpt/wasm/wasm_service_worker_test.https.html [ Failure ]
 
 # Does not work on Mac
-crbug.com/793771 [ Mac ] virtual/modern-media-controls/media/controls/modern/scrubbing.html [ Skip ]
+crbug.com/793771 [ Mac ] media/controls/modern/scrubbing.html [ Skip ]
+crbug.com/793771 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/scrubbing.html [ Skip ]
 
 crbug.com/797138 external/wpt/credential-management/federatedcredential-framed-get.sub.https.html [ Crash ]
 crbug.com/797138 external/wpt/credential-management/passwordcredential-framed-get.sub.https.html [ Crash ]
@@ -4435,7 +4446,7 @@
 # Sheriff failures 2018-01-03
 crbug.com/798680 external/wpt/pointerevents/pointerlock/pointerevent_pointerlock_supercedes_capture-manual.html [ Pass Timeout ]
 crbug.com/804682 [ Mac ] external/wpt/service-workers/service-worker/navigation-preload/resource-timing.https.html [ Pass Failure ]
-crbug.com/799137 [ Mac ] virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-backwards-at-start.html [ Pass Timeout ]
+crbug.com/799137 [ Mac ] media/controls/modern/doubletap-to-jump-backwards-at-start.html [ Pass Timeout ]
 
 # This test is flaking (failing, crashing) on mac_chromium_rel_ng.
 crbug.com/800840 [ Mac ] virtual/wheelscrolllatching/fast/compositor-wheel-scroll-latching/animated-scroll/touchpad-scroll-impl-to-main.html [ Skip ]
@@ -4669,3 +4680,5 @@
 crbug.com/836783 fast/peerconnection/RTCRtpSender-setParameters.html [ Pass Timeout ]
 
 crbug.com/838254 virtual/video-surface-layer/media/webkit-media-controls-webkit-appearance.html [ Failure ]
+
+crbug.com/839332 [ Mac ] virtual/video-surface-layer/media/video-no-audio.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites
index d29aad5..90e9d3b 100644
--- a/third_party/WebKit/LayoutTests/VirtualTestSuites
+++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -633,11 +633,6 @@
     "args": ["--enable-blink-features=SlotInFlatTree,IncrementalShadowDOM"]
   },
   {
-    "prefix": "modern-media-controls",
-    "base": "media/controls/modern",
-    "args": ["--enable-features=UseModernMediaControls"]
-  },
-  {
     "prefix": "unified-autoplay",
     "base": "external/wpt/feature-policy",
     "args": ["--autoplay-policy=document-user-activation-required"]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index 19ca48c3..da304c2 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -91895,6 +91895,18 @@
      {}
     ]
    ],
+   "html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode.html": [
+    [
+     "/html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode.html",
+     [
+      [
+       "/html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "html/rendering/replaced-elements/images/space.html": [
     [
      "/html/rendering/replaced-elements/images/space.html",
@@ -99013,6 +99025,11 @@
      {}
     ]
    ],
+   "FileAPI/historical.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "FileAPI/reading-data-section/support/blue-100x100.png": [
     [
      {}
@@ -148778,6 +148795,11 @@
      {}
     ]
    ],
+   "html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode-ref.html": [
+    [
+     {}
+    ]
+   ],
    "html/rendering/replaced-elements/image-maps-0/.gitkeep": [
     [
      {}
@@ -254286,8 +254308,12 @@
    "fa1e9bd48a2e1f5fe91e6f9b3aa401b4ccf15dfa",
    "support"
   ],
+  "FileAPI/historical.https-expected.txt": [
+   "428665e730ea0722d498c21ded7d16f19e8f3af7",
+   "support"
+  ],
   "FileAPI/historical.https.html": [
-   "e1cf63d05a0e401cc38a11d2b42efb9e8d315610",
+   "8a0e866521c4cbfb010260c29777f1c93101a576",
    "testharness"
   ],
   "FileAPI/idlharness.html": [
@@ -277035,7 +277061,7 @@
    "reftest"
   ],
   "css/css-backgrounds/background-clip-content-box-001.html": [
-   "0274ddcafae18210539741524c8d142adfabfed6",
+   "edfac77c12fb04febf258794980b4e11645c7d9b",
    "reftest"
   ],
   "css/css-backgrounds/background-clip-content-box.html": [
@@ -279695,7 +279721,7 @@
    "support"
   ],
   "css/css-backgrounds/reference/background-clip-content-box-ref.html": [
-   "8d6167560bb724cd2cabb59984821bb2569945c8",
+   "a818d18fc2089057ae818e20e4263ee2b0d88ad8",
    "support"
   ],
   "css/css-backgrounds/reference/background-image-001-ref.html": [
@@ -346970,6 +346996,14 @@
    "9c96574d448d5df8aeb64bcdda404660e99d815f",
    "support"
   ],
+  "html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode-ref.html": [
+   "0f71104298fa4dbfa07139c34f1735279f78a1c7",
+   "support"
+  ],
+  "html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode.html": [
+   "5b111e4a102e7d1795a9a68daad92dda9fa707d3",
+   "reftest"
+  ],
   "html/rendering/replaced-elements/image-maps-0/.gitkeep": [
    "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/FileAPI/historical.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/FileAPI/historical.https-expected.txt
new file mode 100644
index 0000000..0542764
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/FileAPI/historical.https-expected.txt
@@ -0,0 +1,16 @@
+This is a testharness.js-based test.
+PASS "toNativeLineEndings" should not be supported
+PASS "FileError" should not be supported
+PASS "FileException" should not be supported
+PASS "FileHandle" should not be supported
+PASS "FileRequest" should not be supported
+PASS "MutableFile" should not be supported
+PASS Blob should not support slice prefixed
+PASS BlobBuilder should not be supported.
+PASS createFor method should not be supported
+PASS Blob.close() should not be supported
+FAIL File's lastModifiedDate should not be supported assert_false: expected false got true
+PASS Service worker test setup
+PASS "FileReaderSync" should not be supported in service workers
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/FileAPI/historical.https.html b/third_party/WebKit/LayoutTests/external/wpt/FileAPI/historical.https.html
index 877aed0..4f841f1 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/FileAPI/historical.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/FileAPI/historical.https.html
@@ -53,9 +53,13 @@
         assert_false('isClosed' in Blob.prototype, 'isClosed in Blob.prototype');
     }, 'Blob.close() should not be supported');
 
-    // Only add service worker test if service workers are actually supported.
-    if (navigator.serviceWorker)
-      service_worker_test('support/historical-serviceworker.js', 'Service worker test setup');
+    test(() => {
+      const f = new File([], "");
+      assert_false("lastModifiedDate" in f);
+      assert_false("lastModifiedDate" in File.prototype);
+    }, "File's lastModifiedDate should not be supported");
+
+    service_worker_test('support/historical-serviceworker.js', 'Service worker test setup');
   </script>
  </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-clip-content-box-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-clip-content-box-001.html
index a3b8436a..f0777e8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-clip-content-box-001.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-clip-content-box-001.html
@@ -1,36 +1,25 @@
 <!DOCTYPE html>
-<html>
-<head>
-    <title>CSS Backgrounds and Borders Test: background-clip Reference</title>
-    <link rel="author" title="James Wang" href="mailto:wangjian@ucweb.com">
-	<link rel="help" href="http://www.w3.org/TR/css3-background/#the-background-clip" />
-    <meta name="flags" content="">
-    <meta name="assert" content="background-clip with content-box means paint the background within the content box">
-
-    <link rel="match" href="reference/background-clip-content-box-ref.html">
-
-    <style type="text/css">
-    	* { padding: 0; margin: 0; }
-    	#test-color-blue {
-    		background-color: blue;
-    		height: 200px;
-            position: absolute;
-    		width: 200px;
-    	}
-    	#test-color-green {
-    		background-clip: content-box;
-    		background-color: rgba(0, 255, 0, 1);
-    		height: 180px;
-    		padding: 10px;
-            position: absolute;
-    		width: 180px;
-    	}
-    </style>
-</head>
-<body>
-    <p>Test pass if the green box has a 10px width blue edge</p>
-    <!-- background -->
-    <div id="test-color-blue"></div>
-    <div id="test-color-green"></div>
-</body>
-</html>
+<title>CSS Backgrounds and Borders Test: background-clip Reference</title>
+<link rel="author" title="James Wang" href="mailto:wangjian@ucweb.com">
+<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#the-background-clip">
+<link rel="match" href="reference/background-clip-content-box-ref.html">
+<style>
+#test-color-blue {
+  background-color: blue;
+  height: 200px;
+  position: absolute;
+  width: 200px;
+}
+#test-color-orange {
+  background-clip: content-box;
+  background-color: rgba(255, 165, 0, 1);
+  height: 180px;
+  padding: 10px;
+  position: absolute;
+  width: 180px;
+}
+</style>
+<p>Test passes if the orange box has a 10px width blue edge.</p>
+<!-- background -->
+<div id="test-color-blue"></div>
+<div id="test-color-orange"></div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/reference/background-clip-content-box-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/reference/background-clip-content-box-ref.html
index 133e57a..dc6d9a0 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/reference/background-clip-content-box-ref.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/reference/background-clip-content-box-ref.html
@@ -1,22 +1,15 @@
 <!DOCTYPE html>
-<html>
-<head>
-    <title>CSS Backgrounds and Borders Test: background-clip Reference</title>
-    <link rel="author" title="James Wang" href="mailto:wangjian@ucweb.com">
-    <style type="text/css">
-    	* { padding: 0; margin: 0; }
-    	#test-color-box {
-            position: absolute;
-    		width: 180px;
-    		height: 180px;
-    		background-color: rgba(0, 255, 0, 1);
-            border: 10px solid blue;
-    	}
-    </style>
-</head>
-<body>
-    <p>Test pass if the green box has a 10px width blue edge</p>
-    <!-- background -->
-    <div id="test-color-box"></div>
-</body>
-</html>
+<title>CSS Backgrounds and Borders Test: background-clip Reference</title>
+<link rel="author" title="James Wang" href="mailto:wangjian@ucweb.com">
+<style>
+#test-color-box {
+  position: absolute;
+  width: 180px;
+  height: 180px;
+  background-color: rgba(255, 165, 0, 1);
+  border: 10px solid blue;
+}
+</style>
+<p>Test passes if the orange box has a 10px width blue edge.</p>
+<!-- background -->
+<div id="test-color-box"></div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getSettings.https.html b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getSettings.https.html
index 42674ba..4c2feef3 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getSettings.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getSettings.https.html
@@ -57,4 +57,22 @@
       });
     });
   }, 'A device can be opened twice with different resolutions');
+
+  promise_test(t => {
+    return navigator.mediaDevices.enumerateDevices().then(async devices => {
+      for (var device of devices) {
+        if (device.kind == "audiooutput")
+          continue;
+        var device_id_constraint = {deviceId: {exact: device.deviceId}};
+        var constraints = device.kind == "audioinput"
+          ? {audio: device_id_constraint}
+          : {video: device_id_constraint};
+
+        var stream = await navigator.mediaDevices.getUserMedia(constraints);
+        assert_equals(stream.getTracks()[0].getSettings().groupId,
+                      device.groupId);
+        assert_true(device.groupId.length > 0);
+      }
+    });
+  }, 'groupId is correctly reported by getSettings() for all devices');
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaDevices-enumerateDevices-iframe.html b/third_party/WebKit/LayoutTests/fast/mediastream/MediaDevices-enumerateDevices-iframe.html
new file mode 100644
index 0000000..78e318d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaDevices-enumerateDevices-iframe.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<html>
+<head>
+<title>enumerateDevices: test that enumerateDevices() returns the same result on
+  a same-origin iframe.
+</title>
+</head>
+<body>
+<h1 class="instructions">Description</h1>
+<p class="instructions">This test checks that the result of the
+  <code>navigator.mediaDevices.enumerateDevices()</code> method on a same-origin
+  iframe matches the results on the main frame.</p>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+var t = async_test(
+  "Result of enumerateDevices() on an iframe matches that of the main frame",
+   {timeout: 4000});
+var iframe = document.createElement('iframe');
+window.onmessage = t.step_func(event => {
+  if (event.source != iframe.contentWindow)
+    return;
+
+  var iframe_devices = JSON.parse(event.data);
+  navigator.mediaDevices.enumerateDevices().then(main_devices => {
+    assert_equals(main_devices.length, iframe_devices.length);
+    for (var i = 0; i < main_devices.length; i++) {
+      assert_equals(main_devices[i].deviceId, iframe_devices[i].deviceId);
+      assert_equals(main_devices[i].groupId, iframe_devices[i].groupId);
+      assert_equals(main_devices[i].kind, iframe_devices[i].kind);
+      assert_equals(main_devices[i].label, iframe_devices[i].label);
+    }
+    t.done();
+  });
+});
+
+iframe.src = "resources/MediaDevices-enumerateDevices-iframe-child.html";
+document.body.appendChild(iframe);
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/resources/MediaDevices-enumerateDevices-iframe-child.html b/third_party/WebKit/LayoutTests/fast/mediastream/resources/MediaDevices-enumerateDevices-iframe-child.html
new file mode 100644
index 0000000..0425de91
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/mediastream/resources/MediaDevices-enumerateDevices-iframe-child.html
@@ -0,0 +1,5 @@
+<script>
+  navigator.mediaDevices.enumerateDevices().then(devices => {
+    window.parent.postMessage(JSON.stringify(devices), "*");
+  });
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression-expected.png b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression-expected.png
new file mode 100644
index 0000000..79cd43a9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression-expected.txt b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression-expected.txt
new file mode 100644
index 0000000..e277e977
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x202
+  LayoutBlockFlow {HTML} at (0,0) size 800x202
+    LayoutBlockFlow {BODY} at (8,8) size 784x186
+      LayoutText {#text} at (0,0) size 0x0
+layer at (8,8) size 444x184
+  LayoutIFrame {IFRAME} at (0,0) size 444x184 [border: (2px inset #EEEEEE)]
+    layer at (0,0) size 440x180
+      LayoutView at (0,0) size 440x180
+    layer at (0,0) size 440x168
+      LayoutBlockFlow {HTML} at (0,0) size 440x168
+        LayoutBlockFlow {BODY} at (8,8) size 424x152
+          LayoutImage {IMG} at (200,0) size 200x150
+          LayoutText {#text} at (0,0) size 0x0
+    layer at (8,8) size 200x150
+      LayoutImage {IMG} at (0,0) size 200x150
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression.html b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression.html
new file mode 100644
index 0000000..4e003bc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<style>
+body {
+  font: 10px Ahem;
+}
+</style>
+<body><iframe src="resources/frame-with-compression-test-images.html" allow="image-compression 'none'" width="440" height="180"></iframe></body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-legacy-formats-expected.png b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-legacy-formats-expected.png
new file mode 100644
index 0000000..9879b047
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-legacy-formats-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-legacy-formats-expected.txt b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-legacy-formats-expected.txt
new file mode 100644
index 0000000..9838c8d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-legacy-formats-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x202
+  LayoutBlockFlow {HTML} at (0,0) size 800x202
+    LayoutBlockFlow {BODY} at (8,8) size 784x186
+      LayoutText {#text} at (0,0) size 0x0
+layer at (8,8) size 444x184
+  LayoutIFrame {IFRAME} at (0,0) size 444x184 [border: (2px inset #EEEEEE)]
+    layer at (0,0) size 440x180
+      LayoutView at (0,0) size 440x180
+    layer at (0,0) size 440x168
+      LayoutBlockFlow {HTML} at (0,0) size 440x168
+        LayoutBlockFlow {BODY} at (8,8) size 424x152
+          LayoutImage {IMG} at (0,0) size 200x150
+          LayoutText {#text} at (0,0) size 0x0
+    layer at (208,8) size 200x150
+      LayoutImage {IMG} at (200,0) size 200x150
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-legacy-formats.html b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-legacy-formats.html
new file mode 100644
index 0000000..5052764
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-legacy-formats.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<style>
+body {
+  font: 10px Ahem;
+}
+</style>
+<body><iframe src="resources/frame-with-legacy-image.html" allow="legacy-image-formats 'none'" width="440" height="180"></iframe></body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/resources/Fisher-large.jpg b/third_party/WebKit/LayoutTests/http/tests/images/resources/Fisher-large.jpg
new file mode 100644
index 0000000..599137a5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/images/resources/Fisher-large.jpg
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/resources/Fisher-small.jpg b/third_party/WebKit/LayoutTests/http/tests/images/resources/Fisher-small.jpg
new file mode 100644
index 0000000..4502996
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/images/resources/Fisher-small.jpg
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/resources/Fisher.bmp b/third_party/WebKit/LayoutTests/http/tests/images/resources/Fisher.bmp
new file mode 100644
index 0000000..e6e5c02e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/images/resources/Fisher.bmp
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/resources/frame-with-compression-test-images.html b/third_party/WebKit/LayoutTests/http/tests/images/resources/frame-with-compression-test-images.html
new file mode 100644
index 0000000..cc9e116
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/images/resources/frame-with-compression-test-images.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<style>
+body {
+  font: 10px Ahem;
+}
+</style>
+<body><img src="Fisher-large.jpg"/><img src="Fisher-small.jpg"/></body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/resources/frame-with-legacy-image.html b/third_party/WebKit/LayoutTests/http/tests/images/resources/frame-with-legacy-image.html
new file mode 100644
index 0000000..00d3d5c4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/images/resources/frame-with-legacy-image.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<style>
+body {
+  font: 10px Ahem;
+}
+</style>
+<body><img src="Fisher-large.jpg"/><img src="Fisher.bmp"/></body>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps-expected.png
deleted file mode 100644
index 77a55e4..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps-expected.txt
deleted file mode 100644
index cab8077..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps-expected.txt
+++ /dev/null
@@ -1,149 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='overlap'",
-      "bounds": [300, 500],
-      "drawsContent": false,
-      "transform": 1
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='item')",
-      "position": [15, 35],
-      "bounds": [100, 210],
-      "paintInvalidations": [
-        {
-          "object": "InlineTextBox 'ipsum'",
-          "rect": [0, 80, 40, 39],
-          "reason": "geometry"
-        },
-        {
-          "object": "InlineTextBox 'lorem'",
-          "rect": [0, 80, 40, 39],
-          "reason": "geometry"
-        }
-      ]
-    }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ],
-      "flattenInheritedTransform": false
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutText #text",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'lorem'",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'ipsum'",
-      "reason": "geometry"
-    }
-  ]
-}
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='overlap'",
-      "bounds": [300, 500],
-      "drawsContent": false,
-      "transform": 1
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='item')",
-      "position": [15, 35],
-      "bounds": [100, 210],
-      "paintInvalidations": [
-        {
-          "object": "InlineTextBox 'ipsum'",
-          "rect": [0, 80, 42, 39],
-          "reason": "geometry"
-        },
-        {
-          "object": "InlineTextBox 'lorem'",
-          "rect": [0, 80, 42, 39],
-          "reason": "geometry"
-        },
-        {
-          "object": "InlineTextBox 'ipsum'",
-          "rect": [0, 160, 40, 39],
-          "reason": "geometry"
-        },
-        {
-          "object": "InlineTextBox 'lorem'",
-          "rect": [0, 160, 40, 39],
-          "reason": "geometry"
-        }
-      ]
-    }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ],
-      "flattenInheritedTransform": false
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutText #text",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'lorem'",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'ipsum'",
-      "reason": "geometry"
-    },
-    {
-      "object": "LayoutText #text",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'lorem'",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'ipsum'",
-      "reason": "geometry"
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-rls/compositing/squashing/vertical-writing-mode-squashed-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-rls/compositing/squashing/vertical-writing-mode-squashed-expected.png
deleted file mode 100644
index 07b475f..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-rls/compositing/squashing/vertical-writing-mode-squashed-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default-expected.txt
deleted file mode 100644
index 7e03694..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This tests that scrollbars always receive events even when there is an element underneath the scrollbar which swallows the event. In this case an event handler is added to the window which swallows the event but this may also happen with elements underneath of overlay scrollbars.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS receivedMousedownEvent is true
-PASS window.scrollY became 0
-PASS receivedMousedownEvent is true
-PASS subframe.scrollTop became 0
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/basic-scrollbar-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/basic-scrollbar-expected.txt
deleted file mode 100644
index 74de2d18..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/basic-scrollbar-expected.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-layer at (8,8) size 200x200 clip at (8,8) size 183x200 scrollHeight 980
-  LayoutBlockFlow {DIV} at (0,0) size 200x200
-    LayoutText {#text} at (0,0) size 35x19
-      text run at (0,0) width 35: "Hello"
-    LayoutBR {BR} at (35,15) size 0x0
-    LayoutText {#text} at (0,20) size 35x19
-      text run at (0,20) width 35: "Hello"
-    LayoutBR {BR} at (35,35) size 0x0
-    LayoutText {#text} at (0,40) size 35x19
-      text run at (0,40) width 35: "Hello"
-    LayoutBR {BR} at (35,55) size 0x0
-    LayoutText {#text} at (0,60) size 35x19
-      text run at (0,60) width 35: "Hello"
-    LayoutBR {BR} at (35,75) size 0x0
-    LayoutText {#text} at (0,80) size 35x19
-      text run at (0,80) width 35: "Hello"
-    LayoutBR {BR} at (35,95) size 0x0
-    LayoutText {#text} at (0,100) size 35x19
-      text run at (0,100) width 35: "Hello"
-    LayoutBR {BR} at (35,115) size 0x0
-    LayoutText {#text} at (0,120) size 35x19
-      text run at (0,120) width 35: "Hello"
-    LayoutBR {BR} at (35,135) size 0x0
-    LayoutText {#text} at (0,140) size 35x19
-      text run at (0,140) width 35: "Hello"
-    LayoutBR {BR} at (35,155) size 0x0
-    LayoutText {#text} at (0,160) size 35x19
-      text run at (0,160) width 35: "Hello"
-    LayoutBR {BR} at (35,175) size 0x0
-    LayoutText {#text} at (0,180) size 35x19
-      text run at (0,180) width 35: "Hello"
-    LayoutBR {BR} at (35,195) size 0x0
-    LayoutText {#text} at (0,200) size 35x19
-      text run at (0,200) width 35: "Hello"
-    LayoutBR {BR} at (35,215) size 0x0
-    LayoutText {#text} at (0,220) size 35x19
-      text run at (0,220) width 35: "Hello"
-    LayoutBR {BR} at (35,235) size 0x0
-    LayoutText {#text} at (0,240) size 35x19
-      text run at (0,240) width 35: "Hello"
-    LayoutBR {BR} at (35,255) size 0x0
-    LayoutText {#text} at (0,260) size 35x19
-      text run at (0,260) width 35: "Hello"
-    LayoutBR {BR} at (35,275) size 0x0
-    LayoutText {#text} at (0,280) size 35x19
-      text run at (0,280) width 35: "Hello"
-    LayoutBR {BR} at (35,295) size 0x0
-    LayoutText {#text} at (0,300) size 35x19
-      text run at (0,300) width 35: "Hello"
-    LayoutBR {BR} at (35,315) size 0x0
-    LayoutText {#text} at (0,320) size 35x19
-      text run at (0,320) width 35: "Hello"
-    LayoutBR {BR} at (35,335) size 0x0
-    LayoutText {#text} at (0,340) size 35x19
-      text run at (0,340) width 35: "Hello"
-    LayoutBR {BR} at (35,355) size 0x0
-    LayoutText {#text} at (0,360) size 35x19
-      text run at (0,360) width 35: "Hello"
-    LayoutBR {BR} at (35,375) size 0x0
-    LayoutText {#text} at (0,380) size 35x19
-      text run at (0,380) width 35: "Hello"
-    LayoutBR {BR} at (35,395) size 0x0
-    LayoutText {#text} at (0,400) size 35x19
-      text run at (0,400) width 35: "Hello"
-    LayoutBR {BR} at (35,415) size 0x0
-    LayoutText {#text} at (0,420) size 35x19
-      text run at (0,420) width 35: "Hello"
-    LayoutBR {BR} at (35,435) size 0x0
-    LayoutText {#text} at (0,440) size 35x19
-      text run at (0,440) width 35: "Hello"
-    LayoutBR {BR} at (35,455) size 0x0
-    LayoutText {#text} at (0,460) size 35x19
-      text run at (0,460) width 35: "Hello"
-    LayoutBR {BR} at (35,475) size 0x0
-    LayoutText {#text} at (0,480) size 35x19
-      text run at (0,480) width 35: "Hello"
-    LayoutBR {BR} at (35,495) size 0x0
-    LayoutText {#text} at (0,500) size 35x19
-      text run at (0,500) width 35: "Hello"
-    LayoutBR {BR} at (35,515) size 0x0
-    LayoutText {#text} at (0,520) size 35x19
-      text run at (0,520) width 35: "Hello"
-    LayoutBR {BR} at (35,535) size 0x0
-    LayoutText {#text} at (0,540) size 35x19
-      text run at (0,540) width 35: "Hello"
-    LayoutBR {BR} at (35,555) size 0x0
-    LayoutText {#text} at (0,560) size 35x19
-      text run at (0,560) width 35: "Hello"
-    LayoutBR {BR} at (35,575) size 0x0
-    LayoutText {#text} at (0,580) size 35x19
-      text run at (0,580) width 35: "Hello"
-    LayoutBR {BR} at (35,595) size 0x0
-    LayoutText {#text} at (0,600) size 35x19
-      text run at (0,600) width 35: "Hello"
-    LayoutBR {BR} at (35,615) size 0x0
-    LayoutText {#text} at (0,620) size 35x19
-      text run at (0,620) width 35: "Hello"
-    LayoutBR {BR} at (35,635) size 0x0
-    LayoutText {#text} at (0,640) size 35x19
-      text run at (0,640) width 35: "Hello"
-    LayoutBR {BR} at (35,655) size 0x0
-    LayoutText {#text} at (0,660) size 35x19
-      text run at (0,660) width 35: "Hello"
-    LayoutBR {BR} at (35,675) size 0x0
-    LayoutText {#text} at (0,680) size 35x19
-      text run at (0,680) width 35: "Hello"
-    LayoutBR {BR} at (35,695) size 0x0
-    LayoutText {#text} at (0,700) size 35x19
-      text run at (0,700) width 35: "Hello"
-    LayoutBR {BR} at (35,715) size 0x0
-    LayoutText {#text} at (0,720) size 35x19
-      text run at (0,720) width 35: "Hello"
-    LayoutBR {BR} at (35,735) size 0x0
-    LayoutText {#text} at (0,740) size 35x19
-      text run at (0,740) width 35: "Hello"
-    LayoutBR {BR} at (35,755) size 0x0
-    LayoutText {#text} at (0,760) size 35x19
-      text run at (0,760) width 35: "Hello"
-    LayoutBR {BR} at (35,775) size 0x0
-    LayoutText {#text} at (0,780) size 35x19
-      text run at (0,780) width 35: "Hello"
-    LayoutBR {BR} at (35,795) size 0x0
-    LayoutText {#text} at (0,800) size 35x19
-      text run at (0,800) width 35: "Hello"
-    LayoutBR {BR} at (35,815) size 0x0
-    LayoutText {#text} at (0,820) size 35x19
-      text run at (0,820) width 35: "Hello"
-    LayoutBR {BR} at (35,835) size 0x0
-    LayoutText {#text} at (0,840) size 35x19
-      text run at (0,840) width 35: "Hello"
-    LayoutBR {BR} at (35,855) size 0x0
-    LayoutText {#text} at (0,860) size 35x19
-      text run at (0,860) width 35: "Hello"
-    LayoutBR {BR} at (35,875) size 0x0
-    LayoutText {#text} at (0,880) size 35x19
-      text run at (0,880) width 35: "Hello"
-    LayoutBR {BR} at (35,895) size 0x0
-    LayoutText {#text} at (0,900) size 35x19
-      text run at (0,900) width 35: "Hello"
-    LayoutBR {BR} at (35,915) size 0x0
-    LayoutText {#text} at (0,920) size 35x19
-      text run at (0,920) width 35: "Hello"
-    LayoutBR {BR} at (35,935) size 0x0
-    LayoutText {#text} at (0,940) size 35x19
-      text run at (0,940) width 35: "Hello"
-    LayoutBR {BR} at (35,955) size 0x0
-    LayoutText {#text} at (0,960) size 35x19
-      text run at (0,960) width 35: "Hello"
-    LayoutBR {BR} at (35,975) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-appearance-property-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-appearance-property-expected.txt
deleted file mode 100644
index 32cc836..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-appearance-property-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x86
-  LayoutBlockFlow {HTML} at (0,0) size 800x86
-    LayoutBlockFlow {BODY} at (8,8) size 784x70
-      LayoutBlockFlow (anonymous) at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 131x19
-          text run at (0,0) width 131: "PASS if not crashed."
-layer at (8,28) size 50x50 clip at (8,28) size 39x39 scrollWidth 200 scrollHeight 200
-  LayoutBlockFlow {DIV} at (0,20) size 50x50
-    LayoutBlockFlow {DIV} at (0,0) size 200x200
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-with-incomplete-style-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-with-incomplete-style-expected.png
deleted file mode 100644
index 4485ffb..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-with-incomplete-style-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-with-incomplete-style-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-with-incomplete-style-expected.txt
deleted file mode 100644
index 5ee917d..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-with-incomplete-style-expected.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-layer at (0,0) size 800x600 clip at (0,0) size 787x600 scrollHeight 1412
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 787x1412 backgroundClip at (0,0) size 787x600 clip at (0,0) size 787x600
-  LayoutBlockFlow {HTML} at (0,0) size 787x1411.91
-    LayoutBlockFlow {BODY} at (8,8) size 771x1390.91
-      LayoutBlockFlow {H2} at (0,0) size 771x54
-        LayoutText {#text} at (0,0) size 737x53
-          text run at (0,0) width 737: "It's OK if nothing drawn for a scrollbar (for an outermost frame and an"
-          text run at (0,27) width 228: "element with overlow)"
-      LayoutBlockFlow {P} at (0,73.91) size 771x20
-        LayoutText {#text} at (0,0) size 579x19
-          text run at (0,0) width 579: "Note that Safari doesn't allow to customize the outermost scdrollbars and just show Cocoa's."
-      LayoutBlockFlow {PRE} at (0,222.91) size 771x1168 [bgcolor=#008000]
-      LayoutBlockFlow {PRE} at (0,1403.91) size 1542x0 [bgcolor=#008000]
-layer at (8,118) size 100x100 clip at (8,118) size 87x87 scrollWidth 1432 scrollHeight 112
-  LayoutBlockFlow {PRE} at (0,109.91) size 100x100 [bgcolor=#008000]
-    LayoutText {#text} at (0,0) size 1432x112
-      text run at (0,0) width 1432: "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog."
-      text run at (1432,0) width 0: " "
-      text run at (0,16) width 1432: "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog."
-      text run at (1432,16) width 0: " "
-      text run at (0,32) width 1432: "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog."
-      text run at (1432,32) width 0: " "
-      text run at (0,48) width 1432: "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog."
-      text run at (1432,48) width 0: " "
-      text run at (0,64) width 1432: "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog."
-      text run at (1432,64) width 0: " "
-      text run at (0,80) width 1432: "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog."
-      text run at (1432,80) width 0: " "
-      text run at (0,96) width 1432: "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog."
-      text run at (1432,96) width 0: " "
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/disabled-scrollbar-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/disabled-scrollbar-expected.txt
deleted file mode 100644
index 635b843..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/disabled-scrollbar-expected.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-layer at (8,8) size 200x200 clip at (8,8) size 183x183 scrollHeight 980
-  LayoutBlockFlow {DIV} at (0,0) size 200x200
-    LayoutText {#text} at (0,0) size 35x19
-      text run at (0,0) width 35: "Hello"
-    LayoutBR {BR} at (35,15) size 0x0
-    LayoutText {#text} at (0,20) size 35x19
-      text run at (0,20) width 35: "Hello"
-    LayoutBR {BR} at (35,35) size 0x0
-    LayoutText {#text} at (0,40) size 35x19
-      text run at (0,40) width 35: "Hello"
-    LayoutBR {BR} at (35,55) size 0x0
-    LayoutText {#text} at (0,60) size 35x19
-      text run at (0,60) width 35: "Hello"
-    LayoutBR {BR} at (35,75) size 0x0
-    LayoutText {#text} at (0,80) size 35x19
-      text run at (0,80) width 35: "Hello"
-    LayoutBR {BR} at (35,95) size 0x0
-    LayoutText {#text} at (0,100) size 35x19
-      text run at (0,100) width 35: "Hello"
-    LayoutBR {BR} at (35,115) size 0x0
-    LayoutText {#text} at (0,120) size 35x19
-      text run at (0,120) width 35: "Hello"
-    LayoutBR {BR} at (35,135) size 0x0
-    LayoutText {#text} at (0,140) size 35x19
-      text run at (0,140) width 35: "Hello"
-    LayoutBR {BR} at (35,155) size 0x0
-    LayoutText {#text} at (0,160) size 35x19
-      text run at (0,160) width 35: "Hello"
-    LayoutBR {BR} at (35,175) size 0x0
-    LayoutText {#text} at (0,180) size 35x19
-      text run at (0,180) width 35: "Hello"
-    LayoutBR {BR} at (35,195) size 0x0
-    LayoutText {#text} at (0,200) size 35x19
-      text run at (0,200) width 35: "Hello"
-    LayoutBR {BR} at (35,215) size 0x0
-    LayoutText {#text} at (0,220) size 35x19
-      text run at (0,220) width 35: "Hello"
-    LayoutBR {BR} at (35,235) size 0x0
-    LayoutText {#text} at (0,240) size 35x19
-      text run at (0,240) width 35: "Hello"
-    LayoutBR {BR} at (35,255) size 0x0
-    LayoutText {#text} at (0,260) size 35x19
-      text run at (0,260) width 35: "Hello"
-    LayoutBR {BR} at (35,275) size 0x0
-    LayoutText {#text} at (0,280) size 35x19
-      text run at (0,280) width 35: "Hello"
-    LayoutBR {BR} at (35,295) size 0x0
-    LayoutText {#text} at (0,300) size 35x19
-      text run at (0,300) width 35: "Hello"
-    LayoutBR {BR} at (35,315) size 0x0
-    LayoutText {#text} at (0,320) size 35x19
-      text run at (0,320) width 35: "Hello"
-    LayoutBR {BR} at (35,335) size 0x0
-    LayoutText {#text} at (0,340) size 35x19
-      text run at (0,340) width 35: "Hello"
-    LayoutBR {BR} at (35,355) size 0x0
-    LayoutText {#text} at (0,360) size 35x19
-      text run at (0,360) width 35: "Hello"
-    LayoutBR {BR} at (35,375) size 0x0
-    LayoutText {#text} at (0,380) size 35x19
-      text run at (0,380) width 35: "Hello"
-    LayoutBR {BR} at (35,395) size 0x0
-    LayoutText {#text} at (0,400) size 35x19
-      text run at (0,400) width 35: "Hello"
-    LayoutBR {BR} at (35,415) size 0x0
-    LayoutText {#text} at (0,420) size 35x19
-      text run at (0,420) width 35: "Hello"
-    LayoutBR {BR} at (35,435) size 0x0
-    LayoutText {#text} at (0,440) size 35x19
-      text run at (0,440) width 35: "Hello"
-    LayoutBR {BR} at (35,455) size 0x0
-    LayoutText {#text} at (0,460) size 35x19
-      text run at (0,460) width 35: "Hello"
-    LayoutBR {BR} at (35,475) size 0x0
-    LayoutText {#text} at (0,480) size 35x19
-      text run at (0,480) width 35: "Hello"
-    LayoutBR {BR} at (35,495) size 0x0
-    LayoutText {#text} at (0,500) size 35x19
-      text run at (0,500) width 35: "Hello"
-    LayoutBR {BR} at (35,515) size 0x0
-    LayoutText {#text} at (0,520) size 35x19
-      text run at (0,520) width 35: "Hello"
-    LayoutBR {BR} at (35,535) size 0x0
-    LayoutText {#text} at (0,540) size 35x19
-      text run at (0,540) width 35: "Hello"
-    LayoutBR {BR} at (35,555) size 0x0
-    LayoutText {#text} at (0,560) size 35x19
-      text run at (0,560) width 35: "Hello"
-    LayoutBR {BR} at (35,575) size 0x0
-    LayoutText {#text} at (0,580) size 35x19
-      text run at (0,580) width 35: "Hello"
-    LayoutBR {BR} at (35,595) size 0x0
-    LayoutText {#text} at (0,600) size 35x19
-      text run at (0,600) width 35: "Hello"
-    LayoutBR {BR} at (35,615) size 0x0
-    LayoutText {#text} at (0,620) size 35x19
-      text run at (0,620) width 35: "Hello"
-    LayoutBR {BR} at (35,635) size 0x0
-    LayoutText {#text} at (0,640) size 35x19
-      text run at (0,640) width 35: "Hello"
-    LayoutBR {BR} at (35,655) size 0x0
-    LayoutText {#text} at (0,660) size 35x19
-      text run at (0,660) width 35: "Hello"
-    LayoutBR {BR} at (35,675) size 0x0
-    LayoutText {#text} at (0,680) size 35x19
-      text run at (0,680) width 35: "Hello"
-    LayoutBR {BR} at (35,695) size 0x0
-    LayoutText {#text} at (0,700) size 35x19
-      text run at (0,700) width 35: "Hello"
-    LayoutBR {BR} at (35,715) size 0x0
-    LayoutText {#text} at (0,720) size 35x19
-      text run at (0,720) width 35: "Hello"
-    LayoutBR {BR} at (35,735) size 0x0
-    LayoutText {#text} at (0,740) size 35x19
-      text run at (0,740) width 35: "Hello"
-    LayoutBR {BR} at (35,755) size 0x0
-    LayoutText {#text} at (0,760) size 35x19
-      text run at (0,760) width 35: "Hello"
-    LayoutBR {BR} at (35,775) size 0x0
-    LayoutText {#text} at (0,780) size 35x19
-      text run at (0,780) width 35: "Hello"
-    LayoutBR {BR} at (35,795) size 0x0
-    LayoutText {#text} at (0,800) size 35x19
-      text run at (0,800) width 35: "Hello"
-    LayoutBR {BR} at (35,815) size 0x0
-    LayoutText {#text} at (0,820) size 35x19
-      text run at (0,820) width 35: "Hello"
-    LayoutBR {BR} at (35,835) size 0x0
-    LayoutText {#text} at (0,840) size 35x19
-      text run at (0,840) width 35: "Hello"
-    LayoutBR {BR} at (35,855) size 0x0
-    LayoutText {#text} at (0,860) size 35x19
-      text run at (0,860) width 35: "Hello"
-    LayoutBR {BR} at (35,875) size 0x0
-    LayoutText {#text} at (0,880) size 35x19
-      text run at (0,880) width 35: "Hello"
-    LayoutBR {BR} at (35,895) size 0x0
-    LayoutText {#text} at (0,900) size 35x19
-      text run at (0,900) width 35: "Hello"
-    LayoutBR {BR} at (35,915) size 0x0
-    LayoutText {#text} at (0,920) size 35x19
-      text run at (0,920) width 35: "Hello"
-    LayoutBR {BR} at (35,935) size 0x0
-    LayoutText {#text} at (0,940) size 35x19
-      text run at (0,940) width 35: "Hello"
-    LayoutBR {BR} at (35,955) size 0x0
-    LayoutText {#text} at (0,960) size 35x19
-      text run at (0,960) width 35: "Hello"
-    LayoutBR {BR} at (35,975) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png
deleted file mode 100644
index 50c2460..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.txt
deleted file mode 100644
index ddccb0f..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutText {#text} at (165,0) size 4x19
-        text run at (165,0) width 4: " "
-      LayoutText {#text} at (334,0) size 4x19
-        text run at (334,0) width 4: " "
-      LayoutText {#text} at (503,0) size 4x19
-        text run at (503,0) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-      LayoutText {#text} at (165,140) size 4x19
-        text run at (165,140) width 4: " "
-      LayoutText {#text} at (334,140) size 4x19
-        text run at (334,140) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-layer at (28,28) size 125x100 clip at (29,29) size 110x98
-  LayoutListBox {SELECT} at (20,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 23x14
-        text run at (2,0) width 23: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 34x14
-        text run at (2,0) width 34: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 27x14
-        text run at (2,0) width 27: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "Five"
-layer at (197,28) size 125x100 clip at (198,29) size 110x98
-  LayoutListBox {SELECT} at (189,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 23x14
-        text run at (2,0) width 23: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 34x14
-        text run at (2,0) width 34: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 27x14
-        text run at (2,0) width 27: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "Five"
-layer at (366,28) size 125x100 clip at (367,29) size 110x98
-  LayoutListBox {SELECT} at (358,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 23x14
-        text run at (2,0) width 23: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 34x14
-        text run at (2,0) width 34: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 27x14
-        text run at (2,0) width 27: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "Five"
-layer at (535,28) size 125x100 clip at (536,29) size 110x98
-  LayoutListBox {SELECT} at (527,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 23x14
-        text run at (2,0) width 23: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 34x14
-        text run at (2,0) width 34: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 27x14
-        text run at (2,0) width 27: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "Five"
-layer at (28,168) size 125x100 clip at (29,169) size 110x98
-  LayoutListBox {SELECT} at (20,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 23x14
-        text run at (2,0) width 23: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 34x14
-        text run at (2,0) width 34: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 27x14
-        text run at (2,0) width 27: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "Five"
-layer at (197,168) size 125x100 clip at (198,169) size 110x98
-  LayoutListBox {SELECT} at (189,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 23x14
-        text run at (2,0) width 23: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 34x14
-        text run at (2,0) width 34: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 27x14
-        text run at (2,0) width 27: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "Five"
-layer at (366,168) size 125x100 clip at (367,169) size 110x98
-  LayoutListBox {SELECT} at (358,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 24x14
-        text run at (2,0) width 24: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 23x14
-        text run at (2,0) width 23: "Two"
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.png
deleted file mode 100644
index e04fab9..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.txt
deleted file mode 100644
index a114ef5..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.txt
+++ /dev/null
@@ -1,1239 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutText {#text} at (165,0) size 4x19
-        text run at (165,0) width 4: " "
-      LayoutText {#text} at (334,0) size 4x19
-        text run at (334,0) width 4: " "
-      LayoutText {#text} at (503,0) size 4x19
-        text run at (503,0) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-      LayoutText {#text} at (165,140) size 4x19
-        text run at (165,140) width 4: " "
-      LayoutText {#text} at (334,140) size 4x19
-        text run at (334,140) width 4: " "
-      LayoutText {#text} at (503,140) size 4x19
-        text run at (503,140) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-      LayoutText {#text} at (165,280) size 4x19
-        text run at (165,280) width 4: " "
-      LayoutText {#text} at (334,280) size 4x19
-        text run at (334,280) width 4: " "
-      LayoutText {#text} at (503,280) size 4x19
-        text run at (503,280) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-      LayoutText {#text} at (165,420) size 4x19
-        text run at (165,420) width 4: " "
-      LayoutText {#text} at (334,420) size 4x19
-        text run at (334,420) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-layer at (28,28) size 125x100 clip at (29,29) size 110x85 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (20,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 60: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 53: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (197,28) size 125x100 clip at (198,29) size 110x98 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (189,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 60: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 53: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (366,28) size 125x100 clip at (367,29) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (358,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (535,28) size 125x100 clip at (536,29) size 110x85 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (527,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 60: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 53: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (28,168) size 125x100 clip at (29,169) size 110x98 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (20,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 60: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 53: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (197,168) size 125x100 clip at (198,169) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (189,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (366,168) size 125x100 clip at (367,169) size 110x98 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (358,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 60: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 53: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (535,168) size 125x100 clip at (536,169) size 123x85 scrollWidth 420 scrollHeight 174
-  LayoutBlockFlow {DIV} at (527,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x174
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 88: "condimentum."
-layer at (28,308) size 125x100 clip at (29,309) size 110x98 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (20,300) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 60: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 53: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (197,308) size 125x100 clip at (198,309) size 123x85 scrollWidth 420 scrollHeight 174
-  LayoutBlockFlow {DIV} at (189,300) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x174
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 88: "condimentum."
-layer at (366,308) size 125x100 clip at (367,309) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (358,300) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (535,308) size 125x100 clip at (536,309) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (527,300) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (28,448) size 125x100 clip at (29,449) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (20,440) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (197,448) size 125x100 clip at (198,449) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (189,440) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (366,448) size 125x100 clip at (367,449) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (358,440) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/resize-scales-with-dpi-150-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/resize-scales-with-dpi-150-expected.txt
deleted file mode 100644
index 3a1ad1e..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/resize-scales-with-dpi-150-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-layer at (0,0) size 1200x900
-  LayoutView at (0,0) size 1200x900
-layer at (0,0) size 1200x900
-  LayoutBlockFlow {HTML} at (0,0) size 1200x900
-    LayoutBlockFlow {BODY} at (12,12) size 1176x876
-layer at (12,12) size 300x300 clip at (12,12) size 278x278
-  LayoutBlockFlow {DIV} at (0,0) size 300x300
-    LayoutText {#text} at (0,0) size 242x55
-      text run at (0,0) width 242: "The resize handle should"
-      text run at (0,28) width 148: "grow with DPI."
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/scrollbar-buttons-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/scrollbar-buttons-expected.txt
deleted file mode 100644
index 2d6b3bb3..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/scrollbar-buttons-expected.txt
+++ /dev/null
@@ -1,139 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-layer at (8,8) size 200x200 clip at (8,8) size 183x200 scrollWidth 317 scrollHeight 880
-  LayoutBlockFlow {DIV} at (0,0) size 200x200
-    LayoutText {#text} at (0,0) size 35x19
-      text run at (0,0) width 35: "Hello"
-    LayoutBR {BR} at (35,15) size 0x0
-    LayoutText {#text} at (0,20) size 35x19
-      text run at (0,20) width 35: "Hello"
-    LayoutBR {BR} at (35,35) size 0x0
-    LayoutText {#text} at (0,40) size 35x19
-      text run at (0,40) width 35: "Hello"
-    LayoutBR {BR} at (35,55) size 0x0
-    LayoutText {#text} at (0,60) size 35x19
-      text run at (0,60) width 35: "Hello"
-    LayoutBR {BR} at (35,75) size 0x0
-    LayoutText {#text} at (0,80) size 35x19
-      text run at (0,80) width 35: "Hello"
-    LayoutBR {BR} at (35,95) size 0x0
-    LayoutText {#text} at (0,100) size 35x19
-      text run at (0,100) width 35: "Hello"
-    LayoutBR {BR} at (35,115) size 0x0
-    LayoutText {#text} at (0,120) size 35x19
-      text run at (0,120) width 35: "Hello"
-    LayoutBR {BR} at (35,135) size 0x0
-    LayoutText {#text} at (0,140) size 35x19
-      text run at (0,140) width 35: "Hello"
-    LayoutBR {BR} at (35,155) size 0x0
-    LayoutText {#text} at (0,160) size 35x19
-      text run at (0,160) width 35: "Hello"
-    LayoutBR {BR} at (35,175) size 0x0
-    LayoutText {#text} at (0,180) size 35x19
-      text run at (0,180) width 35: "Hello"
-    LayoutBR {BR} at (35,195) size 0x0
-    LayoutText {#text} at (0,200) size 35x19
-      text run at (0,200) width 35: "Hello"
-    LayoutBR {BR} at (35,215) size 0x0
-    LayoutText {#text} at (0,220) size 35x19
-      text run at (0,220) width 35: "Hello"
-    LayoutBR {BR} at (35,235) size 0x0
-    LayoutText {#text} at (0,240) size 35x19
-      text run at (0,240) width 35: "Hello"
-    LayoutBR {BR} at (35,255) size 0x0
-    LayoutText {#text} at (0,260) size 35x19
-      text run at (0,260) width 35: "Hello"
-    LayoutBR {BR} at (35,275) size 0x0
-    LayoutText {#text} at (0,280) size 35x19
-      text run at (0,280) width 35: "Hello"
-    LayoutBR {BR} at (35,295) size 0x0
-    LayoutText {#text} at (0,300) size 35x19
-      text run at (0,300) width 35: "Hello"
-    LayoutBR {BR} at (35,315) size 0x0
-    LayoutInline {SPAN} at (0,0) size 317x19
-      LayoutText {#text} at (0,320) size 317x19
-        text run at (0,320) width 317: "Hello world this is a long string and will not wrap."
-    LayoutText {#text} at (0,340) size 35x19
-      text run at (0,340) width 35: "Hello"
-    LayoutBR {BR} at (35,355) size 0x0
-    LayoutText {#text} at (0,360) size 35x19
-      text run at (0,360) width 35: "Hello"
-    LayoutBR {BR} at (35,375) size 0x0
-    LayoutText {#text} at (0,380) size 35x19
-      text run at (0,380) width 35: "Hello"
-    LayoutBR {BR} at (35,395) size 0x0
-    LayoutText {#text} at (0,400) size 35x19
-      text run at (0,400) width 35: "Hello"
-    LayoutBR {BR} at (35,415) size 0x0
-    LayoutText {#text} at (0,420) size 35x19
-      text run at (0,420) width 35: "Hello"
-    LayoutBR {BR} at (35,435) size 0x0
-    LayoutText {#text} at (0,440) size 35x19
-      text run at (0,440) width 35: "Hello"
-    LayoutBR {BR} at (35,455) size 0x0
-    LayoutText {#text} at (0,460) size 35x19
-      text run at (0,460) width 35: "Hello"
-    LayoutBR {BR} at (35,475) size 0x0
-    LayoutText {#text} at (0,480) size 35x19
-      text run at (0,480) width 35: "Hello"
-    LayoutBR {BR} at (35,495) size 0x0
-    LayoutText {#text} at (0,500) size 35x19
-      text run at (0,500) width 35: "Hello"
-    LayoutBR {BR} at (35,515) size 0x0
-    LayoutText {#text} at (0,520) size 35x19
-      text run at (0,520) width 35: "Hello"
-    LayoutBR {BR} at (35,535) size 0x0
-    LayoutText {#text} at (0,540) size 35x19
-      text run at (0,540) width 35: "Hello"
-    LayoutBR {BR} at (35,555) size 0x0
-    LayoutText {#text} at (0,560) size 35x19
-      text run at (0,560) width 35: "Hello"
-    LayoutBR {BR} at (35,575) size 0x0
-    LayoutText {#text} at (0,580) size 35x19
-      text run at (0,580) width 35: "Hello"
-    LayoutBR {BR} at (35,595) size 0x0
-    LayoutText {#text} at (0,600) size 35x19
-      text run at (0,600) width 35: "Hello"
-    LayoutBR {BR} at (35,615) size 0x0
-    LayoutText {#text} at (0,620) size 35x19
-      text run at (0,620) width 35: "Hello"
-    LayoutBR {BR} at (35,635) size 0x0
-    LayoutText {#text} at (0,640) size 35x19
-      text run at (0,640) width 35: "Hello"
-    LayoutBR {BR} at (35,655) size 0x0
-    LayoutText {#text} at (0,660) size 35x19
-      text run at (0,660) width 35: "Hello"
-    LayoutBR {BR} at (35,675) size 0x0
-    LayoutText {#text} at (0,680) size 35x19
-      text run at (0,680) width 35: "Hello"
-    LayoutBR {BR} at (35,695) size 0x0
-    LayoutText {#text} at (0,700) size 35x19
-      text run at (0,700) width 35: "Hello"
-    LayoutBR {BR} at (35,715) size 0x0
-    LayoutText {#text} at (0,720) size 35x19
-      text run at (0,720) width 35: "Hello"
-    LayoutBR {BR} at (35,735) size 0x0
-    LayoutText {#text} at (0,740) size 35x19
-      text run at (0,740) width 35: "Hello"
-    LayoutBR {BR} at (35,755) size 0x0
-    LayoutText {#text} at (0,760) size 35x19
-      text run at (0,760) width 35: "Hello"
-    LayoutBR {BR} at (35,775) size 0x0
-    LayoutText {#text} at (0,780) size 35x19
-      text run at (0,780) width 35: "Hello"
-    LayoutBR {BR} at (35,795) size 0x0
-    LayoutText {#text} at (0,800) size 35x19
-      text run at (0,800) width 35: "Hello"
-    LayoutBR {BR} at (35,815) size 0x0
-    LayoutText {#text} at (0,820) size 35x19
-      text run at (0,820) width 35: "Hello"
-    LayoutBR {BR} at (35,835) size 0x0
-    LayoutText {#text} at (0,840) size 35x19
-      text run at (0,840) width 35: "Hello"
-    LayoutBR {BR} at (35,855) size 0x0
-    LayoutText {#text} at (0,860) size 35x19
-      text run at (0,860) width 35: "Hello"
-    LayoutBR {BR} at (35,875) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/scrollbar-orientation-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/scrollbar-orientation-expected.txt
deleted file mode 100644
index 691458b..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/scrollbar-orientation-expected.txt
+++ /dev/null
@@ -1,139 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-layer at (8,8) size 200x200 clip at (8,8) size 183x183 scrollWidth 317 scrollHeight 880
-  LayoutBlockFlow {DIV} at (0,0) size 200x200
-    LayoutText {#text} at (0,0) size 35x19
-      text run at (0,0) width 35: "Hello"
-    LayoutBR {BR} at (35,15) size 0x0
-    LayoutText {#text} at (0,20) size 35x19
-      text run at (0,20) width 35: "Hello"
-    LayoutBR {BR} at (35,35) size 0x0
-    LayoutText {#text} at (0,40) size 35x19
-      text run at (0,40) width 35: "Hello"
-    LayoutBR {BR} at (35,55) size 0x0
-    LayoutText {#text} at (0,60) size 35x19
-      text run at (0,60) width 35: "Hello"
-    LayoutBR {BR} at (35,75) size 0x0
-    LayoutText {#text} at (0,80) size 35x19
-      text run at (0,80) width 35: "Hello"
-    LayoutBR {BR} at (35,95) size 0x0
-    LayoutText {#text} at (0,100) size 35x19
-      text run at (0,100) width 35: "Hello"
-    LayoutBR {BR} at (35,115) size 0x0
-    LayoutText {#text} at (0,120) size 35x19
-      text run at (0,120) width 35: "Hello"
-    LayoutBR {BR} at (35,135) size 0x0
-    LayoutText {#text} at (0,140) size 35x19
-      text run at (0,140) width 35: "Hello"
-    LayoutBR {BR} at (35,155) size 0x0
-    LayoutText {#text} at (0,160) size 35x19
-      text run at (0,160) width 35: "Hello"
-    LayoutBR {BR} at (35,175) size 0x0
-    LayoutText {#text} at (0,180) size 35x19
-      text run at (0,180) width 35: "Hello"
-    LayoutBR {BR} at (35,195) size 0x0
-    LayoutText {#text} at (0,200) size 35x19
-      text run at (0,200) width 35: "Hello"
-    LayoutBR {BR} at (35,215) size 0x0
-    LayoutText {#text} at (0,220) size 35x19
-      text run at (0,220) width 35: "Hello"
-    LayoutBR {BR} at (35,235) size 0x0
-    LayoutText {#text} at (0,240) size 35x19
-      text run at (0,240) width 35: "Hello"
-    LayoutBR {BR} at (35,255) size 0x0
-    LayoutText {#text} at (0,260) size 35x19
-      text run at (0,260) width 35: "Hello"
-    LayoutBR {BR} at (35,275) size 0x0
-    LayoutText {#text} at (0,280) size 35x19
-      text run at (0,280) width 35: "Hello"
-    LayoutBR {BR} at (35,295) size 0x0
-    LayoutText {#text} at (0,300) size 35x19
-      text run at (0,300) width 35: "Hello"
-    LayoutBR {BR} at (35,315) size 0x0
-    LayoutInline {SPAN} at (0,0) size 317x19
-      LayoutText {#text} at (0,320) size 317x19
-        text run at (0,320) width 317: "Hello world this is a long string and will not wrap."
-    LayoutText {#text} at (0,340) size 35x19
-      text run at (0,340) width 35: "Hello"
-    LayoutBR {BR} at (35,355) size 0x0
-    LayoutText {#text} at (0,360) size 35x19
-      text run at (0,360) width 35: "Hello"
-    LayoutBR {BR} at (35,375) size 0x0
-    LayoutText {#text} at (0,380) size 35x19
-      text run at (0,380) width 35: "Hello"
-    LayoutBR {BR} at (35,395) size 0x0
-    LayoutText {#text} at (0,400) size 35x19
-      text run at (0,400) width 35: "Hello"
-    LayoutBR {BR} at (35,415) size 0x0
-    LayoutText {#text} at (0,420) size 35x19
-      text run at (0,420) width 35: "Hello"
-    LayoutBR {BR} at (35,435) size 0x0
-    LayoutText {#text} at (0,440) size 35x19
-      text run at (0,440) width 35: "Hello"
-    LayoutBR {BR} at (35,455) size 0x0
-    LayoutText {#text} at (0,460) size 35x19
-      text run at (0,460) width 35: "Hello"
-    LayoutBR {BR} at (35,475) size 0x0
-    LayoutText {#text} at (0,480) size 35x19
-      text run at (0,480) width 35: "Hello"
-    LayoutBR {BR} at (35,495) size 0x0
-    LayoutText {#text} at (0,500) size 35x19
-      text run at (0,500) width 35: "Hello"
-    LayoutBR {BR} at (35,515) size 0x0
-    LayoutText {#text} at (0,520) size 35x19
-      text run at (0,520) width 35: "Hello"
-    LayoutBR {BR} at (35,535) size 0x0
-    LayoutText {#text} at (0,540) size 35x19
-      text run at (0,540) width 35: "Hello"
-    LayoutBR {BR} at (35,555) size 0x0
-    LayoutText {#text} at (0,560) size 35x19
-      text run at (0,560) width 35: "Hello"
-    LayoutBR {BR} at (35,575) size 0x0
-    LayoutText {#text} at (0,580) size 35x19
-      text run at (0,580) width 35: "Hello"
-    LayoutBR {BR} at (35,595) size 0x0
-    LayoutText {#text} at (0,600) size 35x19
-      text run at (0,600) width 35: "Hello"
-    LayoutBR {BR} at (35,615) size 0x0
-    LayoutText {#text} at (0,620) size 35x19
-      text run at (0,620) width 35: "Hello"
-    LayoutBR {BR} at (35,635) size 0x0
-    LayoutText {#text} at (0,640) size 35x19
-      text run at (0,640) width 35: "Hello"
-    LayoutBR {BR} at (35,655) size 0x0
-    LayoutText {#text} at (0,660) size 35x19
-      text run at (0,660) width 35: "Hello"
-    LayoutBR {BR} at (35,675) size 0x0
-    LayoutText {#text} at (0,680) size 35x19
-      text run at (0,680) width 35: "Hello"
-    LayoutBR {BR} at (35,695) size 0x0
-    LayoutText {#text} at (0,700) size 35x19
-      text run at (0,700) width 35: "Hello"
-    LayoutBR {BR} at (35,715) size 0x0
-    LayoutText {#text} at (0,720) size 35x19
-      text run at (0,720) width 35: "Hello"
-    LayoutBR {BR} at (35,735) size 0x0
-    LayoutText {#text} at (0,740) size 35x19
-      text run at (0,740) width 35: "Hello"
-    LayoutBR {BR} at (35,755) size 0x0
-    LayoutText {#text} at (0,760) size 35x19
-      text run at (0,760) width 35: "Hello"
-    LayoutBR {BR} at (35,775) size 0x0
-    LayoutText {#text} at (0,780) size 35x19
-      text run at (0,780) width 35: "Hello"
-    LayoutBR {BR} at (35,795) size 0x0
-    LayoutText {#text} at (0,800) size 35x19
-      text run at (0,800) width 35: "Hello"
-    LayoutBR {BR} at (35,815) size 0x0
-    LayoutText {#text} at (0,820) size 35x19
-      text run at (0,820) width 35: "Hello"
-    LayoutBR {BR} at (35,835) size 0x0
-    LayoutText {#text} at (0,840) size 35x19
-      text run at (0,840) width 35: "Hello"
-    LayoutBR {BR} at (35,855) size 0x0
-    LayoutText {#text} at (0,860) size 35x19
-      text run at (0,860) width 35: "Hello"
-    LayoutBR {BR} at (35,875) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/scrollbars-on-positioned-content-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/scrollbars-on-positioned-content-expected.txt
deleted file mode 100644
index 4a3b9b2cc..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/scrollbars-on-positioned-content-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x576
-      LayoutBlockFlow {P} at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 656x19
-          text run at (0,0) width 656: "This test passes if the custom scrollbar paints in the corrext spot, which is at the bottom of the purple div."
-layer at (8,50) size 319x550 clip at (9,51) size 302x548 scrollHeight 1311
-  LayoutBlockFlow (positioned) {DIV} at (8,50) size 319x550 [border: (1px solid #FF0000)]
-    LayoutBlockFlow {DIV} at (1,412) size 15x900 [bgcolor=#008000]
-layer at (9,51) size 302x411 clip at (10,52) size 300x400 scrollWidth 500
-  LayoutBlockFlow {DIV} at (1,1) size 302x411 [border: (1px solid #0000FF)]
-    LayoutBlockFlow {DIV} at (1,1) size 500x400 [bgcolor=#800080]
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-with-incomplete-style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-with-incomplete-style-expected.png
deleted file mode 100644
index 12381d23..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-with-incomplete-style-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default-expected.txt
deleted file mode 100644
index df7d46a0..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This tests that scrollbars always receive events even when there is an element underneath the scrollbar which swallows the event. In this case an event handler is added to the window which swallows the event but this may also happen with elements underneath of overlay scrollbars.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-FAIL receivedMousedownEvent should be true. Was false.
-FAIL window.scrollY failed to change to 0 in 0.5 seconds.
-PASS receivedMousedownEvent is true
-FAIL subframe.scrollTop failed to change to 0 in 0.5 seconds.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-rls/compositing/squashing/frame-clip-squashed-scrolled-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-rls/compositing/squashing/frame-clip-squashed-scrolled-expected.txt
deleted file mode 100644
index 243426c..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-rls/compositing/squashing/frame-clip-squashed-scrolled-expected.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [785, 2036],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF",
-      "transform": 1
-    },
-    {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false,
-      "transform": 1
-    },
-    {
-      "name": "LayoutBlockFlow DIV",
-      "contentsOpaque": true,
-      "drawsContent": false,
-      "transform": 2
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV)",
-      "position": [8, 8],
-      "bounds": [102, 2002],
-      "transform": 1
-    }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [0, -300, 0, 1]
-      ]
-    },
-    {
-      "id": 2,
-      "parent": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ],
-      "flattenInheritedTransform": false
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-rls/compositing/squashing/no-squashing-into-another-clip-layer-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-rls/compositing/squashing/no-squashing-into-another-clip-layer-expected.txt
deleted file mode 100644
index c130381..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-rls/compositing/squashing/no-squashing-into-another-clip-layer-expected.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "LayoutBlockFlow DIV",
-      "bounds": [784, 10],
-      "contentsOpaque": true,
-      "backgroundColor": "#ADD8E6",
-      "transform": 1
-    },
-    {
-      "name": "Child Containment Layer",
-      "bounds": [784, 10],
-      "drawsContent": false,
-      "transform": 1
-    },
-    {
-      "name": "LayoutBlockFlow DIV id='inner'",
-      "bounds": [784, 10],
-      "contentsOpaque": true,
-      "backgroundColor": "#F5F5F5",
-      "transform": 1
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='hoverable'",
-      "position": [8, 0],
-      "bounds": [211, 100],
-      "backgroundColor": "#90EE90"
-    }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ]
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps-expected.txt
deleted file mode 100644
index 461ff5dd..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps-expected.txt
+++ /dev/null
@@ -1,149 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='overlap'",
-      "bounds": [300, 500],
-      "drawsContent": false,
-      "transform": 1
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='item')",
-      "position": [15, 35],
-      "bounds": [100, 210],
-      "paintInvalidations": [
-        {
-          "object": "InlineTextBox 'ipsum'",
-          "rect": [0, 80, 42, 36],
-          "reason": "geometry"
-        },
-        {
-          "object": "InlineTextBox 'lorem'",
-          "rect": [0, 80, 42, 36],
-          "reason": "geometry"
-        }
-      ]
-    }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ],
-      "flattenInheritedTransform": false
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutText #text",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'lorem'",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'ipsum'",
-      "reason": "geometry"
-    }
-  ]
-}
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='overlap'",
-      "bounds": [300, 500],
-      "drawsContent": false,
-      "transform": 1
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='item')",
-      "position": [15, 35],
-      "bounds": [100, 210],
-      "paintInvalidations": [
-        {
-          "object": "InlineTextBox 'ipsum'",
-          "rect": [0, 80, 44, 36],
-          "reason": "geometry"
-        },
-        {
-          "object": "InlineTextBox 'lorem'",
-          "rect": [0, 80, 44, 36],
-          "reason": "geometry"
-        },
-        {
-          "object": "InlineTextBox 'ipsum'",
-          "rect": [0, 160, 42, 36],
-          "reason": "geometry"
-        },
-        {
-          "object": "InlineTextBox 'lorem'",
-          "rect": [0, 160, 42, 36],
-          "reason": "geometry"
-        }
-      ]
-    }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ],
-      "flattenInheritedTransform": false
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutText #text",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'lorem'",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'ipsum'",
-      "reason": "geometry"
-    },
-    {
-      "object": "LayoutText #text",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'lorem'",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'ipsum'",
-      "reason": "geometry"
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-appearance-property-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-appearance-property-expected.txt
deleted file mode 100644
index ba1f6c6..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-appearance-property-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x84
-  LayoutBlockFlow {HTML} at (0,0) size 800x84
-    LayoutBlockFlow {BODY} at (8,8) size 784x68
-      LayoutBlockFlow (anonymous) at (0,0) size 784x18
-        LayoutText {#text} at (0,0) size 132x18
-          text run at (0,0) width 132: "PASS if not crashed."
-layer at (8,26) size 50x50 clip at (8,26) size 36x36 scrollWidth 200 scrollHeight 200
-  LayoutBlockFlow {DIV} at (0,18) size 50x50
-    LayoutBlockFlow {DIV} at (0,0) size 200x200
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png
deleted file mode 100644
index ef18458..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.png
deleted file mode 100644
index 51dc1bc..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/resize-scales-with-dpi-150-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/resize-scales-with-dpi-150-expected.txt
deleted file mode 100644
index 434d19ee..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/resize-scales-with-dpi-150-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-layer at (8,8) size 200x200 clip at (8,8) size 185x185
-  LayoutBlockFlow {DIV} at (0,0) size 200x200
-    LayoutText {#text} at (0,0) size 160x36
-      text run at (0,0) width 160: "The resize handle should"
-      text run at (0,18) width 100: "grow with DPI."
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/scrollbars-on-positioned-content-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/scrollbars-on-positioned-content-expected.txt
deleted file mode 100644
index 4680d963..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/rootlayerscrolls/scrollbars/scrollbars-on-positioned-content-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x576
-      LayoutBlockFlow {P} at (0,0) size 784x18
-        LayoutText {#text} at (0,0) size 673x18
-          text run at (0,0) width 673: "This test passes if the custom scrollbar paints in the corrext spot, which is at the bottom of the purple div."
-layer at (8,50) size 319x550 clip at (9,51) size 302x548 scrollHeight 1311
-  LayoutBlockFlow (positioned) {DIV} at (8,50) size 319x550 [border: (1px solid #FF0000)]
-    LayoutBlockFlow {DIV} at (1,412) size 15x900 [bgcolor=#008000]
-layer at (9,51) size 302x411 clip at (10,52) size 300x400 scrollWidth 500
-  LayoutBlockFlow {DIV} at (1,1) size 302x411 [border: (1px solid #0000FF)]
-    LayoutBlockFlow {DIV} at (1,1) size 500x400 [bgcolor=#800080]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps-expected.txt
deleted file mode 100644
index f05b622..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-rls/compositing/squashing/selection-repaint-with-gaps-expected.txt
+++ /dev/null
@@ -1,149 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='overlap'",
-      "bounds": [300, 500],
-      "drawsContent": false,
-      "transform": 1
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='item')",
-      "position": [15, 35],
-      "bounds": [100, 210],
-      "paintInvalidations": [
-        {
-          "object": "InlineTextBox 'ipsum'",
-          "rect": [0, 80, 38, 39],
-          "reason": "geometry"
-        },
-        {
-          "object": "InlineTextBox 'lorem'",
-          "rect": [0, 80, 38, 39],
-          "reason": "geometry"
-        }
-      ]
-    }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ],
-      "flattenInheritedTransform": false
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutText #text",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'lorem'",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'ipsum'",
-      "reason": "geometry"
-    }
-  ]
-}
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Squashing Containment Layer",
-      "drawsContent": false
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='overlap'",
-      "bounds": [300, 500],
-      "drawsContent": false,
-      "transform": 1
-    },
-    {
-      "name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='item')",
-      "position": [15, 35],
-      "bounds": [100, 210],
-      "paintInvalidations": [
-        {
-          "object": "InlineTextBox 'ipsum'",
-          "rect": [0, 80, 39, 39],
-          "reason": "geometry"
-        },
-        {
-          "object": "InlineTextBox 'lorem'",
-          "rect": [0, 80, 39, 39],
-          "reason": "geometry"
-        },
-        {
-          "object": "InlineTextBox 'ipsum'",
-          "rect": [0, 160, 38, 39],
-          "reason": "geometry"
-        },
-        {
-          "object": "InlineTextBox 'lorem'",
-          "rect": [0, 160, 38, 39],
-          "reason": "geometry"
-        }
-      ]
-    }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [8, 8, 0, 1]
-      ],
-      "flattenInheritedTransform": false
-    }
-  ],
-  "objectPaintInvalidations": [
-    {
-      "object": "LayoutText #text",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'lorem'",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'ipsum'",
-      "reason": "geometry"
-    },
-    {
-      "object": "LayoutText #text",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'lorem'",
-      "reason": "geometry"
-    },
-    {
-      "object": "InlineTextBox 'ipsum'",
-      "reason": "geometry"
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default-expected.txt
deleted file mode 100644
index df7d46a0..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This tests that scrollbars always receive events even when there is an element underneath the scrollbar which swallows the event. In this case an event handler is added to the window which swallows the event but this may also happen with elements underneath of overlay scrollbars.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-FAIL receivedMousedownEvent should be true. Was false.
-FAIL window.scrollY failed to change to 0 in 0.5 seconds.
-PASS receivedMousedownEvent is true
-FAIL subframe.scrollTop failed to change to 0 in 0.5 seconds.
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/auto-scrollbar-fades-out-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/auto-scrollbar-fades-out-expected.txt
deleted file mode 100644
index edba8fb..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/auto-scrollbar-fades-out-expected.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x425
-  LayoutBlockFlow {HTML} at (0,0) size 800x425
-    LayoutBlockFlow {BODY} at (8,8) size 784x409
-      LayoutText {#text} at (0,0) size 0x0
-layer at (8,8) size 404x404
-  LayoutIFrame {IFRAME} at (0,0) size 404x404 [border: (2px inset #EEEEEE)]
-    layer at (0,0) size 400x400
-      LayoutView at (0,0) size 400x400
-    layer at (0,0) size 400x316
-      LayoutBlockFlow {HTML} at (0,0) size 400x316
-        LayoutBlockFlow {BODY} at (8,8) size 384x300
-    layer at (8,8) size 300x300 scrollHeight 2000
-      LayoutBlockFlow {DIV} at (0,0) size 300x300
-        LayoutBlockFlow {DIV} at (0,0) size 100x2000 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-appearance-property-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-appearance-property-expected.txt
deleted file mode 100644
index 4629a01..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/custom-scrollbar-appearance-property-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x86
-  LayoutBlockFlow {HTML} at (0,0) size 800x86
-    LayoutBlockFlow {BODY} at (8,8) size 784x70
-      LayoutBlockFlow (anonymous) at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 126x19
-          text run at (0,0) width 126: "PASS if not crashed."
-layer at (8,28) size 50x50 clip at (8,28) size 39x39 scrollWidth 200 scrollHeight 200
-  LayoutBlockFlow {DIV} at (0,20) size 50x50
-    LayoutBlockFlow {DIV} at (0,0) size 200x200
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png
deleted file mode 100644
index bca7646..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.txt
deleted file mode 100644
index 8b91a65..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutText {#text} at (165,0) size 4x19
-        text run at (165,0) width 4: " "
-      LayoutText {#text} at (334,0) size 4x19
-        text run at (334,0) width 4: " "
-      LayoutText {#text} at (503,0) size 4x19
-        text run at (503,0) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-      LayoutText {#text} at (165,140) size 4x19
-        text run at (165,140) width 4: " "
-      LayoutText {#text} at (334,140) size 4x19
-        text run at (334,140) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-layer at (28,28) size 125x100 clip at (29,29) size 110x98
-  LayoutListBox {SELECT} at (20,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 36x14
-        text run at (2,0) width 36: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 28x14
-        text run at (2,0) width 28: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Five"
-layer at (197,28) size 125x100 clip at (198,29) size 110x98
-  LayoutListBox {SELECT} at (189,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 36x14
-        text run at (2,0) width 36: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 28x14
-        text run at (2,0) width 28: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Five"
-layer at (366,28) size 125x100 clip at (367,29) size 110x98
-  LayoutListBox {SELECT} at (358,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 36x14
-        text run at (2,0) width 36: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 28x14
-        text run at (2,0) width 28: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Five"
-layer at (535,28) size 125x100 clip at (536,29) size 110x98
-  LayoutListBox {SELECT} at (527,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 36x14
-        text run at (2,0) width 36: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 28x14
-        text run at (2,0) width 28: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Five"
-layer at (28,168) size 125x100 clip at (29,169) size 110x98
-  LayoutListBox {SELECT} at (20,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 36x14
-        text run at (2,0) width 36: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 28x14
-        text run at (2,0) width 28: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Five"
-layer at (197,168) size 125x100 clip at (198,169) size 110x98
-  LayoutListBox {SELECT} at (189,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 36x14
-        text run at (2,0) width 36: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 28x14
-        text run at (2,0) width 28: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Five"
-layer at (366,168) size 125x100 clip at (367,169) size 110x98
-  LayoutListBox {SELECT} at (358,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Two"
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.png
deleted file mode 100644
index 654e2028..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.txt
deleted file mode 100644
index c96b07b..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.txt
+++ /dev/null
@@ -1,1239 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutText {#text} at (165,0) size 4x17
-        text run at (165,0) width 4: " "
-      LayoutText {#text} at (334,0) size 4x17
-        text run at (334,0) width 4: " "
-      LayoutText {#text} at (503,0) size 4x17
-        text run at (503,0) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-      LayoutText {#text} at (165,140) size 4x17
-        text run at (165,140) width 4: " "
-      LayoutText {#text} at (334,140) size 4x17
-        text run at (334,140) width 4: " "
-      LayoutText {#text} at (503,140) size 4x17
-        text run at (503,140) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-      LayoutText {#text} at (165,280) size 4x17
-        text run at (165,280) width 4: " "
-      LayoutText {#text} at (334,280) size 4x17
-        text run at (334,280) width 4: " "
-      LayoutText {#text} at (503,280) size 4x17
-        text run at (503,280) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-      LayoutText {#text} at (165,420) size 4x17
-        text run at (165,420) width 4: " "
-      LayoutText {#text} at (334,420) size 4x17
-        text run at (334,420) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-layer at (28,28) size 125x100 clip at (29,29) size 110x85 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (20,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 60: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 53: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (197,28) size 125x100 clip at (198,29) size 110x98 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (189,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 60: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 53: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (366,28) size 125x100 clip at (367,29) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (358,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (535,28) size 125x100 clip at (536,29) size 110x85 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (527,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 60: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 53: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (28,168) size 125x100 clip at (29,169) size 110x98 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (20,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 60: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 53: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (197,168) size 125x100 clip at (198,169) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (189,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (366,168) size 125x100 clip at (367,169) size 110x98 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (358,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 60: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 53: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (535,168) size 125x100 clip at (536,169) size 123x85 scrollWidth 420 scrollHeight 174
-  LayoutBlockFlow {DIV} at (527,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x174
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 88: "condimentum."
-layer at (28,308) size 125x100 clip at (29,309) size 110x98 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (20,300) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 60: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 53: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (197,308) size 125x100 clip at (198,309) size 123x85 scrollWidth 420 scrollHeight 174
-  LayoutBlockFlow {DIV} at (189,300) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x174
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 88: "condimentum."
-layer at (366,308) size 125x100 clip at (367,309) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (358,300) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (535,308) size 125x100 clip at (536,309) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (527,300) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (28,448) size 125x100 clip at (29,449) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (20,440) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (197,448) size 125x100 clip at (198,449) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (189,440) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (366,448) size 125x100 clip at (367,449) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (358,440) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 397x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 397: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 384: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 389: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/rtl/overflow-scroll-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/rtl/overflow-scroll-rtl-expected.png
deleted file mode 100644
index cfa439a..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/rtl/overflow-scroll-rtl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/scrollbars-on-positioned-content-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/scrollbars-on-positioned-content-expected.txt
deleted file mode 100644
index 6caa621..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/scrollbars-on-positioned-content-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x576
-      LayoutBlockFlow {P} at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 627x19
-          text run at (0,0) width 627: "This test passes if the custom scrollbar paints in the corrext spot, which is at the bottom of the purple div."
-layer at (8,50) size 319x550 clip at (9,51) size 302x548 scrollHeight 1311
-  LayoutBlockFlow (positioned) {DIV} at (8,50) size 319x550 [border: (1px solid #FF0000)]
-    LayoutBlockFlow {DIV} at (1,412) size 15x900 [bgcolor=#008000]
-layer at (9,51) size 302x411 clip at (10,52) size 300x400 scrollWidth 500
-  LayoutBlockFlow {DIV} at (1,1) size 302x411 [border: (1px solid #0000FF)]
-    LayoutBlockFlow {DIV} at (1,1) size 500x400 [bgcolor=#800080]
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default-expected.txt
deleted file mode 100644
index 7e03694..0000000
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/fast/scrolling/scrollbar-prevent-default-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This tests that scrollbars always receive events even when there is an element underneath the scrollbar which swallows the event. In this case an event handler is added to the window which swallows the event but this may also happen with elements underneath of overlay scrollbars.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS receivedMousedownEvent is true
-PASS window.scrollY became 0
-PASS receivedMousedownEvent is true
-PASS subframe.scrollTop became 0
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png
deleted file mode 100644
index 5b79efb..0000000
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.txt
deleted file mode 100644
index c67af57..0000000
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutText {#text} at (165,0) size 4x19
-        text run at (165,0) width 4: " "
-      LayoutText {#text} at (334,0) size 4x19
-        text run at (334,0) width 4: " "
-      LayoutText {#text} at (503,0) size 4x19
-        text run at (503,0) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-      LayoutText {#text} at (165,140) size 4x19
-        text run at (165,140) width 4: " "
-      LayoutText {#text} at (334,140) size 4x19
-        text run at (334,140) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-layer at (28,28) size 125x100 clip at (29,29) size 110x98
-  LayoutListBox {SELECT} at (20,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 36x14
-        text run at (2,0) width 36: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 28x14
-        text run at (2,0) width 28: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Five"
-layer at (197,28) size 125x100 clip at (198,29) size 110x98
-  LayoutListBox {SELECT} at (189,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 36x14
-        text run at (2,0) width 36: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 28x14
-        text run at (2,0) width 28: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Five"
-layer at (366,28) size 125x100 clip at (367,29) size 110x98
-  LayoutListBox {SELECT} at (358,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 36x14
-        text run at (2,0) width 36: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 28x14
-        text run at (2,0) width 28: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Five"
-layer at (535,28) size 125x100 clip at (536,29) size 110x98
-  LayoutListBox {SELECT} at (527,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 36x14
-        text run at (2,0) width 36: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 28x14
-        text run at (2,0) width 28: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Five"
-layer at (28,168) size 125x100 clip at (29,169) size 110x98
-  LayoutListBox {SELECT} at (20,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 36x14
-        text run at (2,0) width 36: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 28x14
-        text run at (2,0) width 28: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Five"
-layer at (197,168) size 125x100 clip at (198,169) size 110x98
-  LayoutListBox {SELECT} at (189,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "Two"
-    LayoutBlockFlow {OPTION} at (11,41.78) size 90x15.39
-      LayoutText {#text} at (2,0) size 36x14
-        text run at (2,0) width 36: "Three"
-    LayoutBlockFlow {OPTION} at (11,57.17) size 90x15.39
-      LayoutText {#text} at (2,0) size 28x14
-        text run at (2,0) width 28: "Four"
-    LayoutBlockFlow {OPTION} at (11,72.56) size 90x15.39
-      LayoutText {#text} at (2,0) size 25x14
-        text run at (2,0) width 25: "Five"
-layer at (366,168) size 125x100 clip at (367,169) size 110x98
-  LayoutListBox {SELECT} at (358,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {OPTION} at (11,11) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "One"
-    LayoutBlockFlow {OPTION} at (11,26.39) size 90x15.39
-      LayoutText {#text} at (2,0) size 26x14
-        text run at (2,0) width 26: "Two"
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.png
deleted file mode 100644
index dc0207c..0000000
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.txt
deleted file mode 100644
index 66235ba..0000000
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/overflow-scrollbar-combinations-expected.txt
+++ /dev/null
@@ -1,1239 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutText {#text} at (165,0) size 4x17
-        text run at (165,0) width 4: " "
-      LayoutText {#text} at (334,0) size 4x17
-        text run at (334,0) width 4: " "
-      LayoutText {#text} at (503,0) size 4x17
-        text run at (503,0) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-      LayoutText {#text} at (165,140) size 4x17
-        text run at (165,140) width 4: " "
-      LayoutText {#text} at (334,140) size 4x17
-        text run at (334,140) width 4: " "
-      LayoutText {#text} at (503,140) size 4x17
-        text run at (503,140) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-      LayoutText {#text} at (165,280) size 4x17
-        text run at (165,280) width 4: " "
-      LayoutText {#text} at (334,280) size 4x17
-        text run at (334,280) width 4: " "
-      LayoutText {#text} at (503,280) size 4x17
-        text run at (503,280) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-      LayoutText {#text} at (165,420) size 4x17
-        text run at (165,420) width 4: " "
-      LayoutText {#text} at (334,420) size 4x17
-        text run at (334,420) width 4: " "
-      LayoutText {#text} at (0,0) size 0x0
-layer at (28,28) size 125x100 clip at (29,29) size 110x85 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (20,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 61: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 54: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (197,28) size 125x100 clip at (198,29) size 110x98 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (189,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 61: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 54: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (366,28) size 125x100 clip at (367,29) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (358,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 398x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 398: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 386: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 390: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (535,28) size 125x100 clip at (536,29) size 110x85 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (527,20) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 61: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 54: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (28,168) size 125x100 clip at (29,169) size 110x98 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (20,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 61: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 54: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (197,168) size 125x100 clip at (198,169) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (189,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 398x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 398: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 386: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 390: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (366,168) size 125x100 clip at (367,169) size 110x98 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (358,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 61: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 54: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (535,168) size 125x100 clip at (536,169) size 123x85 scrollWidth 420 scrollHeight 174
-  LayoutBlockFlow {DIV} at (527,160) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x174
-      LayoutText {#text} at (10,10) size 398x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 398: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 88: "condimentum."
-layer at (28,308) size 125x100 clip at (29,309) size 110x98 scrollHeight 2050
-  LayoutBlockFlow {DIV} at (20,300) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutText {#text} at (11,11) size 89x770
-      text run at (11,11) width 80: "Lorem ipsum"
-      text run at (11,25) width 51: "dolor sit"
-      text run at (11,39) width 36: "amet,"
-      text run at (11,53) width 82: "consectetuer"
-      text run at (11,67) width 89: "adipiscing elit."
-      text run at (11,81) width 76: "Morbi et nisi"
-      text run at (11,95) width 37: "ut est"
-      text run at (11,109) width 62: "venenatis"
-      text run at (11,123) width 47: "viverra."
-      text run at (11,137) width 84: "Aenean pede"
-      text run at (11,151) width 73: "orci, blandit"
-      text run at (11,165) width 86: "quis, faucibus"
-      text run at (11,179) width 85: "quis, egestas"
-      text run at (11,193) width 39: "ut, mi."
-      text run at (11,207) width 82: "Pellentesque"
-      text run at (11,221) width 74: "enim purus,"
-      text run at (11,235) width 62: "venenatis"
-      text run at (11,249) width 62: "dignissim,"
-      text run at (11,263) width 70: "tincidunt a,"
-      text run at (11,277) width 73: "ullamcorper"
-      text run at (11,291) width 68: "eget, nibh."
-      text run at (11,305) width 89: "Nullam ut sem"
-      text run at (11,319) width 88: "adipiscing orci"
-      text run at (11,333) width 51: "vehicula"
-      text run at (11,347) width 60: "interdum."
-      text run at (11,361) width 82: "Proin a enim."
-      text run at (11,375) width 60: "Phasellus"
-      text run at (11,389) width 69: "sollicitudin,"
-      text run at (11,403) width 78: "magna vitae"
-      text run at (11,417) width 68: "vestibulum"
-      text run at (11,431) width 86: "facilisis, tellus"
-      text run at (11,445) width 72: "nunc iaculis"
-      text run at (11,459) width 46: "arcu, in"
-      text run at (11,473) width 83: "molestie sem"
-      text run at (11,487) width 77: "velit tempus"
-      text run at (11,501) width 41: "est. In"
-      text run at (11,515) width 80: "eleifend velit"
-      text run at (11,529) width 43: "at sem"
-      text run at (11,543) width 62: "adipiscing"
-      text run at (11,557) width 88: "sodales. Nunc"
-      text run at (11,571) width 75: "sapien felis,"
-      text run at (11,585) width 70: "aliquam et,"
-      text run at (11,599) width 52: "volutpat"
-      text run at (11,613) width 54: "rhoncus,"
-      text run at (11,627) width 84: "condimentum"
-      text run at (11,641) width 61: "ut, tortor."
-      text run at (11,655) width 75: "Integer est."
-      text run at (11,669) width 52: "Quisque"
-      text run at (11,683) width 47: "viverra."
-      text run at (11,697) width 84: "Praesent sed"
-      text run at (11,711) width 31: "arcu."
-      text run at (11,725) width 78: "Maecenas id"
-      text run at (11,739) width 70: "lorem a leo"
-      text run at (11,753) width 47: "lobortis"
-      text run at (11,767) width 88: "condimentum."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,781) size 0x14
-    LayoutText {#text} at (11,795) size 90x728
-      text run at (11,795) width 29: "Cras"
-      text run at (11,809) width 60: "commodo"
-      text run at (11,823) width 90: "rutrum augue."
-      text run at (11,837) width 52: "Vivamus"
-      text run at (11,851) width 88: "iaculis. Nullam"
-      text run at (11,865) width 24: "est."
-      text run at (11,879) width 63: "Maecenas"
-      text run at (11,893) width 70: "consequat."
-      text run at (11,907) width 66: "Sed id dui."
-      text run at (11,921) width 64: "Vivamus a"
-      text run at (11,935) width 68: "nisl. Donec"
-      text run at (11,949) width 48: "pretium"
-      text run at (11,963) width 82: "sapien. Proin"
-      text run at (11,977) width 67: "et ligula et"
-      text run at (11,991) width 88: "ligula placerat"
-      text run at (11,1005) width 54: "pulvinar."
-      text run at (11,1019) width 79: "Aliquam erat"
-      text run at (11,1033) width 56: "volutpat."
-      text run at (11,1047) width 75: "Proin id est."
-      text run at (11,1061) width 80: "Suspendisse"
-      text run at (11,1075) width 45: "cursus,"
-      text run at (11,1089) width 60: "magna at"
-      text run at (11,1103) width 58: "hendrerit"
-      text run at (11,1117) width 70: "consequat,"
-      text run at (11,1131) width 66: "mauris est"
-      text run at (11,1145) width 59: "imperdiet"
-      text run at (11,1159) width 56: "neque, a"
-      text run at (11,1173) width 76: "ultrices arcu"
-      text run at (11,1187) width 57: "urna non"
-      text run at (11,1201) width 90: "nunc. Quisque"
-      text run at (11,1215) width 73: "tellus. Nulla"
-      text run at (11,1229) width 70: "nulla justo,"
-      text run at (11,1243) width 81: "vehicula nec,"
-      text run at (11,1257) width 82: "pellentesque"
-      text run at (11,1271) width 83: "eu, iaculis et,"
-      text run at (11,1285) width 37: "ligula."
-      text run at (11,1299) width 57: "Praesent"
-      text run at (11,1313) width 72: "mattis ante"
-      text run at (11,1327) width 52: "vel sem."
-      text run at (11,1341) width 80: "Suspendisse"
-      text run at (11,1355) width 88: "porta rhoncus"
-      text run at (11,1369) width 33: "urna."
-      text run at (11,1383) width 60: "Phasellus"
-      text run at (11,1397) width 90: "felis. Praesent"
-      text run at (11,1411) width 43: "viverra"
-      text run at (11,1425) width 53: "convallis"
-      text run at (11,1439) width 39: "libero."
-      text run at (11,1453) width 63: "Maecenas"
-      text run at (11,1467) width 72: "non augue."
-      text run at (11,1481) width 39: "Donec"
-      text run at (11,1495) width 58: "hendrerit"
-      text run at (11,1509) width 90: "lectus id enim."
-    LayoutBR {BR} at (0,0) size 0x0
-    LayoutBR {BR} at (11,1523) size 0x14
-    LayoutText {#text} at (11,1537) size 90x504
-      text run at (11,1537) width 68: "Nulla ligula"
-      text run at (11,1551) width 80: "dui, euismod"
-      text run at (11,1565) width 70: "et, sodales"
-      text run at (11,1579) width 30: "quis,"
-      text run at (11,1593) width 65: "sollicitudin"
-      text run at (11,1607) width 74: "quis, elit. In"
-      text run at (11,1621) width 86: "adipiscing est"
-      text run at (11,1635) width 61: "sed enim."
-      text run at (11,1649) width 53: "Fusce at"
-      text run at (11,1663) width 76: "massa vitae"
-      text run at (11,1677) width 90: "metus semper"
-      text run at (11,1691) width 62: "hendrerit."
-      text run at (11,1705) width 82: "Integer vitae"
-      text run at (11,1719) width 68: "urna. Nulla"
-      text run at (11,1733) width 70: "eget ligula."
-      text run at (11,1747) width 78: "Etiam libero."
-      text run at (11,1761) width 88: "Maecenas nisi"
-      text run at (11,1775) width 88: "nibh, convallis"
-      text run at (11,1789) width 60: "a, feugiat"
-      text run at (11,1803) width 89: "vitae, pulvinar"
-      text run at (11,1817) width 39: "et, mi."
-      text run at (11,1831) width 90: "Curabitur arcu"
-      text run at (11,1845) width 36: "pede,"
-      text run at (11,1859) width 62: "adipiscing"
-      text run at (11,1873) width 82: "sed, egestas"
-      text run at (11,1887) width 90: "nec, commodo"
-      text run at (11,1901) width 77: "in, elit. Nulla"
-      text run at (11,1915) width 77: "facilisi. Proin"
-      text run at (11,1929) width 74: "varius pede"
-      text run at (11,1943) width 79: "et dui lacinia"
-      text run at (11,1957) width 54: "dapibus."
-      text run at (11,1971) width 60: "Morbi nec"
-      text run at (11,1985) width 80: "augue. Proin"
-      text run at (11,1999) width 59: "imperdiet"
-      text run at (11,2013) width 52: "lacus eu"
-      text run at (11,2027) width 38: "tellus."
-layer at (197,308) size 125x100 clip at (198,309) size 123x85 scrollWidth 420 scrollHeight 174
-  LayoutBlockFlow {DIV} at (189,300) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x174
-      LayoutText {#text} at (10,10) size 398x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 398: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 88: "condimentum."
-layer at (366,308) size 125x100 clip at (367,309) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (358,300) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 398x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 398: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 386: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 390: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (535,308) size 125x100 clip at (536,309) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (527,300) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 398x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 398: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 386: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 390: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (28,448) size 125x100 clip at (29,449) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (20,440) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 398x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 398: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 386: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 390: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (197,448) size 125x100 clip at (198,449) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (189,440) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 398x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 398: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 386: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 390: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
-layer at (366,448) size 125x100 clip at (367,449) size 110x85 scrollWidth 420 scrollHeight 440
-  LayoutBlockFlow {DIV} at (358,440) size 125x100 [color=#DCDCDC] [bgcolor=#718D93] [border: (1px solid #D3D3D3)]
-    LayoutBlockFlow {DIV} at (1,1) size 420x440
-      LayoutText {#text} at (10,10) size 398x154
-        text run at (10,10) width 392: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi"
-        text run at (10,24) width 395: "et nisi ut est venenatis viverra. Aenean pede orci, blandit quis,"
-        text run at (10,38) width 348: "faucibus quis, egestas ut, mi. Pellentesque enim purus,"
-        text run at (10,52) width 397: "venenatis dignissim, tincidunt a, ullamcorper eget, nibh. Nullam"
-        text run at (10,66) width 340: "ut sem adipiscing orci vehicula interdum. Proin a enim."
-        text run at (10,80) width 377: "Phasellus sollicitudin, magna vitae vestibulum facilisis, tellus"
-        text run at (10,94) width 389: "nunc iaculis arcu, in molestie sem velit tempus est. In eleifend"
-        text run at (10,108) width 384: "velit at sem adipiscing sodales. Nunc sapien felis, aliquam et,"
-        text run at (10,122) width 398: "volutpat rhoncus, condimentum ut, tortor. Integer est. Quisque"
-        text run at (10,136) width 377: "viverra. Praesent sed arcu. Maecenas id lorem a leo lobortis"
-        text run at (10,150) width 92: "condimentum. "
-      LayoutBR {BR} at (102,162) size 0x0
-      LayoutBR {BR} at (10,164) size 0x14
-      LayoutText {#text} at (10,178) size 399x140
-        text run at (10,178) width 363: "Cras commodo rutrum augue. Vivamus iaculis. Nullam est."
-        text run at (10,192) width 399: "Maecenas consequat. Sed id dui. Vivamus a nisl. Donec pretium"
-        text run at (10,206) width 386: "sapien. Proin et ligula et ligula placerat pulvinar. Aliquam erat"
-        text run at (10,220) width 394: "volutpat. Proin id est. Suspendisse cursus, magna at hendrerit"
-        text run at (10,234) width 376: "consequat, mauris est imperdiet neque, a ultrices arcu urna"
-        text run at (10,248) width 354: "non nunc. Quisque tellus. Nulla nulla justo, vehicula nec,"
-        text run at (10,262) width 369: "pellentesque eu, iaculis et, ligula. Praesent mattis ante vel"
-        text run at (10,276) width 340: "sem. Suspendisse porta rhoncus urna. Phasellus felis."
-        text run at (10,290) width 390: "Praesent viverra convallis libero. Maecenas non augue. Donec"
-        text run at (10,304) width 156: "hendrerit lectus id enim. "
-      LayoutBR {BR} at (166,316) size 0x0
-      LayoutBR {BR} at (10,318) size 0x14
-      LayoutText {#text} at (10,332) size 399x98
-        text run at (10,332) width 390: "Nulla ligula dui, euismod et, sodales quis, sollicitudin quis, elit."
-        text run at (10,346) width 399: "In adipiscing est sed enim. Fusce at massa vitae metus semper"
-        text run at (10,360) width 376: "hendrerit. Integer vitae urna. Nulla eget ligula. Etiam libero."
-        text run at (10,374) width 380: "Maecenas nisi nibh, convallis a, feugiat vitae, pulvinar et, mi."
-        text run at (10,388) width 395: "Curabitur arcu pede, adipiscing sed, egestas nec, commodo in,"
-        text run at (10,402) width 396: "elit. Nulla facilisi. Proin varius pede et dui lacinia dapibus. Morbi"
-        text run at (10,416) width 267: "nec augue. Proin imperdiet lacus eu tellus."
diff --git a/third_party/WebKit/LayoutTests/virtual/modern-media-controls/media/controls/modern/README.txt b/third_party/WebKit/LayoutTests/virtual/modern-media-controls/media/controls/modern/README.txt
deleted file mode 100644
index 83608d41..0000000
--- a/third_party/WebKit/LayoutTests/virtual/modern-media-controls/media/controls/modern/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-These are tests specific to the modern media controls. As such they should be
-run with the modern media controls enabled.
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_util.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_util.cpp
index da9490b..7e06619 100644
--- a/third_party/android_crazy_linker/src/src/crazy_linker_util.cpp
+++ b/third_party/android_crazy_linker/src/src/crazy_linker_util.cpp
@@ -25,38 +25,48 @@
 String::String() { Init(); }
 
 String::String(const String& other) {
-  Init();
-  Assign(other.ptr_, other.size_);
+  InitFrom(other.ptr_, other.size_);
+}
+
+String::String(String&& other)
+    : ptr_(other.ptr_), size_(other.size_), capacity_(other.capacity_) {
+  other.Init();
 }
 
 String::String(const char* str) {
-  Init();
-  Assign(str, strlen(str));
+  InitFrom(str, ::strlen(str));
 }
 
 String::String(char ch) {
-  Init();
-  Assign(&ch, 1);
+  InitFrom(&ch, 1);
 }
 
 String::~String() {
-  if (ptr_ != const_cast<char*>(kEmpty)) {
+  if (HasValidPointer()) {
     free(ptr_);
     ptr_ = const_cast<char*>(kEmpty);
   }
 }
 
 String::String(const char* str, size_t len) {
-  Init();
-  Assign(str, len);
+  InitFrom(str, len);
+}
+
+String& String::operator=(String&& other) {
+  if (this != &other) {
+    this->~String();  // Free pointer if needed.
+    ptr_ = other.ptr_;
+    size_ = other.size_;
+    capacity_ = other.capacity_;
+    other.Init();
+  }
+  return *this;
 }
 
 void String::Assign(const char* str, size_t len) {
   Resize(len);
   if (len > 0) {
     memcpy(ptr_, str, len);
-    ptr_[len] = '\0';
-    size_ = len;
   }
 }
 
@@ -81,12 +91,13 @@
     memset(ptr_ + size_, '\0', new_size - size_);
 
   size_ = new_size;
-  if (ptr_ != kEmpty)
+  if (HasValidPointer()) {
     ptr_[size_] = '\0';
+  }
 }
 
 void String::Reserve(size_t new_capacity) {
-  char* old_ptr = (ptr_ == const_cast<char*>(kEmpty)) ? NULL : ptr_;
+  char* old_ptr = HasValidPointer() ? ptr_ : nullptr;
   // Always allocate one more byte for the trailing \0
   ptr_ = reinterpret_cast<char*>(realloc(old_ptr, new_capacity + 1));
   ptr_[new_capacity] = '\0';
@@ -96,29 +107,12 @@
     size_ = new_capacity;
 }
 
-#if 0
-String Format(const char* fmt, ...) {
-  va_list args;
-  va_start(args, fmt);
-  String result(FormatArgs(fmt, args));
-  va_end(args);
-  return result;
-}
-
-String FormatArgs(const char* fmt, va_list args) {
-  String result;
-  for (;;) {
-    va_list args2;
-    va_copy(args2, args);
-    int ret = vsnprintf(&result[0], result.capacity(), fmt, args2);
-    va_end(args2);
-    if (static_cast<size_t>(ret) <= result.capacity())
-      break;
-
-    result.Resize(static_cast<size_t>(ret));
+void String::InitFrom(const char* str, size_t len) {
+  Init();
+  if (str != nullptr && len != 0) {
+    Resize(len);
+    memcpy(ptr_, str, len);
   }
-  return result;
 }
-#endif
 
 }  // namespace crazy
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_util.h b/third_party/android_crazy_linker/src/src/crazy_linker_util.h
index 38369f5d..cc6a2a91 100644
--- a/third_party/android_crazy_linker/src/src/crazy_linker_util.h
+++ b/third_party/android_crazy_linker/src/src/crazy_linker_util.h
@@ -68,6 +68,8 @@
   String();
   String(const char* str, size_t len);
   String(const String& other);
+  String(String&& other);
+
   explicit String(const char* str);
   explicit String(char ch);
 
@@ -78,6 +80,15 @@
   size_t size() const { return size_; }
   size_t capacity() const { return capacity_; }
 
+  const char* begin() const { return ptr_; }
+  const char* end() const { return ptr_ + size_; }
+
+  char* begin() { return ptr_; }
+  char* end() { return ptr_ + size_; }
+
+  const char* cbegin() const { return ptr_; }
+  const char* cend() const { return ptr_ + size_; }
+
   bool IsEmpty() const { return size_ == 0; }
 
   char& operator[](size_t index) { return ptr_[index]; }
@@ -87,6 +98,8 @@
     return *this;
   }
 
+  String& operator=(String&& other);
+
   String& operator=(const char* str) {
     Assign(str, strlen(str));
     return *this;
@@ -129,12 +142,18 @@
   void Append(const char* str) { Append(str, strlen(str)); }
 
  private:
-  void Init(void) {
+  inline void Init() {
     ptr_ = const_cast<char*>(kEmpty);
     size_ = 0;
     capacity_ = 0;
   }
 
+  inline bool HasValidPointer() const {
+    return ptr_ != const_cast<char*>(kEmpty);
+  }
+
+  void InitFrom(const char* str, size_t len);
+
   static const char kEmpty[];
 
   char* ptr_;
@@ -142,7 +161,7 @@
   size_t capacity_;
 };
 
-// Helper template used to implement a simple vector or POD-struct items.
+// Helper template used to implement a simple vector of POD-struct items.
 // I.e. this uses memmove() to move items during insertion / removal.
 //
 // Required because crazy linker should only link against the system
@@ -151,7 +170,7 @@
 template <class T>
 class Vector {
  public:
-  Vector() : items_(0), count_(0), capacity_(0) {}
+  Vector() = default;
 
   ~Vector() { free(items_); }
 
@@ -160,7 +179,12 @@
   Vector(const Vector& other) = delete;
   Vector& operator=(const Vector& other) = delete;
 
+  // Allow move operations.
+  Vector(Vector&& other);
+  Vector& operator=(Vector&& other);
+
   const T& operator[](size_t index) const { return items_[index]; }
+
   T& operator[](size_t index) { return items_[index]; }
 
   bool IsEmpty() const { return count_ == 0; }
@@ -200,9 +224,15 @@
   void Resize(size_t new_count);
 
  private:
-  T* items_;
-  size_t count_;
-  size_t capacity_;
+  void DoReset() {
+    items_ = nullptr;
+    count_ = 0;
+    capacity_ = 0;
+  }
+
+  T* items_ = nullptr;
+  size_t count_ = 0;
+  size_t capacity_ = 0;
 };
 
 template <class T>
@@ -215,6 +245,28 @@
 }
 
 template <class T>
+Vector<T>::Vector(Vector&& other)
+    : items_(other.items_), count_(other.count_), capacity_(other.capacity_) {
+  other.items_ = nullptr;
+  other.count_ = 0;
+  other.capacity_ = 0;
+}
+
+template <class T>
+Vector<T>& Vector<T>::operator=(Vector&& other) {
+  if (this != &other) {
+    free(items_);
+    items_ = other.items_;
+    count_ = other.count_;
+    capacity_ = other.capacity_;
+    other.items_ = nullptr;
+    other.count_ = 0;
+    other.capacity_ = 0;
+  }
+  return *this;
+}
+
+template <class T>
 void Vector<T>::InsertAt(int index, T item) {
   if (count_ >= capacity_)
     Reserve(capacity_ + (capacity_ >> 1) + 4);
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_util_unittest.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_util_unittest.cpp
index 0dc6134..7b396ea 100644
--- a/third_party/android_crazy_linker/src/src/crazy_linker_util_unittest.cpp
+++ b/third_party/android_crazy_linker/src/src/crazy_linker_util_unittest.cpp
@@ -6,6 +6,8 @@
 
 #include <gtest/gtest.h>
 
+#include <utility>
+
 namespace crazy {
 
 TEST(GetBaseNamePtr, Test) {
@@ -40,12 +42,39 @@
   EXPECT_STREQ(s2.c_str(), s1.c_str());
 }
 
+TEST(String, MoveConstructor) {
+  String s1("Source");
+  String s2(std::move(s1));
+
+  EXPECT_TRUE(s1.IsEmpty());
+  EXPECT_EQ(6U, s2.size());
+  EXPECT_STREQ(s2.c_str(), "Source");
+}
+
 TEST(String, CharConstructor) {
   String s('H');
   EXPECT_EQ(1U, s.size());
   EXPECT_STREQ("H", s.c_str());
 }
 
+TEST(String, CopyAssign) {
+  String s1("Source");
+  String s2("Destination");
+
+  s1 = s2;
+  EXPECT_STREQ(s1.c_str(), s2.c_str());
+}
+
+TEST(String, MoveAssign) {
+  String s1("Source");
+  String s2("Destination");
+
+  s2 = std::move(s1);
+
+  EXPECT_TRUE(s1.IsEmpty());
+  EXPECT_STREQ("Source", s2.c_str());
+}
+
 TEST(String, AppendCString) {
   String s("Foo");
   s += "Bar";
@@ -109,6 +138,42 @@
   EXPECT_EQ(static_cast<size_t>(kMaxCount), v.GetCount());
 }
 
+TEST(Vector, MoveConstructor) {
+  const int kMaxCount = 500;
+  Vector<int> v1;
+  for (int n = 0; n < kMaxCount; ++n)
+    v1.PushBack(n * 100);
+
+  Vector<int> v2(std::move(v1));
+
+  EXPECT_TRUE(v1.IsEmpty());
+  EXPECT_FALSE(v2.IsEmpty());
+
+  EXPECT_EQ(static_cast<size_t>(kMaxCount), v2.GetCount());
+  for (int n = 0; n < kMaxCount; ++n) {
+    EXPECT_EQ(n * 100, v2[n]) << "Checking v[" << n << "]";
+  }
+}
+
+TEST(Vector, MoveAssign) {
+  const int kMaxCount = 500;
+  Vector<int> v1;
+  for (int n = 0; n < kMaxCount; ++n)
+    v1.PushBack(n * 100);
+
+  Vector<int> v2;
+
+  v2 = std::move(v1);
+
+  EXPECT_TRUE(v1.IsEmpty());
+  EXPECT_FALSE(v2.IsEmpty());
+
+  EXPECT_EQ(static_cast<size_t>(kMaxCount), v2.GetCount());
+  for (int n = 0; n < kMaxCount; ++n) {
+    EXPECT_EQ(n * 100, v2[n]) << "Checking v[" << n << "]";
+  }
+}
+
 TEST(Vector, At) {
   const int kMaxCount = 500;
   Vector<int> v;
diff --git a/third_party/blink/common/feature_policy/feature_policy.cc b/third_party/blink/common/feature_policy/feature_policy.cc
index e2afaa3..8761b0a 100644
--- a/third_party/blink/common/feature_policy/feature_policy.cc
+++ b/third_party/blink/common/feature_policy/feature_policy.cc
@@ -294,6 +294,10 @@
                             FeaturePolicy::FeatureDefault::EnableForSelf},
                            {mojom::FeaturePolicyFeature::kMagnetometer,
                             FeaturePolicy::FeatureDefault::EnableForSelf},
+                           {mojom::FeaturePolicyFeature::kImageCompression,
+                            FeaturePolicy::FeatureDefault::EnableForAll},
+                           {mojom::FeaturePolicyFeature::kLegacyImageFormats,
+                            FeaturePolicy::FeatureDefault::EnableForAll},
                            {mojom::FeaturePolicyFeature::kUnsizedMedia,
                             FeaturePolicy::FeatureDefault::EnableForAll},
                            {mojom::FeaturePolicyFeature::kPictureInPicture,
diff --git a/third_party/blink/public/blink_resources.grd b/third_party/blink/public/blink_resources.grd
index 2bfaa4d..9db01442b 100644
--- a/third_party/blink/public/blink_resources.grd
+++ b/third_party/blink/public/blink_resources.grd
@@ -47,10 +47,6 @@
         <include name="IDR_LIST_PICKER_JS" file="../renderer/core/html/forms/resources/listPicker.js" type="BINDATA" compress="gzip"/>
       </if>
       <include name="IDR_AUDIO_SPATIALIZATION_COMPOSITE" file="../renderer/platform/audio/resources/Composite.flac" type="BINDATA"/>
-
-      <!-- Layered API scripts. Should be consistent with kLayeredAPIResources
-           in renderer/core/script/layered_api.cc -->
-      <include name="IDR_LAYERED_API_BLANK_INDEX_JS" file="../renderer/core/script/resources/layered_api/blank/index.js" type="BINDATA"/>
     </includes>
   </release>
 </grit>
diff --git a/third_party/blink/public/mojom/feature_policy/feature_policy.mojom b/third_party/blink/public/mojom/feature_policy/feature_policy.mojom
index 7a8541b..f471cd1 100644
--- a/third_party/blink/public/mojom/feature_policy/feature_policy.mojom
+++ b/third_party/blink/public/mojom/feature_policy/feature_policy.mojom
@@ -81,6 +81,10 @@
   // Controls the layout size of intrinsically sized images and videos. When
   // disabled, default size (300 x 150) is used to prevent relayout.
   kUnsizedMedia,
+  // Controls which image formats are allowed to be used in the document.
+  kLegacyImageFormats,
+  // When disallowed, requires images to have a reasonable byte-to-pixel ratio.
+  kImageCompression,
   // Controls access to Picture-in-Picture.
   kPictureInPicture,
   // Controls the ability to block and interfere with vertical scrolling.
diff --git a/third_party/blink/public/platform/web_media_stream_source.h b/third_party/blink/public/platform/web_media_stream_source.h
index 46472f8..3f37effe 100644
--- a/third_party/blink/public/platform/web_media_stream_source.h
+++ b/third_party/blink/public/platform/web_media_stream_source.h
@@ -116,6 +116,9 @@
   BLINK_PLATFORM_EXPORT WebString GetName() const;
   BLINK_PLATFORM_EXPORT bool Remote() const;
 
+  BLINK_PLATFORM_EXPORT void SetGroupId(const WebString& group_id);
+  BLINK_PLATFORM_EXPORT WebString GroupId() const;
+
   BLINK_PLATFORM_EXPORT void SetReadyState(ReadyState);
   BLINK_PLATFORM_EXPORT ReadyState GetReadyState() const;
 
diff --git a/third_party/blink/public/platform/web_media_stream_track.h b/third_party/blink/public/platform/web_media_stream_track.h
index ab74e1c..dd95d558 100644
--- a/third_party/blink/public/platform/web_media_stream_track.h
+++ b/third_party/blink/public/platform/web_media_stream_track.h
@@ -62,6 +62,7 @@
     long height = -1;
     double aspect_ratio = -1.0;
     WebString device_id;
+    WebString group_id;
     FacingMode facing_mode = FacingMode::kNone;
     base::Optional<bool> echo_cancellation;
     base::Optional<bool> auto_gain_control;
diff --git a/third_party/blink/renderer/controller/BUILD.gn b/third_party/blink/renderer/controller/BUILD.gn
index dd83de4..1aaa34c 100644
--- a/third_party/blink/renderer/controller/BUILD.gn
+++ b/third_party/blink/renderer/controller/BUILD.gn
@@ -61,6 +61,7 @@
     "../core/testing/data/",
     "../core/paint/test_data/",
     "../core/animation/test_data/",
+    "../core/css/test_data/",
   ]
 }
 
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index 3860c06..4a61cbf 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1644,6 +1644,7 @@
     "css/css_font_face_source_test.cc",
     "css/css_gradient_value_test.cc",
     "css/css_page_rule_test.cc",
+    "css/css_paint_value_test.cc",
     "css/css_selector_test.cc",
     "css/css_selector_watch_test.cc",
     "css/css_style_declaration_test.cc",
@@ -2039,7 +2040,6 @@
     "scheduler/throttling_test.cc",
     "scheduler/virtual_time_test.cc",
     "script/dynamic_module_resolver_test.cc",
-    "script/layered_api_test.cc",
     "script/mock_script_element_base.h",
     "script/modulator_test.cc",
     "script/module_map_test.cc",
diff --git a/third_party/blink/renderer/core/css/css_custom_ident_value.h b/third_party/blink/renderer/core/css/css_custom_ident_value.h
index 41f7ede..dd2cef1 100644
--- a/third_party/blink/renderer/core/css/css_custom_ident_value.h
+++ b/third_party/blink/renderer/core/css/css_custom_ident_value.h
@@ -11,7 +11,7 @@
 
 namespace blink {
 
-class CSSCustomIdentValue : public CSSValue {
+class CORE_EXPORT CSSCustomIdentValue : public CSSValue {
  public:
   static CSSCustomIdentValue* Create(const AtomicString& str) {
     return new CSSCustomIdentValue(str);
diff --git a/third_party/blink/renderer/core/css/css_paint_value.cc b/third_party/blink/renderer/core/css/css_paint_value.cc
index 731362e..78a4816 100644
--- a/third_party/blink/renderer/core/css/css_paint_value.cc
+++ b/third_party/blink/renderer/core/css/css_paint_value.cc
@@ -46,8 +46,13 @@
 scoped_refptr<Image> CSSPaintValue::GetImage(
     const ImageResourceObserver& client,
     const Document& document,
-    const ComputedStyle&,
+    const ComputedStyle& style,
     const FloatSize& target_size) {
+  // https://crbug.com/835589: early exit when paint target is associated with
+  // a link.
+  if (style.InsideLink() != EInsideLink::kNotInsideLink)
+    return nullptr;
+
   if (!generator_) {
     generator_ = CSSPaintImageGenerator::Create(
         GetName(), document, paint_image_generator_observer_);
diff --git a/third_party/blink/renderer/core/css/css_paint_value.h b/third_party/blink/renderer/core/css/css_paint_value.h
index 6458d3a..fc879596 100644
--- a/third_party/blink/renderer/core/css/css_paint_value.h
+++ b/third_party/blink/renderer/core/css/css_paint_value.h
@@ -15,7 +15,7 @@
 
 namespace blink {
 
-class CSSPaintValue : public CSSImageGeneratorValue {
+class CORE_EXPORT CSSPaintValue : public CSSImageGeneratorValue {
  public:
   static CSSPaintValue* Create(CSSCustomIdentValue* name) {
     return new CSSPaintValue(name);
diff --git a/third_party/blink/renderer/core/css/css_paint_value_test.cc b/third_party/blink/renderer/core/css/css_paint_value_test.cc
new file mode 100644
index 0000000..923faea
--- /dev/null
+++ b/third_party/blink/renderer/core/css/css_paint_value_test.cc
@@ -0,0 +1,81 @@
+// 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 "third_party/blink/renderer/core/css/css_paint_value.h"
+
+#include <memory>
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
+#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/layout/layout_object.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
+
+namespace blink {
+
+class CSSPaintValueTest : public RenderingTest {
+ public:
+  void LoadTestData(const std::string& file_name) {
+    String testing_path = test::BlinkRootDir();
+    testing_path.append("/renderer/core/css/test_data/");
+    WebURL url = URLTestHelpers::RegisterMockedURLLoadFromBase(
+        WebString::FromUTF8(base_url_), testing_path,
+        WebString::FromUTF8(file_name));
+    FrameTestHelpers::LoadFrame(helper_.GetWebView()->MainFrameImpl(),
+                                base_url_ + file_name);
+    ForceFullCompositingUpdate();
+    URLTestHelpers::RegisterMockedURLUnregister(url);
+  }
+
+  void ForceFullCompositingUpdate() {
+    helper_.GetWebView()->UpdateAllLifecyclePhases();
+  }
+
+  LocalFrame* GetFrame() const { return helper_.LocalMainFrame()->GetFrame(); }
+
+ private:
+  void SetUp() override {
+    RenderingTest::SetUp();
+    EnableCompositing();
+    helper_.Initialize(nullptr, nullptr, nullptr);
+    base_url_ = "https://www.test.com/";
+  }
+  FrameTestHelpers::WebViewHelper helper_;
+  std::string base_url_;
+};
+
+void CheckTargetObject(Document* document) {
+  LayoutObject* target_layout_object =
+      document->getElementById("target")->GetLayoutObject();
+  EXPECT_NE(target_layout_object, nullptr);
+  EXPECT_NE(target_layout_object->Style()->InsideLink(),
+            EInsideLink::kNotInsideLink);
+
+  CSSPaintValue* css_paint_value =
+      CSSPaintValue::Create(CSSCustomIdentValue::Create("linkpainter"));
+  EXPECT_EQ(css_paint_value->GetImage(*target_layout_object, *document,
+                                      target_layout_object->StyleRef(),
+                                      FloatSize(100.0f, 100.0f)),
+            nullptr);
+}
+
+// Regression test for https://crbug.com/835589.
+TEST_F(CSSPaintValueTest, CSSPaintDoNotPaintForLink) {
+  LoadTestData("csspaint-do-not-paint-for-link.html");
+  Document* document = GetFrame()->GetDocument();
+  CheckTargetObject(document);
+}
+
+// Regression test for https://crbug.com/835589.
+TEST_F(CSSPaintValueTest, CSSPaintDoNotPaintWhenParentHasLink) {
+  LoadTestData("csspaint-do-not-paint-for-link-descendant.html");
+  Document* document = GetFrame()->GetDocument();
+  CheckTargetObject(document);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/css/test_data/csspaint-do-not-paint-for-link-descendant.html b/third_party/blink/renderer/core/css/test_data/csspaint-do-not-paint-for-link-descendant.html
new file mode 100644
index 0000000..958ea8f
--- /dev/null
+++ b/third_party/blink/renderer/core/css/test_data/csspaint-do-not-paint-for-link-descendant.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+a {
+  width: 200px;
+  height: 200px;
+}
+b {
+  background-image: paint(linkpainter);
+  width: 100px;
+  height: 100px;
+}
+</style>
+</head>
+<body>
+  <a id="ancestor">
+    <b id="target"></b>
+  </a>
+<script>
+function addPaintletFromSource (src) {
+  var uri = 'data:application/javascript;charset=utf-8;base64,' + btoa(src);
+  CSS.paintWorklet.addModule(uri).then();
+}
+
+addPaintletFromSource(`
+  class LinkPainter {
+    paint(ctx, geom) {
+      ctx.fillStyle = 'black';
+      ctx.fillRect(0, 0, geom.width, geom.height);
+    }
+  }
+  registerPaint('linkpainter', LinkPainter);
+`);
+
+ancestor.href = 'https://cs.chromium.org';
+</script>
+</body>
+</html>
diff --git a/third_party/blink/renderer/core/css/test_data/csspaint-do-not-paint-for-link.html b/third_party/blink/renderer/core/css/test_data/csspaint-do-not-paint-for-link.html
new file mode 100644
index 0000000..1d78b53
--- /dev/null
+++ b/third_party/blink/renderer/core/css/test_data/csspaint-do-not-paint-for-link.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+a {
+  background-image: paint(linkpainter);
+  width: 100px;
+  height: 100px;
+}
+</style>
+</head>
+<body>
+  <a id="target"></a>
+<script>
+function addPaintletFromSource (src) {
+  var uri = 'data:application/javascript;charset=utf-8;base64,' + btoa(src);
+  CSS.paintWorklet.addModule(uri).then();
+}
+
+addPaintletFromSource(`
+  class LinkPainter {
+    paint(ctx, geom) {
+      ctx.fillStyle = 'black';
+      ctx.fillRect(0, 0, geom.width, geom.height);
+    }
+  }
+  registerPaint('linkpainter', LinkPainter);
+`);
+
+target.href = 'https://cs.chromium.org';
+</script>
+</body>
+</html>
diff --git a/third_party/blink/renderer/core/html/html_image_loader.cc b/third_party/blink/renderer/core/html/html_image_loader.cc
index 45bcc55..f5ebd697 100644
--- a/third_party/blink/renderer/core/html/html_image_loader.cc
+++ b/third_party/blink/renderer/core/html/html_image_loader.cc
@@ -75,10 +75,30 @@
 
   bool load_error = cached_image->ErrorOccurred();
   if (auto* image = ToHTMLImageElementOrNull(*element)) {
-    if (load_error)
+    if (load_error) {
       image->EnsureCollapsedOrFallbackContent();
-    else
+    } else {
       image->EnsurePrimaryContent();
+      // Check policies
+      if (auto* frame = image->GetDocument().GetFrame()) {
+        // Invert the image if the document does not have the
+        // 'legacy-image-formats' feature enabled, and the image is not one of
+        // the allowed formats.
+        if (!frame->IsFeatureEnabled(
+                mojom::FeaturePolicyFeature::kLegacyImageFormats)) {
+          if (!cached_image->IsAcceptableContentType())
+            image->UpdateShouldInvertColor(true);
+        }
+        // Invert the image if the document does not have the
+        // 'image-compression' feature enabled and the image is not
+        // sufficiently-well-compressed.
+        if (!frame->IsFeatureEnabled(
+                mojom::FeaturePolicyFeature::kImageCompression)) {
+          if (!cached_image->IsAcceptableCompressionRatio())
+            image->UpdateShouldInvertColor(true);
+        }
+      }
+    }
   }
 
   if (auto* input = ToHTMLInputElementOrNull(*element)) {
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc
index a368a12b..ca93e323 100644
--- a/third_party/blink/renderer/core/input/event_handler.cc
+++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -209,6 +209,7 @@
   gesture_manager_->Clear();
   mouse_event_manager_->Clear();
   mouse_wheel_event_manager_->Clear();
+  last_show_press_timestamp_.reset();
   last_deferred_tap_element_ = nullptr;
   event_handler_will_reset_capturing_mouse_events_node_ = false;
   should_use_touch_event_adjusted_point_ = false;
@@ -1323,6 +1324,9 @@
   // etc.
   DCHECK(!targeted_event.Event().IsScrollEvent());
 
+  if (targeted_event.Event().GetType() == WebInputEvent::kGestureShowPress)
+    last_show_press_timestamp_ = CurrentTimeTicks();
+
   // Update mouseout/leave/over/enter events before jumping directly to the
   // inner most frame.
   if (targeted_event.Event().GetType() == WebInputEvent::kGestureTap)
@@ -1641,12 +1645,11 @@
   if (read_only) {
     hit_type |= HitTestRequest::kReadOnly;
   } else if (gesture_event.GetType() == WebInputEvent::kGestureTap &&
-             gesture_manager_->GetLastShowPressTimestamp()) {
+             last_show_press_timestamp_) {
     // If the Tap is received very shortly after ShowPress, we want to
     // delay clearing of the active state so that it's visible to the user
     // for at least a couple of frames.
-    active_interval = CurrentTimeTicks() -
-                      gesture_manager_->GetLastShowPressTimestamp().value();
+    active_interval = CurrentTimeTicks() - last_show_press_timestamp_.value();
     should_keep_active_for_min_interval =
         active_interval < kMinimumActiveInterval;
     if (should_keep_active_for_min_interval)
@@ -1657,9 +1660,10 @@
       HitTestResultForGestureEvent(gesture_event, hit_type);
   // Now apply hover/active state to the final target.
   HitTestRequest request(hit_type | HitTestRequest::kAllowChildFrameContent);
-  if (!request.ReadOnly())
+  if (!request.ReadOnly()) {
     UpdateGestureHoverActiveState(
         request, event_with_hit_test_results.GetHitTestResult().InnerElement());
+  }
 
   if (should_keep_active_for_min_interval) {
     last_deferred_tap_element_ =
diff --git a/third_party/blink/renderer/core/input/event_handler.h b/third_party/blink/renderer/core/input/event_handler.h
index 673bb5e..3d4d803 100644
--- a/third_party/blink/renderer/core/input/event_handler.h
+++ b/third_party/blink/renderer/core/input/event_handler.h
@@ -28,6 +28,7 @@
 
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/optional.h"
 #include "third_party/blink/public/platform/web_input_event.h"
 #include "third_party/blink/public/platform/web_input_event_result.h"
 #include "third_party/blink/public/platform/web_menu_source_type.h"
@@ -51,6 +52,7 @@
 #include "third_party/blink/renderer/platform/wtf/forward.h"
 #include "third_party/blink/renderer/platform/wtf/hash_map.h"
 #include "third_party/blink/renderer/platform/wtf/hash_traits.h"
+#include "third_party/blink/renderer/platform/wtf/time.h"
 
 namespace blink {
 
@@ -398,7 +400,13 @@
   bool long_tap_should_invoke_context_menu_;
 
   TaskRunnerTimer<EventHandler> active_interval_timer_;
-  double last_show_press_timestamp_;
+
+  // last_show_press_timestamp_ prevents the active state rewrited by following
+  // events too soon (less than 0.15s).
+  // It is ok we only record last_show_press_timestamp_ in root frame since
+  // root frame will have subframe as active element if subframe has active
+  // element.
+  base::Optional<WTF::TimeTicks> last_show_press_timestamp_;
   Member<Element> last_deferred_tap_element_;
 
   // Set on GestureTapDown if unique_touch_event_id_ matches cached adjusted
diff --git a/third_party/blink/renderer/core/input/event_handler_test.cc b/third_party/blink/renderer/core/input/event_handler_test.cc
index 965348ed..1e5b10e 100644
--- a/third_party/blink/renderer/core/input/event_handler_test.cc
+++ b/third_party/blink/renderer/core/input/event_handler_test.cc
@@ -27,6 +27,7 @@
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
 #include "third_party/blink/renderer/core/testing/sim/sim_request.h"
 #include "third_party/blink/renderer/core/testing/sim/sim_test.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
 
 namespace blink {
 
@@ -55,6 +56,36 @@
   }
 };
 
+class TapDownEventBuilder : public WebGestureEvent {
+ public:
+  TapDownEventBuilder(FloatPoint position)
+      : WebGestureEvent(WebInputEvent::kGestureTapDown,
+                        WebInputEvent::kNoModifiers,
+                        CurrentTimeTicks(),
+                        kWebGestureDeviceTouchscreen) {
+    SetPositionInWidget(position);
+    SetPositionInScreen(position);
+    data.tap_down.width = 5;
+    data.tap_down.height = 5;
+    frame_scale_ = 1;
+  }
+};
+
+class ShowPressEventBuilder : public WebGestureEvent {
+ public:
+  ShowPressEventBuilder(FloatPoint position)
+      : WebGestureEvent(WebInputEvent::kGestureShowPress,
+                        WebInputEvent::kNoModifiers,
+                        CurrentTimeTicks(),
+                        kWebGestureDeviceTouchscreen) {
+    SetPositionInWidget(position);
+    SetPositionInScreen(position);
+    data.show_press.width = 5;
+    data.show_press.height = 5;
+    frame_scale_ = 1;
+  }
+};
+
 class LongPressEventBuilder : public WebGestureEvent {
  public:
   LongPressEventBuilder(FloatPoint position)
@@ -1154,4 +1185,68 @@
                                      .GetType());
 }
 
+// Ensure that tap on element in iframe should apply active state.
+TEST_F(EventHandlerSimTest, TapActiveInFrame) {
+  WebView().Resize(WebSize(800, 600));
+
+  SimRequest main_resource("https://example.com/test.html", "text/html");
+  SimRequest frame_resource("https://example.com/iframe.html", "text/html");
+  LoadURL("https://example.com/test.html");
+  main_resource.Complete(R"HTML(
+    <!DOCTYPE html>
+    <style>
+    body {
+      margin: 0;
+    }
+    iframe {
+      width: 200px;
+      height: 200px;
+    }
+    </style>
+    <iframe id='iframe' src='iframe.html'>
+    </iframe>
+  )HTML");
+
+  frame_resource.Complete(R"HTML(
+    <!DOCTYPE html>
+    <style>
+    body {
+      margin: 0;
+    }
+    div {
+      width: 100px;
+      height: 100px;
+    }
+    </style>
+    <div></div>
+  )HTML");
+  Compositor().BeginFrame();
+
+  auto* iframe_element =
+      ToHTMLIFrameElement(GetDocument().getElementById("iframe"));
+  Document* iframe_doc = iframe_element->contentDocument();
+
+  TapDownEventBuilder tap_down(FloatPoint(10, 10));
+  GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(tap_down);
+
+  ShowPressEventBuilder show_press(FloatPoint(10, 10));
+  GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(show_press);
+
+  // TapDown and ShowPress active the iframe.
+  EXPECT_TRUE(GetDocument().GetActiveElement());
+  EXPECT_TRUE(iframe_doc->GetActiveElement());
+
+  TapEventBuilder tap(FloatPoint(10, 10), 1);
+  GetDocument().GetFrame()->GetEventHandler().HandleGestureEvent(tap);
+
+  // Should still active.
+  EXPECT_TRUE(GetDocument().GetActiveElement());
+  EXPECT_TRUE(iframe_doc->GetActiveElement());
+
+  // The active will cancel after 15ms.
+  test::RunDelayedTasks(TimeDelta::FromSecondsD(0.2));
+  EXPECT_FALSE(GetDocument().GetActiveElement());
+  EXPECT_FALSE(iframe_doc->GetActiveElement());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/input/gesture_manager.cc b/third_party/blink/renderer/core/input/gesture_manager.cc
index efb6bf0..513f0e3 100644
--- a/third_party/blink/renderer/core/input/gesture_manager.cc
+++ b/third_party/blink/renderer/core/input/gesture_manager.cc
@@ -49,7 +49,6 @@
 void GestureManager::Clear() {
   suppress_mouse_events_from_gestures_ = false;
   long_tap_should_invoke_context_menu_ = false;
-  last_show_press_timestamp_.reset();
 }
 
 void GestureManager::Trace(blink::Visitor* visitor) {
@@ -430,8 +429,6 @@
 }
 
 WebInputEventResult GestureManager::HandleGestureShowPress() {
-  last_show_press_timestamp_ = CurrentTimeTicks();
-
   LocalFrameView* view = frame_->View();
   if (!view)
     return WebInputEventResult::kNotHandled;
@@ -448,11 +445,6 @@
   return WebInputEventResult::kNotHandled;
 }
 
-base::Optional<WTF::TimeTicks> GestureManager::GetLastShowPressTimestamp()
-    const {
-  return last_show_press_timestamp_;
-}
-
 void GestureManager::ShowUnhandledTapUIIfNeeded(
     bool dom_tree_changed,
     bool style_changed,
diff --git a/third_party/blink/renderer/core/input/gesture_manager.h b/third_party/blink/renderer/core/input/gesture_manager.h
index d0e4e171..7d9c046 100644
--- a/third_party/blink/renderer/core/input/gesture_manager.h
+++ b/third_party/blink/renderer/core/input/gesture_manager.h
@@ -6,13 +6,11 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_INPUT_GESTURE_MANAGER_H_
 
 #include "base/macros.h"
-#include "base/optional.h"
 #include "third_party/blink/public/platform/web_input_event_result.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/layout/hit_test_request.h"
 #include "third_party/blink/renderer/core/page/event_with_hit_test_results.h"
-#include "third_party/blink/renderer/platform/wtf/time.h"
 
 namespace blink {
 
@@ -41,11 +39,6 @@
   WebInputEventResult HandleGestureEventInFrame(
       const GestureEventWithHitTestResults&);
 
-  // TODO(nzolghadr): This can probably be hidden and the related logic
-  // be moved to this class (see crrev.com/112023010). Since that might cause
-  // regression it's better to move that logic in another change.
-  base::Optional<WTF::TimeTicks> GetLastShowPressTimestamp() const;
-
  private:
   WebInputEventResult HandleGestureShowPress();
   WebInputEventResult HandleGestureTapDown(
@@ -85,7 +78,6 @@
 
   const Member<SelectionController> selection_controller_;
 
-  base::Optional<WTF::TimeTicks> last_show_press_timestamp_;
   DISALLOW_COPY_AND_ASSIGN(GestureManager);
 };
 
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_multi_line.cc b/third_party/blink/renderer/core/layout/layout_text_control_multi_line.cc
index 0ac12fb..1a71eb5 100644
--- a/third_party/blink/renderer/core/layout/layout_text_control_multi_line.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_control_multi_line.cc
@@ -99,9 +99,6 @@
   if (!placeholder_layout_object->IsBox())
     return placeholder_layout_object;
   LayoutBox* placeholder_box = ToLayoutBox(placeholder_layout_object);
-  placeholder_box->MutableStyleRef().SetLogicalWidth(Length(
-      ContentLogicalWidth() - placeholder_box->BorderAndPaddingLogicalWidth(),
-      kFixed));
   placeholder_box->LayoutIfNeeded();
   placeholder_box->SetX(BorderLeft() + PaddingLeft());
   placeholder_box->SetY(BorderTop() + PaddingTop());
diff --git a/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc b/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc
index 422db9f..6263ec7 100644
--- a/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_control_single_line.cc
@@ -131,13 +131,11 @@
   HTMLElement* placeholder_element = InputElement()->PlaceholderElement();
   if (LayoutBox* placeholder_box =
           placeholder_element ? placeholder_element->GetLayoutBox() : nullptr) {
-    LayoutSize inner_editor_size;
+    LayoutUnit inner_editor_logical_width;
 
     if (inner_editor_layout_object)
-      inner_editor_size = inner_editor_layout_object->Size();
-    placeholder_box->MutableStyleRef().SetWidth(Length(
-        inner_editor_size.Width() - placeholder_box->BorderAndPaddingWidth(),
-        kFixed));
+      inner_editor_logical_width = inner_editor_layout_object->LogicalWidth();
+    placeholder_box->SetOverrideLogicalWidth(inner_editor_logical_width);
     bool needed_layout = placeholder_box->NeedsLayout();
     placeholder_box->LayoutIfNeeded();
     LayoutPoint text_offset;
diff --git a/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc
index 7c8215a..ca59095 100644
--- a/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc
@@ -7,11 +7,9 @@
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h"
-#include "third_party/blink/renderer/core/script/layered_api.h"
 #include "third_party/blink/renderer/platform/loader/cors/cors.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_utils.h"
 #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 
 namespace blink {
 
@@ -78,42 +76,9 @@
 void DocumentModuleScriptFetcher::Fetch(FetchParameters& fetch_params,
                                         ModuleScriptFetcher::Client* client) {
   SetClient(client);
-
-  if (FetchIfLayeredAPI(fetch_params))
-    return;
-
   ScriptResource::Fetch(fetch_params, fetcher_, this);
 }
 
-bool DocumentModuleScriptFetcher::FetchIfLayeredAPI(
-    FetchParameters& fetch_params) {
-  if (!RuntimeEnabledFeatures::LayeredAPIEnabled())
-    return false;
-
-  KURL layered_api_url = blink::layered_api::GetInternalURL(fetch_params.Url());
-
-  if (layered_api_url.IsNull())
-    return false;
-
-  const String source_text = blink::layered_api::GetSourceText(layered_api_url);
-
-  if (source_text.IsNull()) {
-    HeapVector<Member<ConsoleMessage>> error_messages;
-    error_messages.push_back(ConsoleMessage::CreateForRequest(
-        kJSMessageSource, kErrorMessageLevel, "Unexpected data error",
-        fetch_params.Url().GetString(), nullptr, 0));
-    Finalize(base::nullopt, error_messages);
-    return true;
-  }
-
-  ModuleScriptCreationParams params(
-      layered_api_url, source_text,
-      fetch_params.GetResourceRequest().GetFetchCredentialsMode(),
-      kSharableCrossOrigin);
-  Finalize(params, HeapVector<Member<ConsoleMessage>>());
-  return true;
-}
-
 void DocumentModuleScriptFetcher::NotifyFinished(Resource* resource) {
   ClearResource();
 
diff --git a/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.h b/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.h
index 0dd6136..aefa503 100644
--- a/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.h
+++ b/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.h
@@ -44,9 +44,6 @@
   void Finalize(const base::Optional<ModuleScriptCreationParams>&,
                 const HeapVector<Member<ConsoleMessage>>& error_messages);
 
-  // Returns true if loaded as Layered API.
-  bool FetchIfLayeredAPI(FetchParameters&);
-
   Member<ResourceFetcher> fetcher_;
 };
 
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
index 2ef9b731c..e1f2d31 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
@@ -7,11 +7,9 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_module.h"
 #include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h"
 #include "third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h"
-#include "third_party/blink/renderer/core/script/layered_api.h"
 #include "third_party/blink/renderer/core/script/module_script.h"
 #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_loading_log.h"
-#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 #include "v8/include/v8.h"
 
@@ -130,38 +128,15 @@
 }
 
 // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-script-tree
-void ModuleTreeLinker::FetchRoot(const KURL& original_url,
+void ModuleTreeLinker::FetchRoot(const KURL& url,
                                  const ScriptFetchOptions& options) {
 #if DCHECK_IS_ON()
-  original_url_ = original_url;
+  url_ = url;
   root_is_inline_ = false;
 #endif
 
   AdvanceState(State::kFetchingSelf);
 
-  KURL url = original_url;
-  // <spec
-  // href="https://github.com/drufball/layered-apis/blob/master/spec.md#fetch-a-module-script-graph"
-  // step="1">Set url to the layered API fetching URL for url.</spec>
-  if (RuntimeEnabledFeatures::LayeredAPIEnabled())
-    url = blink::layered_api::ResolveFetchingURL(url);
-
-#if DCHECK_IS_ON()
-  url_ = url;
-#endif
-
-  // <spec
-  // href="https://github.com/drufball/layered-apis/blob/master/spec.md#fetch-a-module-script-graph"
-  // step="2">If url is failure, asynchronously complete this algorithm with
-  // null.</spec>
-  if (!url.IsValid()) {
-    result_ = nullptr;
-    modulator_->TaskRunner()->PostTask(
-        FROM_HERE, WTF::Bind(&ModuleTreeLinker::AdvanceState,
-                             WrapPersistent(this), State::kFinished));
-    return;
-  }
-
   // Step 1. Let visited set be << url >>.
   visited_set_.insert(url);
 
@@ -179,8 +154,7 @@
   // Top-level entry point for [FDaI] for an inline module script.
   DCHECK(module_script);
 #if DCHECK_IS_ON()
-  original_url_ = module_script->BaseURL();
-  url_ = original_url_;
+  url_ = module_script->BaseURL();
   root_is_inline_ = true;
 #endif
 
@@ -513,7 +487,6 @@
 #if DCHECK_IS_ON()
 std::ostream& operator<<(std::ostream& stream, const ModuleTreeLinker& linker) {
   stream << "ModuleTreeLinker[" << &linker
-         << ", original_url=" << linker.original_url_.GetString()
          << ", url=" << linker.url_.GetString()
          << ", inline=" << linker.root_is_inline_ << "]";
   return stream;
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
index ee7d659130..741c10b 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
+++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
@@ -113,7 +113,6 @@
   size_t num_incomplete_fetches_ = 0;
 
 #if DCHECK_IS_ON()
-  KURL original_url_;
   KURL url_;
   bool root_is_inline_;
 
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_content.cc b/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
index cbacff7c..a46c71d 100644
--- a/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
+++ b/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
@@ -16,6 +16,7 @@
 #include "third_party/blink/renderer/platform/histogram.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/blink/renderer/platform/network/http_parsers.h"
+#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
 #include "third_party/blink/renderer/platform/shared_buffer.h"
 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
@@ -509,6 +510,32 @@
   return UpdateImageResult::kNoDecodeError;
 }
 
+// Return true if the image type is one of the hard-coded 'modern' image
+// formats.
+// TODO(crbug.com/838263): Support site-defined list of acceptable formats
+// through feature policy declarations.
+bool ImageResourceContent::IsAcceptableContentType() {
+  AtomicString mime_type = GetResponse().HttpContentType();
+  // If this was loaded from disk, there is no mime type. Return true for now.
+  if (mime_type.IsNull())
+    return true;
+  return MIMETypeRegistry::IsModernImageMIMEType(mime_type);
+}
+
+// Return true if the image content is well-compressed (and not full of
+// extraneous metadata). This is currently defined as no using more than 10 bits
+// per pixel of image data.
+// TODO(crbug.com/838263): Support site-defined bit-per-pixel ratio through
+// feature policy declarations.
+bool ImageResourceContent::IsAcceptableCompressionRatio() {
+  uint64_t pixels = IntrinsicSize(kDoNotRespectImageOrientation).Area();
+  if (!pixels)
+    return true;
+  long long resource_length = GetResponse().DecodedBodyLength();
+  // Allow no more than 10 bits per compressed pixel
+  return (double)resource_length / pixels <= 1.25;
+}
+
 void ImageResourceContent::DecodedSizeChangedTo(const blink::Image* image,
                                                 size_t new_size) {
   if (!image || image != image_)
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_content.h b/third_party/blink/renderer/core/loader/resource/image_resource_content.h
index 45e7185..47693d5f 100644
--- a/third_party/blink/renderer/core/loader/resource/image_resource_content.h
+++ b/third_party/blink/renderer/core/loader/resource/image_resource_content.h
@@ -176,6 +176,12 @@
     return is_refetchable_data_from_disk_cache_;
   }
 
+  // Optimized image policies: These methods are used to determine whether the
+  // image resource violates any of the image policies in effect on the current
+  // page.
+  bool IsAcceptableContentType();
+  bool IsAcceptableCompressionRatio();
+
  private:
   using CanDeferInvalidation = ImageResourceObserver::CanDeferInvalidation;
 
diff --git a/third_party/blink/renderer/core/script/BUILD.gn b/third_party/blink/renderer/core/script/BUILD.gn
index b22ddd3..adc2c9c1 100644
--- a/third_party/blink/renderer/core/script/BUILD.gn
+++ b/third_party/blink/renderer/core/script/BUILD.gn
@@ -22,8 +22,6 @@
     "html_parser_script_runner.h",
     "html_parser_script_runner_host.h",
     "ignore_destructive_write_count_incrementer.h",
-    "layered_api.cc",
-    "layered_api.h",
     "modulator.cc",
     "modulator.h",
     "modulator_impl_base.cc",
diff --git a/third_party/blink/renderer/core/script/layered_api.cc b/third_party/blink/renderer/core/script/layered_api.cc
deleted file mode 100644
index 2e7083c3..0000000
--- a/third_party/blink/renderer/core/script/layered_api.cc
+++ /dev/null
@@ -1,126 +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.
-
-#include "third_party/blink/renderer/core/script/layered_api.h"
-
-#include "base/stl_util.h"
-#include "third_party/blink/public/resources/grit/blink_resources.h"
-#include "third_party/blink/renderer/platform/media/resource_bundle_helper.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
-
-namespace blink {
-
-namespace layered_api {
-
-namespace {
-
-static const char kStdScheme[] = "std";
-static const char kInternalScheme[] = "std-internal";
-
-struct LayeredAPIResource {
-  const char* path;
-  int resource_id;
-};
-
-const LayeredAPIResource kLayeredAPIResources[] = {
-    {"blank/index.js", IDR_LAYERED_API_BLANK_INDEX_JS},
-};
-
-int GetResourceIDFromPath(const String& path) {
-  for (size_t i = 0; i < base::size(kLayeredAPIResources); ++i) {
-    if (path == kLayeredAPIResources[i].path) {
-      return kLayeredAPIResources[i].resource_id;
-    }
-  }
-  return -1;
-}
-
-bool IsImplemented(const String& name) {
-  return GetResourceIDFromPath(name + "/index.js") >= 0;
-}
-
-}  // namespace
-
-// https://github.com/drufball/layered-apis/blob/master/spec.md#user-content-layered-api-fetching-url
-KURL ResolveFetchingURL(const KURL& url) {
-  // <spec step="1">If url's scheme is not "std", return url.</spec>
-  if (!url.ProtocolIs(kStdScheme))
-    return url;
-
-  // <spec step="2">Let path be url's path[0].</spec>
-  const String path = url.GetPath();
-
-  // <spec step="3">Let identifier be the portion of path before the first
-  // U+007C (|), or all of path if no U+007C is present.</spec>
-  //
-  // <spec step="4">Let fallback be the portion of path after the first U+007C,
-  // or null if no U+007C is present.</spec>
-  String identifier;
-  String fallback;
-  const size_t separator_position = path.find('|');
-  if (separator_position != WTF::kNotFound) {
-    identifier = path.Substring(0, separator_position);
-    fallback = path.Substring(separator_position + 1);
-  } else {
-    identifier = path;
-  }
-
-  // <spec step="5">If the layered API identified by path is implemented by this
-  // user agent, return the result of parsing the concatenation of "std:" with
-  // identifier.</spec>
-  if (IsImplemented(identifier)) {
-    StringBuilder url_string;
-    url_string.Append(kStdScheme);
-    url_string.Append(":");
-    url_string.Append(identifier);
-    return KURL(NullURL(), url_string.ToString());
-  }
-
-  // <spec step="6">If fallback is null, return failure.</spec>
-  if (fallback.IsNull())
-    return NullURL();
-
-  // <spec step="7">Return the result of parsing fallback.</spec>
-  return KURL(NullURL(), fallback);
-}
-
-KURL GetInternalURL(const KURL& url) {
-  if (url.ProtocolIs(kStdScheme)) {
-    StringBuilder url_string;
-    url_string.Append(kInternalScheme);
-    url_string.Append("://");
-    url_string.Append(url.GetPath());
-    url_string.Append("/index.js");
-    return KURL(NullURL(), url_string.ToString());
-  }
-
-  if (url.ProtocolIs(kInternalScheme)) {
-    return url;
-  }
-
-  return NullURL();
-}
-
-String GetSourceText(const KURL& url) {
-  if (!url.ProtocolIs(kInternalScheme))
-    return String();
-
-  String path = url.GetPath();
-  // According to the URL spec, the host/path of "std-internal://foo/bar"
-  // is "foo" and "/bar", respectively, but in Blink they are "" and
-  // "//foo/bar". This is a workaround to get "foo/bar" here.
-  if (path.StartsWith("//")) {
-    path = path.Substring(2);
-  }
-
-  int resource_id = GetResourceIDFromPath(path);
-  if (resource_id < 0)
-    return String();
-
-  return ResourceBundleHelper::GetResourceAsString(resource_id);
-}
-
-}  // namespace layered_api
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/script/layered_api.h b/third_party/blink/renderer/core/script/layered_api.h
deleted file mode 100644
index f9d3599..0000000
--- a/third_party/blink/renderer/core/script/layered_api.h
+++ /dev/null
@@ -1,37 +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.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/platform/weborigin/kurl.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-// Implements Layered API.
-// Spec: https://github.com/drufball/layered-apis/blob/master/spec.md
-// Implementation Design Doc:
-// https://docs.google.com/document/d/1V-WaCZQbBcQJRSYSYBb8Y6p0DOdDpiNDSmD41ui_73s/edit
-namespace layered_api {
-
-// <spec
-// href="https://github.com/drufball/layered-apis/blob/master/spec.md#user-content-layered-api-fetching-url">
-// This operation maps URLs of the form std:x|y to either std:x or y
-// URLs.</spec>
-CORE_EXPORT KURL ResolveFetchingURL(const KURL&);
-
-// Returns std-internal://x/index.js if the URL is Layered API, or null URL
-// otherwise (not specced).
-CORE_EXPORT KURL GetInternalURL(const KURL&);
-
-// Gets source text for std-internal://x/index.js.
-CORE_EXPORT String GetSourceText(const KURL&);
-
-}  // namespace layered_api
-
-}  // namespace blink
-
-#endif
diff --git a/third_party/blink/renderer/core/script/layered_api_test.cc b/third_party/blink/renderer/core/script/layered_api_test.cc
deleted file mode 100644
index 0f056fc..0000000
--- a/third_party/blink/renderer/core/script/layered_api_test.cc
+++ /dev/null
@@ -1,66 +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.
-
-#include "third_party/blink/renderer/core/script/layered_api.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-namespace layered_api {
-
-namespace {
-
-TEST(LayeredAPITest, ResolveFetchingURL) {
-  EXPECT_EQ(ResolveFetchingURL(KURL("https://example.com/")),
-            KURL("https://example.com/"));
-  EXPECT_EQ(ResolveFetchingURL(KURL("std:blank")), KURL("std:blank"));
-  EXPECT_EQ(ResolveFetchingURL(KURL("std:blank|https://fallback.example.com/")),
-            KURL("std:blank"));
-  EXPECT_EQ(ResolveFetchingURL(KURL("std:blank|https://:invalid-url")),
-            KURL("std:blank"));
-  EXPECT_EQ(ResolveFetchingURL(KURL("std:none")), NullURL());
-  EXPECT_EQ(ResolveFetchingURL(KURL("std:none|https://fallback.example.com/")),
-            KURL("https://fallback.example.com/"));
-  EXPECT_FALSE(
-      ResolveFetchingURL(KURL("std:none|https://:invalid-url")).IsValid());
-}
-
-TEST(LayeredAPITest, GetInternalURL) {
-  EXPECT_EQ(GetInternalURL(KURL("https://example.com/")), NullURL());
-
-  EXPECT_EQ(GetInternalURL(KURL("std:blank")),
-            KURL("std-internal://blank/index.js"));
-
-  EXPECT_EQ(GetInternalURL(KURL("std-internal://blank/index.js")),
-            KURL("std-internal://blank/index.js"));
-  EXPECT_EQ(GetInternalURL(KURL("std-internal://blank/foo/bar.js")),
-            KURL("std-internal://blank/foo/bar.js"));
-}
-
-TEST(LayeredAPITest, InternalURLRelativeResolution) {
-  EXPECT_EQ(KURL(KURL("std-internal://blank/index.js"), "./sub.js"),
-            KURL("std-internal://blank/sub.js"));
-  EXPECT_EQ(KURL(KURL("std-internal://blank/index.js"), "/sub.js"),
-            KURL("std-internal://blank/sub.js"));
-  EXPECT_EQ(KURL(KURL("std-internal://blank/index.js"), "./foo/bar.js"),
-            KURL("std-internal://blank/foo/bar.js"));
-  EXPECT_EQ(KURL(KURL("std-internal://blank/foo/bar.js"), "../baz.js"),
-            KURL("std-internal://blank/baz.js"));
-}
-
-TEST(LayeredAPITest, GetSourceText) {
-  EXPECT_EQ(GetSourceText(KURL("std-internal://blank/index.js")), String(""));
-
-  EXPECT_EQ(GetSourceText(KURL("std-internal://blank/not-found.js")), String());
-  EXPECT_EQ(GetSourceText(KURL("std-internal://none/index.js")), String());
-
-  EXPECT_EQ(GetSourceText(KURL("https://example.com/")), String());
-}
-
-}  // namespace
-
-}  // namespace layered_api
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/script/modulator.cc b/third_party/blink/renderer/core/script/modulator.cc
index c958aee..c317188 100644
--- a/third_party/blink/renderer/core/script/modulator.cc
+++ b/third_party/blink/renderer/core/script/modulator.cc
@@ -9,7 +9,6 @@
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/script/document_modulator_impl.h"
-#include "third_party/blink/renderer/core/script/layered_api.h"
 #include "third_party/blink/renderer/core/script/worker_modulator_impl.h"
 #include "third_party/blink/renderer/core/script/worklet_modulator_impl.h"
 #include "third_party/blink/renderer/core/workers/worklet_global_scope.h"
@@ -87,17 +86,8 @@
   // <spec step="1">Apply the URL parser to specifier. If the result is not
   // failure, return the result.</spec>
   KURL url(NullURL(), module_request);
-  if (url.IsValid()) {
-    // <spec
-    // href="https://github.com/drufball/layered-apis/blob/master/spec.md#resolve-a-module-specifier"
-    // step="1">Let parsed be the result of applying the URL parser to
-    // specifier. If parsed is not failure, then return the layered API fetching
-    // URL for parsed.</spec>
-    if (RuntimeEnabledFeatures::LayeredAPIEnabled())
-      return blink::layered_api::ResolveFetchingURL(url);
-
+  if (url.IsValid())
     return url;
-  }
 
   // <spec step="2">If specifier does not start with the character U+002F
   // SOLIDUS (/), the two-character sequence U+002E FULL STOP, U+002F SOLIDUS
diff --git a/third_party/blink/renderer/core/script/resources/layered_api/blank/index.js b/third_party/blink/renderer/core/script/resources/layered_api/blank/index.js
deleted file mode 100644
index e69de29..0000000
--- a/third_party/blink/renderer/core/script/resources/layered_api/blank/index.js
+++ /dev/null
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc
index ebcc6a2d9..58e8e78 100644
--- a/third_party/blink/renderer/core/style/computed_style.cc
+++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -721,6 +721,11 @@
 bool ComputedStyle::DiffNeedsPaintInvalidationObjectForPaintImage(
     const StyleImage& image,
     const ComputedStyle& other) const {
+  // https://crbug.com/835589: early exit when paint target is associated with
+  // a link.
+  if (InsideLink() != EInsideLink::kNotInsideLink)
+    return false;
+
   CSSPaintValue* value = ToCSSPaintValue(image.CssValue());
 
   // NOTE: If the invalidation properties vectors are null, we are invalid as
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
index 7164d4e9..d1bf239 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
@@ -435,6 +435,8 @@
       settings.setFocalLengthY(platform_settings.focal_length_y);
   }
   settings.setDeviceId(platform_settings.device_id);
+  if (!platform_settings.group_id.IsNull())
+    settings.setGroupId(platform_settings.group_id);
   if (platform_settings.HasFacingMode()) {
     switch (platform_settings.facing_mode) {
       case WebMediaStreamTrack::FacingMode::kUser:
diff --git a/third_party/blink/renderer/modules/mediastream/media_track_settings.idl b/third_party/blink/renderer/modules/mediastream/media_track_settings.idl
index 8cbdef9d..0e085aa 100644
--- a/third_party/blink/renderer/modules/mediastream/media_track_settings.idl
+++ b/third_party/blink/renderer/modules/mediastream/media_track_settings.idl
@@ -21,8 +21,7 @@
     // double latency;
     // long channelCount;
     DOMString deviceId;
-    // groupId is not implemented.
-    // DOMString groupId;
+    DOMString groupId;
     // Media Capture Depth Stream Extensions
     // https://w3c.github.io/mediacapture-depth/#mediatracksettings-dictionary
     // TODO(aleksandar.stojiljkovic): videoKind, depthNear, depthFar,
diff --git a/third_party/blink/renderer/platform/exported/web_media_stream_source.cc b/third_party/blink/renderer/platform/exported/web_media_stream_source.cc
index 514f1de..d79a908 100644
--- a/third_party/blink/renderer/platform/exported/web_media_stream_source.cc
+++ b/third_party/blink/renderer/platform/exported/web_media_stream_source.cc
@@ -127,6 +127,16 @@
   return private_.Get()->Remote();
 }
 
+void WebMediaStreamSource::SetGroupId(const blink::WebString& group_id) {
+  DCHECK(!private_.IsNull());
+  private_->SetGroupId(group_id);
+}
+
+WebString WebMediaStreamSource::GroupId() const {
+  DCHECK(!private_.IsNull());
+  return private_->GroupId();
+}
+
 void WebMediaStreamSource::SetReadyState(ReadyState state) {
   DCHECK(!private_.IsNull());
   private_->SetReadyState(static_cast<MediaStreamSource::ReadyState>(state));
diff --git a/third_party/blink/renderer/platform/feature_policy/feature_policy.cc b/third_party/blink/renderer/platform/feature_policy/feature_policy.cc
index b96ed0e..397ce9cf 100644
--- a/third_party/blink/renderer/platform/feature_policy/feature_policy.cc
+++ b/third_party/blink/renderer/platform/feature_policy/feature_policy.cc
@@ -195,6 +195,11 @@
           "picture-in-picture", mojom::FeaturePolicyFeature::kPictureInPicture);
     }
     if (RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled()) {
+      default_feature_name_map.Set(
+          "image-compression", mojom::FeaturePolicyFeature::kImageCompression);
+      default_feature_name_map.Set(
+          "legacy-image-formats",
+          mojom::FeaturePolicyFeature::kLegacyImageFormats);
       default_feature_name_map.Set("sync-script",
                                    mojom::FeaturePolicyFeature::kSyncScript);
       default_feature_name_map.Set("unsized-media",
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn
index 254b8b9..d196bb5 100644
--- a/third_party/blink/renderer/platform/heap/BUILD.gn
+++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -8,16 +8,14 @@
 import("//testing/test.gni")
 
 declare_args() {
-  # Enables incremental marking in Oilpan.
+  # Build Blink with incremental marking infrastructure for Oilpan.
   #
-  # Note: Incremental marking is currently considered experimental and also
-  # enables 'enable_blink_heap_incremental_marking'. See default value below.
-  enable_blink_heap_incremental_marking = false
-}
+  # To turn on incremental marking also use
+  #   --enable-blink-features=HeapIncrementalMarking
+  enable_blink_heap_incremental_marking = true
 
-declare_args() {
   # Enables heap verification.
-  enable_blink_heap_verification = enable_blink_heap_incremental_marking
+  enable_blink_heap_verification = false
 }
 
 buildflag_header("blink_heap_buildflags") {
diff --git a/third_party/blink/renderer/platform/heap/incremental_marking_test.cc b/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
index 33f93792..a7204374 100644
--- a/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
+++ b/third_party/blink/renderer/platform/heap/incremental_marking_test.cc
@@ -76,7 +76,7 @@
 // Base class for initializing worklists.
 class IncrementalMarkingScopeBase {
  public:
-  IncrementalMarkingScopeBase(ThreadState* thread_state)
+  explicit IncrementalMarkingScopeBase(ThreadState* thread_state)
       : thread_state_(thread_state), heap_(thread_state_->Heap()) {
     heap_.CommitCallbackStacks();
   }
@@ -155,16 +155,15 @@
     MarkingItem item;
     // All objects watched should be on the marking stack.
     while (marking_worklist_->Pop(WorklistTaskId::MainThread, &item)) {
-      T* obj = reinterpret_cast<T*>(item.object);
       // Inspect backing stores to allow specifying objects that are only
       // reachable through a backing store.
       if (!ThreadHeap::IsNormalArenaIndex(
-              PageFromObject(obj)->Arena()->ArenaIndex())) {
+              PageFromObject(item.object)->Arena()->ArenaIndex())) {
         BackingVisitor<T> visitor(thread_state_, &objects_);
-        visitor.ProcessBackingStore(HeapObjectHeader::FromPayload(obj));
+        visitor.ProcessBackingStore(HeapObjectHeader::FromPayload(item.object));
         continue;
       }
-      auto pos = std::find(objects_.begin(), objects_.end(), obj);
+      auto pos = std::find(objects_.begin(), objects_.end(), item.object);
       if (objects_.end() != pos)
         objects_.erase(pos);
     }
@@ -190,27 +189,25 @@
  public:
   ExpectNoWriteBarrierFires(ThreadState* thread_state,
                             std::initializer_list<T*> objects)
-      : IncrementalMarkingScope(thread_state), objects_(objects) {
+      : IncrementalMarkingScope(thread_state) {
     EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
     for (T* object : objects_) {
       HeapObjectHeader* header = HeapObjectHeader::FromPayload(object);
-      headers_.push_back(header);
-      was_marked_.push_back(header->IsMarked());
+      headers_.push_back({header, header->IsMarked()});
     }
   }
 
   ~ExpectNoWriteBarrierFires() {
     EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
-    for (size_t i = 0; i < headers_.size(); i++) {
-      EXPECT_EQ(was_marked_[i], headers_[i]->IsMarked());
-      headers_[i]->Unmark();
+    for (const auto& pair : headers_) {
+      EXPECT_EQ(pair.second, pair.first->IsMarked());
+      pair.first->Unmark();
     }
   }
 
  private:
   std::vector<T*> objects_;
-  std::vector<HeapObjectHeader*> headers_;
-  std::vector<bool> was_marked_;
+  std::vector<std::pair<HeapObjectHeader*, bool /* was marked */>> headers_;
 };
 
 class Object : public GarbageCollected<Object> {
@@ -220,12 +217,12 @@
 
   void set_next(Object* next) { next_ = next; }
 
-  virtual void Trace(blink::Visitor* visitor) { visitor->Trace(next_); }
-
   bool IsMarked() const {
     return HeapObjectHeader::FromPayload(this)->IsMarked();
   }
 
+  virtual void Trace(blink::Visitor* visitor) { visitor->Trace(next_); }
+
  private:
   Object() : next_(nullptr) {}
   explicit Object(Object* next) : next_(next) {}
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 91f5d06..edebcf2 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
@@ -29,11 +29,7 @@
 const char kOutstandingLimitForBackgroundSubFrameName[] = "bg_sub_limit";
 
 // Field trial default parameters.
-// Note: Giving smaller sub-frame threshold seems to work better for improving
-// foreground loading performance, while setting it to 1u easily breaks some
-// services that have one long-polling request, and needs other resources.
-constexpr size_t kOutstandingLimitForBackgroundMainFrameDefault = 3u;
-constexpr size_t kOutstandingLimitForBackgroundSubFrameDefault = 2u;
+constexpr size_t kOutstandingLimitForBackgroundFrameDefault = 16u;
 
 // Maximum request count that request count metrics assume.
 constexpr base::HistogramBase::Sample kMaximumReportSize10K = 10000;
@@ -99,14 +95,18 @@
   if (!RuntimeEnabledFeatures::ResourceLoadSchedulerEnabled())
     return ResourceLoadScheduler::kOutstandingUnlimited;
 
-  static size_t main_frame_limit = GetFieldTrialUint32Param(
+  uint32_t main_frame_limit = GetFieldTrialUint32Param(
       kResourceLoadSchedulerTrial, kOutstandingLimitForBackgroundMainFrameName,
-      kOutstandingLimitForBackgroundMainFrameDefault);
-  static size_t sub_frame_limit = GetFieldTrialUint32Param(
-      kResourceLoadSchedulerTrial, kOutstandingLimitForBackgroundSubFrameName,
-      kOutstandingLimitForBackgroundSubFrameDefault);
+      kOutstandingLimitForBackgroundFrameDefault);
+  if (context->IsMainFrame())
+    return main_frame_limit;
 
-  return context->IsMainFrame() ? main_frame_limit : sub_frame_limit;
+  // We do not have a fixed default limit for sub-frames, but use the limit for
+  // the main frame so that it works as how previous versions that haven't
+  // consider sub-frames' specific limit work.
+  return GetFieldTrialUint32Param(kResourceLoadSchedulerTrial,
+                                  kOutstandingLimitForBackgroundSubFrameName,
+                                  main_frame_limit);
 }
 
 int TakeWholeKilobytes(int64_t& bytes) {
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_source.cc b/third_party/blink/renderer/platform/mediastream/media_stream_source.cc
index 282cf74..57accfc 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_source.cc
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_source.cc
@@ -56,6 +56,10 @@
       ready_state_(ready_state),
       requires_consumer_(requires_consumer) {}
 
+void MediaStreamSource::SetGroupId(const String& group_id) {
+  group_id_ = group_id;
+}
+
 void MediaStreamSource::SetReadyState(ReadyState ready_state) {
   if (ready_state_ != kReadyStateEnded && ready_state_ != ready_state) {
     ready_state_ = ready_state;
@@ -117,6 +121,7 @@
 
 void MediaStreamSource::GetSettings(WebMediaStreamTrack::Settings& settings) {
   settings.device_id = Id();
+  settings.group_id = GroupId();
 
   if (echo_cancellation_)
     settings.echo_cancellation = *echo_cancellation_;
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_source.h b/third_party/blink/renderer/platform/mediastream/media_stream_source.h
index 7c0ee69..4e86d91 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_source.h
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_source.h
@@ -84,6 +84,9 @@
   const String& GetName() const { return name_; }
   bool Remote() const { return remote_; }
 
+  void SetGroupId(const String& group_id);
+  const String& GroupId() { return group_id_; }
+
   void SetReadyState(ReadyState);
   ReadyState GetReadyState() const { return ready_state_; }
 
@@ -138,6 +141,7 @@
   String id_;
   StreamType type_;
   String name_;
+  String group_id_;
   bool remote_;
   ReadyState ready_state_;
   bool requires_consumer_;
diff --git a/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc b/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc
index 4b66929..e024e360 100644
--- a/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc
+++ b/third_party/blink/renderer/platform/network/mime/mime_type_registry.cc
@@ -104,12 +104,17 @@
 
 bool MIMETypeRegistry::IsSupportedImageMIMETypeForEncoding(
     const String& mime_type) {
-  if (DeprecatedEqualIgnoringCase(mime_type, "image/jpeg") ||
-      DeprecatedEqualIgnoringCase(mime_type, "image/png"))
-    return true;
-  if (DeprecatedEqualIgnoringCase(mime_type, "image/webp"))
-    return true;
-  return false;
+  return (EqualIgnoringASCIICase(mime_type, "image/jpeg") ||
+          EqualIgnoringASCIICase(mime_type, "image/png") ||
+          EqualIgnoringASCIICase(mime_type, "image/webp"));
+}
+
+bool MIMETypeRegistry::IsModernImageMIMEType(const String& mime_type) {
+  return (EqualIgnoringASCIICase(mime_type, "image/gif") ||
+          EqualIgnoringASCIICase(mime_type, "image/jpeg") ||
+          EqualIgnoringASCIICase(mime_type, "image/png") ||
+          EqualIgnoringASCIICase(mime_type, "image/svg+xml") ||
+          EqualIgnoringASCIICase(mime_type, "image/webp"));
 }
 
 bool MIMETypeRegistry::IsSupportedJavaScriptMIMEType(const String& mime_type) {
@@ -184,7 +189,7 @@
 }
 
 bool MIMETypeRegistry::IsSupportedStyleSheetMIMEType(const String& mime_type) {
-  return DeprecatedEqualIgnoringCase(mime_type, "text/css");
+  return EqualIgnoringASCIICase(mime_type, "text/css");
 }
 
 bool MIMETypeRegistry::IsSupportedFontMIMEType(const String& mime_type) {
@@ -197,7 +202,7 @@
 }
 
 bool MIMETypeRegistry::IsSupportedTextTrackMIMEType(const String& mime_type) {
-  return DeprecatedEqualIgnoringCase(mime_type, "text/vtt");
+  return EqualIgnoringASCIICase(mime_type, "text/vtt");
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/network/mime/mime_type_registry.h b/third_party/blink/renderer/platform/network/mime/mime_type_registry.h
index c487cec..94629bc 100644
--- a/third_party/blink/renderer/platform/network/mime/mime_type_registry.h
+++ b/third_party/blink/renderer/platform/network/mime/mime_type_registry.h
@@ -64,6 +64,10 @@
   // Checks to see if a mime type is suitable for being encoded.
   static bool IsSupportedImageMIMETypeForEncoding(const String& mime_type);
 
+  // Checks to see if a mime type is one of the default modern formats supported
+  // when the 'legacy-image-formats' feature is disabled.
+  static bool IsModernImageMIMEType(const String& mime_type);
+
   // Checks to see if a mime type is suitable for being loaded as a JavaScript
   // resource.
   static bool IsSupportedJavaScriptMIMEType(const String& mime_type);
diff --git a/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.cc b/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.cc
index 46883b04c..73ef02a5 100644
--- a/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.cc
+++ b/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.cc
@@ -313,22 +313,34 @@
       break;
     case TaskQueue::kHighestPriority:
       low_priority_starvation_score_ +=
-          kSmallScoreIncrementForLowPriorityStarvation;
+          HasTasksWithPriority(TaskQueue::kLowPriority)
+              ? kSmallScoreIncrementForLowPriorityStarvation
+              : 0;
       normal_priority_starvation_score_ +=
-          kSmallScoreIncrementForNormalPriorityStarvation;
+          HasTasksWithPriority(TaskQueue::kNormalPriority)
+              ? kSmallScoreIncrementForNormalPriorityStarvation
+              : 0;
       high_priority_starvation_score_ +=
-          kSmallScoreIncrementForHighPriorityStarvation;
+          HasTasksWithPriority(TaskQueue::kHighPriority)
+              ? kSmallScoreIncrementForHighPriorityStarvation
+              : 0;
       break;
     case TaskQueue::kHighPriority:
       low_priority_starvation_score_ +=
-          kLargeScoreIncrementForLowPriorityStarvation;
+          HasTasksWithPriority(TaskQueue::kLowPriority)
+              ? kLargeScoreIncrementForLowPriorityStarvation
+              : 0;
       normal_priority_starvation_score_ +=
-          kLargeScoreIncrementForNormalPriorityStarvation;
+          HasTasksWithPriority(TaskQueue::kNormalPriority)
+              ? kLargeScoreIncrementForNormalPriorityStarvation
+              : 0;
       high_priority_starvation_score_ = 0;
       break;
     case TaskQueue::kNormalPriority:
       low_priority_starvation_score_ +=
-          kLargeScoreIncrementForLowPriorityStarvation;
+          HasTasksWithPriority(TaskQueue::kLowPriority)
+              ? kLargeScoreIncrementForLowPriorityStarvation
+              : 0;
       normal_priority_starvation_score_ = 0;
       break;
     case TaskQueue::kLowPriority:
@@ -383,6 +395,14 @@
   immediate_starvation_count_ = immediate_starvation_count;
 }
 
+bool TaskQueueSelector::HasTasksWithPriority(
+    TaskQueue::QueuePriority priority) {
+  return !prioritizing_selector_.delayed_work_queue_sets()->IsSetEmpty(
+             priority) ||
+         !prioritizing_selector_.immediate_work_queue_sets()->IsSetEmpty(
+             priority);
+}
+
 }  // namespace internal
 }  // namespace scheduler
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h b/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h
index 8f39be1..4c5bcfeb 100644
--- a/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h
+++ b/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h
@@ -147,18 +147,6 @@
     return &prioritizing_selector_;
   }
 
- private:
-  // Returns the priority which is next after |priority|.
-  static TaskQueue::QueuePriority NextPriority(
-      TaskQueue::QueuePriority priority);
-
-  bool SelectWorkQueueToServiceInternal(WorkQueue** out_work_queue);
-
-  // Called whenever the selector chooses a task queue for execution with the
-  // priority |priority|.
-  void DidSelectQueueWithPriority(TaskQueue::QueuePriority priority,
-                                  bool chose_delayed_over_immediate);
-
   // Maximum score to accumulate before high priority tasks are run even in
   // the presence of highest priority tasks.
   static const size_t kMaxHighPriorityStarvationScore = 3;
@@ -206,6 +194,20 @@
   static const size_t kMaxDelayedStarvationTasks = 3;
 
  private:
+  // Returns the priority which is next after |priority|.
+  static TaskQueue::QueuePriority NextPriority(
+      TaskQueue::QueuePriority priority);
+
+  bool SelectWorkQueueToServiceInternal(WorkQueue** out_work_queue);
+
+  // Called whenever the selector chooses a task queue for execution with the
+  // priority |priority|.
+  void DidSelectQueueWithPriority(TaskQueue::QueuePriority priority,
+                                  bool chose_delayed_over_immediate);
+
+  // Returns true if there are pending tasks with priority |priority|.
+  bool HasTasksWithPriority(TaskQueue::QueuePriority priority);
+
   base::ThreadChecker main_thread_checker_;
 
   PrioritizingSelector prioritizing_selector_;
diff --git a/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_unittest.cc b/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_unittest.cc
index bd00d68..2984c39 100644
--- a/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_unittest.cc
@@ -44,6 +44,46 @@
   using TaskQueueSelector::prioritizing_selector_for_test;
   using TaskQueueSelector::PrioritizingSelector;
   using TaskQueueSelector::SetImmediateStarvationCountForTest;
+
+  // Returns the number of highest priority tasks needed to starve high priority
+  // task.
+  static constexpr size_t NumberOfHighestPriorityToStarveHighPriority() {
+    return (kMaxHighPriorityStarvationScore +
+            kSmallScoreIncrementForHighPriorityStarvation - 1) /
+           kSmallScoreIncrementForHighPriorityStarvation;
+  }
+
+  // Returns the number of highest priority tasks needed to starve normal
+  // priority tasks.
+  static constexpr size_t NumberOfHighestPriorityToStarveNormalPriority() {
+    return (kMaxNormalPriorityStarvationScore +
+            kSmallScoreIncrementForNormalPriorityStarvation - 1) /
+           kSmallScoreIncrementForNormalPriorityStarvation;
+  }
+
+  // Returns the number of high priority tasks needed to starve normal priority
+  // tasks.
+  static constexpr size_t NumberOfHighPriorityToStarveNormalPriority() {
+    return (kMaxNormalPriorityStarvationScore +
+            kLargeScoreIncrementForNormalPriorityStarvation - 1) /
+           kLargeScoreIncrementForNormalPriorityStarvation;
+  }
+
+  // Returns the number of highest priority tasks needed to starve low priority
+  // ones.
+  static constexpr size_t NumberOfHighestPriorityToStarveLowPriority() {
+    return (kMaxLowPriorityStarvationScore +
+            kSmallScoreIncrementForLowPriorityStarvation - 1) /
+           kSmallScoreIncrementForLowPriorityStarvation;
+  }
+
+  // Returns the number of high/normal priority tasks needed to starve low
+  // priority ones.
+  static constexpr size_t NumberOfHighAndNormalPriorityToStarveLowPriority() {
+    return (kMaxLowPriorityStarvationScore +
+            kLargeScoreIncrementForLowPriorityStarvation - 1) /
+           kLargeScoreIncrementForLowPriorityStarvation;
+  }
 };
 
 class TaskQueueSelectorTest : public testing::Test {
@@ -530,6 +570,133 @@
   }
 }
 
+TEST_F(TaskQueueSelectorTest,
+       TestHighPriorityStarvationScoreIncreasedOnlyWhenTasksArePresent) {
+  size_t queue_order[] = {0, 1};
+  PushTasks(queue_order, 2);
+  selector_.SetQueuePriority(task_queues_[0].get(),
+                             TaskQueue::kHighestPriority);
+  selector_.SetQueuePriority(task_queues_[1].get(),
+                             TaskQueue::kHighestPriority);
+
+  // Run a number of highest priority tasks needed to starve high priority
+  // tasks (when present).
+  for (size_t num_tasks = 0;
+       num_tasks <=
+       TaskQueueSelectorForTest::NumberOfHighestPriorityToStarveHighPriority();
+       num_tasks++) {
+    WorkQueue* chosen_work_queue = nullptr;
+    ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
+    // Don't remove task from queue to simulate the queue is still full.
+  }
+
+  // Post a high priority task.
+  selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::kHighPriority);
+  WorkQueue* chosen_work_queue = nullptr;
+  ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
+
+  // Check that the high priority task is not considered starved, and thus isn't
+  // processed.
+  EXPECT_NE(
+      static_cast<int>(
+          queue_to_index_map_.find(chosen_work_queue->task_queue())->second),
+      1);
+}
+
+TEST_F(TaskQueueSelectorTest,
+       TestNormalPriorityStarvationScoreIncreasedOnllWhenTasksArePresent) {
+  size_t queue_order[] = {0, 1};
+  PushTasks(queue_order, 2);
+  selector_.SetQueuePriority(task_queues_[0].get(),
+                             TaskQueue::kHighestPriority);
+  selector_.SetQueuePriority(task_queues_[1].get(),
+                             TaskQueue::kHighestPriority);
+
+  // Run a number of highest priority tasks needed to starve normal priority
+  // tasks (when present).
+  for (size_t num_tasks = 0;
+       num_tasks <= TaskQueueSelectorForTest::
+                        NumberOfHighestPriorityToStarveNormalPriority();
+       num_tasks++) {
+    WorkQueue* chosen_work_queue = nullptr;
+    ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
+    // Don't remove task from queue to simulate the queue is still full.
+  }
+
+  selector_.SetQueuePriority(task_queues_[0].get(), TaskQueue::kHighPriority);
+  selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::kHighPriority);
+
+  // Run a number of high priority tasks needed to starve normal priority
+  // tasks (when present).
+  for (size_t num_tasks = 0;
+       num_tasks <=
+       TaskQueueSelectorForTest::NumberOfHighPriorityToStarveNormalPriority();
+       num_tasks++) {
+    WorkQueue* chosen_work_queue = nullptr;
+    ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
+    // Don't remove task from queue to simulate the queue is still full.
+  }
+
+  // Post a normal priority task.
+  selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::kNormalPriority);
+  WorkQueue* chosen_work_queue = nullptr;
+  ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
+
+  // Check that the normal priority task is not considered starved, and thus
+  // isn't processed.
+  EXPECT_NE(
+      static_cast<int>(
+          queue_to_index_map_.find(chosen_work_queue->task_queue())->second),
+      1);
+}
+
+TEST_F(TaskQueueSelectorTest,
+       TestLowPriorityTaskStarvationOnlyIncreasedWhenTasksArePresent) {
+  size_t queue_order[] = {0, 1};
+  PushTasks(queue_order, 2);
+  selector_.SetQueuePriority(task_queues_[0].get(),
+                             TaskQueue::kHighestPriority);
+  selector_.SetQueuePriority(task_queues_[1].get(),
+                             TaskQueue::kHighestPriority);
+
+  // Run a number of highest priority tasks needed to starve low priority
+  // tasks (when present).
+  for (size_t num_tasks = 0;
+       num_tasks <=
+       TaskQueueSelectorForTest::NumberOfHighestPriorityToStarveLowPriority();
+       num_tasks++) {
+    WorkQueue* chosen_work_queue = nullptr;
+    ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
+    // Don't remove task from queue to simulate the queue is still full.
+  }
+
+  selector_.SetQueuePriority(task_queues_[0].get(), TaskQueue::kHighPriority);
+  selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::kNormalPriority);
+
+  // Run a number of high/normal priority tasks needed to starve low priority
+  // tasks (when present).
+  for (size_t num_tasks = 0;
+       num_tasks <= TaskQueueSelectorForTest::
+                        NumberOfHighAndNormalPriorityToStarveLowPriority();
+       num_tasks++) {
+    WorkQueue* chosen_work_queue = nullptr;
+    ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
+    // Don't remove task from queue to simulate the queue is still full.
+  }
+
+  // Post a low  priority task.
+  selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::kLowPriority);
+  WorkQueue* chosen_work_queue = nullptr;
+  ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue));
+
+  // Check that the low priority task is not considered starved, and thus
+  // isn't processed.
+  EXPECT_NE(
+      static_cast<int>(
+          queue_to_index_map_.find(chosen_work_queue->task_queue())->second),
+      1);
+}
+
 TEST_F(TaskQueueSelectorTest, AllEnabledWorkQueuesAreEmpty) {
   EXPECT_TRUE(selector_.AllEnabledWorkQueuesAreEmpty());
   size_t queue_order[] = {0, 1};
diff --git a/third_party/openh264/README.chromium b/third_party/openh264/README.chromium
index 19afb5f..406d3db 100644
--- a/third_party/openh264/README.chromium
+++ b/third_party/openh264/README.chromium
@@ -2,7 +2,7 @@
 Short Name: openh264
 URL: http://www.openh264.org/
 Version: unknown
-(Cut at 2e96d62426547ac4fb5cbcd122e5f6eb68d66ee6, which is between 1.7.0 and
+(Cut at 3b51f16a4a41df729f8d647f03e48c5f272911ff, which is between 1.7.0 and
 1.8.0)
 License: 2-Clause BSD
 License File: src/LICENSE
diff --git a/tools/code_coverage/coverage.py b/tools/code_coverage/coverage.py
index 68878302..00df624 100755
--- a/tools/code_coverage/coverage.py
+++ b/tools/code_coverage/coverage.py
@@ -68,6 +68,7 @@
 import os
 import re
 import shlex
+import shutil
 import subprocess
 import urllib2
 
@@ -487,6 +488,16 @@
     subprocess_cmd.append('-ignore-filename-regex=%s' % ignore_filename_regex)
 
   subprocess.check_call(subprocess_cmd)
+
+  # llvm-cov creates "coverage" subdir in the output dir. We would like to use
+  # the platform name instead, as it simplifies the report dir structure when
+  # the same report is generated for different platforms.
+  default_report_subdir_path = os.path.join(OUTPUT_DIR, 'coverage')
+  platform_report_subdir_path = os.path.join(OUTPUT_DIR, _GetHostPlatform())
+  if os.path.exists(platform_report_subdir_path):
+    shutil.rmtree(platform_report_subdir_path)
+  os.rename(default_report_subdir_path, platform_report_subdir_path)
+
   logging.debug('Finished running "llvm-cov show" command')
 
 
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 8bde388..525f4e2 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -1718,7 +1718,7 @@
     },
 
     'cast_audio': {
-      'gn_args': 'is_cast_audio_only=true enable_webrtc=false'
+      'gn_args': 'is_cast_audio_only=true'
     },
 
     'cfi': {
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index d714adb..08905b0 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -19264,6 +19264,10 @@
 </action>
 
 <action name="TouchscreenScroll">
+  <obsolete>
+    Not needed as of 05/2018 since performance metrics for ScrollBegin show the
+    frequency of GSBs.
+  </obsolete>
   <owner>tdresser@chromium.org</owner>
   <description>
     Logged at the beginning of touchscreen based scrolling. In M56 and earlier,
@@ -19298,6 +19302,10 @@
 </action>
 
 <action name="TrackpadScroll">
+  <obsolete>
+    Not needed as of 05/2018 since performance metrics for ScrollBegin show the
+    frequency of GSBs.
+  </obsolete>
   <owner>tdresser@chromium.org</owner>
   <description>
     Logged on trackpad scroll events. Logging was removed in M57, because it
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 5ca54276..4127b44 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -27592,6 +27592,7 @@
   <int value="834033186" label="enable-data-reduction-proxy-dev"/>
   <int value="834326277" label="enable-answers-in-suggest"/>
   <int value="835018878" label="disable-quic"/>
+  <int value="836406476" label="EnableTouchableAppContextMenu:enabled"/>
   <int value="838887742" label="manual-enhanced-bookmarks"/>
   <int value="841276069" label="ChromeHomeDoodle:disabled"/>
   <int value="841343322" label="disable-new-korean-ime"/>
@@ -27819,6 +27820,7 @@
   <int value="1320201920" label="enable-touchpad-three-finger-click"/>
   <int value="1330264457" label="OmniboxUIExperimentVerticalLayout:disabled"/>
   <int value="1333847867" label="NoScriptPreviews:enabled"/>
+  <int value="1338864675" label="EnableTouchableAppContextMenu:disabled"/>
   <int value="1339426771" label="TopSitesFromSiteEngagement:disabled"/>
   <int value="1340690624" label="WebPaymentsMethodSectionOrderV2:disabled"/>
   <int value="1344833841" label="ImeThread:enabled"/>
@@ -41400,6 +41402,7 @@
   <int value="0" label="Loaded"/>
   <int value="1" label="Revoked by Dice migration"/>
   <int value="2" label="Revoked as secondary account"/>
+  <int value="3" label="Revoked on load due to cookie settings"/>
 </enum>
 
 <enum name="SigninReason">
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index 4ff07aa..66317dd 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -251,6 +251,7 @@
 crbug.com/673775 [ Win ] system_health.common_desktop/browse:search:google [ Skip ]
 crbug.com/773393 [ Win ] system_health.common_desktop/browse:media:tumblr [ Skip ]
 crbug.com/799106 [ Win ] system_health.common_desktop/browse:media:flickr_infinite_scroll [ Skip ]
+crbug.com/839411 [ Win ] system_health.common_desktop/browse:social:twitter_infinite_scroll [ Skip ]
 
 # Benchmark: system_health.common_mobile
 [ Android_Webview ] system_health.common_mobile/browse:chrome:omnibox [ Skip ]
@@ -362,6 +363,7 @@
 crbug.com/798465 [ Win ] v8.browsing_desktop-future/browse:news:flipboard [ Skip ]
 crbug.com/676336 [ Win ] v8.browsing_desktop-future/browse:media:flickr_infinite_scroll [ Skip ]
 crbug.com/805934 [ Mac_10.12 ] v8.browsing_desktop-future/browse:tech:discourse_infinite_scroll [ Skip ]
+crbug.com/839470 [ Win ] v8.browsing_desktop-future/browse:social:twitter_infinite_scroll [ Skip ]
 
 # Benchmark: v8.browsing_mobile
 crbug.com/714650 [ Android ] v8.browsing_mobile/browse:news:globo [ Skip ]
diff --git a/ui/gfx/color_space.cc b/ui/gfx/color_space.cc
index d178427a..3500c40 100644
--- a/ui/gfx/color_space.cc
+++ b/ui/gfx/color_space.cc
@@ -938,7 +938,7 @@
   }
 }
 
-bool ColorSpace::ToSkYUVColorSpace(SkYUVColorSpace* out) {
+bool ColorSpace::ToSkYUVColorSpace(SkYUVColorSpace* out) const {
   if (range_ == RangeID::FULL) {
     *out = kJPEG_SkYUVColorSpace;
     return true;
diff --git a/ui/gfx/color_space.h b/ui/gfx/color_space.h
index 4186aee..dab49f5 100644
--- a/ui/gfx/color_space.h
+++ b/ui/gfx/color_space.h
@@ -200,7 +200,7 @@
 
   // For YUV color spaces, return the closest SkYUVColorSpace.
   // Returns true if a close match is found.
-  bool ToSkYUVColorSpace(SkYUVColorSpace* out);
+  bool ToSkYUVColorSpace(SkYUVColorSpace* out) const;
 
   void GetPrimaryMatrix(SkMatrix44* to_XYZD50) const;
   bool GetTransferFunction(SkColorSpaceTransferFn* fn) const;
diff --git a/ui/gl/gl_switches_util.cc b/ui/gl/gl_switches_util.cc
index df9e4f9a..cdf0932 100644
--- a/ui/gl/gl_switches_util.cc
+++ b/ui/gl/gl_switches_util.cc
@@ -13,7 +13,7 @@
 
 bool IsPresentationCallbackEnabled() {
 // TODO(peng): always enable once 776877 is fixed.
-#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
+#if defined(OS_CHROMEOS) || defined(OS_ANDROID) || defined(OS_LINUX)
   return true;
 #else
   return base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
index c1ba2578..3c13425 100644
--- a/ui/views/controls/menu/menu_controller.cc
+++ b/ui/views/controls/menu/menu_controller.cc
@@ -165,7 +165,7 @@
   return NULL;
 }
 
-#if defined(OS_WIN) || defined(OS_CHROMEOS)
+#if defined(OS_WIN)
 // Determines the correct coordinates and window to repost |event| to, if it is
 // a mouse or touch event.
 static void RepostEventImpl(const ui::LocatedEvent* event,
@@ -252,7 +252,7 @@
     PostMessage(target_window, event_type, target, window_coords);
     return;
   }
-#endif
+#endif  // defined(OS_WIN)
 
 #if defined(USE_AURA)
   if (!window)
@@ -276,7 +276,7 @@
   root->GetHost()->dispatcher()->RepostEvent(located_event.get());
 #endif  // defined(USE_AURA)
 }
-#endif  // defined(OS_WIN) || defined(OS_CHROMEOS)
+#endif  // defined(OS_WIN)
 
 }  // namespace
 
@@ -2477,14 +2477,6 @@
       exit_type = EXIT_OUTERMOST;
   }
   Cancel(exit_type);
-
-#if defined(OS_CHROMEOS)
-  // We're going to exit the menu and want to repost the event so that is
-  // is handled normally after the context menu has exited. We call
-  // RepostEvent after Cancel so that event capture has been released so
-  // that finding the event target is unaffected by the current capture.
-  RepostEventImpl(event, screen_loc, native_view, window);
-#endif
 }
 
 void MenuController::SetDropMenuItem(