diff --git a/DEPS b/DEPS
index 13dcd7d6..5fee2e3 100644
--- a/DEPS
+++ b/DEPS
@@ -78,11 +78,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': 'da6d0720300a29a4deb5dd4c433a92a3ec41286e',
+  'skia_revision': 'f4f3f0fb29d493108cbf0f3d1d648ea8bf7e2011',
   # 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': '73cec2c89096b4cf728b99f41bcc1d846d2e1496',
+  'v8_revision': '59d313a72fe632d6892139a5cec1dbf593b723d0',
   # 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.
@@ -90,7 +90,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '8b5e8fdb3c353d46c81243b31889856181ff66ae',
+  'angle_revision': '47c8ea3fb265682b6dd040bf04488747f0292da1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -102,7 +102,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': 'cbd4410908e2a4898fdd5e0d6d17591fc2c71f54',
+  'pdfium_revision': '45da0f2d84c97a9856492265a1fc706d04bdfccd',
   # 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.
@@ -134,7 +134,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': '19e11600d3a9410651e6c12e801a03eeca7274cc',
+  'catapult_revision': '2de84c0d21c28eeb042dc4d6a1a88553f6d286da',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -197,7 +197,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '7e090434dde5009a693101a63864ab47b895e87f',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'e6f6b5f6a28df8c2212441978394f77725e4e9c3',
       'condition': 'checkout_ios',
   },
 
@@ -327,7 +327,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'ebe839b6bfc3e9276b8d1e42a0d6e830bb04899e',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'edac7184bc0b8d75725d224c4f8d8c302ff9e9e3',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -640,7 +640,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd458ada06171a85af00367251a4ed55db7fe2018',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '35d2b7e9de9ddb40cac35a21d50977dc5ca231d8', # commit position 20628
+    Var('webrtc_git') + '/src.git' + '@' + '8e126fca476a2264e65f3c311795fe1748d32a0f', # commit position 20628
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1318,7 +1318,7 @@
     'action': [
       'vpython',
       'src/build/fuchsia/update_sdk.py',
-      '0ea54bf34d90fadbb160baea697de60d7ada7b09',
+      '16f4a04b24e5affe5e3e4a43016f667894a54e63',
     ],
   },
 
diff --git a/android_webview/browser/aw_quota_manager_bridge.cc b/android_webview/browser/aw_quota_manager_bridge.cc
index b73e3f6..b10a864 100644
--- a/android_webview/browser/aw_quota_manager_bridge.cc
+++ b/android_webview/browser/aw_quota_manager_bridge.cc
@@ -16,8 +16,7 @@
 #include "content/public/common/content_client.h"
 #include "jni/AwQuotaManagerBridge_jni.h"
 #include "storage/browser/quota/quota_manager.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 using base::android::AttachCurrentThread;
@@ -48,10 +47,10 @@
   ~GetOriginsTask();
 
   void OnOriginsObtained(const std::set<GURL>& origins,
-                         blink::StorageType type);
+                         blink::mojom::StorageType type);
 
   void OnUsageAndQuotaObtained(const GURL& origin,
-                               blink::QuotaStatusCode status_code,
+                               blink::mojom::QuotaStatusCode status_code,
                                int64_t usage,
                                int64_t quota);
 
@@ -85,13 +84,13 @@
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
       base::Bind(&QuotaManager::GetOriginsModifiedSince, quota_manager_,
-                 blink::StorageType::kTemporary,
+                 blink::mojom::StorageType::kTemporary,
                  base::Time() /* Since beginning of time. */,
                  base::Bind(&GetOriginsTask::OnOriginsObtained, this)));
 }
 
 void GetOriginsTask::OnOriginsObtained(const std::set<GURL>& origins,
-                                       blink::StorageType type) {
+                                       blink::mojom::StorageType type) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   num_callbacks_to_wait_ = origins.size();
   num_callbacks_received_ = 0u;
@@ -106,12 +105,13 @@
   CheckDone();
 }
 
-void GetOriginsTask::OnUsageAndQuotaObtained(const GURL& origin,
-                                             blink::QuotaStatusCode status_code,
-                                             int64_t usage,
-                                             int64_t quota) {
+void GetOriginsTask::OnUsageAndQuotaObtained(
+    const GURL& origin,
+    blink::mojom::QuotaStatusCode status_code,
+    int64_t usage,
+    int64_t quota) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (status_code == blink::QuotaStatusCode::kOk) {
+  if (status_code == blink::mojom::QuotaStatusCode::kOk) {
     origin_.push_back(origin.spec());
     usage_.push_back(usage);
     quota_.push_back(quota);
@@ -274,11 +274,11 @@
 
 void OnUsageAndQuotaObtained(
     const AwQuotaManagerBridge::QuotaUsageCallback& ui_callback,
-    blink::QuotaStatusCode status_code,
+    blink::mojom::QuotaStatusCode status_code,
     int64_t usage,
     int64_t quota) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (status_code != blink::QuotaStatusCode::kOk) {
+  if (status_code != blink::mojom::QuotaStatusCode::kOk) {
     usage = 0;
     quota = 0;
   }
@@ -313,7 +313,7 @@
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
       base::Bind(&QuotaManager::GetUsageAndQuota, GetQuotaManager(),
-                 GURL(origin), blink::StorageType::kTemporary,
+                 GURL(origin), blink::mojom::StorageType::kTemporary,
                  base::Bind(&OnUsageAndQuotaObtained, ui_callback)));
 }
 
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 513d365..b2ebfbb 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -1387,6 +1387,7 @@
     "login/mock_login_screen_client.h",
     "login/ui/lock_contents_view_unittest.cc",
     "login/ui/lock_screen_sanity_unittest.cc",
+    "login/ui/lock_window_unittest.cc",
     "login/ui/login_auth_user_view_unittest.cc",
     "login/ui/login_bubble_unittest.cc",
     "login/ui/login_password_view_test.cc",
diff --git a/ash/app_list/model/BUILD.gn b/ash/app_list/model/BUILD.gn
index 7701cb6..d0e60852 100644
--- a/ash/app_list/model/BUILD.gn
+++ b/ash/app_list/model/BUILD.gn
@@ -56,6 +56,7 @@
   defines = [ "APP_LIST_MODEL_IMPLEMENTATION" ]
 
   deps = [
+    ":speech_ui_model",
     "//base:i18n",
     "//ui/base",
     "//ui/gfx",
diff --git a/ash/app_list/model/search/search_box_model.cc b/ash/app_list/model/search/search_box_model.cc
index 42ddcb0b..b683ebd 100644
--- a/ash/app_list/model/search/search_box_model.cc
+++ b/ash/app_list/model/search/search_box_model.cc
@@ -12,6 +12,18 @@
 
 namespace app_list {
 
+namespace {
+
+std::unique_ptr<SearchBoxModel::SpeechButtonProperty> CreateNewProperty(
+    SpeechRecognitionState state) {
+  // Currently no speech support in app list.
+  // TODO(xiaohuic): when implementing speech support in new app list, we should
+  // either reuse this and related logic or delete them.
+  return nullptr;
+}
+
+}  // namespace
+
 SearchBoxModel::SpeechButtonProperty::SpeechButtonProperty(
     const gfx::ImageSkia& icon,
     const base::string16& tooltip,
@@ -24,9 +36,8 @@
 
 SearchBoxModel::~SearchBoxModel() = default;
 
-void SearchBoxModel::SetSpeechRecognitionButton(
-    std::unique_ptr<SearchBoxModel::SpeechButtonProperty> speech_button) {
-  speech_button_ = std::move(speech_button);
+void SearchBoxModel::SetSpeechRecognitionButton(SpeechRecognitionState state) {
+  speech_button_ = CreateNewProperty(state);
   for (auto& observer : observers_)
     observer.SpeechRecognitionButtonPropChanged();
 }
diff --git a/ash/app_list/model/search/search_box_model.h b/ash/app_list/model/search/search_box_model.h
index 74b50cf..cdfc817 100644
--- a/ash/app_list/model/search/search_box_model.h
+++ b/ash/app_list/model/search/search_box_model.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "ash/app_list/model/app_list_model_export.h"
+#include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/macros.h"
 #include "base/observer_list.h"
 #include "base/strings/string16.h"
@@ -18,7 +19,7 @@
 
 class SearchBoxModelObserver;
 
-// SearchBoxModel consisits of an icon, a hint text, a user text and a selection
+// SearchBoxModel consists of an icon, a hint text, a user text and a selection
 // model. The icon is rendered to the side of the query editor. The hint text
 // is used as query edit control's placeholder text and displayed when there is
 // no user text in the control. The selection model and the text represents the
@@ -43,8 +44,7 @@
   ~SearchBoxModel();
 
   // Sets/gets the properties for the button of speech recognition.
-  void SetSpeechRecognitionButton(
-      std::unique_ptr<SpeechButtonProperty> speech_button);
+  void SetSpeechRecognitionButton(SpeechRecognitionState state);
   const SpeechButtonProperty* speech_button() const {
     return speech_button_.get();
   }
diff --git a/ash/app_list/model/speech/speech_ui_model.cc b/ash/app_list/model/speech/speech_ui_model.cc
index 05f44eb7..2c557e2 100644
--- a/ash/app_list/model/speech/speech_ui_model.cc
+++ b/ash/app_list/model/speech/speech_ui_model.cc
@@ -9,6 +9,8 @@
 #include <algorithm>
 #include <limits>
 
+#include "ash/app_list/model/speech/speech_ui_model_observer.h"
+
 namespace app_list {
 
 namespace {
diff --git a/ash/app_list/model/speech/speech_ui_model.h b/ash/app_list/model/speech/speech_ui_model.h
index 71b14ab8..2e2fa14db 100644
--- a/ash/app_list/model/speech/speech_ui_model.h
+++ b/ash/app_list/model/speech/speech_ui_model.h
@@ -8,7 +8,6 @@
 #include <stdint.h>
 
 #include "ash/app_list/model/app_list_model_export.h"
-#include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/macros.h"
 #include "base/observer_list.h"
 #include "base/strings/string16.h"
@@ -16,6 +15,17 @@
 
 namespace app_list {
 
+class SpeechUIModelObserver;
+
+enum SpeechRecognitionState {
+  SPEECH_RECOGNITION_OFF = 0,
+  SPEECH_RECOGNITION_READY,
+  SPEECH_RECOGNITION_RECOGNIZING,
+  SPEECH_RECOGNITION_IN_SPEECH,
+  SPEECH_RECOGNITION_STOPPING,
+  SPEECH_RECOGNITION_NETWORK_ERROR,
+};
+
 // SpeechUIModel provides the interface to update the UI for speech recognition.
 class APP_LIST_MODEL_EXPORT SpeechUIModel {
  public:
diff --git a/ash/app_list/model/speech/speech_ui_model_observer.h b/ash/app_list/model/speech/speech_ui_model_observer.h
index 1ec96b5..c688338 100644
--- a/ash/app_list/model/speech/speech_ui_model_observer.h
+++ b/ash/app_list/model/speech/speech_ui_model_observer.h
@@ -8,19 +8,11 @@
 #include <stdint.h>
 
 #include "ash/app_list/model/app_list_model_export.h"
+#include "ash/app_list/model/speech/speech_ui_model.h"
 #include "base/strings/string16.h"
 
 namespace app_list {
 
-enum SpeechRecognitionState {
-  SPEECH_RECOGNITION_OFF = 0,
-  SPEECH_RECOGNITION_READY,
-  SPEECH_RECOGNITION_RECOGNIZING,
-  SPEECH_RECOGNITION_IN_SPEECH,
-  SPEECH_RECOGNITION_STOPPING,
-  SPEECH_RECOGNITION_NETWORK_ERROR,
-};
-
 class APP_LIST_MODEL_EXPORT SpeechUIModelObserver {
  public:
   // Invoked when sound level for the speech recognition has changed. |level|
diff --git a/ash/lock_screen_action/lock_screen_action_background_controller.cc b/ash/lock_screen_action/lock_screen_action_background_controller.cc
index e9b8712..9c0a8197 100644
--- a/ash/lock_screen_action/lock_screen_action_background_controller.cc
+++ b/ash/lock_screen_action/lock_screen_action_background_controller.cc
@@ -27,7 +27,7 @@
   // Web UI based lock screen implements its own background - use the stub
   // lock action background controller implementation unless md-based lock UI
   // is used.
-  if (switches::IsUsingWebUiLock())
+  if (!switches::IsUsingViewsLock())
     return std::make_unique<LockScreenActionBackgroundControllerStub>();
   return std::make_unique<LockScreenActionBackgroundControllerImpl>();
 }
diff --git a/ash/login/ui/lock_debug_view.h b/ash/login/ui/lock_debug_view.h
index 3e1bb40..b27b9c333 100644
--- a/ash/login/ui/lock_debug_view.h
+++ b/ash/login/ui/lock_debug_view.h
@@ -38,6 +38,8 @@
   // views::ButtonListener:
   void ButtonPressed(views::Button* sender, const ui::Event& event) override;
 
+  LockContentsView* lock() { return lock_; }
+
  private:
   class DebugDataDispatcherTransformer;
 
diff --git a/ash/login/ui/lock_screen.cc b/ash/login/ui/lock_screen.cc
index 92a9f3e..08dc08d7 100644
--- a/ash/login/ui/lock_screen.cc
+++ b/ash/login/ui/lock_screen.cc
@@ -27,15 +27,6 @@
 namespace ash {
 namespace {
 
-views::View* BuildContentsView(mojom::TrayActionState initial_note_action_state,
-                               LoginDataDispatcher* data_dispatcher) {
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          chromeos::switches::kShowLoginDevOverlay)) {
-    return new LockDebugView(initial_note_action_state, data_dispatcher);
-  }
-  return new LockContentsView(initial_note_action_state, data_dispatcher);
-}
-
 ui::Layer* GetWallpaperLayerForWindow(aura::Window* window) {
   return RootWindowController::ForWindow(window)
       ->wallpaper_widget_controller()
@@ -49,6 +40,15 @@
 
 }  // namespace
 
+LockScreen::TestApi::TestApi(LockScreen* lock_screen)
+    : lock_screen_(lock_screen) {}
+
+LockScreen::TestApi::~TestApi() = default;
+
+LockContentsView* LockScreen::TestApi::contents_view() const {
+  return lock_screen_->contents_view_;
+}
+
 LockScreen::LockScreen(ScreenType type)
     : type_(type), tray_action_observer_(this), session_observer_(this) {
   tray_action_observer_.Add(ash::Shell::Get()->tray_action());
@@ -67,16 +67,27 @@
   CHECK(!instance_);
   instance_ = new LockScreen(type);
 
-  auto data_dispatcher = std::make_unique<LoginDataDispatcher>();
-  auto* contents = BuildContentsView(
-      ash::Shell::Get()->tray_action()->GetLockScreenNoteState(),
-      data_dispatcher.get());
+  instance_->window_ = new LockWindow(Shell::GetAshConfig());
+  instance_->window_->SetBounds(
+      display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
 
-  auto* window = instance_->window_ = new LockWindow(Shell::GetAshConfig());
-  window->SetBounds(display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
-  window->SetContentsView(contents);
-  window->set_data_dispatcher(std::move(data_dispatcher));
-  window->Show();
+  auto data_dispatcher = std::make_unique<LoginDataDispatcher>();
+  auto initial_note_action_state =
+      ash::Shell::Get()->tray_action()->GetLockScreenNoteState();
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          chromeos::switches::kShowLoginDevOverlay)) {
+    auto* debug_view =
+        new LockDebugView(initial_note_action_state, data_dispatcher.get());
+    instance_->contents_view_ = debug_view->lock();
+    instance_->window_->SetContentsView(debug_view);
+  } else {
+    instance_->contents_view_ =
+        new LockContentsView(initial_note_action_state, data_dispatcher.get());
+    instance_->window_->SetContentsView(instance_->contents_view_);
+  }
+
+  instance_->window_->set_data_dispatcher(std::move(data_dispatcher));
+  instance_->window_->Show();
 }
 
 // static
diff --git a/ash/login/ui/lock_screen.h b/ash/login/ui/lock_screen.h
index e0bb5a6e..15220e4b 100644
--- a/ash/login/ui/lock_screen.h
+++ b/ash/login/ui/lock_screen.h
@@ -19,6 +19,7 @@
 
 namespace ash {
 
+class LockContentsView;
 class LockWindow;
 class LoginDataDispatcher;
 class TrayAction;
@@ -26,6 +27,18 @@
 class ASH_EXPORT LockScreen : public TrayActionObserver,
                               public SessionObserver {
  public:
+  // TestApi is used for tests to get internal implementation details.
+  class ASH_EXPORT TestApi {
+   public:
+    explicit TestApi(LockScreen* lock_screen);
+    ~TestApi();
+
+    LockContentsView* contents_view() const;
+
+   private:
+    LockScreen* const lock_screen_;
+  };
+
   // The UI that this instance is displaying.
   enum class ScreenType { kLogin, kLock };
 
@@ -68,6 +81,9 @@
   // Unowned pointer to the window which hosts the lock screen.
   LockWindow* window_ = nullptr;
 
+  // Unowned pointer to the LockContentsView hosted in lock window.
+  LockContentsView* contents_view_ = nullptr;
+
   // The wallpaper bluriness before entering lock_screen.
   std::unordered_map<ui::Layer*, float> initial_blur_;
 
diff --git a/ash/login/ui/lock_window.cc b/ash/login/ui/lock_window.cc
index 6216981..d2dc278 100644
--- a/ash/login/ui/lock_window.cc
+++ b/ash/login/ui/lock_window.cc
@@ -27,8 +27,6 @@
   Init(params);
   SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE);
 
-  // TODO(agawronska): Add tests for UI visibility when virtual keyboard is
-  // present.
   // Disable virtual keyboard overscroll because it interferes with scrolling
   // login/lock content. See crbug.com/363635.
   keyboard::SetKeyboardOverscrollOverride(
diff --git a/ash/login/ui/lock_window_unittest.cc b/ash/login/ui/lock_window_unittest.cc
new file mode 100644
index 0000000..03aa027
--- /dev/null
+++ b/ash/login/ui/lock_window_unittest.cc
@@ -0,0 +1,111 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/login/ui/lock_window.h"
+
+#include "ash/login/login_screen_controller.h"
+#include "ash/login/ui/lock_contents_view.h"
+#include "ash/login/ui/lock_screen.h"
+#include "ash/login/ui/login_test_base.h"
+#include "ash/login/ui/login_test_utils.h"
+#include "ash/public/interfaces/login_user_info.mojom.h"
+#include "ash/root_window_controller.h"
+#include "ash/session/session_controller.h"
+#include "ash/session/test_session_controller_client.h"
+#include "ash/shell.h"
+#include "base/command_line.h"
+#include "base/run_loop.h"
+#include "ui/keyboard/keyboard_controller.h"
+#include "ui/keyboard/keyboard_switches.h"
+#include "ui/keyboard/keyboard_test_util.h"
+#include "ui/keyboard/keyboard_ui.h"
+#include "ui/keyboard/keyboard_util.h"
+
+namespace ash {
+
+class LockWindowVirtualKeyboardTest : public LoginTestBase {
+ public:
+  LockWindowVirtualKeyboardTest() = default;
+
+  ~LockWindowVirtualKeyboardTest() override = default;
+
+  void SetUp() override {
+    base::CommandLine::ForCurrentProcess()->AppendSwitch(
+        keyboard::switches::kEnableVirtualKeyboard);
+    AshTestBase::SetUp();
+    GetSessionControllerClient()->SetSessionState(
+        session_manager::SessionState::LOCKED);
+    login_controller_ = Shell::Get()->login_screen_controller();
+    ASSERT_NE(nullptr, login_controller_);
+  }
+
+  void TearDown() override {
+    if (ash::LockScreen::IsShown())
+      ash::LockScreen::Get()->Destroy();
+    AshTestBase::TearDown();
+  }
+
+  void ShowLockScreen() {
+    base::Optional<bool> result;
+    login_controller_->ShowLockScreen(base::BindOnce(
+        [](base::Optional<bool>* result, bool did_show) { *result = did_show; },
+        &result));
+    base::RunLoop().RunUntilIdle();
+    ASSERT_TRUE(result.has_value());
+    ASSERT_EQ(*result, true);
+  }
+
+  void LoadUser() {
+    std::vector<mojom::LoginUserInfoPtr> users;
+    users.push_back(CreateUser("user1"));
+    login_controller_->LoadUsers(std::move(users), false);
+  }
+
+  void ShowKeyboard() {
+    keyboard::KeyboardController* controller =
+        keyboard::KeyboardController::GetInstance();
+    ASSERT_NE(nullptr, controller);
+
+    Shell::GetPrimaryRootWindowController()->ActivateKeyboard(controller);
+    controller->ShowKeyboard(false);
+
+    // Set keyboard height to half of the root window - this should overlap with
+    // lock/login layout.
+    if (controller->ui()->GetContentsWindow()->bounds().height() == 0) {
+      int height = Shell::GetPrimaryRootWindow()->bounds().height() / 2;
+      controller->ui()->GetContentsWindow()->SetBounds(
+          keyboard::KeyboardBoundsFromRootBounds(
+              Shell::GetPrimaryRootWindow()->bounds(), height));
+    }
+    ASSERT_TRUE(controller->keyboard_visible());
+  }
+
+  LoginScreenController* login_controller_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(LockWindowVirtualKeyboardTest);
+};
+
+TEST_F(LockWindowVirtualKeyboardTest, VirtualKeyboardDoesNotCoverAuthView) {
+  ASSERT_NO_FATAL_FAILURE(ShowLockScreen());
+  LockContentsView* lock_contents =
+      LockScreen::TestApi(LockScreen::Get()).contents_view();
+  ASSERT_NE(nullptr, lock_contents);
+
+  LoadUser();
+  LoginAuthUserView* auth_view =
+      MakeLockContentsViewTestApi(lock_contents).primary_auth();
+  ASSERT_NE(nullptr, auth_view);
+
+  ASSERT_NO_FATAL_FAILURE(ShowKeyboard());
+  const gfx::Rect keyboard_bounds_in_screen =
+      keyboard::KeyboardController::GetInstance()
+          ->ui()
+          ->GetContentsWindow()
+          ->GetBoundsInScreen();
+  EXPECT_FALSE(
+      auth_view->GetBoundsInScreen().Intersects(keyboard_bounds_in_screen));
+}
+
+}  // namespace ash
diff --git a/ash/login/ui/login_password_view.cc b/ash/login/ui/login_password_view.cc
index e31391d..3374d67 100644
--- a/ash/login/ui/login_password_view.cc
+++ b/ash/login/ui/login_password_view.cc
@@ -451,6 +451,9 @@
     ime_keyboard_observer_.Add(keyboard);
     OnCapsLockChanged(keyboard->CapsLockIsEnabled());
   }
+
+  // Make sure the UI start with the correct states.
+  UpdateUiState();
 }
 
 LoginPasswordView::~LoginPasswordView() = default;
diff --git a/ash/login/ui/login_password_view_test.cc b/ash/login/ui/login_password_view_test.cc
index 9b4da41..0598a06 100644
--- a/ash/login/ui/login_password_view_test.cc
+++ b/ash/login/ui/login_password_view_test.cc
@@ -58,6 +58,42 @@
 
 }  // namespace
 
+// Verifies that the submit button updates its UI state.
+TEST_F(LoginPasswordViewTest, SubmitButtonUpdatesUiState) {
+  LoginPasswordView::TestApi test_api(view_);
+  ui::test::EventGenerator& generator = GetEventGenerator();
+
+  // The submit button starts with the disabled state.
+  EXPECT_TRUE(is_password_field_empty_);
+  EXPECT_FALSE(test_api.submit_button()->enabled());
+  // Enter 'a'. The submit button is enabled.
+  generator.PressKey(ui::KeyboardCode::VKEY_A, 0);
+  EXPECT_FALSE(is_password_field_empty_);
+  EXPECT_TRUE(test_api.submit_button()->enabled());
+  // Enter 'b'. The submit button stays enabled.
+  generator.PressKey(ui::KeyboardCode::VKEY_B, 0);
+  EXPECT_FALSE(is_password_field_empty_);
+  EXPECT_TRUE(test_api.submit_button()->enabled());
+
+  // Clear password. The submit button is disabled.
+  view_->Clear();
+  EXPECT_TRUE(is_password_field_empty_);
+  EXPECT_FALSE(test_api.submit_button()->enabled());
+
+  // Enter 'a'. The submit button is enabled.
+  generator.PressKey(ui::KeyboardCode::VKEY_A, 0);
+  EXPECT_FALSE(is_password_field_empty_);
+  EXPECT_TRUE(test_api.submit_button()->enabled());
+  // Set the text field to be read-only. The submit button is disabled.
+  view_->SetReadOnly(true);
+  EXPECT_FALSE(is_password_field_empty_);
+  EXPECT_FALSE(test_api.submit_button()->enabled());
+  // Set the text field to be not read-only. The submit button is enabled.
+  view_->SetReadOnly(false);
+  EXPECT_FALSE(is_password_field_empty_);
+  EXPECT_TRUE(test_api.submit_button()->enabled());
+}
+
 // Verifies that password submit works with 'Enter'.
 TEST_F(LoginPasswordViewTest, PasswordSubmitIncludesPasswordText) {
   LoginPasswordView::TestApi test_api(view_);
diff --git a/ash/login/ui/login_test_base.h b/ash/login/ui/login_test_base.h
index 6ebaade..f87070b 100644
--- a/ash/login/ui/login_test_base.h
+++ b/ash/login/ui/login_test_base.h
@@ -27,7 +27,7 @@
   ~LoginTestBase() override;
 
   // Sets the primary test widget. The widget can be retrieved using |widget()|.
-  // This can be used to make a wdiget scoped to the whole test, e.g. if the
+  // This can be used to make a widget scoped to the whole test, e.g. if the
   // widget is created in a SetUp override.
   // May be called at most once.
   void SetWidget(std::unique_ptr<views::Widget> widget);
diff --git a/ash/public/cpp/ash_switches.cc b/ash/public/cpp/ash_switches.cc
index 629eb3d6..1d53dcd 100644
--- a/ash/public/cpp/ash_switches.cc
+++ b/ash/public/cpp/ash_switches.cc
@@ -185,8 +185,8 @@
   return base::CommandLine::ForCurrentProcess()->HasSwitch(kShowViewsLogin);
 }
 
-bool IsUsingWebUiLock() {
-  return base::CommandLine::ForCurrentProcess()->HasSwitch(kShowWebUiLock);
+bool IsUsingViewsLock() {
+  return !base::CommandLine::ForCurrentProcess()->HasSwitch(kShowWebUiLock);
 }
 
 }  // namespace switches
diff --git a/ash/public/cpp/ash_switches.h b/ash/public/cpp/ash_switches.h
index f448c338..90d1550d 100644
--- a/ash/public/cpp/ash_switches.h
+++ b/ash/public/cpp/ash_switches.h
@@ -68,7 +68,7 @@
 ASH_PUBLIC_EXPORT bool IsNightLightEnabled();
 ASH_PUBLIC_EXPORT bool IsSidebarEnabled();
 ASH_PUBLIC_EXPORT bool IsUsingViewsLogin();
-ASH_PUBLIC_EXPORT bool IsUsingWebUiLock();
+ASH_PUBLIC_EXPORT bool IsUsingViewsLock();
 
 }  // namespace switches
 }  // namespace ash
diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc
index 3c72eec..524e935 100644
--- a/ash/shelf/shelf_widget.cc
+++ b/ash/shelf/shelf_widget.cc
@@ -119,7 +119,7 @@
       return true;
     case session_manager::SessionState::LOCKED:
     case session_manager::SessionState::LOGIN_SECONDARY:
-      return !switches::IsUsingWebUiLock();
+      return switches::IsUsingViewsLock();
     case session_manager::SessionState::UNKNOWN:
     case session_manager::SessionState::OOBE:
     case session_manager::SessionState::LOGIN_PRIMARY:
diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc
index 3ce49d2..ac786b1 100644
--- a/ash/shell/app_list.cc
+++ b/ash/shell/app_list.cc
@@ -244,10 +244,9 @@
     NOTIMPLEMENTED();
   }
 
-  void StartSearch() override {
+  void StartSearch(const base::string16& raw_query) override {
     base::string16 query;
-    base::TrimWhitespace(search_model_->search_box()->text(), base::TRIM_ALL,
-                         &query);
+    base::TrimWhitespace(raw_query, base::TRIM_ALL, &query);
     query = base::i18n::ToLower(query);
 
     search_model_->results()->DeleteAll();
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 0544de5..67d622c 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -50,6 +50,11 @@
 
   # Set to true to disable COM init check hooks.
   com_init_check_hook_disabled = false
+
+  # Set to true to enable mutex priority inheritance. See the comments in
+  # LockImpl::PriorityInheritanceAvailable() in lock_impl_posix.cc for the
+  # platform requirements to safely enable priority inheritance.
+  enable_mutex_priority_inheritance = false
 }
 
 if (is_android) {
@@ -1146,6 +1151,7 @@
     ":cfi_flags",
     ":debugging_flags",
     ":protected_memory_flags",
+    ":synchronization_flags",
     "//base/numerics:base_numerics",
   ]
 
@@ -1758,6 +1764,14 @@
   flags = [ "USE_LLD=$use_lld" ]
 }
 
+buildflag_header("synchronization_flags") {
+  header = "synchronization_flags.h"
+  header_dir = "base/synchronization"
+
+  flags =
+      [ "ENABLE_MUTEX_PRIORITY_INHERITANCE=$enable_mutex_priority_inheritance" ]
+}
+
 # This is the subset of files from base that should not be used with a dynamic
 # library. Note that this library cannot depend on base because base depends on
 # base_static.
@@ -2331,6 +2345,7 @@
     "win/shortcut_unittest.cc",
     "win/startup_information_unittest.cc",
     "win/wait_chain_unittest.cc",
+    "win/win_includes_unittest.cc",
     "win/win_util_unittest.cc",
     "win/windows_version_unittest.cc",
     "win/winrt_storage_util_unittest.cc",
diff --git a/base/allocator/allocator_shim_override_ucrt_symbols_win.h b/base/allocator/allocator_shim_override_ucrt_symbols_win.h
index 9fb7d067..ed02656 100644
--- a/base/allocator/allocator_shim_override_ucrt_symbols_win.h
+++ b/base/allocator/allocator_shim_override_ucrt_symbols_win.h
@@ -12,6 +12,8 @@
 
 #include <malloc.h>
 
+#include <windows.h>
+
 extern "C" {
 
 void* (*malloc_unchecked)(size_t) = &base::allocator::UncheckedAlloc;
diff --git a/base/allocator/partition_allocator/address_space_randomization.cc b/base/allocator/partition_allocator/address_space_randomization.cc
index 114ad95..dc90824b 100644
--- a/base/allocator/partition_allocator/address_space_randomization.cc
+++ b/base/allocator/partition_allocator/address_space_randomization.cc
@@ -11,6 +11,8 @@
 #include "build/build_config.h"
 
 #if defined(OS_WIN)
+#include <windows.h>  // Must be in front of other Windows header files.
+
 #include <VersionHelpers.h>
 #endif
 
diff --git a/base/allocator/partition_allocator/page_allocator.cc b/base/allocator/partition_allocator/page_allocator.cc
index 3f53e06..8fc4c6d 100644
--- a/base/allocator/partition_allocator/page_allocator.cc
+++ b/base/allocator/partition_allocator/page_allocator.cc
@@ -103,22 +103,12 @@
   DCHECK(commit || page_accessibility == PageInaccessible);
 
   void* ret;
-  // Retry failed allocations once after calling ReleaseReservation().
-  bool have_retried = false;
 #if defined(OS_WIN)
   DWORD access_flag = GetAccessFlags(page_accessibility);
   const DWORD type_flags = commit ? (MEM_RESERVE | MEM_COMMIT) : MEM_RESERVE;
-  while (true) {
-    ret = VirtualAlloc(hint, length, type_flags, access_flag);
-    if (ret)
-      break;
-    if (have_retried) {
-      s_allocPageErrorCode = GetLastError();
-      break;
-    }
-    ReleaseReservation();
-    have_retried = true;
-  }
+  ret = VirtualAlloc(hint, length, type_flags, access_flag);
+  if (ret == nullptr)
+    s_allocPageErrorCode = GetLastError();
 #else
 
 #if defined(OS_MACOSX)
@@ -129,22 +119,33 @@
   int fd = -1;
 #endif
   int access_flag = GetAccessFlags(page_accessibility);
-  while (true) {
-    ret = mmap(hint, length, access_flag, MAP_ANONYMOUS | MAP_PRIVATE, fd, 0);
-    if (ret != MAP_FAILED)
-      break;
-    if (have_retried) {
-      s_allocPageErrorCode = errno;
-      ret = nullptr;
-      break;
-    }
-    ReleaseReservation();
-    have_retried = true;
+  ret = mmap(hint, length, access_flag, MAP_ANONYMOUS | MAP_PRIVATE, fd, 0);
+  if (ret == MAP_FAILED) {
+    s_allocPageErrorCode = errno;
+    ret = nullptr;
   }
 #endif
   return ret;
 }
 
+static void* AllocPagesIncludingReserved(
+    void* address,
+    size_t length,
+    PageAccessibilityConfiguration page_accessibility,
+    bool commit) {
+  void* ret = SystemAllocPages(address, length, page_accessibility, commit);
+  if (ret == nullptr) {
+    const bool cant_alloc_length = kHintIsAdvisory || address == nullptr;
+    if (cant_alloc_length) {
+      // The system cannot allocate |length| bytes. Release any reserved address
+      // space and try once more.
+      ReleaseReservation();
+      ret = SystemAllocPages(address, length, page_accessibility, commit);
+    }
+  }
+  return ret;
+}
+
 // Trims base to given length and alignment. Windows returns null on failure and
 // frees base.
 static void* TrimMapping(void* base,
@@ -162,7 +163,9 @@
   DCHECK(post_slack < base_length);
   void* ret = base;
 
-#if defined(OS_POSIX)  // On POSIX we can resize the allocation run.
+#if defined(OS_POSIX)
+  // On POSIX we can resize the allocation run. Release unneeded memory before
+  // and after the aligned range.
   (void)page_accessibility;
   if (pre_slack) {
     int res = munmap(base, pre_slack);
@@ -173,8 +176,10 @@
     int res = munmap(reinterpret_cast<char*>(ret) + trim_length, post_slack);
     CHECK(!res);
   }
-#else  // On Windows we can't resize the allocation run.
+#else
   if (pre_slack || post_slack) {
+    // On Windows we can't resize the allocation run. Free it and retry at the
+    // aligned address within the freed range.
     ret = reinterpret_cast<char*>(base) + pre_slack;
     FreePages(base, base_length);
     ret = SystemAllocPages(ret, trim_length, page_accessibility, commit);
@@ -211,22 +216,26 @@
 
   // First try to force an exact-size, aligned allocation from our random base.
   for (int count = 0; count < 3; ++count) {
-    void* ret = SystemAllocPages(address, length, page_accessibility, commit);
-    if (kHintIsAdvisory || ret) {
+    void* ret = AllocPagesIncludingReserved(address, length, page_accessibility,
+                                            commit);
+    if (ret) {
       // If the alignment is to our liking, we're done.
       if (!(reinterpret_cast<uintptr_t>(ret) & align_offset_mask))
         return ret;
+      // Free the memory and try again.
       FreePages(ret, length);
 #if defined(ARCH_CPU_32_BITS)
+      // For small address spaces, try an aligned hint in the free range.
       address = reinterpret_cast<void*>(
           (reinterpret_cast<uintptr_t>(ret) + align) & align_base_mask);
 #endif
-    } else if (!address) {  // We know we're OOM when an unhinted allocation
-                            // fails.
-      return nullptr;
     } else {
+      // |ret| is null; we're OOM when an unhinted allocation fails.
+      if (kHintIsAdvisory || address == nullptr)
+        return nullptr;
 #if defined(ARCH_CPU_32_BITS)
-      address = reinterpret_cast<char*>(address) + align;
+      // On 32-bit systems, let the OS choose the base.
+      address = nullptr;
 #endif
     }
 
@@ -238,16 +247,16 @@
 #endif
   }
 
-  // Map a larger allocation so we can force alignment, but continue randomizing
-  // only on 64-bit POSIX.
+  // Make a larger allocation so we can force alignment.
   size_t try_length = length + (align - kPageAllocationGranularity);
   CHECK(try_length >= length);
   void* ret;
 
   do {
-    // Don't continue to burn cycles on mandatory hints (Windows).
+    // Continue randomizing only on POSIX.
     address = kHintIsAdvisory ? GetRandomPageBase() : nullptr;
-    ret = SystemAllocPages(address, try_length, page_accessibility, commit);
+    ret = AllocPagesIncludingReserved(address, try_length, page_accessibility,
+                                      commit);
     // The retries are for Windows, where a race can steal our mapping on
     // resize.
   } while (ret && (ret = TrimMapping(ret, try_length, length, align,
@@ -363,29 +372,24 @@
 }
 
 bool ReserveAddressSpace(size_t size) {
-  // Don't take |s_reserveLock| while allocating, since a failure would invoke
-  // ReleaseReservation and deadlock.
-  void* mem = AllocPages(nullptr, size, kPageAllocationGranularity,
-                         PageInaccessible, false);
-  // We guarantee this alignment when reserving address space.
-  DCHECK(!(reinterpret_cast<uintptr_t>(mem) &
-           kPageAllocationGranularityOffsetMask));
-  if (mem != nullptr) {
-    {
-      subtle::SpinLock::Guard guard(s_reserveLock.Get());
-      if (s_reservation_address == nullptr) {
-        s_reservation_address = mem;
-        s_reservation_size = size;
-        return true;
-      }
+  // To avoid deadlock, call only SystemAllocPages.
+  subtle::SpinLock::Guard guard(s_reserveLock.Get());
+  if (s_reservation_address == nullptr) {
+    void* mem = SystemAllocPages(nullptr, size, PageInaccessible, false);
+    if (mem != nullptr) {
+      // We guarantee this alignment when reserving address space.
+      DCHECK(!(reinterpret_cast<uintptr_t>(mem) &
+               kPageAllocationGranularityOffsetMask));
+      s_reservation_address = mem;
+      s_reservation_size = size;
+      return true;
     }
-    // There was already a reservation.
-    FreePages(mem, size);
   }
   return false;
 }
 
 void ReleaseReservation() {
+  // To avoid deadlock, call only FreePages.
   subtle::SpinLock::Guard guard(s_reserveLock.Get());
   if (s_reservation_address != nullptr) {
     FreePages(s_reservation_address, s_reservation_size);
diff --git a/base/android/java/src/org/chromium/base/ApplicationStatus.java b/base/android/java/src/org/chromium/base/ApplicationStatus.java
index fdaf83e..db30e7f 100644
--- a/base/android/java/src/org/chromium/base/ApplicationStatus.java
+++ b/base/android/java/src/org/chromium/base/ApplicationStatus.java
@@ -298,7 +298,9 @@
      * Asserts that initialize method has been called.
      */
     private static void assertInitialized() {
-        assert sIsInitialized;
+        if (!sIsInitialized) {
+            throw new IllegalStateException("ApplicationStatus has not been initialized yet.");
+        }
     }
 
     /**
@@ -496,7 +498,9 @@
     @SuppressLint("NewApi")
     public static void registerStateListenerForActivity(ActivityStateListener listener,
             Activity activity) {
-        assert activity != null;
+        if (activity == null) {
+            throw new IllegalStateException("Attempting to register listener on a null activity.");
+        }
         ApplicationStatus.assertInitialized();
 
         ActivityInfo info = sActivityInfo.get(activity);
@@ -508,7 +512,11 @@
             info = new ActivityInfo();
             sActivityInfo.put(activity, info);
         }
-        assert info != null && info.getStatus() != ActivityState.DESTROYED;
+        if (info == null) {
+            throw new IllegalStateException(
+                    "Attempting to register listener on an untracked activity.");
+        }
+        assert info.getStatus() != ActivityState.DESTROYED;
         info.getListeners().addObserver(listener);
     }
 
diff --git a/base/atomicops_internals_x86_msvc.h b/base/atomicops_internals_x86_msvc.h
index 9f05b7e..ee9043e 100644
--- a/base/atomicops_internals_x86_msvc.h
+++ b/base/atomicops_internals_x86_msvc.h
@@ -7,7 +7,7 @@
 #ifndef BASE_ATOMICOPS_INTERNALS_X86_MSVC_H_
 #define BASE_ATOMICOPS_INTERNALS_X86_MSVC_H_
 
-#include <windows.h>
+#include "base/win/windows_types.h"
 
 #include <intrin.h>
 
@@ -61,8 +61,10 @@
   // See #undef and note at the top of this file.
   __faststorefence();
 #else
-  // We use MemoryBarrier from WinNT.h
-  ::MemoryBarrier();
+  // We use the implementation of MemoryBarrier from WinNT.h
+  LONG barrier;
+
+  _InterlockedOr(&barrier, 0);
 #endif
 }
 
@@ -115,25 +117,25 @@
 inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
                                          Atomic64 old_value,
                                          Atomic64 new_value) {
-  PVOID result = InterlockedCompareExchangePointer(
-    reinterpret_cast<volatile PVOID*>(ptr),
-    reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value));
+  PVOID result = _InterlockedCompareExchangePointer(
+      reinterpret_cast<volatile PVOID*>(ptr),
+      reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value));
   return reinterpret_cast<Atomic64>(result);
 }
 
 inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
                                          Atomic64 new_value) {
-  PVOID result = InterlockedExchangePointer(
-    reinterpret_cast<volatile PVOID*>(ptr),
-    reinterpret_cast<PVOID>(new_value));
+  PVOID result =
+      _InterlockedExchangePointer(reinterpret_cast<volatile PVOID*>(ptr),
+                                  reinterpret_cast<PVOID>(new_value));
   return reinterpret_cast<Atomic64>(result);
 }
 
 inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
                                         Atomic64 increment) {
-  return InterlockedExchangeAdd64(
-      reinterpret_cast<volatile LONGLONG*>(ptr),
-      static_cast<LONGLONG>(increment)) + increment;
+  return _InterlockedExchangeAdd64(reinterpret_cast<volatile LONGLONG*>(ptr),
+                                   static_cast<LONGLONG>(increment)) +
+         increment;
 }
 
 inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
diff --git a/base/files/file_path_watcher_win.cc b/base/files/file_path_watcher_win.cc
index 7096c7a..46147509 100644
--- a/base/files/file_path_watcher_win.cc
+++ b/base/files/file_path_watcher_win.cc
@@ -15,6 +15,8 @@
 #include "base/time/time.h"
 #include "base/win/object_watcher.h"
 
+#include <windows.h>
+
 namespace base {
 
 namespace {
diff --git a/base/files/file_util.h b/base/files/file_util.h
index 2ebb7378..780bb22c 100644
--- a/base/files/file_util.h
+++ b/base/files/file_util.h
@@ -23,7 +23,7 @@
 #include "build/build_config.h"
 
 #if defined(OS_WIN)
-#include <windows.h>
+#include "base/win/windows_types.h"
 #elif defined(OS_POSIX)
 #include <sys/stat.h>
 #include <unistd.h>
diff --git a/base/files/file_win.cc b/base/files/file_win.cc
index 1bf51d2..a9d322f 100644
--- a/base/files/file_win.cc
+++ b/base/files/file_win.cc
@@ -11,6 +11,8 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/threading/thread_restrictions.h"
 
+#include <windows.h>
+
 namespace base {
 
 // Make sure our Whence mappings match the system headers.
diff --git a/base/files/memory_mapped_file_win.cc b/base/files/memory_mapped_file_win.cc
index 087ca9f..26869f6ac 100644
--- a/base/files/memory_mapped_file_win.cc
+++ b/base/files/memory_mapped_file_win.cc
@@ -13,6 +13,8 @@
 #include "base/strings/string16.h"
 #include "base/threading/thread_restrictions.h"
 
+#include <windows.h>
+
 namespace base {
 
 MemoryMappedFile::MemoryMappedFile() : data_(NULL), length_(0) {
diff --git a/base/files/platform_file.h b/base/files/platform_file.h
index 6b4a0c21..4b8b539b 100644
--- a/base/files/platform_file.h
+++ b/base/files/platform_file.h
@@ -9,8 +9,8 @@
 #include "build/build_config.h"
 
 #if defined(OS_WIN)
-#include <windows.h>
 #include "base/win/scoped_handle.h"
+#include "base/win/windows_types.h"
 #endif
 
 // This file defines platform-independent types for dealing with
diff --git a/base/memory/discardable_shared_memory.cc b/base/memory/discardable_shared_memory.cc
index 7aeddab..e9a2d63 100644
--- a/base/memory/discardable_shared_memory.cc
+++ b/base/memory/discardable_shared_memory.cc
@@ -28,6 +28,7 @@
 #endif
 
 #if defined(OS_WIN)
+#include <windows.h>
 #include "base/win/windows_version.h"
 #endif
 
diff --git a/base/memory/shared_memory_handle.h b/base/memory/shared_memory_handle.h
index c4e140e..22b9737 100644
--- a/base/memory/shared_memory_handle.h
+++ b/base/memory/shared_memory_handle.h
@@ -11,8 +11,8 @@
 #include "build/build_config.h"
 
 #if defined(OS_WIN)
-#include <windows.h>
 #include "base/process/process_handle.h"
+#include "base/win/windows_types.h"
 #elif defined(OS_MACOSX) && !defined(OS_IOS)
 #include <mach/mach.h>
 #include "base/base_export.h"
diff --git a/base/memory/shared_memory_handle_win.cc b/base/memory/shared_memory_handle_win.cc
index 8b72856..8c11d39 100644
--- a/base/memory/shared_memory_handle_win.cc
+++ b/base/memory/shared_memory_handle_win.cc
@@ -7,6 +7,8 @@
 #include "base/logging.h"
 #include "base/unguessable_token.h"
 
+#include <windows.h>
+
 namespace base {
 
 SharedMemoryHandle::SharedMemoryHandle() {}
diff --git a/base/metrics/persistent_memory_allocator.cc b/base/metrics/persistent_memory_allocator.cc
index 65adaaa..065c028 100644
--- a/base/metrics/persistent_memory_allocator.cc
+++ b/base/metrics/persistent_memory_allocator.cc
@@ -8,6 +8,7 @@
 #include <algorithm>
 
 #if defined(OS_WIN)
+#include <windows.h>
 #include "winbase.h"
 #elif defined(OS_POSIX)
 #include <sys/mman.h>
diff --git a/base/process/memory_win.cc b/base/process/memory_win.cc
index 88244fe..2ae826b 100644
--- a/base/process/memory_win.cc
+++ b/base/process/memory_win.cc
@@ -4,10 +4,11 @@
 
 #include "base/process/memory.h"
 
+#include <windows.h>  // Must be in front of other Windows header files.
+
 #include <new.h>
 #include <psapi.h>
 #include <stddef.h>
-#include <windows.h>
 
 // malloc_unchecked is required to implement UncheckedMalloc properly.
 // It's provided by allocator_shim_win.cc but since that's not always present,
diff --git a/base/process/process_handle.h b/base/process/process_handle.h
index ae54b72d..f3f6343 100644
--- a/base/process/process_handle.h
+++ b/base/process/process_handle.h
@@ -13,7 +13,7 @@
 #include "build/build_config.h"
 
 #if defined(OS_WIN)
-#include <windows.h>
+#include "base/win/windows_types.h"
 #endif
 
 #if defined(OS_FUCHSIA)
diff --git a/base/process/process_metrics.h b/base/process/process_metrics.h
index 7a12b6e..29ee0ab 100644
--- a/base/process/process_metrics.h
+++ b/base/process/process_metrics.h
@@ -33,13 +33,20 @@
 
 #if defined(OS_WIN)
 #include "base/win/scoped_handle.h"
+#include "base/win/windows_types.h"
 #endif
 
 namespace base {
 
 #if defined(OS_WIN)
+// _WINDOWS_ will be defined if Windows.h was included - include Windows.h first
+// to get access to the full struct definition.
+#if defined(_WINDOWS_)
 struct IoCounters : public IO_COUNTERS {
 };
+#else
+struct IoCounters;
+#endif
 #elif defined(OS_POSIX)
 struct IoCounters {
   uint64_t ReadOperationCount;
diff --git a/base/process/process_metrics_win.cc b/base/process/process_metrics_win.cc
index e5643ec..76f09f52 100644
--- a/base/process/process_metrics_win.cc
+++ b/base/process/process_metrics_win.cc
@@ -2,9 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Must be included before process_metrics.h to get full IoCounters definition
+#include <windows.h>
+
 #include "base/process/process_metrics.h"
 
-#include <windows.h>
 #include <psapi.h>
 #include <stddef.h>
 #include <stdint.h>
diff --git a/base/process/process_win.cc b/base/process/process_win.cc
index c3b59924..10a67f3 100644
--- a/base/process/process_win.cc
+++ b/base/process/process_win.cc
@@ -10,6 +10,8 @@
 #include "base/process/kill.h"
 #include "base/threading/thread_restrictions.h"
 
+#include <windows.h>
+
 namespace {
 
 DWORD kBasicProcessAccess =
diff --git a/base/synchronization/condition_variable.h b/base/synchronization/condition_variable.h
index b5677511..6d95c678 100644
--- a/base/synchronization/condition_variable.h
+++ b/base/synchronization/condition_variable.h
@@ -76,7 +76,7 @@
 #endif
 
 #if defined(OS_WIN)
-#include <windows.h>
+#include "base/win/windows_types.h"
 #endif
 
 namespace base {
@@ -105,8 +105,8 @@
  private:
 
 #if defined(OS_WIN)
-  CONDITION_VARIABLE cv_;
-  SRWLOCK* const srwlock_;
+  CHROME_CONDITION_VARIABLE cv_;
+  CHROME_SRWLOCK* const srwlock_;
 #elif defined(OS_POSIX)
   pthread_cond_t condition_;
   pthread_mutex_t* user_mutex_;
diff --git a/base/synchronization/condition_variable_win.cc b/base/synchronization/condition_variable_win.cc
index 378785a..ddaef07 100644
--- a/base/synchronization/condition_variable_win.cc
+++ b/base/synchronization/condition_variable_win.cc
@@ -9,6 +9,8 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/time/time.h"
 
+#include <windows.h>
+
 namespace base {
 
 ConditionVariable::ConditionVariable(Lock* user_lock)
@@ -18,7 +20,7 @@
 #endif
 {
   DCHECK(user_lock);
-  InitializeConditionVariable(&cv_);
+  InitializeConditionVariable(reinterpret_cast<PCONDITION_VARIABLE>(&cv_));
 }
 
 ConditionVariable::~ConditionVariable() = default;
@@ -36,7 +38,9 @@
   user_lock_->CheckHeldAndUnmark();
 #endif
 
-  if (!SleepConditionVariableSRW(&cv_, srwlock_, timeout, 0)) {
+  if (!SleepConditionVariableSRW(reinterpret_cast<PCONDITION_VARIABLE>(&cv_),
+                                 reinterpret_cast<PSRWLOCK>(srwlock_), timeout,
+                                 0)) {
     // On failure, we only expect the CV to timeout. Any other error value means
     // that we've unexpectedly woken up.
     // Note that WAIT_TIMEOUT != ERROR_TIMEOUT. WAIT_TIMEOUT is used with the
@@ -51,11 +55,11 @@
 }
 
 void ConditionVariable::Broadcast() {
-  WakeAllConditionVariable(&cv_);
+  WakeAllConditionVariable(reinterpret_cast<PCONDITION_VARIABLE>(&cv_));
 }
 
 void ConditionVariable::Signal() {
-  WakeConditionVariable(&cv_);
+  WakeConditionVariable(reinterpret_cast<PCONDITION_VARIABLE>(&cv_));
 }
 
 }  // namespace base
diff --git a/base/synchronization/lock_impl.h b/base/synchronization/lock_impl.h
index 880e70d..7ec081f4 100644
--- a/base/synchronization/lock_impl.h
+++ b/base/synchronization/lock_impl.h
@@ -11,7 +11,7 @@
 #include "build/build_config.h"
 
 #if defined(OS_WIN)
-#include <windows.h>
+#include "base/win/windows_types.h"
 #elif defined(OS_POSIX)
 #include <errno.h>
 #include <pthread.h>
@@ -26,7 +26,7 @@
 class BASE_EXPORT LockImpl {
  public:
 #if defined(OS_WIN)
-  using NativeHandle = SRWLOCK;
+  using NativeHandle = CHROME_SRWLOCK;
 #elif defined(OS_POSIX)
   using NativeHandle = pthread_mutex_t;
 #endif
@@ -63,7 +63,7 @@
 
 #if defined(OS_WIN)
 void LockImpl::Unlock() {
-  ::ReleaseSRWLockExclusive(&native_handle_);
+  ::ReleaseSRWLockExclusive(reinterpret_cast<PSRWLOCK>(&native_handle_));
 }
 #elif defined(OS_POSIX)
 void LockImpl::Unlock() {
diff --git a/base/synchronization/lock_impl_posix.cc b/base/synchronization/lock_impl_posix.cc
index 3bfd9c2e5..43c9d49 100644
--- a/base/synchronization/lock_impl_posix.cc
+++ b/base/synchronization/lock_impl_posix.cc
@@ -8,6 +8,8 @@
 
 #include "base/debug/activity_tracker.h"
 #include "base/synchronization/lock.h"
+#include "base/synchronization/synchronization_flags.h"
+#include "build/build_config.h"
 
 namespace base {
 namespace internal {
@@ -76,11 +78,13 @@
 
 // static
 bool LockImpl::PriorityInheritanceAvailable() {
-#if PRIORITY_INHERITANCE_LOCKS_POSSIBLE() && defined(OS_MACOSX)
+#if BUILDFLAG(ENABLE_MUTEX_PRIORITY_INHERITANCE)
+  return true;
+#elif PRIORITY_INHERITANCE_LOCKS_POSSIBLE() && defined(OS_MACOSX)
   return true;
 #else
   // Security concerns prevent the use of priority inheritance mutexes on Linux.
-  //   * CVE-2010-0622 - wake_futex_pi unlocks incorrect, possible DoS.
+  //   * CVE-2010-0622 - Linux < 2.6.33-rc7, wake_futex_pi possible DoS.
   //     https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-0622
   //   * CVE-2012-6647 - Linux < 3.5.1, futex_wait_requeue_pi possible DoS.
   //     https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-6647
@@ -92,7 +96,7 @@
   //   * glibc Bug 14652: https://sourceware.org/bugzilla/show_bug.cgi?id=14652
   //     Fixed in glibc 2.17.
   //     Priority inheritance mutexes may deadlock with condition variables
-  //     during recacquisition of the mutex after the condition variable is
+  //     during reacquisition of the mutex after the condition variable is
   //     signalled.
   return false;
 #endif
diff --git a/base/synchronization/lock_impl_win.cc b/base/synchronization/lock_impl_win.cc
index 80a5316..e0c4e9d7 100644
--- a/base/synchronization/lock_impl_win.cc
+++ b/base/synchronization/lock_impl_win.cc
@@ -6,6 +6,8 @@
 
 #include "base/debug/activity_tracker.h"
 
+#include <windows.h>
+
 namespace base {
 namespace internal {
 
@@ -14,7 +16,8 @@
 LockImpl::~LockImpl() = default;
 
 bool LockImpl::Try() {
-  return !!::TryAcquireSRWLockExclusive(&native_handle_);
+  return !!::TryAcquireSRWLockExclusive(
+      reinterpret_cast<PSRWLOCK>(&native_handle_));
 }
 
 void LockImpl::Lock() {
@@ -30,7 +33,7 @@
       return;
 
   base::debug::ScopedLockAcquireActivity lock_activity(this);
-  ::AcquireSRWLockExclusive(&native_handle_);
+  ::AcquireSRWLockExclusive(reinterpret_cast<PSRWLOCK>(&native_handle_));
 }
 
 }  // namespace internal
diff --git a/base/synchronization/waitable_event_watcher_win.cc b/base/synchronization/waitable_event_watcher_win.cc
index d28b6a7..6d2511d 100644
--- a/base/synchronization/waitable_event_watcher_win.cc
+++ b/base/synchronization/waitable_event_watcher_win.cc
@@ -8,6 +8,8 @@
 #include "base/synchronization/waitable_event.h"
 #include "base/win/object_watcher.h"
 
+#include <windows.h>
+
 namespace base {
 
 WaitableEventWatcher::WaitableEventWatcher() = default;
diff --git a/base/syslog_logging.cc b/base/syslog_logging.cc
index 54e6e96..03c2b5ea 100644
--- a/base/syslog_logging.cc
+++ b/base/syslog_logging.cc
@@ -5,6 +5,7 @@
 #include "base/syslog_logging.h"
 
 #if defined(OS_WIN)
+#include <windows.h>
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/debug/stack_trace.h"
diff --git a/base/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc b/base/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc
index 345a116e..af432ef 100644
--- a/base/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc
+++ b/base/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc
@@ -246,10 +246,12 @@
   waitable_event_background.Wait();
   waitable_event_normal.Wait();
 
-  if (Lock::HandlesMultipleThreadPriorities())
+  if (Lock::HandlesMultipleThreadPriorities() &&
+      PlatformThread::CanIncreaseCurrentThreadPriority()) {
     EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background);
-  else
+  } else {
     EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background);
+  }
   EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_normal);
 }
 
diff --git a/base/test/test_reg_util_win.cc b/base/test/test_reg_util_win.cc
index 4301756..9ce4ad1 100644
--- a/base/test/test_reg_util_win.cc
+++ b/base/test/test_reg_util_win.cc
@@ -15,6 +15,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#include <windows.h>
+
 namespace registry_util {
 
 namespace {
diff --git a/base/threading/platform_thread.h b/base/threading/platform_thread.h
index fc850a8a..da58d0cf 100644
--- a/base/threading/platform_thread.h
+++ b/base/threading/platform_thread.h
@@ -17,7 +17,7 @@
 #include "build/build_config.h"
 
 #if defined(OS_WIN)
-#include <windows.h>
+#include "base/win/windows_types.h"
 #elif defined(OS_MACOSX)
 #include <mach/mach_types.h>
 #elif defined(OS_FUCHSIA)
diff --git a/base/threading/platform_thread_win.cc b/base/threading/platform_thread_win.cc
index eb2edce..77603cc 100644
--- a/base/threading/platform_thread_win.cc
+++ b/base/threading/platform_thread_win.cc
@@ -16,6 +16,8 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/win/scoped_handle.h"
 
+#include <windows.h>
+
 namespace base {
 
 namespace {
diff --git a/base/threading/thread_local_storage.h b/base/threading/thread_local_storage.h
index b6f34c3..09d426b 100644
--- a/base/threading/thread_local_storage.h
+++ b/base/threading/thread_local_storage.h
@@ -13,7 +13,7 @@
 #include "build/build_config.h"
 
 #if defined(OS_WIN)
-#include <windows.h>
+#include "base/win/windows_types.h"
 #elif defined(OS_POSIX)
 #include <pthread.h>
 #endif
diff --git a/base/time/time.h b/base/time/time.h
index c1e2513..5c2f588 100644
--- a/base/time/time.h
+++ b/base/time/time.h
@@ -79,10 +79,8 @@
 #endif
 
 #if defined(OS_WIN)
-// For FILETIME in FromFileTime, until it moves to a new converter class.
-// See TODO(iyengar) below.
-#include <windows.h>
 #include "base/gtest_prod_util.h"
+#include "base/win/windows_types.h"
 #endif
 
 namespace base {
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc
index 28eff7a..6f1ff205 100644
--- a/base/time/time_unittest.cc
+++ b/base/time/time_unittest.cc
@@ -19,6 +19,8 @@
 
 #if defined(OS_IOS)
 #include "base/ios/ios_util.h"
+#elif defined(OS_WIN)
+#include <windows.h>
 #endif
 
 namespace base {
diff --git a/base/trace_event/process_memory_dump.cc b/base/trace_event/process_memory_dump.cc
index 3d068af..8bd8973 100644
--- a/base/trace_event/process_memory_dump.cc
+++ b/base/trace_event/process_memory_dump.cc
@@ -29,6 +29,8 @@
 #endif
 
 #if defined(OS_WIN)
+#include <windows.h>  // Must be in front of other Windows header files
+
 #include <Psapi.h>
 #endif
 
diff --git a/base/trace_event/process_memory_dump_unittest.cc b/base/trace_event/process_memory_dump_unittest.cc
index 01485882..e2b0e6f9 100644
--- a/base/trace_event/process_memory_dump_unittest.cc
+++ b/base/trace_event/process_memory_dump_unittest.cc
@@ -18,6 +18,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if defined(OS_WIN)
+#include <windows.h>
 #include "winbase.h"
 #elif defined(OS_POSIX)
 #include <sys/mman.h>
diff --git a/base/trace_event/trace_event_etw_export_win.cc b/base/trace_event/trace_event_etw_export_win.cc
index 74cfb74..ff8d2ff 100644
--- a/base/trace_event/trace_event_etw_export_win.cc
+++ b/base/trace_event/trace_event_etw_export_win.cc
@@ -15,6 +15,8 @@
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/trace_event_impl.h"
 
+#include <windows.h>
+
 // The GetProcAddress technique is borrowed from
 // https://github.com/google/UIforETW/tree/master/ETWProviders
 //
diff --git a/base/win/current_module.h b/base/win/current_module.h
index bbc4134..ee141db 100644
--- a/base/win/current_module.h
+++ b/base/win/current_module.h
@@ -5,6 +5,8 @@
 #ifndef BASE_WIN_CURRENT_MODULE_H_
 #define BASE_WIN_CURRENT_MODULE_H_
 
+#include <windows.h>
+
 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
 extern "C" IMAGE_DOS_HEADER __ImageBase;
 
diff --git a/base/win/object_watcher.cc b/base/win/object_watcher.cc
index 426f52e2..4c1c235 100644
--- a/base/win/object_watcher.cc
+++ b/base/win/object_watcher.cc
@@ -8,6 +8,8 @@
 #include "base/logging.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 
+#include <windows.h>
+
 namespace base {
 namespace win {
 
diff --git a/base/win/object_watcher.h b/base/win/object_watcher.h
index 6fddc58..b7ed76d 100644
--- a/base/win/object_watcher.h
+++ b/base/win/object_watcher.h
@@ -5,7 +5,7 @@
 #ifndef BASE_WIN_OBJECT_WATCHER_H_
 #define BASE_WIN_OBJECT_WATCHER_H_
 
-#include <windows.h>
+#include "base/win/windows_types.h"
 
 #include "base/base_export.h"
 #include "base/callback.h"
diff --git a/base/win/registry.h b/base/win/registry.h
index 9acbea2..53327ec5 100644
--- a/base/win/registry.h
+++ b/base/win/registry.h
@@ -5,10 +5,10 @@
 #ifndef BASE_WIN_REGISTRY_H_
 #define BASE_WIN_REGISTRY_H_
 
-#include <windows.h>
 #include <stdint.h>
 #include <string>
 #include <vector>
+#include "base/win/windows_types.h"
 
 #include "base/base_export.h"
 #include "base/macros.h"
diff --git a/base/win/scoped_handle.cc b/base/win/scoped_handle.cc
index d8c9212..6eb32712 100644
--- a/base/win/scoped_handle.cc
+++ b/base/win/scoped_handle.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <windows.h>
+
 #include "base/win/scoped_handle.h"
 
 #include <stddef.h>
diff --git a/base/win/scoped_handle.h b/base/win/scoped_handle.h
index c1e4597..0d65a953 100644
--- a/base/win/scoped_handle.h
+++ b/base/win/scoped_handle.h
@@ -5,7 +5,7 @@
 #ifndef BASE_WIN_SCOPED_HANDLE_H_
 #define BASE_WIN_SCOPED_HANDLE_H_
 
-#include <windows.h>
+#include "base/win/windows_types.h"
 
 #include "base/base_export.h"
 #include "base/gtest_prod_util.h"
diff --git a/base/win/win_includes_unittest.cc b/base/win/win_includes_unittest.cc
new file mode 100644
index 0000000..73b7b55
--- /dev/null
+++ b/base/win/win_includes_unittest.cc
@@ -0,0 +1,32 @@
+// Copyright (c) 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.
+
+// This file ensures that these header files don't include Windows.h and can
+// compile without including Windows.h. This helps to improve compile times.
+
+#include "base/files/file_util.h"
+#include "base/files/platform_file.h"
+#include "base/process/process_handle.h"
+#include "base/synchronization/condition_variable.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/platform_thread.h"
+#include "base/threading/thread_local_storage.h"
+#include "base/win/registry.h"
+#include "base/win/scoped_handle.h"
+#include "base/win/win_util.h"
+
+#ifdef _WINDOWS_
+#error Windows.h was included inappropriately.
+#endif
+
+// Make sure windows.h can be included after windows_types.h
+#include "base/win/windows_types.h"
+
+#include <windows.h>
+
+// Check that type sizes match.
+static_assert(sizeof(CHROME_CONDITION_VARIABLE) == sizeof(CONDITION_VARIABLE),
+              "Definition mismatch.");
+static_assert(sizeof(CHROME_SRWLOCK) == sizeof(SRWLOCK),
+              "Definition mismatch.");
diff --git a/base/win/win_util.cc b/base/win/win_util.cc
index fccafc90..6d14f36a 100644
--- a/base/win/win_util.cc
+++ b/base/win/win_util.cc
@@ -2,13 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Must be included before process_metrics.h to get full IoCounters definition
+#include <windows.h>
+
 #include "base/win/win_util.h"
 
 #include <aclapi.h>
 #include <cfgmgr32.h>
+#include <initguid.h>
 #include <powrprof.h>
 #include <shobjidl.h>  // Must be before propkey.
-#include <initguid.h>
+
 #include <inspectable.h>
 #include <mdmregistration.h>
 #include <objbase.h>
@@ -23,7 +27,7 @@
 #include <signal.h>
 #include <stddef.h>
 #include <stdlib.h>
-#include <tchar.h> // Must be before tpcshrd.h or for any use of _T macro
+#include <tchar.h>  // Must be before tpcshrd.h or for any use of _T macro
 #include <tpcshrd.h>
 #include <uiviewsettingsinterop.h>
 #include <windows.ui.viewmanagement.h>
diff --git a/base/win/win_util.h b/base/win/win_util.h
index 570dad4c..2aa0999 100644
--- a/base/win/win_util.h
+++ b/base/win/win_util.h
@@ -22,8 +22,8 @@
 #ifndef BASE_WIN_WIN_UTIL_H_
 #define BASE_WIN_WIN_UTIL_H_
 
-#include <windows.h>
 #include <stdint.h>
+#include "base/win/windows_types.h"
 
 #include <string>
 #include <vector>
@@ -35,6 +35,9 @@
 struct _tagpropertykey;
 typedef _tagpropertykey PROPERTYKEY;
 
+// _WINDOWS_ will be defined if Windows.h was included - include Windows.h first
+// to get access to the full struct definition.
+#if defined(_WINDOWS_)
 // This is the same as NONCLIENTMETRICS except that the
 // unused member |iPaddedBorderWidth| has been removed.
 struct NONCLIENTMETRICS_XP {
@@ -54,6 +57,9 @@
     LOGFONTW lfStatusFont;
     LOGFONTW lfMessageFont;
 };
+#else
+struct NONCLIENTMETRICS_XP;
+#endif
 
 namespace base {
 namespace win {
diff --git a/base/win/windows_full.h b/base/win/windows_full.h
new file mode 100644
index 0000000..8b9e43a
--- /dev/null
+++ b/base/win/windows_full.h
@@ -0,0 +1,13 @@
+// Copyright (c) 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.
+
+// This header is needed so that mojo typemap files can specify their dependence
+// on Windows.h. This can be removed once https://crbug.com/798763 is resolved.
+
+#ifndef BASE_WIN_WINDOWS_FULL_H
+#define BASE_WIN_WINDOWS_FULL_H
+
+#include <windows.h>
+
+#endif  // BASE_WIN_WINDOWS_FULL_H
diff --git a/base/win/windows_types.h b/base/win/windows_types.h
new file mode 100644
index 0000000..091e47f
--- /dev/null
+++ b/base/win/windows_types.h
@@ -0,0 +1,250 @@
+// Copyright (c) 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.
+
+// This file contains defines and typedefs that allow popular Windows types to
+// be used without the overhead of including windows.h.
+
+#ifndef BASE_WIN_WINDOWS_TYPES_H
+#define BASE_WIN_WINDOWS_TYPES_H
+
+// Needed for function prototypes.
+#include <concurrencysal.h>
+#include <sal.h>
+#include <specstrings.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// typedef and define the most commonly used Windows integer types.
+
+typedef unsigned long DWORD;
+typedef long LONG;
+typedef __int64 LONGLONG;
+typedef unsigned __int64 ULONGLONG;
+
+#define VOID void
+typedef char CHAR;
+typedef short SHORT;
+typedef long LONG;
+typedef int INT;
+typedef unsigned int UINT;
+typedef unsigned int* PUINT;
+typedef void* LPVOID;
+typedef void* PVOID;
+typedef void* HANDLE;
+typedef int BOOL;
+typedef unsigned char BYTE;
+typedef BYTE BOOLEAN;
+typedef DWORD ULONG;
+typedef unsigned short WORD;
+typedef WORD UWORD;
+typedef WORD ATOM;
+
+#if defined(_WIN64)
+typedef __int64 INT_PTR, *PINT_PTR;
+typedef unsigned __int64 UINT_PTR, *PUINT_PTR;
+
+typedef __int64 LONG_PTR, *PLONG_PTR;
+typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
+#else
+typedef __w64 int INT_PTR, *PINT_PTR;
+typedef __w64 unsigned int UINT_PTR, *PUINT_PTR;
+
+typedef __w64 long LONG_PTR, *PLONG_PTR;
+typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;
+#endif
+
+typedef UINT_PTR WPARAM;
+typedef LONG_PTR LPARAM;
+typedef LONG_PTR LRESULT;
+#define LRESULT LONG_PTR
+typedef _Return_type_success_(return >= 0) long HRESULT;
+
+typedef ULONG_PTR SIZE_T, *PSIZE_T;
+typedef LONG_PTR SSIZE_T, *PSSIZE_T;
+
+typedef DWORD ACCESS_MASK;
+typedef ACCESS_MASK REGSAM;
+
+
+// Forward declare Windows compatible handles.
+
+#define CHROME_DECLARE_HANDLE(name) \
+  struct name##__;                  \
+  typedef struct name##__* name
+CHROME_DECLARE_HANDLE(HGLRC);
+CHROME_DECLARE_HANDLE(HICON);
+CHROME_DECLARE_HANDLE(HINSTANCE);
+CHROME_DECLARE_HANDLE(HKEY);
+CHROME_DECLARE_HANDLE(HMENU);
+CHROME_DECLARE_HANDLE(HWND);
+typedef HINSTANCE HMODULE;
+#undef CHROME_DECLARE_HANDLE
+
+
+// Forward declare some Windows struct/typedef sets.
+
+typedef struct _OVERLAPPED OVERLAPPED;
+typedef struct tagMSG MSG, *PMSG, *NPMSG, *LPMSG;
+
+typedef struct _RTL_SRWLOCK RTL_SRWLOCK;
+typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
+
+typedef struct _GUID GUID;
+typedef GUID CLSID;
+
+typedef struct tagLOGFONTW LOGFONTW, *PLOGFONTW, *NPLOGFONTW, *LPLOGFONTW;
+typedef LOGFONTW LOGFONT;
+
+typedef struct _FILETIME FILETIME;
+
+typedef struct tagMENUITEMINFOW MENUITEMINFOW, MENUITEMINFO;
+
+
+// Declare Chrome versions of some Windows structures. These are needed for
+// when we need a concrete type but don't want to pull in Windows.h. We can't
+// declare the Windows types so we declare our types and cast to the Windows
+// types in a few places.
+
+struct CHROME_SRWLOCK {
+  PVOID Ptr;
+};
+
+struct CHROME_CONDITION_VARIABLE {
+  PVOID Ptr;
+};
+
+
+// Define some commonly used Windows constants. Note that the layout of these
+// macros - including internal spacing - must be 100% consistent with windows.h.
+
+#ifndef INVALID_HANDLE_VALUE
+// Work around there being two slightly different definitions in the SDK.
+#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
+#endif
+#define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
+#define HTNOWHERE 0
+#define MAX_PATH 260
+#define CS_GLOBALCLASS 0x4000
+
+#define ERROR_SUCCESS 0L
+#define ERROR_FILE_NOT_FOUND 2L
+#define ERROR_ACCESS_DENIED 5L
+#define ERROR_INVALID_HANDLE 6L
+#define ERROR_SHARING_VIOLATION 32L
+#define ERROR_LOCK_VIOLATION 33L
+#define REG_BINARY ( 3ul )
+
+#define STATUS_PENDING ((DWORD   )0x00000103L)
+#define STILL_ACTIVE STATUS_PENDING
+#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
+#define FAILED(hr) (((HRESULT)(hr)) < 0)
+
+#define HKEY_CLASSES_ROOT (( HKEY ) (ULONG_PTR)((LONG)0x80000000) )
+#define HKEY_LOCAL_MACHINE (( HKEY ) (ULONG_PTR)((LONG)0x80000002) )
+#define HKEY_CURRENT_USER (( HKEY ) (ULONG_PTR)((LONG)0x80000001) )
+#define KEY_QUERY_VALUE (0x0001)
+#define KEY_SET_VALUE (0x0002)
+#define KEY_CREATE_SUB_KEY (0x0004)
+#define KEY_ENUMERATE_SUB_KEYS (0x0008)
+#define KEY_NOTIFY (0x0010)
+#define KEY_CREATE_LINK (0x0020)
+#define KEY_WOW64_32KEY (0x0200)
+#define KEY_WOW64_64KEY (0x0100)
+#define KEY_WOW64_RES (0x0300)
+
+#define READ_CONTROL (0x00020000L)
+#define SYNCHRONIZE (0x00100000L)
+
+#define STANDARD_RIGHTS_READ (READ_CONTROL)
+#define STANDARD_RIGHTS_WRITE (READ_CONTROL)
+#define STANDARD_RIGHTS_ALL (0x001F0000L)
+
+#define KEY_READ                ((STANDARD_RIGHTS_READ       |\
+                                  KEY_QUERY_VALUE            |\
+                                  KEY_ENUMERATE_SUB_KEYS     |\
+                                  KEY_NOTIFY)                 \
+                                  &                           \
+                                 (~SYNCHRONIZE))
+
+
+#define KEY_WRITE               ((STANDARD_RIGHTS_WRITE      |\
+                                  KEY_SET_VALUE              |\
+                                  KEY_CREATE_SUB_KEY)         \
+                                  &                           \
+                                 (~SYNCHRONIZE))
+
+#define KEY_ALL_ACCESS          ((STANDARD_RIGHTS_ALL        |\
+                                  KEY_QUERY_VALUE            |\
+                                  KEY_SET_VALUE              |\
+                                  KEY_CREATE_SUB_KEY         |\
+                                  KEY_ENUMERATE_SUB_KEYS     |\
+                                  KEY_NOTIFY                 |\
+                                  KEY_CREATE_LINK)            \
+                                  &                           \
+                                 (~SYNCHRONIZE))
+
+// Define some macros needed when prototyping Windows functions.
+
+#define DECLSPEC_IMPORT __declspec(dllimport)
+#define WINBASEAPI DECLSPEC_IMPORT
+#define WINUSERAPI DECLSPEC_IMPORT
+#define WINAPI __stdcall
+#define CALLBACK __stdcall
+
+// Needed for optimal lock performance.
+WINBASEAPI _Releases_exclusive_lock_(*SRWLock) VOID WINAPI
+    ReleaseSRWLockExclusive(_Inout_ PSRWLOCK SRWLock);
+
+// Needed to support protobuf's GetMessage macro magic.
+WINUSERAPI BOOL WINAPI GetMessageW(_Out_ LPMSG lpMsg,
+                                   _In_opt_ HWND hWnd,
+                                   _In_ UINT wMsgFilterMin,
+                                   _In_ UINT wMsgFilterMax);
+
+// Needed for thread_local_storage.h
+WINBASEAPI LPVOID WINAPI TlsGetValue(_In_ DWORD dwTlsIndex);
+
+// Needed for scoped_handle.h
+WINBASEAPI _Check_return_ _Post_equals_last_error_ DWORD WINAPI
+    GetLastError(VOID);
+
+WINBASEAPI VOID WINAPI SetLastError(_In_ DWORD dwErrCode);
+
+#ifdef __cplusplus
+}
+#endif
+
+// These macros are all defined by windows.h and are also used as the names of
+// functions in the Chromium code base. Add to this list as needed whenever
+// there is a Windows macro which causes a function call to be renamed. This
+// ensures that the same renaming will happen everywhere. Includes of this file
+// can be added wherever needed to ensure this consistent renaming.
+
+#define CopyFile CopyFileW
+#define CreateDirectory CreateDirectoryW
+#define CreateEvent CreateEventW
+#define CreateFile CreateFileW
+#define CreateService CreateServiceW
+#define DeleteFile DeleteFileW
+#define DispatchMessage DispatchMessageW
+#define DrawText DrawTextW
+#define GetComputerName GetComputerNameW
+#define GetCurrentDirectory GetCurrentDirectoryW
+#define GetCurrentTime() GetTickCount()
+#define GetFileAttributes GetFileAttributesW
+#define GetMessage GetMessageW
+#define GetUserName GetUserNameW
+#define LoadIcon LoadIconW
+#define LoadImage LoadImageW
+#define PostMessage PostMessageW
+#define ReplaceFile ReplaceFileW
+#define ReportEvent ReportEventW
+#define SendMessage SendMessageW
+#define SendMessageCallback SendMessageCallbackW
+#define SetCurrentDirectory SetCurrentDirectoryW
+#define StartService StartServiceW
+
+#endif  // BASE_WIN_WINDOWS_TYPES_H
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index 767cb4f9..086ecc6 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -2490,10 +2490,8 @@
 
       if (_has_lint_target) {
         android_lint("${_main_target_name}__lint") {
-          # TODO(agrieve): Move this forward into the if block once downstream
-          #     is updated.
-          forward_variables_from(invoker, [ "android_manifest" ])
           if (invoker.type == "android_apk") {
+            forward_variables_from(invoker, [ "android_manifest" ])
           } else if (defined(invoker.android_manifest_for_lint)) {
             android_manifest = invoker.android_manifest_for_lint
           }
diff --git a/build/config/android/sdk.gni b/build/config/android/sdk.gni
index 2fe0400..0493cfaf 100644
--- a/build/config/android/sdk.gni
+++ b/build/config/android/sdk.gni
@@ -8,3 +8,8 @@
 
 # SDK releases against which public builds are supported.
 public_sdk_releases = [ "o_mr1" ]
+
+# The default AFDO profile used by public builds. Value may differ in
+# internal builds.
+clang_default_afdo_profile =
+    rebase_path("//chrome/android/profiles/chrome-profile-3309-text.prof")
diff --git a/build/fuchsia/runner_common.py b/build/fuchsia/runner_common.py
index bb8eaad7..6494a7e 100755
--- a/build/fuchsia/runner_common.py
+++ b/build/fuchsia/runner_common.py
@@ -287,13 +287,11 @@
     autorun_file.write('export CHROME_HEADLESS=1\n')
 
   if wait_for_network:
-    # Quietly block until `ping google.com` succeeds.
-    autorun_file.write("""echo "Waiting for network connectivity..."
-                       until ping -c 1 google.com >/dev/null 2>/dev/null
-                       do
-                       :
-                       done
-                       """)
+    # Quietly block until `ping -c 0 google.com` succeeds. With -c 0 ping
+    # resolves the domain name, but doesn't send any pings.
+    autorun_file.write("echo Waiting for network connectivity...\n" +
+                       "until ping -c 0 google.com >/dev/null 2>&1\n" +
+                       "do sleep 1; done\n")
 
   if summary_output:
     # Unfortunately, devmgr races with this autorun script. This delays long
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index e46cde82..06e1aa9b 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -1050,10 +1050,8 @@
     gfx::BufferUsage usage,
     viz::ResourceFormat format) const {
   gfx::BufferFormat buffer_format = BufferFormat(format);
-  bool found = std::find(texture_target_exception_list_.begin(),
-                         texture_target_exception_list_.end(),
-                         std::make_pair(usage, buffer_format)) !=
-               texture_target_exception_list_.end();
+  bool found = base::ContainsValue(texture_target_exception_list_,
+                                   std::make_pair(usage, buffer_format));
   return found ? gpu::GetPlatformSpecificTextureTarget() : GL_TEXTURE_2D;
 }
 
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index 5036233..6301006 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -447,112 +447,114 @@
     return external_resources;
   }
 
-  std::unique_ptr<media::HalfFloatMaker> half_float_maker;
+  const viz::ResourceFormat yuv_resource_format =
+      resource_provider_->YuvResourceFormat(bits_per_channel);
+  DCHECK(yuv_resource_format == viz::LUMINANCE_F16 ||
+         yuv_resource_format == viz::R16_EXT ||
+         yuv_resource_format == viz::LUMINANCE_8 ||
+         yuv_resource_format == viz::RED_8)
+      << yuv_resource_format;
 
-  switch (resource_provider_->YuvResourceFormat(bits_per_channel)) {
-    case viz::LUMINANCE_F16:
-      half_float_maker =
-          media::HalfFloatMaker::NewHalfFloatMaker(bits_per_channel);
-      external_resources.offset = half_float_maker->Offset();
-      external_resources.multiplier = half_float_maker->Multiplier();
-      break;
-    case viz::R16_EXT:
-      external_resources.multiplier = 65535.0f / ((1 << bits_per_channel) - 1);
-      external_resources.offset = 0;
-      break;
-    case viz::LUMINANCE_8:
-    case viz::RED_8:
-      break;
-    case viz::ALPHA_8:
-    case viz::RGBA_8888:
-    case viz::RGBA_4444:
-    case viz::BGRA_8888:
-    case viz::RGB_565:
-    case viz::ETC1:
-    case viz::RGBA_F16:
-      NOTREACHED();
+  std::unique_ptr<media::HalfFloatMaker> half_float_maker;
+  if (yuv_resource_format == viz::LUMINANCE_F16) {
+    half_float_maker =
+        media::HalfFloatMaker::NewHalfFloatMaker(bits_per_channel);
+    external_resources.offset = half_float_maker->Offset();
+    external_resources.multiplier = half_float_maker->Multiplier();
+  } else if (yuv_resource_format == viz::R16_EXT) {
+    external_resources.multiplier = 65535.0f / ((1 << bits_per_channel) - 1);
+    external_resources.offset = 0;
   }
 
+  // We need to transfer data from |video_frame| to the plane resources.
   for (size_t i = 0; i < plane_resources.size(); ++i) {
     PlaneResource& plane_resource = *plane_resources[i];
-    // Update each plane's resource id with its content.
-    DCHECK_EQ(plane_resource.resource_format(),
-              resource_provider_->YuvResourceFormat(bits_per_channel));
+    // Skip the transfer if this |video_frame|'s plane has been processed.
+    if (plane_resource.Matches(video_frame->unique_id(), i))
+      continue;
 
-    if (!plane_resource.Matches(video_frame->unique_id(), i)) {
-      // TODO(hubbe): Move upload code to media/.
-      // We need to transfer data from |video_frame| to the plane resource.
-      // TODO(reveman): Can use GpuMemoryBuffers here to improve performance.
+    const viz::ResourceFormat plane_resource_format =
+        plane_resource.resource_format();
+    DCHECK_EQ(plane_resource_format, yuv_resource_format);
 
-      // The |resource_size_pixels| is the size of the resource we want to
-      // upload to.
-      const gfx::Size resource_size_pixels = plane_resource.resource_size();
-      // The |video_stride_bytes| is the width of the video frame we are
-      // uploading (including non-frame data to fill in the stride).
-      const int video_stride_bytes = video_frame->stride(i);
+    // TODO(hubbe): Move upload code to media/.
+    // TODO(reveman): Can use GpuMemoryBuffers here to improve performance.
 
-      const size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>(
-          resource_size_pixels.width(), plane_resource.resource_format());
-      // Use 4-byte row alignment (OpenGL default) for upload performance.
-      // Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
-      const size_t upload_image_stride =
-          MathUtil::CheckedRoundUp<size_t>(bytes_per_row, 4u);
+    // |video_stride_bytes| is the width of the |video_frame| we are uploading
+    // (including non-frame data to fill in the stride).
+    const int video_stride_bytes = video_frame->stride(i);
 
-      // R16_EXT can represent 16-bit int, so we don't need a conversion step.
-      bool needs_conversion = false;
+    // |resource_size_pixels| is the size of the destination resource.
+    const gfx::Size resource_size_pixels = plane_resource.resource_size();
 
-      // viz::LUMINANCE_F16 uses half-floats, so we always need a conversion
-      // step.
-      if (plane_resource.resource_format() == viz::LUMINANCE_F16) {
-        needs_conversion = true;
-      } else if (plane_resource.resource_format() != viz::R16_EXT &&
-                 bits_per_channel > 8) {
-        // If bits_per_channel > 8 and we can't use viz::LUMINANCE_F16 or
-        // R16_EXT we need to shift the data down and create an 8-bit texture.
-        needs_conversion = true;
-      }
-      const uint8_t* pixels;
-      if (static_cast<int>(upload_image_stride) == video_stride_bytes &&
-          !needs_conversion) {
-        pixels = video_frame->data(i);
-      } else {
-        // Avoid malloc for each frame/plane if possible.
-        const size_t needed_size =
-            upload_image_stride * resource_size_pixels.height();
-        if (upload_pixels_.size() < needed_size)
-          upload_pixels_.resize(needed_size);
+    const size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>(
+        resource_size_pixels.width(), plane_resource_format);
+    // Use 4-byte row alignment (OpenGL default) for upload performance.
+    // Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
+    const size_t upload_image_stride =
+        MathUtil::CheckedRoundUp<size_t>(bytes_per_row, 4u);
 
-        if (plane_resource.resource_format() == viz::LUMINANCE_F16) {
-          for (int row = 0; row < resource_size_pixels.height(); ++row) {
-            uint16_t* dst = reinterpret_cast<uint16_t*>(
-                &upload_pixels_[upload_image_stride * row]);
-            const uint16_t* src = reinterpret_cast<uint16_t*>(
-                video_frame->data(i) + (video_stride_bytes * row));
-            half_float_maker->MakeHalfFloats(src, bytes_per_row / 2, dst);
-          }
-        } else if (bits_per_channel > 8) {
-          const int scale = 0x10000 >> (bits_per_channel - 8);
-          libyuv::Convert16To8Plane(
-              reinterpret_cast<uint16_t*>(video_frame->data(i)),
-              video_stride_bytes / 2, upload_pixels_.data(),
-              upload_image_stride, scale, bytes_per_row,
-              resource_size_pixels.height());
-        } else {
-          // Make a copy because input and output are the same size and
-          // format, but differ in stride.
-          libyuv::CopyPlane(video_frame->data(i), video_stride_bytes,
-                            upload_pixels_.data(), upload_image_stride,
-                            resource_size_pixels.width(),
-                            resource_size_pixels.height());
+    const size_t resource_bit_depth =
+        static_cast<size_t>(viz::BitsPerPixel(plane_resource_format));
+
+    // Data downshifting is needed if the resource bit depth is not enough.
+    const bool needs_bit_downshifting = bits_per_channel > resource_bit_depth;
+
+    // A copy to adjust strides is needed if those are different and both source
+    // and destination have the same bit depth.
+    const bool needs_stride_adaptation =
+        (bits_per_channel == resource_bit_depth) &&
+        (upload_image_stride != static_cast<size_t>(video_stride_bytes));
+
+    // We need to convert the incoming data if we're transferring to half float,
+    // if the need a bit downshift or if the strides need to be reconciled.
+    const bool needs_conversion = plane_resource_format == viz::LUMINANCE_F16 ||
+                                  needs_bit_downshifting ||
+                                  needs_stride_adaptation;
+
+    const uint8_t* pixels;
+    if (!needs_conversion) {
+      pixels = video_frame->data(i);
+    } else {
+      // Avoid malloc for each frame/plane if possible.
+      const size_t needed_size =
+          upload_image_stride * resource_size_pixels.height();
+      if (upload_pixels_.size() < needed_size)
+        upload_pixels_.resize(needed_size);
+
+      if (plane_resource_format == viz::LUMINANCE_F16) {
+        for (int row = 0; row < resource_size_pixels.height(); ++row) {
+          uint16_t* dst = reinterpret_cast<uint16_t*>(
+              &upload_pixels_[upload_image_stride * row]);
+          const uint16_t* src = reinterpret_cast<uint16_t*>(
+              video_frame->data(i) + (video_stride_bytes * row));
+          half_float_maker->MakeHalfFloats(src, bytes_per_row / 2, dst);
         }
-
-        pixels = &upload_pixels_[0];
+      } else if (needs_bit_downshifting) {
+        DCHECK(plane_resource_format == viz::LUMINANCE_8 ||
+               plane_resource_format == viz::RED_8);
+        const int scale = 0x10000 >> (bits_per_channel - 8);
+        libyuv::Convert16To8Plane(
+            reinterpret_cast<uint16_t*>(video_frame->data(i)),
+            video_stride_bytes / 2, upload_pixels_.data(), upload_image_stride,
+            scale, bytes_per_row, resource_size_pixels.height());
+      } else {
+        // Make a copy to reconcile stride, size and format being equal.
+        DCHECK(needs_stride_adaptation);
+        DCHECK(plane_resource_format == viz::LUMINANCE_8 ||
+               plane_resource_format == viz::RED_8);
+        libyuv::CopyPlane(video_frame->data(i), video_stride_bytes,
+                          upload_pixels_.data(), upload_image_stride,
+                          resource_size_pixels.width(),
+                          resource_size_pixels.height());
       }
 
-      resource_provider_->CopyToResource(plane_resource.resource_id(), pixels,
-                                         resource_size_pixels);
-      plane_resource.SetUniqueId(video_frame->unique_id(), i);
+      pixels = &upload_pixels_[0];
     }
+
+    resource_provider_->CopyToResource(plane_resource.resource_id(), pixels,
+                                       resource_size_pixels);
+    plane_resource.SetUniqueId(video_frame->unique_id(), i);
   }
 
   // Set the sync token otherwise resource is assumed to be synchronized.
diff --git a/chrome/VERSION b/chrome/VERSION
index d20c7af6..af62f9a 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=65
 MINOR=0
-BUILD=3311
+BUILD=3312
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 060215d2..b5fbaa2 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -290,6 +290,7 @@
     "//components/browsing_data/core:browsing_data_utils_java",
     "//components/browsing_data/core:clear_browsing_data_tab_java",
     "//components/favicon_base:favicon_base_enums_java",
+    "//components/dom_distiller/core:distiller_type_java",
     "//components/infobars/core:infobar_enums_java",
     "//components/ntp_snippets:ntp_snippets_java_enums_srcjar",
     "//components/ntp_tiles:ntp_tiles_enums_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerTabUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerTabUtils.java
index 04ad8ec..00fb0061c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerTabUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerTabUtils.java
@@ -6,6 +6,9 @@
 
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.chrome.browser.preferences.Pref;
+import org.chromium.chrome.browser.preferences.PrefServiceBridge;
+import org.chromium.chrome.browser.util.AccessibilityUtil;
 import org.chromium.components.navigation_interception.InterceptNavigationDelegate;
 import org.chromium.content_public.browser.WebContents;
 
@@ -14,6 +17,8 @@
  */
 @JNINamespace("android")
 public class DomDistillerTabUtils {
+    // Triggering heuristics encoded in native enum DistillerHeuristicsType.
+    private static Integer sHeuristics;
 
     private DomDistillerTabUtils() {
     }
@@ -63,13 +68,13 @@
     }
 
     /**
-     * Detect if any heuristic is being used to determine if a page is distillable. On the native
-     * side, this is testing if the heuristic is not "NONE".
+     * Detect if any heuristic is being used to determine if a page is distillable.
+     * This is testing if the heuristic is not "NONE".
      *
      * @return True if heuristics are being used to detect distillable pages.
      */
     public static boolean isDistillerHeuristicsEnabled() {
-        return nativeIsDistillerHeuristicsEnabled();
+        return getDistillerHeuristics() != DistillerHeuristicsType.NONE;
     }
 
     /**
@@ -78,7 +83,31 @@
      * @return True if heuristic is ALWAYS_TRUE.
      */
     public static boolean isHeuristicAlwaysTrue() {
-        return nativeIsHeuristicAlwaysTrue();
+        return getDistillerHeuristics() == DistillerHeuristicsType.ALWAYS_TRUE;
+    }
+
+    /**
+     * Check if the distiller should report mobile-friendly pages as non-distillable.
+     *
+     * @return True if heuristic is ADABOOST_MODEL, and neither "Simplified view for accessibility"
+     * nor TalkBack is enabled.
+     */
+    public static boolean shouldExcludeMobileFriendly() {
+        if (PrefServiceBridge.getInstance().getBoolean(Pref.READER_FOR_ACCESSIBILITY_ENABLED)
+                || AccessibilityUtil.isAccessibilityEnabled()) {
+            return false;
+        }
+        return getDistillerHeuristics() == DistillerHeuristicsType.ADABOOST_MODEL;
+    }
+
+    /**
+     * Cached version of nativeGetDistillerHeuristics().
+     */
+    public static @DistillerHeuristicsType int getDistillerHeuristics() {
+        if (sHeuristics == null) {
+            sHeuristics = nativeGetDistillerHeuristics();
+        }
+        return sHeuristics;
     }
 
     /**
@@ -106,8 +135,7 @@
     private static native void nativeDistillAndView(
             WebContents sourceWebContents, WebContents destinationWebContents);
     private static native String nativeGetFormattedUrlFromOriginalDistillerUrl(String url);
-    private static native boolean nativeIsDistillerHeuristicsEnabled();
-    private static native boolean nativeIsHeuristicAlwaysTrue();
+    private static native int nativeGetDistillerHeuristics();
     private static native void nativeSetInterceptNavigationDelegate(
             InterceptNavigationDelegate delegate, WebContents webContents);
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java
index 397a341..88545ff 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java
@@ -78,9 +78,6 @@
     /** The primary means of getting the currently active tab. */
     private TabModelSelector mTabModelSelector;
 
-    /** If Reader Mode is detecting all pages as distillable. */
-    private boolean mIsReaderHeuristicAlwaysTrue;
-
     // Hold on to the InterceptNavigationDelegate that the custom tab uses.
     InterceptNavigationDelegate mCustomTabNavigationDelegate;
 
@@ -89,15 +86,6 @@
         mTabModelSelector = selector;
         mChromeActivity = activity;
         mTabStatusMap = new HashMap<>();
-        mIsReaderHeuristicAlwaysTrue = isDistillerHeuristicAlwaysTrue();
-    }
-
-    /**
-     * This function wraps a method that calls native code and is overridden by tests.
-     * @return True if the heuristic is ALWAYS_TRUE.
-     */
-    protected boolean isDistillerHeuristicAlwaysTrue() {
-        return DomDistillerTabUtils.isHeuristicAlwaysTrue();
     }
 
     /**
@@ -428,7 +416,7 @@
         // ALWAYS_TRUE.
         boolean usingRequestDesktopSite = getBasePageWebContents() != null
                 && getBasePageWebContents().getNavigationController().getUseDesktopUserAgent()
-                && !mIsReaderHeuristicAlwaysTrue;
+                && !DomDistillerTabUtils.isHeuristicAlwaysTrue();
 
         if (!mTabStatusMap.containsKey(currentTabId) || usingRequestDesktopSite
                 || mTabStatusMap.get(currentTabId).getStatus() != POSSIBLE
@@ -515,38 +503,36 @@
             return;
         }
 
-        DistillablePageUtils.setDelegate(currentTab.getWebContents(),
-                new DistillablePageUtils.PageDistillableDelegate() {
-                    @Override
-                    public void onIsPageDistillableResult(boolean isDistillable, boolean isLast) {
-                        if (mTabModelSelector == null) return;
+        DistillablePageUtils.setDelegate(
+                currentTab.getWebContents(), (isDistillable, isLast, isMobileOptimized) -> {
+                    if (mTabModelSelector == null) return;
 
-                        ReaderModeTabInfo tabInfo = mTabStatusMap.get(tabId);
-                        Tab readerTab = mTabModelSelector.getTabById(tabId);
+                    ReaderModeTabInfo tabInfo = mTabStatusMap.get(tabId);
+                    Tab readerTab = mTabModelSelector.getTabById(tabId);
 
-                        // It is possible that the tab was destroyed before this callback happens.
-                        // TODO(wychen/mdjones): Remove the callback when a Tab/WebContents is
-                        // destroyed so that this never happens.
-                        if (readerTab == null || tabInfo == null) return;
+                    // It is possible that the tab was destroyed before this callback happens.
+                    // TODO(wychen/mdjones): Remove the callback when a Tab/WebContents is
+                    // destroyed so that this never happens.
+                    if (readerTab == null || tabInfo == null) return;
 
-                        // Make sure the page didn't navigate while waiting for a response.
-                        if (!readerTab.getUrl().equals(tabInfo.getUrl())) return;
+                    // Make sure the page didn't navigate while waiting for a response.
+                    if (!readerTab.getUrl().equals(tabInfo.getUrl())) return;
 
-                        if (isDistillable) {
-                            tabInfo.setStatus(POSSIBLE);
-                            // The user may have changed tabs.
-                            if (tabId == mTabModelSelector.getCurrentTabId()) {
-                                tryShowingInfoBar();
-                            }
-                        } else {
-                            tabInfo.setStatus(NOT_POSSIBLE);
+                    boolean excludedMobileFriendly =
+                            DomDistillerTabUtils.shouldExcludeMobileFriendly() && isMobileOptimized;
+                    if (isDistillable && !excludedMobileFriendly) {
+                        tabInfo.setStatus(POSSIBLE);
+                        // The user may have changed tabs.
+                        if (tabId == mTabModelSelector.getCurrentTabId()) {
+                            tryShowingInfoBar();
                         }
-                        if (!mIsUmaRecorded && (tabInfo.getStatus() == POSSIBLE || isLast)) {
-                            mIsUmaRecorded = true;
-                            RecordHistogram.recordBooleanHistogram(
-                                    "DomDistiller.PageDistillable",
-                                    tabInfo.getStatus() == POSSIBLE);
-                        }
+                    } else {
+                        tabInfo.setStatus(NOT_POSSIBLE);
+                    }
+                    if (!mIsUmaRecorded && (tabInfo.getStatus() == POSSIBLE || isLast)) {
+                        mIsUmaRecorded = true;
+                        RecordHistogram.recordBooleanHistogram(
+                                "DomDistiller.PageDistillable", tabInfo.getStatus() == POSSIBLE);
                     }
                 });
         mTabStatusMap.get(tabId).setIsCallbackSet(true);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunFragment.java
index 40dab576..7b602d5a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunFragment.java
@@ -40,8 +40,10 @@
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
 
-        boolean isChildAccount = getProperties().getBoolean(IS_CHILD_ACCOUNT);
-        String forceAccountTo = getProperties().getString(FORCE_SIGNIN_ACCOUNT_TO);
+        Bundle freProperties = getPageDelegate().getProperties();
+        boolean isChildAccount = freProperties.getBoolean(IS_CHILD_ACCOUNT);
+        String forceAccountTo = freProperties.getString(FORCE_SIGNIN_ACCOUNT_TO);
+
         AccountSigninView.Listener listener = new AccountSigninView.Listener() {
             @Override
             public void onAccountSelectionCanceled() {
@@ -89,15 +91,16 @@
 
     @Override
     public boolean interceptBackPressed() {
-        boolean forceSignin = getProperties().getString(FORCE_SIGNIN_ACCOUNT_TO) != null;
+        Bundle freProperties = getPageDelegate().getProperties();
+        boolean forceSignin = freProperties.getString(FORCE_SIGNIN_ACCOUNT_TO) != null;
         if (!mView.isInConfirmationScreen()
-                || (forceSignin && !getProperties().getBoolean(PRESELECT_BUT_ALLOW_TO_CHANGE))) {
+                || (forceSignin && !freProperties.getBoolean(PRESELECT_BUT_ALLOW_TO_CHANGE))) {
             return false;
         }
 
-        if (forceSignin && getProperties().getBoolean(PRESELECT_BUT_ALLOW_TO_CHANGE)) {
+        if (forceSignin && freProperties.getBoolean(PRESELECT_BUT_ALLOW_TO_CHANGE)) {
             // Don't force signin if Activity is recreated.
-            getProperties().remove(FORCE_SIGNIN_ACCOUNT_TO);
+            freProperties.remove(FORCE_SIGNIN_ACCOUNT_TO);
         }
 
         mView.cancelConfirmationScreen();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
index 7a3a69e..bc3ff23 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -228,8 +228,7 @@
                     return;
                 }
 
-                mPagerAdapter =
-                        new FirstRunPagerAdapter(getFragmentManager(), mPages, mFreProperties);
+                mPagerAdapter = new FirstRunPagerAdapter(getFragmentManager(), mPages);
                 stopProgressionIfNotAcceptedTermsOfService();
                 mPager.setAdapter(mPagerAdapter);
 
@@ -338,6 +337,11 @@
 
     // FirstRunPageDelegate:
     @Override
+    public Bundle getProperties() {
+        return mFreProperties;
+    }
+
+    @Override
     public void advanceToNextPage() {
         jumpToPage(mPager.getCurrentItem() + 1);
     }
@@ -480,7 +484,7 @@
         int currentPageIndex = mPager.getCurrentItem();
         while (currentPageIndex < mPagerAdapter.getCount()) {
             FirstRunPage currentPage = (FirstRunPage) mPagerAdapter.getItem(currentPageIndex);
-            if (!currentPage.shouldSkipPageOnCreate(getApplicationContext())) return;
+            if (!currentPage.shouldSkipPageOnCreate()) return;
             if (!jumpToPage(currentPageIndex + 1)) return;
             currentPageIndex = mPager.getCurrentItem();
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPage.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPage.java
index e20120e..ce17106 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPage.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPage.java
@@ -5,42 +5,18 @@
 package org.chromium.chrome.browser.firstrun;
 
 import android.app.Fragment;
-import android.content.Context;
-import android.os.Bundle;
 
 /**
  * A first run page shown in the First Run ViewPager.
  */
 public class FirstRunPage extends Fragment {
-    private Bundle mProperties = new Bundle();
-
     /**
      * @return Whether this page should be skipped on the FRE creation.
-     * @param appContext An application context.
      */
-    public boolean shouldSkipPageOnCreate(Context appContext) {
+    public boolean shouldSkipPageOnCreate() {
         return false;
     }
 
-    // Fragment:
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (savedInstanceState != null) {
-            mProperties = savedInstanceState;
-        } else if (getArguments() != null) {
-            mProperties = getArguments();
-        } else {
-            mProperties = new Bundle();
-        }
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putAll(mProperties);
-    }
-
     /**
      * @return Whether the back button press was handled by this page.
      */
@@ -49,13 +25,6 @@
     }
 
     /**
-     * @return Passed arguments if any, or saved instance state if any, or an empty bundle.
-     */
-    protected Bundle getProperties() {
-        return mProperties;
-    }
-
-    /**
      * @return The interface to the host.
      */
     protected FirstRunPageDelegate getPageDelegate() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java
index 742c28c..ccbd842d54 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPageDelegate.java
@@ -4,11 +4,18 @@
 
 package org.chromium.chrome.browser.firstrun;
 
+import android.os.Bundle;
+
 /**
  * Defines the host interface for First Run Experience pages.
  */
 public interface FirstRunPageDelegate {
     /**
+     * Returns FRE properties bundle.
+     */
+    Bundle getProperties();
+
+    /**
      * Advances the First Run Experience to the next page.
      * Successfully finishes FRE if the current page is the last page.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPagerAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPagerAdapter.java
index 1f88389..28f5cf5a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPagerAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunPagerAdapter.java
@@ -6,7 +6,6 @@
 
 import android.app.Fragment;
 import android.app.FragmentManager;
-import android.os.Bundle;
 import android.support.v13.app.FragmentStatePagerAdapter;
 
 import java.util.List;
@@ -17,18 +16,15 @@
  */
 class FirstRunPagerAdapter extends FragmentStatePagerAdapter {
     private final List<Callable<FirstRunPage>> mPages;
-    private final Bundle mFreProperties;
 
     private boolean mStopAtTheFirstPage;
 
-    public FirstRunPagerAdapter(FragmentManager fragmentManager,
-            List<Callable<FirstRunPage>> pages, Bundle freProperties) {
+    public FirstRunPagerAdapter(
+            FragmentManager fragmentManager, List<Callable<FirstRunPage>> pages) {
         super(fragmentManager);
         assert pages != null;
         assert pages.size() > 0;
-        assert freProperties != null;
         mPages = pages;
-        mFreProperties = freProperties;
     }
 
     /**
@@ -51,12 +47,6 @@
         } catch (Exception e) {
             // We can always return null and it will be properly handled at the caller level.
         }
-        if (result == null) return null;
-
-        Bundle props = new Bundle();
-        props.putAll(mFreProperties);
-        result.setArguments(props);
-
         return result;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
index 8006fb1..68d06cd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
@@ -4,7 +4,6 @@
 
 package org.chromium.chrome.browser.firstrun;
 
-import android.content.Context;
 import android.os.Bundle;
 import android.text.method.LinkMovementMethod;
 import android.view.LayoutInflater;
@@ -101,7 +100,8 @@
         };
 
         final CharSequence tosAndPrivacyText;
-        if (getProperties().getBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT)) {
+        Bundle freProperties = getPageDelegate().getProperties();
+        if (freProperties.getBoolean(AccountFirstRunFragment.IS_CHILD_ACCOUNT)) {
             tosAndPrivacyText =
                     SpanApplier.applySpans(getString(R.string.fre_tos_and_privacy_child_account),
                             new SpanInfo("<LINK1>", "</LINK1>", clickableTermsSpan),
@@ -147,7 +147,7 @@
     }
 
     @Override
-    public boolean shouldSkipPageOnCreate(Context appContext) {
+    public boolean shouldSkipPageOnCreate() {
         return FirstRunStatus.shouldSkipWelcomePage();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java
index 3bd44e2..95757ea 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java
@@ -671,6 +671,7 @@
         mBillingAddressField = EditorFieldModel.createDropdown(
                 mContext.getString(R.string.autofill_credit_card_editor_billing_address),
                 billingAddresses, mContext.getString(R.string.select));
+        mBillingAddressField.setDisplayPlusIcon(true);
 
         // The billing address is required.
         mBillingAddressField.setRequiredErrorMessage(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/AddressDropDownAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/AddressDropDownAdapter.java
deleted file mode 100644
index 1cd4d8e..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/AddressDropDownAdapter.java
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.payments.ui;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import org.chromium.base.ApiCompatibilityUtils;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.widget.TintedDrawable;
-import org.chromium.ui.UiUtils;
-
-import java.util.List;
-
-/**
- * Subclass of DropdownFieldAdapter used to display a dropdown hint that won't appear in the
- * expanded dropdown options but will be used when no element is selected. In some cases, the last
- * shown element will have a "+" icon on its left and a blue tint to indicate the option to add an
- * element.
- *
- * @param <T> The type of element to be inserted into the adapter.
- *
- *
- * collapsed view:       --------          Expanded view:   ------------
- * (no item selected)   | hint   |                         | option 1   |
- *                       --------                          |------------|
- *                                                         | option 2   |
- * collapsed view:       ----------                        |------------|
- * (with selected item) | option X |                       | + option N | -> stylized and "+" icon
- *                       ----------                        .------------.
- *                                                         . hint       . -> hidden
- *                                                         ..............
- */
-public class AddressDropDownAdapter<T> extends DropdownFieldAdapter<T> {
-    private final int mTextViewResourceId;
-    private boolean mAddButtonIncluded;
-
-    /**
-     * Creates an array adapter for which the last element is a hint that is not shown in the
-     * expanded view and where in some cases, the last shown element has a "+" icon on its left and
-     * has a blue tint.
-     *
-     * @param context            The current context.
-     * @param resource           The resource ID for a layout file containing a layout to use when
-     *                           instantiating views.
-     * @param textViewResourceId The id of the TextView within the layout resource to be populated.
-     * @param objects            The objects to represent in the ListView, in some cases, the last
-     *                           item will have a "+" icon on its left and will have a blue tint.
-     * @param hint               The element to be used as a hint when no element is selected. It is
-     *                           not taken into account in the count function and thus will not be
-     *                           displayed when in the expanded dropdown view.
-     */
-    public AddressDropDownAdapter(
-            Context context, int resource, int textViewResourceId, List<T> objects, T hint) {
-        // Make a copy of objects so the hint is not added to the original list.
-        super(context, resource, textViewResourceId, objects);
-        // The hint is added as the last element. It will not be shown when the dropdown is
-        // expanded and not be taken into account in the getCount function.
-        add(hint);
-
-        mTextViewResourceId = textViewResourceId;
-        // The "+" icon is displayed only when the last item is "Add Address."
-        mAddButtonIncluded = objects.get(getCount() - 1)
-                                     .toString()
-                                     .equals(context.getString(R.string.payments_add_address));
-    }
-
-    @Override
-    public int getCount() {
-        // Don't display last item, it is used as hint.
-        int count = super.getCount();
-        return count > 0 ? count - 1 : count;
-    }
-
-    @Override
-    public View getDropDownView(int position, View convertView, ViewGroup parent) {
-        TextView textView = convertView == null
-                ? null
-                : (TextView) convertView.findViewById(mTextViewResourceId);
-        if (textView != null) {
-            // Clear the possible changes for the first and last view.
-            ApiCompatibilityUtils.setPaddingRelative(convertView,
-                    ApiCompatibilityUtils.getPaddingStart(convertView), 0,
-                    ApiCompatibilityUtils.getPaddingEnd(convertView), 0);
-            textView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
-            ApiCompatibilityUtils.setTextAppearance(
-                    textView, android.R.style.TextAppearance_Widget_DropDownItem);
-        }
-        convertView = super.getDropDownView(position, convertView, parent);
-
-        if (position == 0) {
-            // Padding at the top of the dropdown.
-            ApiCompatibilityUtils.setPaddingRelative(convertView,
-                    ApiCompatibilityUtils.getPaddingStart(convertView),
-                    getContext().getResources().getDimensionPixelSize(
-                            R.dimen.payments_section_small_spacing),
-                    ApiCompatibilityUtils.getPaddingEnd(convertView),
-                    convertView.getPaddingBottom());
-        }
-        // When the last item is "ADD ADDRESS", show the "+" icon.
-        if (mAddButtonIncluded && position == getCount() - 1) {
-            // Add a "+" icon and a blue tint to the last element.
-            Resources resources = getContext().getResources();
-            if (textView == null) {
-                textView = (TextView) convertView.findViewById(mTextViewResourceId);
-            }
-
-            // Create the "+" icon, put it left of the text and add appropriate padding.
-            textView.setCompoundDrawablesWithIntrinsicBounds(
-                    TintedDrawable.constructTintedDrawable(
-                            resources, R.drawable.plus, R.color.light_active_color),
-                    null, null, null);
-            textView.setCompoundDrawablePadding(
-                    resources.getDimensionPixelSize(R.dimen.payments_section_large_spacing));
-
-            // Set the correct appearance, face and style for the text.
-            ApiCompatibilityUtils.setTextAppearance(
-                    textView, R.style.PaymentsUiSectionAddButtonLabel);
-            textView.setTypeface(UiUtils.createRobotoMediumTypeface());
-
-            // Padding at the bottom of the dropdown.
-            ApiCompatibilityUtils.setPaddingRelative(convertView,
-                    ApiCompatibilityUtils.getPaddingStart(convertView), convertView.getPaddingTop(),
-                    ApiCompatibilityUtils.getPaddingEnd(convertView),
-                    getContext().getResources().getDimensionPixelSize(
-                            R.dimen.payments_section_small_spacing));
-        }
-
-        return convertView;
-    }
-}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDropdownField.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDropdownField.java
index 8eae330d..255c33c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDropdownField.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDropdownField.java
@@ -6,6 +6,7 @@
 
 import android.annotation.SuppressLint;
 import android.content.Context;
+import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -35,6 +36,7 @@
     private final TextView mLabel;
     private final Spinner mDropdown;
     private int mSelectedIndex;
+    private ArrayAdapter<CharSequence> mAdapter;
     @Nullable
     private EditorObserverForTest mObserverForTest;
 
@@ -62,47 +64,56 @@
                         : mFieldModel.getLabel());
 
         final List<DropdownKeyValue> dropdownKeyValues = mFieldModel.getDropdownKeyValues();
-        mSelectedIndex = getDropdownIndex(dropdownKeyValues, mFieldModel.getValue());
-
         final List<CharSequence> dropdownValues = getDropdownValues(dropdownKeyValues);
-        ArrayAdapter<CharSequence> adapter;
         if (mFieldModel.getHint() != null) {
-            // Use the AddressDropDownAdapter and pass it a hint to be displayed as default.
-            adapter = new AddressDropDownAdapter<CharSequence>(context,
-                    R.layout.multiline_spinner_item, R.id.spinner_item, dropdownValues,
-                    mFieldModel.getHint().toString());
+            // Pass the hint to be displayed as default. If there is a '+' icon needed, use the
+            // appropriate class to display it.
+            if (mFieldModel.isDisplayPlusIcon()) {
+                mAdapter = new HintedDropDownAdapterWithPlusIcon<CharSequence>(context,
+                        R.layout.multiline_spinner_item, R.id.spinner_item, dropdownValues,
+                        mFieldModel.getHint().toString());
+            } else {
+                mAdapter = new HintedDropDownAdapter<CharSequence>(context,
+                        R.layout.multiline_spinner_item, R.id.spinner_item, dropdownValues,
+                        mFieldModel.getHint().toString());
+            }
             // Wrap the TextView in the dropdown popup around with a FrameLayout to display the text
             // in multiple lines.
             // Note that the TextView in the dropdown popup is displayed in a DropDownListView for
             // the dropdown style Spinner and the DropDownListView sets to display TextView instance
             // in a single line.
-            adapter.setDropDownViewResource(R.layout.payment_request_dropdown_item);
-
-            // If no value is selected, select the hint entry which is the last item in the adapter.
-            // Using getCount will not result in an out of bounds index because the hint value is
-            // ommited in the count.
-            if (mFieldModel.getValue() == null || mFieldModel.getValue().length() == 0) {
-                mSelectedIndex = adapter.getCount();
-            }
+            mAdapter.setDropDownViewResource(R.layout.payment_request_dropdown_item);
         } else {
-            adapter = new DropdownFieldAdapter<CharSequence>(
+            mAdapter = new DropdownFieldAdapter<CharSequence>(
                     context, R.layout.multiline_spinner_item, dropdownValues);
-            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+            mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
         }
 
+        // If no value is selected, we'll  select the hint, which is the first item on the dropdown
+        // adapter.
+        mSelectedIndex = TextUtils.isEmpty(mFieldModel.getValue())
+                ? 0
+                : mAdapter.getPosition(
+                          mFieldModel.getDropdownValueByKey((mFieldModel.getValue().toString())));
+
+        assert mSelectedIndex >= 0;
+
         mDropdown = (Spinner) mLayout.findViewById(R.id.spinner);
         mDropdown.setTag(this);
         mDropdown.setContentDescription(mFieldModel.getLabel());
-        mDropdown.setAdapter(adapter);
+        mDropdown.setAdapter(mAdapter);
         mDropdown.setSelection(mSelectedIndex);
         mDropdown.setOnItemSelectedListener(new OnItemSelectedListener() {
             @Override
             public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                 if (mSelectedIndex != position) {
+                    String key = mFieldModel.getDropdownKeyByValue(mAdapter.getItem(position));
+                    // If the hint is selected, it means that no value is entered by the user.
+                    if (mFieldModel.getHint() != null && position == 0) {
+                        key = null;
+                    }
                     mSelectedIndex = position;
-                    mFieldModel.setDropdownKey(
-                            mFieldModel.getDropdownKeyValues().get(position).getKey(),
-                            changedCallback);
+                    mFieldModel.setDropdownKey(key, changedCallback);
                 }
                 if (mObserverForTest != null) {
                     mObserverForTest.onEditorTextUpdate();
@@ -112,7 +123,6 @@
             @Override
             public void onNothingSelected(AdapterView<?> parent) {}
         });
-        final int count = adapter.getCount();
         mDropdown.setOnTouchListener(new View.OnTouchListener() {
             @SuppressLint("ClickableViewAccessibility")
             @Override
@@ -172,15 +182,13 @@
 
     @Override
     public void update() {
-        // If the adapter supports a hint and no value was selected, select the hint.
-        if (mFieldModel.getHint() != null && mFieldModel.getValue() == null) {
-            // The hint is hidden right after the last element.
-            mSelectedIndex = mFieldModel.getDropdownKeyValues().size();
-        } else {
-            mSelectedIndex =
-                getDropdownIndex(mFieldModel.getDropdownKeyValues(), mFieldModel.getValue());
-        }
-
+        // If no value is selected, we'll  select the hint, which is the first item on the dropdown
+        // adapter.
+        mSelectedIndex = TextUtils.isEmpty(mFieldModel.getValue())
+                ? 0
+                : mAdapter.getPosition(
+                          mFieldModel.getDropdownValueByKey((mFieldModel.getValue().toString())));
+        assert mSelectedIndex >= 0;
         mDropdown.setSelection(mSelectedIndex);
     }
 
@@ -191,12 +199,4 @@
         }
         return dropdownValues;
     }
-
-    private static int getDropdownIndex(
-            List<DropdownKeyValue> dropdownKeyValues, CharSequence value) {
-        for (int i = 0; i < dropdownKeyValues.size(); i++) {
-            if (dropdownKeyValues.get(i).getKey().equals(value)) return i;
-        }
-        return 0;
-    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorFieldModel.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorFieldModel.java
index 6617d34f..c480596 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorFieldModel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorFieldModel.java
@@ -13,6 +13,7 @@
 import org.chromium.chrome.browser.preferences.autofill.AutofillProfileBridge.DropdownKeyValue;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -117,6 +118,10 @@
     @Nullable private List<Integer> mIconResourceIds;
     @Nullable private List<Integer> mIconDescriptionsForAccessibility;
     @Nullable private List<DropdownKeyValue> mDropdownKeyValues;
+    @Nullable
+    private HashMap<String, CharSequence> mDropdownKeyToValueMap;
+    @Nullable
+    private HashMap<CharSequence, String> mDropdownValueToKeyMap;
     @Nullable private Set<String> mDropdownKeys;
     @Nullable private List<CharSequence> mSuggestions;
     @Nullable
@@ -137,6 +142,7 @@
     private int mActionIconResourceId;
     private int mActionIconDescriptionForAccessibility;
     private boolean mIsFullLine = true;
+    private boolean mPlusIconIsDisplayed = false;
 
     /**
      * Constructs a label to show in the editor. This can be, for example, description of a server
@@ -401,17 +407,70 @@
         return mDropdownKeys;
     }
 
+    /**
+     * In the dropdown list, finds the key that corresponds to the value.
+     * If the value is not in the list, returns null.
+     * This assumes a one-to-one relation between keys and values.
+     *
+     * @param value The value to lookup.
+     * @return The key that corresponds to the value.
+     */
+    @Nullable
+    public String getDropdownKeyByValue(@Nullable CharSequence value) {
+        assert mInputTypeHint == INPUT_TYPE_HINT_DROPDOWN;
+        return mDropdownValueToKeyMap.get(value);
+    }
+
+    /**
+     * In the dropdown list, finds the value that corresponds to the key.
+     * If the key is not in the list, returns null.
+     * This assumes a one-to-one relation between keys and values.
+     *
+     * @param key The key to lookup.
+     * @return The value that corresponds to the key.
+     */
+    @Nullable
+    public CharSequence getDropdownValueByKey(@Nullable String key) {
+        assert mInputTypeHint == INPUT_TYPE_HINT_DROPDOWN;
+        return mDropdownKeyToValueMap.get(key);
+    }
+
     /** Updates the dropdown key values. */
     public void setDropdownKeyValues(List<DropdownKeyValue> dropdownKeyValues) {
         assert mInputTypeHint == INPUT_TYPE_HINT_DROPDOWN;
         mDropdownKeyValues = dropdownKeyValues;
         mDropdownKeys = new HashSet<>();
+        mDropdownKeyToValueMap = new HashMap<>();
+        mDropdownValueToKeyMap = new HashMap<>();
         for (int i = 0; i < mDropdownKeyValues.size(); i++) {
             mDropdownKeys.add(mDropdownKeyValues.get(i).getKey());
+            mDropdownValueToKeyMap.put(
+                    mDropdownKeyValues.get(i).getValue(), mDropdownKeyValues.get(i).getKey());
+            mDropdownKeyToValueMap.put(
+                    mDropdownKeyValues.get(i).getKey(), mDropdownKeyValues.get(i).getValue());
         }
         assert mDropdownKeyValues.size() == mDropdownKeys.size();
     }
 
+    /**
+     * @return True if the last visible item on the dropdown list, needs a '+' icon on the right.
+     */
+    public boolean isDisplayPlusIcon() {
+        assert mInputTypeHint == INPUT_TYPE_HINT_DROPDOWN;
+        return mPlusIconIsDisplayed;
+    }
+
+    /**
+     * Sets whether the last item of this dropdown list needs a '+' icon on the right. By
+     * default, the item doesn't need that.
+     *
+     * @param plusIconIsDisplayed Whether the last item of the this dropdown list needs a '+' icon.
+     */
+    public void setDisplayPlusIcon(boolean plusIconIsDisplayed) {
+        assert mInputTypeHint == INPUT_TYPE_HINT_DROPDOWN;
+        mPlusIconIsDisplayed = plusIconIsDisplayed;
+    }
+
     /** @return The human-readable label for this field. */
     public CharSequence getLabel() {
         return mLabel;
@@ -483,8 +542,12 @@
      * @param key      The new dropdown key.
      * @param callback The callback to invoke when the change has been processed.
      */
-    public void setDropdownKey(String key, Runnable callback) {
+    public void setDropdownKey(@Nullable String key, Runnable callback) {
         assert mInputTypeHint == INPUT_TYPE_HINT_DROPDOWN;
+        // The mValue can only be set to null if there is a hint.
+        if (key == null && mHint == null) {
+            return;
+        }
         mValue = key;
         if (mDropdownCallback != null) {
             mDropdownCallback.onResult(new Pair<String, Runnable>(key, callback));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/HintedDropDownAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/HintedDropDownAdapter.java
new file mode 100644
index 0000000..f7d8adf8e
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/HintedDropDownAdapter.java
@@ -0,0 +1,84 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.payments.ui;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.chrome.R;
+
+import java.util.List;
+
+/**
+ * Subclass of DropdownFieldAdapter used to display a hinted dropdown. The hint will be used when no
+ * element is selected.
+ *
+ * @param <T> The type of element to be inserted into the adapter.
+ *
+ *
+ * collapsed view:       --------          Expanded view:   ------------
+ *                                                         . hint       .
+ *                                                         ..............
+ * (no item selected)   | hint   |                         | option 1   |
+ *                       --------                          |------------|
+ *                                                         | option 2   |
+ * collapsed view:       ----------                        |------------|
+ * (with selected item) | option X |                       .    ...     .
+ *                       ----------                        .------------.
+ */
+public class HintedDropDownAdapter<T> extends DropdownFieldAdapter<T> {
+    protected final int mTextViewResourceId;
+    protected TextView mTextView;
+
+    /**
+     * Creates an array adapter for which the first element is a hint.
+     *
+     * @param context            The current context.
+     * @param resource           The resource ID for a layout file containing a layout to use when
+     *                           instantiating views.
+     * @param textViewResourceId The id of the TextView within the layout resource to be populated.
+     * @param objects            The objects to represent in the ListView.
+     * @param hint               The element to be used as a hint when no element is selected.
+     */
+    public HintedDropDownAdapter(
+            Context context, int resource, int textViewResourceId, List<T> objects, T hint) {
+        // Make a copy of objects so the hint is not added to the original list.
+        super(context, resource, textViewResourceId, objects);
+        // The hint is added as the first element.
+        insert(hint, 0);
+
+        mTextViewResourceId = textViewResourceId;
+    }
+
+    @Override
+    public View getDropDownView(int position, View convertView, ViewGroup parent) {
+        mTextView = convertView == null ? null
+                                        : (TextView) convertView.findViewById(mTextViewResourceId);
+        if (mTextView != null) {
+            // Clear the possible changes for the first and last view.
+            ApiCompatibilityUtils.setPaddingRelative(convertView,
+                    ApiCompatibilityUtils.getPaddingStart(convertView), 0,
+                    ApiCompatibilityUtils.getPaddingEnd(convertView), 0);
+            mTextView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+            ApiCompatibilityUtils.setTextAppearance(
+                    mTextView, android.R.style.TextAppearance_Widget_DropDownItem);
+        }
+        convertView = super.getDropDownView(position, convertView, parent);
+
+        if (position == 0) {
+            // Padding at the top of the dropdown.
+            ApiCompatibilityUtils.setPaddingRelative(convertView,
+                    ApiCompatibilityUtils.getPaddingStart(convertView),
+                    getContext().getResources().getDimensionPixelSize(
+                            R.dimen.payments_section_small_spacing),
+                    ApiCompatibilityUtils.getPaddingEnd(convertView),
+                    convertView.getPaddingBottom());
+        }
+        return convertView;
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/HintedDropDownAdapterWithPlusIcon.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/HintedDropDownAdapterWithPlusIcon.java
new file mode 100644
index 0000000..dc5926e
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/HintedDropDownAdapterWithPlusIcon.java
@@ -0,0 +1,91 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.payments.ui;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.widget.TintedDrawable;
+import org.chromium.ui.UiUtils;
+
+import java.util.List;
+
+/**
+ * Subclass of HintedDropDownAdapter used to display a hinted dropdown . The last
+ * displayed element on the list will have a "+" icon on its left and a blue tint to indicate that
+ * the option is for adding an element.
+ *
+ * @param <T> The type of element to be inserted into the adapter.
+ *
+ *
+ * collapsed view:       --------          Expanded view:   ------------
+ *                                                         . hint       .
+ *                                                         ..............
+ * (no item selected)   | hint   |                         | option 1   |
+ *                       --------                          |------------|
+ *                                                         | option 2   |
+ * collapsed view:       ----------                        |------------|
+ * (with selected item) | option X |                       | + option N | -> stylized and "+" icon
+ *                       ----------                        .------------.
+ */
+public class HintedDropDownAdapterWithPlusIcon<T> extends HintedDropDownAdapter<T> {
+    /**
+     * Creates an array adapter for which the first element is a hint and where the
+     * last displayed element has a "+" icon on its left and has a blue tint.
+     *
+     * @param context            The current context.
+     * @param resource           The resource ID for a layout file containing a layout to use when
+     *                           instantiating views.
+     * @param mTextViewResourceId The id of the TextView within the layout resource to be populated.
+     * @param objects            The objects to represent in the ListView, the last
+     *                           item will have a "+" icon on its left and will have a blue tint.
+     * @param hint               The element to be used as a hint when no element is selected.
+     */
+    public HintedDropDownAdapterWithPlusIcon(
+            Context context, int resource, int textViewResourceId, List<T> objects, T hint) {
+        super(context, resource, textViewResourceId, objects, hint);
+    }
+
+    @Override
+    public View getDropDownView(int position, View convertView, ViewGroup parent) {
+        convertView = super.getDropDownView(position, convertView, parent);
+
+        // The plus icon is for the last item on the list.
+        if (position == getCount() - 1) {
+            // Add a "+" icon and a blue tint to the last element.
+            Resources resources = getContext().getResources();
+            if (mTextView == null) {
+                mTextView = (TextView) convertView.findViewById(mTextViewResourceId);
+            }
+
+            // Create the "+" icon, put it left of the text and add appropriate padding.
+            mTextView.setCompoundDrawablesWithIntrinsicBounds(
+                    TintedDrawable.constructTintedDrawable(
+                            resources, R.drawable.plus, R.color.light_active_color),
+                    null, null, null);
+            mTextView.setCompoundDrawablePadding(
+                    resources.getDimensionPixelSize(R.dimen.payments_section_large_spacing));
+
+            // Set the correct appearance, face and style for the text.
+            ApiCompatibilityUtils.setTextAppearance(
+                    mTextView, R.style.PaymentsUiSectionAddButtonLabel);
+            mTextView.setTypeface(UiUtils.createRobotoMediumTypeface());
+
+            // Padding at the bottom of the dropdown.
+            ApiCompatibilityUtils.setPaddingRelative(convertView,
+                    ApiCompatibilityUtils.getPaddingStart(convertView), convertView.getPaddingTop(),
+                    ApiCompatibilityUtils.getPaddingEnd(convertView),
+                    getContext().getResources().getDimensionPixelSize(
+                            R.dimen.payments_section_small_spacing));
+        }
+
+        return convertView;
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java
index 2c6ed38..127dbe36 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java
@@ -958,6 +958,24 @@
         nativeMoveAcceptLanguage(languageCode, offset);
     }
 
+    /**
+     * @param languageCode A valid language code to check.
+     * @return Whether the given language is blocked by the user.
+     */
+    public boolean isBlockedLanguage(String languageCode) {
+        return nativeIsBlockedLanguage(languageCode);
+    }
+
+    /**
+     * Sets the blocked state of a given language.
+     *
+     * @param languageCode A valid language code to change.
+     * @param blocked Whether to set language blocked.
+     */
+    public void setLanguageBlockedState(String languageCode, boolean blocked) {
+        nativeSetLanguageBlockedState(languageCode, blocked);
+    }
+
     private native boolean nativeIsContentSettingEnabled(int contentSettingType);
     private native boolean nativeIsContentSettingManaged(int contentSettingType);
     private native void nativeSetContentSettingEnabled(int contentSettingType, boolean allow);
@@ -1146,6 +1164,8 @@
     private native void nativeGetUserAcceptLanguages(List<String> list);
     private native void nativeUpdateUserAcceptLanguages(String language, boolean add);
     private native void nativeMoveAcceptLanguage(String language, int offset);
+    private native boolean nativeIsBlockedLanguage(String language);
+    private native void nativeSetLanguageBlockedState(String language, boolean blocked);
     private native String nativeGetDownloadDefaultDirectory();
     private native void nativeSetDownloadDefaultDirectory(String directory);
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/languages/LanguageListPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/languages/LanguageListPreference.java
index 3a2da40..bc9798d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/languages/LanguageListPreference.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/languages/LanguageListPreference.java
@@ -49,8 +49,14 @@
                     ArrayList<Item> menuItems = new ArrayList<>();
                     // Show "Offer to translate" option if "Chrome Translate" is enabled.
                     if (PrefServiceBridge.getInstance().isTranslateEnabled()) {
+                        // Set this row checked if the language is unblocked.
+                        int endIconResId =
+                                PrefServiceBridge.getInstance().isBlockedLanguage(info.getCode())
+                                ? 0
+                                : R.drawable.ic_check_googblue_24dp;
+                        // Add checked icon at the end.
                         menuItems.add(new Item(mContext,
-                                R.string.languages_item_option_offer_to_translate,
+                                R.string.languages_item_option_offer_to_translate, endIconResId,
                                 info.isSupported()));
                     }
 
@@ -64,7 +70,10 @@
                 @Override
                 public void onItemSelected(Item item) {
                     if (item.getTextId() == R.string.languages_item_option_offer_to_translate) {
-                        // TODO(crbug/783049): Handle "offer to translate" event.
+                        // Toggle current blocked state of this language.
+                        boolean state = (item.getEndIconId() == 0);
+                        PrefServiceBridge.getInstance().setLanguageBlockedState(
+                                info.getCode(), !state);
                     } else if (item.getTextId() == R.string.remove) {
                         LanguagesManager.getInstance().removeFromAcceptLanguages(info.getCode());
                     }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index f838d7b..9d87fc7 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -846,7 +846,8 @@
   "java/src/org/chromium/chrome/browser/payments/ShippingStrings.java",
   "java/src/org/chromium/chrome/browser/payments/SslValidityChecker.java",
   "java/src/org/chromium/chrome/browser/payments/UriUtils.java",
-  "java/src/org/chromium/chrome/browser/payments/ui/AddressDropDownAdapter.java",
+  "java/src/org/chromium/chrome/browser/payments/ui/HintedDropDownAdapter.java",
+  "java/src/org/chromium/chrome/browser/payments/ui/HintedDropDownAdapterWithPlusIcon.java",
   "java/src/org/chromium/chrome/browser/payments/ui/Completable.java",
   "java/src/org/chromium/chrome/browser/payments/ui/ContactDetailsSection.java",
   "java/src/org/chromium/chrome/browser/payments/ui/DropdownFieldAdapter.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressTest.java
index d4555ba..21bd421 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressTest.java
@@ -43,7 +43,7 @@
      * The index at which the option to add a billing address is located in the billing address
      * selection dropdown.
      */
-    private static final int ADD_BILLING_ADDRESS = 7;
+    private static final int ADD_BILLING_ADDRESS = 8;
 
     /** The index of the billing address dropdown in the card editor. */
     private static final int BILLING_ADDRESS_DROPDOWN_INDEX = 2;
@@ -147,9 +147,9 @@
         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
                 R.id.payments_add_option_button, mPaymentRequestTestRule.getReadyToEdit());
 
-        // There should only be 8 suggestions, the 7 saved addresses and the option to add a new
-        // address.
-        Assert.assertEquals(8,
+        // There should only be 9 suggestions, the 7 saved addresses, the select hint and the
+        // option to add a new address.
+        Assert.assertEquals(9,
                 mPaymentRequestTestRule.getSpinnerItemCountInCardEditor(
                         BILLING_ADDRESS_DROPDOWN_INDEX));
     }
@@ -178,10 +178,9 @@
         // Cancel the creation of a new billing address.
         mPaymentRequestTestRule.clickInEditorAndWait(
                 R.id.payments_edit_cancel_button, mPaymentRequestTestRule.getReadyToEdit());
-
-        // There should still only be 8 suggestions, the 7 saved addresses and the option to add a
-        // new address.
-        Assert.assertEquals(8,
+        // There should still only be 9 suggestions, the 7 saved addresses, the select hint and
+        // the option to add a new address.
+        Assert.assertEquals(9,
                 mPaymentRequestTestRule.getSpinnerItemCountInCardEditor(
                         BILLING_ADDRESS_DROPDOWN_INDEX));
     }
@@ -276,8 +275,9 @@
         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
                 R.id.payments_add_option_button, mPaymentRequestTestRule.getReadyToEdit());
 
-        // There should be 8 suggestions, the 7 saved addresses and the option to add a new address.
-        Assert.assertEquals(8,
+        // There should be 9 suggestions, the 7 saved addresses, the select hint and the option to
+        // add a new address.
+        Assert.assertEquals(9,
                 mPaymentRequestTestRule.getSpinnerItemCountInCardEditor(
                         BILLING_ADDRESS_DROPDOWN_INDEX));
 
@@ -285,18 +285,22 @@
         Assert.assertTrue(
                 mPaymentRequestTestRule
                         .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 0)
-                        .equals("Rob Doe, 340 Main St, Los Angeles, CA 90291"));
+                        .equals("Select"));
         Assert.assertTrue(
                 mPaymentRequestTestRule
                         .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 1)
-                        .equals("Jon Doe, 340 Main St, Los Angeles, CA 90291"));
+                        .equals("Rob Doe, 340 Main St, Los Angeles, CA 90291"));
         Assert.assertTrue(
                 mPaymentRequestTestRule
                         .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 2)
+                        .equals("Jon Doe, 340 Main St, Los Angeles, CA 90291"));
+        Assert.assertTrue(
+                mPaymentRequestTestRule
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 3)
                         .equals("Tom Doe, 340 Main St, Los Angeles, CA 90291"));
         Assert.assertTrue(
                 mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 7)
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 8)
                         .equals("Add address"));
     }
 
@@ -327,34 +331,38 @@
         mPaymentRequestTestRule.clickInEditorAndWait(
                 R.id.payments_edit_done_button, mPaymentRequestTestRule.getReadyToEdit());
 
-        // There should be 9 suggestions, the 7 initial addresses, the newly added address and the
-        // option to add a new address.
-        Assert.assertEquals(9,
+        // There should be 10 suggestions, the 7 initial addresses, the newly added address, the
+        // select hint and the option to add a new address.
+        Assert.assertEquals(10,
                 mPaymentRequestTestRule.getSpinnerItemCountInCardEditor(
                         BILLING_ADDRESS_DROPDOWN_INDEX));
 
-        // The fist suggestion should be the newly added address.
         Assert.assertTrue(
                 mPaymentRequestTestRule
                         .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 0)
+                        .equals("Select"));
+        // The fist address suggestion should be the newly added address.
+        Assert.assertTrue(
+                mPaymentRequestTestRule
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 1)
                         .equals("Seb Doe, 340 Main St, Los Angeles, CA 90291"));
 
         // The rest of the billing address suggestions should be ordered by frecency.
         Assert.assertTrue(
                 mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 1)
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 2)
                         .equals("Rob Doe, 340 Main St, Los Angeles, CA 90291"));
         Assert.assertTrue(
                 mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 2)
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 3)
                         .equals("Jon Doe, 340 Main St, Los Angeles, CA 90291"));
         Assert.assertTrue(
                 mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 3)
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 4)
                         .equals("Tom Doe, 340 Main St, Los Angeles, CA 90291"));
         Assert.assertTrue(
                 mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 8)
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 9)
                         .equals("Add address"));
     }
 
@@ -387,17 +395,18 @@
         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
                 R.id.payments_add_option_button, mPaymentRequestTestRule.getReadyToEdit());
 
-        // There should be 9 suggestions, the 7 initial addresses, the newly added address and the
-        // option to add a new address.
-        Assert.assertEquals(9,
+        // There should be 10 suggestions, the 7 initial addresses, the newly added address, the
+        // select hint and the option to add a new address.
+        Assert.assertEquals(10,
                 mPaymentRequestTestRule.getSpinnerItemCountInCardEditor(
                         BILLING_ADDRESS_DROPDOWN_INDEX));
 
-        // The new address should be suggested first.
-        Assert.assertTrue(
-                mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 0)
-                        .equals("Seb Doe, 340 Main St, Los Angeles, CA 90291"));
+        // The new address must be put at the top of the dropdown list, right after the
+        // select hint.
+        Assert.assertTrue(mPaymentRequestTestRule
+                                  .getSpinnerTextAtPositionInCardEditor(
+                                          BILLING_ADDRESS_DROPDOWN_INDEX, FIRST_BILLING_ADDRESS)
+                                  .equals("Seb Doe, 340 Main St, Los Angeles, CA 90291"));
     }
 
     @Test
@@ -421,21 +430,21 @@
         // The incomplete addresses in the dropdown contain edit required messages.
         Assert.assertTrue(
                 mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 4)
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 5)
                         .endsWith("Name required"));
         Assert.assertTrue(
                 mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 5)
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 6)
                         .endsWith("More information required"));
         Assert.assertTrue(
                 mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 6)
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 7)
                         .endsWith("Enter a valid address"));
 
-        // Selects the fourth billing addresss that misses recipient name brings up the address
-        // editor.
+        // Selects the fourth billing address (the 5th option on the dropdown list) that misses
+        // recipient name brings up the address editor.
         mPaymentRequestTestRule.setSpinnerSelectionsInCardEditorAndWait(
-                new int[] {DECEMBER, NEXT_YEAR, 4}, mPaymentRequestTestRule.getReadyToEdit());
+                new int[] {DECEMBER, NEXT_YEAR, 5}, mPaymentRequestTestRule.getReadyToEdit());
         mPaymentRequestTestRule.setTextInEditorAndWait(
                 new String[] {"Lisa Doh", "Google", "340 Main St", "Los Angeles", "CA", "90291",
                         "650-253-0000"},
@@ -443,15 +452,17 @@
         mPaymentRequestTestRule.clickInEditorAndWait(
                 R.id.payments_edit_done_button, mPaymentRequestTestRule.getReadyToEdit());
 
-        // The newly completed address must be selected and put at the top of the dropdown.
+        // The newly completed address must be selected and put at the top of the dropdown list,
+        // right after the select hint.
         Assert.assertTrue(
                 mPaymentRequestTestRule
                         .getSpinnerSelectionTextInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX)
                         .equals("Lisa Doh, 340 Main St, Los Angeles, CA 90291"));
-        Assert.assertTrue(
-                mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 0)
-                        .equals("Lisa Doh, 340 Main St, Los Angeles, CA 90291"));
+
+        Assert.assertTrue(mPaymentRequestTestRule
+                                  .getSpinnerTextAtPositionInCardEditor(
+                                          BILLING_ADDRESS_DROPDOWN_INDEX, FIRST_BILLING_ADDRESS)
+                                  .equals("Lisa Doh, 340 Main St, Los Angeles, CA 90291"));
     }
 
     @Test
@@ -475,21 +486,21 @@
         // The incomplete addresses in the dropdown contain edit required messages.
         Assert.assertTrue(
                 mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 4)
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 5)
                         .endsWith("Name required"));
         Assert.assertTrue(
                 mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 5)
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 6)
                         .endsWith("More information required"));
         Assert.assertTrue(
                 mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 6)
+                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 7)
                         .endsWith("Enter a valid address"));
 
-        // Selects the fifth billing addresss that misses recipient name brings up the address
-        // editor.
+        // Selects the forth billing address (the 5th option on the dropdown list) that misses
+        // recipient name brings up the address editor.
         mPaymentRequestTestRule.setSpinnerSelectionsInCardEditorAndWait(
-                new int[] {DECEMBER, NEXT_YEAR, 4}, mPaymentRequestTestRule.getReadyToEdit());
+                new int[] {DECEMBER, NEXT_YEAR, 5}, mPaymentRequestTestRule.getReadyToEdit());
         mPaymentRequestTestRule.clickInEditorAndWait(
                 R.id.payments_edit_cancel_button, mPaymentRequestTestRule.getReadyToEdit());
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressWithoutPhoneTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressWithoutPhoneTest.java
index 1ec6386..cef8e22 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressWithoutPhoneTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBillingAddressWithoutPhoneTest.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.payments;
 
 import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.DECEMBER;
+import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.FIRST_BILLING_ADDRESS;
 import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.NEXT_YEAR;
 
 import android.content.DialogInterface;
@@ -43,7 +44,7 @@
      * The index at which the option to add a billing address is located in the billing address
      * selection dropdown.
      */
-    private static final int ADD_BILLING_ADDRESS = 2;
+    private static final int ADD_BILLING_ADDRESS = 3;
 
     /** The index of the billing address dropdown in the card editor. */
     private static final int BILLING_ADDRESS_DROPDOWN_INDEX = 2;
@@ -103,11 +104,11 @@
                         .equals("Jon NoPhone, 340 Main St, Los Angeles, CA 90291"));
 
         // Even though the current billing address is valid, the one with a phone number should be
-        // suggested first if the user wants to change it.
-        Assert.assertTrue(
-                mPaymentRequestTestRule
-                        .getSpinnerTextAtPositionInCardEditor(BILLING_ADDRESS_DROPDOWN_INDEX, 0)
-                        .equals("Rob Phone, 340 Main St, Los Angeles, CA 90291"));
+        // suggested first (right after the select hint) if the user wants to change it.
+        Assert.assertTrue(mPaymentRequestTestRule
+                                  .getSpinnerTextAtPositionInCardEditor(
+                                          BILLING_ADDRESS_DROPDOWN_INDEX, FIRST_BILLING_ADDRESS)
+                                  .equals("Rob Phone, 340 Main St, Los Angeles, CA 90291"));
     }
 
     @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java
index 517b0bb..28ed8aee5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestCanMakePaymentMetricsTest.java
@@ -4,8 +4,11 @@
 
 package org.chromium.chrome.browser.payments;
 
+import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.DECEMBER;
+import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.FIRST_BILLING_ADDRESS;
 import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.HAVE_INSTRUMENTS;
 import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.IMMEDIATE_RESPONSE;
+import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.NEXT_YEAR;
 
 import android.content.DialogInterface;
 import android.support.test.filters.MediumTest;
@@ -95,7 +98,8 @@
         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
                 R.id.payments_section, mPaymentRequestTestRule.getReadyToEdit());
         mPaymentRequestTestRule.setSpinnerSelectionsInCardEditorAndWait(
-                new int[] {11, 1, 0}, mPaymentRequestTestRule.getBillingAddressChangeProcessed());
+                new int[] {DECEMBER, NEXT_YEAR, FIRST_BILLING_ADDRESS},
+                mPaymentRequestTestRule.getBillingAddressChangeProcessed());
         mPaymentRequestTestRule.setTextInCardEditorAndWait(
                 new String[] {"4111111111111111", "Jon Doe"},
                 mPaymentRequestTestRule.getEditorTextUpdate());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExpiredLocalCardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExpiredLocalCardTest.java
index ac0dc223..e3f3a54 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExpiredLocalCardTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExpiredLocalCardTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.payments;
 
+import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.FIRST_BILLING_ADDRESS;
+
 import android.content.DialogInterface;
 import android.support.test.filters.MediumTest;
 
@@ -116,7 +118,8 @@
         mRule.clickInPaymentMethodAndWait(R.id.payments_section, mRule.getReadyForInput());
         mRule.clickInPaymentMethodAndWait(R.id.payments_add_option_button, mRule.getReadyToEdit());
         // Set the expiration date to past month of the current year.
-        mRule.setSpinnerSelectionsInCardEditorAndWait(new int[] {now.get(Calendar.MONTH) - 1, 0, 0},
+        mRule.setSpinnerSelectionsInCardEditorAndWait(
+                new int[] {now.get(Calendar.MONTH) - 1, 0, FIRST_BILLING_ADDRESS},
                 mRule.getBillingAddressChangeProcessed());
         mRule.setTextInCardEditorAndWait(
                 new String[] {"4111111111111111", "Jon Doe"}, mRule.getEditorTextUpdate());
@@ -125,7 +128,8 @@
 
         // Set the expiration date to the current month of the current year.
         mRule.setSpinnerSelectionsInCardEditorAndWait(
-                new int[] {now.get(Calendar.MONTH), 0, 0}, mRule.getExpirationMonthChange());
+                new int[] {now.get(Calendar.MONTH), 0, FIRST_BILLING_ADDRESS},
+                mRule.getExpirationMonthChange());
 
         mRule.clickInCardEditorAndWait(R.id.payments_edit_done_button, mRule.getReadyToPay());
     }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteServerCardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteServerCardTest.java
index 51d4868..1d6b236 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteServerCardTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteServerCardTest.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.payments;
 
+import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.FIRST_BILLING_ADDRESS;
+
 import android.content.DialogInterface;
 import android.support.test.filters.MediumTest;
 
@@ -35,8 +37,6 @@
     public PaymentRequestTestRule mPaymentRequestTestRule =
             new PaymentRequestTestRule("payment_request_no_shipping_test.html", this);
 
-    private static final int FIRST_BILLING_ADDRESS = 0;
-
     @Override
     public void onMainActivityStarted()
             throws InterruptedException, ExecutionException, TimeoutException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java
index b44b827..cb4a607 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestJourneyLoggerTest.java
@@ -4,9 +4,12 @@
 
 package org.chromium.chrome.browser.payments;
 
+import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.DECEMBER;
 import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.DELAYED_RESPONSE;
+import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.FIRST_BILLING_ADDRESS;
 import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.HAVE_INSTRUMENTS;
 import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.IMMEDIATE_RESPONSE;
+import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.NEXT_YEAR;
 import static org.chromium.chrome.browser.payments.PaymentRequestTestRule.NO_INSTRUMENTS;
 
 import android.content.DialogInterface;
@@ -358,7 +361,8 @@
         mPaymentRequestTestRule.clickInPaymentMethodAndWait(
                 R.id.payments_add_option_button, mPaymentRequestTestRule.getReadyToEdit());
         mPaymentRequestTestRule.setSpinnerSelectionsInCardEditorAndWait(
-                new int[] {11, 1, 0}, mPaymentRequestTestRule.getBillingAddressChangeProcessed());
+                new int[] {DECEMBER, NEXT_YEAR, FIRST_BILLING_ADDRESS},
+                mPaymentRequestTestRule.getBillingAddressChangeProcessed());
         mPaymentRequestTestRule.setTextInCardEditorAndWait(
                 new String[] {"4111111111111111", "Jon Doe"},
                 mPaymentRequestTestRule.getEditorTextUpdate());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java
index abfb8a3..2f2a8c8c4 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java
@@ -242,7 +242,7 @@
 
         // Select December of next year for expiration and [Add address] in the billing address
         // dropdown.
-        int addBillingAddress = 1;
+        int addBillingAddress = 2;
         mPaymentRequestTestRule.setSpinnerSelectionsInCardEditorAndWait(
                 new int[] {DECEMBER, NEXT_YEAR, addBillingAddress},
                 mPaymentRequestTestRule.getReadyToEdit());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestCommon.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestCommon.java
index 7d93774b..12738d2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestCommon.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestCommon.java
@@ -78,8 +78,9 @@
     /** The expiration year dropdown index for the next year. */
     static final int NEXT_YEAR = 1;
 
-    /** The billing address dropdown index for the first billing address. */
-    static final int FIRST_BILLING_ADDRESS = 0;
+    /** The billing address dropdown index for the first billing address. Index 0 is for the
+     * "Select" hint.*/
+    static final int FIRST_BILLING_ADDRESS = 1;
 
     final PaymentsCallbackHelper<PaymentRequestUI> mReadyForInput;
     final PaymentsCallbackHelper<PaymentRequestUI> mReadyToPay;
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index 07aa5cca..7e69045c 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -213,19 +213,8 @@
       <message name="IDS_ABOUT_TERMS_OF_SERVICE" desc="The terms of service label in the About box." translateable="false">
         Not used in Chromium. Placeholder to keep resource maps in sync. It expects one argument: <ph name="ARGUMENT">$1</ph>.
       </message>
-      <if expr="is_macosx">
-        <message name="IDS_MAC_10_678_OBSOLETE_SOON" desc="A message displayed on an at-launch infobar and About (Help) page warning the user that the OS version they are using is about to become unsupported.">
-          Future versions of Chromium will no longer support Mac OS X 10.6, 10.7, or 10.8.
-        </message>
-        <message name="IDS_MAC_10_678_OBSOLETE_NOW" desc="A message displayed on an at-launch infobar and About (Help) page warning the user that the OS version they are using is no longer supported.">
-          Chromium may not function correctly because it is no longer supported on Mac OS X 10.6, 10.7, or 10.8.
-        </message>
-      </if>
       <if expr="is_win">
-        <message name="IDS_WIN_XP_VISTA_OBSOLETE_SOON" desc="A message displayed on an at-launch infobar and about:help warning the user that the computer they are using is about to become unsupported.">
-          Future versions of Chromium will no longer support Windows XP or Windows Vista.
-        </message>
-        <message name="IDS_WIN_XP_VISTA_OBSOLETE_NOW" desc="A message displayed on an at-launch infobar and about:help warning the user that the computer they are using is no longer supported.">
+        <message name="IDS_WIN_XP_VISTA_OBSOLETE" desc="A message displayed on an at-launch infobar and about:help warning the user that the computer they are using is no longer supported.">
           Chromium may not function correctly because it is no longer supported on Windows XP or Windows Vista.
         </message>
       </if>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index f2a91f3e6..a3e87df 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -11043,6 +11043,12 @@
       <message name="IDS_VR_NO_SPEECH_RECOGNITION_RESULT" desc="Text to be shown if speech recognition failed to recognize a speech due to either no sound or noise.">
         Sorry, didn't catch that.
       </message>
+      <message name="IDS_VR_COMPONENT_UPDATE_READY" desc="Text to be shown to indicate a VR component update is ready to be applied.">
+        Update ready
+      </message>
+      <message name="IDS_VR_COMPONENT_APPLY" desc="Text to be shown on the button to apply a new component update.">
+        Apply
+      </message>
     </if>
   </messages>
  </release>
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index b4c8ee2..3d5e764 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -223,20 +223,9 @@
           Google Chrome <ph name="TERMS_OF_SERVICE_LINK">&lt;a target="_blank" href="$1"&gt;</ph>Terms of Service<ph name="END_TERMS_OF_SERVICE_LINK">&lt;/a&gt;</ph>
         </message>
       </if>
-      <if expr="is_macosx">
-        <message name="IDS_MAC_10_678_OBSOLETE_SOON" desc="A message displayed on an at-launch infobar and About (Help) page warning the user that the OS version they are using is about to become unsupported.">
-          This computer will soon stop receiving Google Chrome updates because Mac OS X 10.6, 10.7, and 10.8 will no longer be supported.
-        </message>
-        <message name="IDS_MAC_10_678_OBSOLETE_NOW" desc="A message displayed on an at-launch infobar and About (Help) page warning the user that the OS version they are using is no longer supported.">
-          This computer will no longer receive Google Chrome updates because Mac OS X 10.6, 10.7, and 10.8 are no longer supported.
-        </message>
-      </if>
       <if expr="is_win">
-        <message name="IDS_WIN_XP_VISTA_OBSOLETE_SOON" desc="A message displayed on an at-launch infobar and about:help warning the user that the computer they are using is about to become unsupported.">
-          This computer will soon stop receiving Google Chrome updates because Windows XP and Windows Vista will no longer be supported.
-        </message>
-        <message name="IDS_WIN_XP_VISTA_OBSOLETE_NOW" desc="A message displayed on an at-launch infobar and about:help warning the user that the computer they are using is no longer supported.">
-          This computer will no longer receive Google Chrome updates because Windows XP and Windows Vista are no longer supported.
+        <message name="IDS_WIN_XP_VISTA_OBSOLETE" desc="A message displayed on an at-launch infobar and about:help warning the user that the computer they are using is no longer supported.">
+          This computer will no longer receive Google Chrome updates because Windows XP and Windows Vista are no longer supported
         </message>
       </if>
       <message name="IDS_ACCNAME_APP" desc="The accessible name for the app menu.">
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 2561ffc..9e74e14 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -72,8 +72,8 @@
 #include "components/proximity_auth/switches.h"
 #include "components/search_provider_logos/features.h"
 #include "components/search_provider_logos/switches.h"
+#include "components/security_state/core/features.h"
 #include "components/security_state/core/security_state.h"
-#include "components/security_state/core/switches.h"
 #include "components/signin/core/browser/profile_management_switches.h"
 #include "components/signin/core/browser/signin_features.h"
 #include "components/signin/core/browser/signin_switches.h"
@@ -248,12 +248,6 @@
      switches::kPassiveListenersDefault, "forcealltrue"},
 };
 
-const FeatureEntry::Choice kMarkHttpAsChoices[] = {
-    {flags_ui::kGenericExperimentChoiceDefault, "", ""},
-    {flag_descriptions::kMarkHttpAsDangerous,
-     security_state::switches::kMarkHttpAs,
-     security_state::switches::kMarkHttpAsDangerous}};
-
 const FeatureEntry::Choice kDataReductionProxyServerExperiment[] = {
     {flags_ui::kGenericExperimentChoiceDefault, "", ""},
     {flag_descriptions::kDataReductionProxyServerAlternative1,
@@ -1154,6 +1148,36 @@
      {"No preconnect", kSpeculativePreconnectNoPreconnect,
       arraysize(kSpeculativePreconnectNoPreconnect), nullptr}};
 
+const FeatureEntry::FeatureParam kMarkHttpAsDangerous[] = {
+    {security_state::features::kMarkHttpAsFeatureParameterName,
+     security_state::features::kMarkHttpAsParameterDangerous}};
+const FeatureEntry::FeatureParam kMarkHttpAsWarning[] = {
+    {security_state::features::kMarkHttpAsFeatureParameterName,
+     security_state::features::kMarkHttpAsParameterWarning}};
+const FeatureEntry::FeatureParam kMarkHttpAsWarningAndDangerousOnFormEdits[] = {
+    {security_state::features::kMarkHttpAsFeatureParameterName,
+     security_state::features::
+         kMarkHttpAsParameterWarningAndDangerousOnFormEdits}};
+const FeatureEntry::FeatureParam
+    kMarkHttpAsWarningAndDangerousOnPasswordsAndCreditCards[] = {
+        {security_state::features::kMarkHttpAsFeatureParameterName,
+         security_state::features::
+             kMarkHttpAsParameterWarningAndDangerousOnPasswordsAndCreditCards}};
+
+const FeatureEntry::FeatureVariation kMarkHttpAsFeatureVariations[] = {
+    {"(mark as actively dangerous)", kMarkHttpAsDangerous,
+     arraysize(kMarkHttpAsDangerous), nullptr},
+    {"(mark with a Not Secure warning)", kMarkHttpAsWarning,
+     arraysize(kMarkHttpAsWarning), nullptr},
+    {"(mark with a Not Secure warning and dangerous on form edits)",
+     kMarkHttpAsWarningAndDangerousOnFormEdits,
+     arraysize(kMarkHttpAsWarningAndDangerousOnFormEdits), nullptr},
+    {"(mark with a Not Secure warning and dangerous on passwords and credit "
+     "card fields)",
+     kMarkHttpAsWarningAndDangerousOnPasswordsAndCreditCards,
+     arraysize(kMarkHttpAsWarningAndDangerousOnPasswordsAndCreditCards),
+     nullptr}};
+
 // RECORDING USER METRICS FOR FLAGS:
 // -----------------------------------------------------------------------------
 // The first line of the entry is the internal name.
@@ -1354,6 +1378,9 @@
      flag_descriptions::kEnableWasmStreamingName,
      flag_descriptions::kEnableWasmStreamingDescription, kOsAll,
      FEATURE_VALUE_TYPE(features::kWebAssemblyStreaming)},
+    {"shared-array-buffer", flag_descriptions::kEnableSharedArrayBufferName,
+     flag_descriptions::kEnableSharedArrayBufferDescription, kOsAll,
+     FEATURE_VALUE_TYPE(features::kSharedArrayBuffer)},
     {"enable-future-v8-vm-features", flag_descriptions::kV8VmFutureName,
      flag_descriptions::kV8VmFutureDescription, kOsAll,
      FEATURE_VALUE_TYPE(features::kV8VmFuture)},
@@ -2009,9 +2036,6 @@
      flag_descriptions::kExperimentalSecurityFeaturesDescription, kOsAll,
      SINGLE_VALUE_TYPE(switches::kEnablePotentiallyAnnoyingSecurityFeatures)},
 #endif  // OS_CHROMEOS
-    {"mark-non-secure-as", flag_descriptions::kMarkHttpAsName,
-     flag_descriptions::kMarkHttpAsDescription, kOsAll,
-     MULTI_VALUE_TYPE(kMarkHttpAsChoices)},
     {"enable-http-form-warning", flag_descriptions::kEnableHttpFormWarningName,
      flag_descriptions::kEnableHttpFormWarningDescription, kOsAll,
      FEATURE_VALUE_TYPE(security_state::kHttpFormWarningFeature)},
@@ -3623,6 +3647,13 @@
      FEATURE_VALUE_TYPE(features::kGrantNotificationsToDSE)},
 #endif
 
+    {"enable-mark-http-as", flag_descriptions::kMarkHttpAsName,
+     flag_descriptions::kMarkHttpAsDescription, kOsAll,
+     FEATURE_WITH_PARAMS_VALUE_TYPE(
+         security_state::features::kMarkHttpAsFeature,
+         kMarkHttpAsFeatureVariations,
+         "MarkHttpAs")},
+
     // NOTE: Adding a new flag requires adding a corresponding entry to enum
     // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag
     // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/android/preferences/pref_service_bridge.cc b/chrome/browser/android/preferences/pref_service_bridge.cc
index aa9ddb4..93463b33e 100644
--- a/chrome/browser/android/preferences/pref_service_bridge.cc
+++ b/chrome/browser/android/preferences/pref_service_bridge.cc
@@ -50,6 +50,7 @@
 #include "components/strings/grit/components_locale_settings.h"
 #include "components/translate/core/browser/translate_pref_names.h"
 #include "components/translate/core/browser/translate_prefs.h"
+#include "components/translate/core/common/translate_util.h"
 #include "components/version_info/version_info.h"
 #include "components/web_resource/web_resource_pref_names.h"
 #include "content/public/browser/browser_thread.h"
@@ -1223,6 +1224,35 @@
   }
 }
 
+static jboolean JNI_PrefServiceBridge_IsBlockedLanguage(
+    JNIEnv* env,
+    const JavaParamRef<jobject>& obj,
+    const JavaParamRef<jstring>& language) {
+  std::unique_ptr<translate::TranslatePrefs> translate_prefs =
+      ChromeTranslateClient::CreateTranslatePrefs(GetPrefService());
+
+  std::string language_code(ConvertJavaStringToUTF8(env, language));
+  translate::ToTranslateLanguageSynonym(&language_code);
+
+  return translate_prefs->IsBlockedLanguage(language_code);
+}
+
+static void JNI_PrefServiceBridge_SetLanguageBlockedState(
+    JNIEnv* env,
+    const JavaParamRef<jobject>& obj,
+    const JavaParamRef<jstring>& language,
+    jboolean blocked) {
+  std::unique_ptr<translate::TranslatePrefs> translate_prefs =
+      ChromeTranslateClient::CreateTranslatePrefs(GetPrefService());
+  std::string language_code(ConvertJavaStringToUTF8(env, language));
+
+  if (blocked) {
+    translate_prefs->BlockLanguage(language_code);
+  } else {
+    translate_prefs->UnblockLanguage(language_code);
+  }
+}
+
 static ScopedJavaLocalRef<jstring>
 JNI_PrefServiceBridge_GetDownloadDefaultDirectory(
     JNIEnv* env,
diff --git a/chrome/browser/android/preferences/website_preference_bridge.cc b/chrome/browser/android/preferences/website_preference_bridge.cc
index d838d68..2ea97625 100644
--- a/chrome/browser/android/preferences/website_preference_bridge.cc
+++ b/chrome/browser/android/preferences/website_preference_bridge.cc
@@ -45,8 +45,7 @@
 #include "jni/WebsitePreferenceBridge_jni.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "storage/browser/quota/quota_manager.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/origin.h"
 #include "url/url_constants.h"
 
@@ -680,7 +679,7 @@
 }
 
 void OnStorageInfoCleared(const ScopedJavaGlobalRef<jobject>& java_callback,
-                          blink::QuotaStatusCode code) {
+                          blink::mojom::QuotaStatusCode code) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   Java_StorageInfoClearedCallback_onStorageInfoCleared(
@@ -801,7 +800,7 @@
 
   auto storage_info_fetcher = base::MakeRefCounted<StorageInfoFetcher>(profile);
   storage_info_fetcher->ClearStorage(
-      host, static_cast<blink::StorageType>(type),
+      host, static_cast<blink::mojom::StorageType>(type),
       base::Bind(&OnStorageInfoCleared,
                  ScopedJavaGlobalRef<jobject>(java_callback)));
 }
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.cc b/chrome/browser/android/vr_shell/vr_gl_thread.cc
index 61cbc66..ef586f892 100644
--- a/chrome/browser/android/vr_shell/vr_gl_thread.cc
+++ b/chrome/browser/android/vr_shell/vr_gl_thread.cc
@@ -69,8 +69,7 @@
   }
 
   if (ui_initial_state_.assets_available) {
-    vr::Assets::GetInstance()->Load(
-        base::BindOnce(&VrGLThread::OnAssetsLoaded, base::Unretained(this)));
+    LoadAssets();
   }
 
   vr_shell_gl_ = base::MakeUnique<VrShellGl>(
@@ -208,6 +207,11 @@
       FROM_HERE, base::Bind(&VrShell::StopAutocomplete, weak_vr_shell_));
 }
 
+void VrGLThread::LoadAssets() {
+  vr::Assets::GetInstance()->Load(
+      base::BindOnce(&VrGLThread::OnAssetsLoaded, base::Unretained(this)));
+}
+
 void VrGLThread::SetFullscreen(bool enabled) {
   DCHECK(OnMainThread());
   task_runner()->PostTask(
@@ -339,6 +343,14 @@
                             browser_ui_, base::Passed(std::move(suggestions))));
 }
 
+void VrGLThread::OnAssetsComponentReady() {
+  DCHECK(OnMainThread());
+  task_runner()->PostTask(
+      FROM_HERE,
+      base::BindRepeating(&vr::BrowserUiInterface::OnAssetsComponentReady,
+                          browser_ui_));
+}
+
 bool VrGLThread::OnMainThread() const {
   return main_thread_task_runner_->BelongsToCurrentThread();
 }
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.h b/chrome/browser/android/vr_shell/vr_gl_thread.h
index 6fd7daa8..d42cd7d7 100644
--- a/chrome/browser/android/vr_shell/vr_gl_thread.h
+++ b/chrome/browser/android/vr_shell/vr_gl_thread.h
@@ -72,6 +72,7 @@
   void SetVoiceSearchActive(bool active) override;
   void StartAutocomplete(const base::string16& string) override;
   void StopAutocomplete() override;
+  void LoadAssets() override;
 
   // vr::BrowserUiInterface implementation (Browser calling to UI).
   void SetWebVrMode(bool enabled, bool show_toast) override;
@@ -94,6 +95,7 @@
   void OnSpeechRecognitionStateChanged(int new_state) override;
   void SetOmniboxSuggestions(
       std::unique_ptr<vr::OmniboxSuggestions> result) override;
+  void OnAssetsComponentReady() override;
 
  protected:
   void Init() override;
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc
index 6ab3463d..e86955f 100644
--- a/chrome/browser/android/vr_shell/vr_shell.cc
+++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -166,6 +166,8 @@
     UMA_HISTOGRAM_BOOLEAN("VRAutopresentedWebVR", !ui_initial_state.in_web_vr);
   }
 
+  vr::Assets::GetInstance()->SetOnComponentReadyCallback(base::BindRepeating(
+      &VrShell::OnAssetsComponentReady, weak_ptr_factory_.GetWeakPtr()));
   vr::Assets::GetInstance()->GetMetricsHelper()->OnEnter(vr::Mode::kVr);
 }
 
@@ -958,6 +960,10 @@
       status, component_version);
 }
 
+void VrShell::OnAssetsComponentReady() {
+  ui_->OnAssetsComponentReady();
+}
+
 // ----------------------------------------------------------------------------
 // Native JNI methods
 // ----------------------------------------------------------------------------
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h
index 71fbdad1..7f03eb5 100644
--- a/chrome/browser/android/vr_shell/vr_shell.h
+++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -234,6 +234,8 @@
 
   content::WebContents* GetNonNativePageWebContents() const;
 
+  void OnAssetsComponentReady();
+
   bool vr_shell_enabled_;
 
   bool webvr_mode_ = false;
diff --git a/chrome/browser/apps/guest_view/OWNERS b/chrome/browser/apps/guest_view/OWNERS
index cf8fef33..74d34105 100644
--- a/chrome/browser/apps/guest_view/OWNERS
+++ b/chrome/browser/apps/guest_view/OWNERS
@@ -1,5 +1,3 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-wjmaclean@chromium.org
+file://components/guest_view/OWNERS
 
 # COMPONENT: Platform>Apps>BrowserTag
diff --git a/chrome/browser/browsing_data/browsing_data_quota_helper_impl.cc b/chrome/browser/browsing_data/browsing_data_quota_helper_impl.cc
index 94bca40..f7586c23 100644
--- a/chrome/browser/browsing_data/browsing_data_quota_helper_impl.cc
+++ b/chrome/browser/browsing_data/browsing_data_quota_helper_impl.cc
@@ -20,7 +20,7 @@
 #include "content/public/browser/storage_partition.h"
 #include "storage/browser/quota/quota_manager.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 using content::BrowserThread;
 using content::BrowserContext;
 
@@ -171,5 +171,5 @@
 }
 
 void BrowsingDataQuotaHelperImpl::DidRevokeHostQuota(
-    blink::QuotaStatusCode /*status*/,
+    blink::mojom::QuotaStatusCode /*status*/,
     int64_t /*quota*/) {}
diff --git a/chrome/browser/browsing_data/browsing_data_quota_helper_impl.h b/chrome/browser/browsing_data/browsing_data_quota_helper_impl.h
index 3157b84c..df13833c 100644
--- a/chrome/browser/browsing_data/browsing_data_quota_helper_impl.h
+++ b/chrome/browser/browsing_data/browsing_data_quota_helper_impl.h
@@ -17,8 +17,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/browsing_data/browsing_data_quota_helper.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 class GURL;
 
@@ -35,7 +34,8 @@
   void RevokeHostQuota(const std::string& host) override;
 
  private:
-  using PendingHosts = std::set<std::pair<std::string, blink::StorageType>>;
+  using PendingHosts =
+      std::set<std::pair<std::string, blink::mojom::StorageType>>;
   using QuotaInfoMap = std::map<std::string, QuotaInfo>;
 
   explicit BrowsingDataQuotaHelperImpl(storage::QuotaManager* quota_manager);
@@ -48,7 +48,7 @@
   void GotOrigins(PendingHosts* pending_hosts,
                   const base::Closure& completion,
                   const std::set<GURL>& origins,
-                  blink::StorageType type);
+                  blink::mojom::StorageType type);
 
   // Calls QuotaManager::GetHostUsage for each (origin, type) pair.
   void OnGetOriginsComplete(const FetchResultCallback& callback,
@@ -58,7 +58,7 @@
   void GotHostUsage(QuotaInfoMap* quota_info,
                     const base::Closure& completion,
                     const std::string& host,
-                    blink::StorageType type,
+                    blink::mojom::StorageType type,
                     int64_t usage);
 
   // Called when all QuotaManager::GetHostUsage requests are complete.
@@ -66,7 +66,7 @@
                                QuotaInfoMap* quota_info);
 
   void RevokeHostQuotaOnIOThread(const std::string& host);
-  void DidRevokeHostQuota(blink::QuotaStatusCode status, int64_t quota);
+  void DidRevokeHostQuota(blink::mojom::QuotaStatusCode status, int64_t quota);
 
   scoped_refptr<storage::QuotaManager> quota_manager_;
 
diff --git a/chrome/browser/browsing_data/browsing_data_quota_helper_unittest.cc b/chrome/browser/browsing_data/browsing_data_quota_helper_unittest.cc
index 5746534..5a18c204 100644
--- a/chrome/browser/browsing_data/browsing_data_quota_helper_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_quota_helper_unittest.cc
@@ -19,7 +19,7 @@
 #include "storage/browser/quota/quota_manager_proxy.h"
 #include "storage/browser/test/mock_storage_client.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 using content::BrowserThread;
 using content::MockOriginData;
 using content::MockStorageClient;
@@ -91,8 +91,9 @@
                    weak_factory_.GetWeakPtr()));
   }
 
-  void GotPersistentHostQuota(blink::QuotaStatusCode status, int64_t quota) {
-    EXPECT_EQ(blink::QuotaStatusCode::kOk, status);
+  void GotPersistentHostQuota(blink::mojom::QuotaStatusCode status,
+                              int64_t quota) {
+    EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status);
     quota_ = quota;
   }
 
diff --git a/chrome/browser/browsing_data/browsing_data_shared_worker_helper.cc b/chrome/browser/browsing_data/browsing_data_shared_worker_helper.cc
index 590676a..5cf3f65 100644
--- a/chrome/browser/browsing_data/browsing_data_shared_worker_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_shared_worker_helper.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/shared_worker_service.h"
+#include "content/public/browser/storage_partition.h"
 
 BrowsingDataSharedWorkerHelper::SharedWorkerInfo::SharedWorkerInfo(
     const GURL& worker,
@@ -53,8 +54,8 @@
     const std::string& name,
     const url::Origin& constructor_origin) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  content::SharedWorkerService::GetInstance()->TerminateWorker(
-      worker, name, constructor_origin, storage_partition_, resource_context_);
+  storage_partition_->GetSharedWorkerService()->TerminateWorker(
+      worker, name, constructor_origin);
 }
 
 CannedBrowsingDataSharedWorkerHelper::CannedBrowsingDataSharedWorkerHelper(
diff --git a/chrome/browser/browsing_data/site_data_counting_helper.cc b/chrome/browser/browsing_data/site_data_counting_helper.cc
index 8e753646..4b26439 100644
--- a/chrome/browser/browsing_data/site_data_counting_helper.cc
+++ b/chrome/browser/browsing_data/site_data_counting_helper.cc
@@ -59,9 +59,10 @@
     storage::GetOriginsCallback origins_callback =
         base::Bind(&SiteDataCountingHelper::GetQuotaOriginsCallback,
                    base::Unretained(this));
-    const blink::StorageType types[] = {blink::StorageType::kTemporary,
-                                        blink::StorageType::kPersistent,
-                                        blink::StorageType::kSyncable};
+    const blink::mojom::StorageType types[] = {
+        blink::mojom::StorageType::kTemporary,
+        blink::mojom::StorageType::kPersistent,
+        blink::mojom::StorageType::kSyncable};
     for (auto type : types) {
       tasks_ += 1;
       BrowserThread::PostTask(
@@ -160,7 +161,7 @@
 
 void SiteDataCountingHelper::GetQuotaOriginsCallback(
     const std::set<GURL>& origin_set,
-    blink::StorageType type) {
+    blink::mojom::StorageType type) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   std::vector<GURL> origins(origin_set.begin(), origin_set.end());
   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
diff --git a/chrome/browser/browsing_data/site_data_counting_helper.h b/chrome/browser/browsing_data/site_data_counting_helper.h
index 89a8271..2ae17e5 100644
--- a/chrome/browser/browsing_data/site_data_counting_helper.h
+++ b/chrome/browser/browsing_data/site_data_counting_helper.h
@@ -9,7 +9,7 @@
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "net/cookies/canonical_cookie.h"
 #include "net/ssl/channel_id_store.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 class Profile;
 class BrowsingDataFlashLSOHelper;
@@ -55,7 +55,7 @@
           special_storage_policy,
       const std::vector<content::LocalStorageUsageInfo>& infos);
   void GetQuotaOriginsCallback(const std::set<GURL>& origin_set,
-                               blink::StorageType type);
+                               blink::mojom::StorageType type);
   void SitesWithFlashDataCallback(const std::vector<std::string>& sites);
   void GetChannelIDsOnIOThread(
       const scoped_refptr<net::URLRequestContextGetter>& rq_context);
diff --git a/chrome/browser/chrome_quota_permission_context.cc b/chrome/browser/chrome_quota_permission_context.cc
index 66c9e29..d39989e4 100644
--- a/chrome/browser/chrome_quota_permission_context.cc
+++ b/chrome/browser/chrome_quota_permission_context.cc
@@ -22,7 +22,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/navigation_details.h"
 #include "content/public/browser/web_contents.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "url/gurl.h"
 
@@ -158,7 +158,7 @@
     const content::StorageQuotaParams& params,
     int render_process_id,
     const PermissionCallback& callback) {
-  if (params.storage_type != blink::StorageType::kPersistent) {
+  if (params.storage_type != blink::mojom::StorageType::kPersistent) {
     // For now we only support requesting quota with this interface
     // for Persistent storage type.
     callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
diff --git a/chrome/browser/chromeos/display/display_preferences_unittest.cc b/chrome/browser/chromeos/display/display_preferences_unittest.cc
index 1ff00147..de88e74c 100644
--- a/chrome/browser/chromeos/display/display_preferences_unittest.cc
+++ b/chrome/browser/chromeos/display/display_preferences_unittest.cc
@@ -158,22 +158,6 @@
       pref_data->Set(name, std::move(layout_value));
   }
 
-  bool GetDisplayPropertyFromList(const display::DisplayIdList& list,
-                                  const std::string& key,
-                                  base::Value** out_value) {
-    std::string name = display::DisplayIdListToString(list);
-
-    DictionaryPrefUpdate update(&local_state_, prefs::kSecondaryDisplays);
-    base::DictionaryValue* pref_data = update.Get();
-
-    base::Value* layout_value = pref_data->FindKey(name);
-    if (layout_value) {
-      return static_cast<base::DictionaryValue*>(layout_value)
-          ->Get(key, out_value);
-    }
-    return false;
-  }
-
   void StoreDisplayPropertyForList(const display::DisplayIdList& list,
                                    const std::string& key,
                                    std::unique_ptr<base::Value> value) {
@@ -1179,47 +1163,6 @@
             display_manager()->GetDisplayForId(list[2]).bounds());
 }
 
-TEST_F(DisplayPreferencesTest, MirrorWhenEnterTableMode) {
-  display::Display::SetInternalDisplayId(
-      display::Screen::GetScreen()->GetPrimaryDisplay().id());
-  LoggedInAsUser();
-  UpdateDisplay("800x600,1200x800");
-  EXPECT_FALSE(display_manager()->IsInMirrorMode());
-  ash::TabletModeController* controller =
-      ash::Shell::Get()->tablet_mode_controller();
-  controller->EnableTabletModeWindowManager(true);
-  ASSERT_TRUE(controller->IsTabletModeWindowManagerEnabled());
-  EXPECT_TRUE(display_manager()->IsInMirrorMode());
-
-  // Make sure the mirror mode is not saved in the preference.
-  display::DisplayIdList list = display_manager()->GetCurrentDisplayIdList();
-  ASSERT_EQ(2u, list.size());
-
-  // Exiting the tablet mode should exit mirror mode.
-  controller->EnableTabletModeWindowManager(false);
-  ASSERT_FALSE(controller->IsTabletModeWindowManagerEnabled());
-  EXPECT_FALSE(display_manager()->IsInMirrorMode());
-}
-
-TEST_F(DisplayPreferencesTest, AlreadyMirrorWhenEnterTableMode) {
-  display::Display::SetInternalDisplayId(
-      display::Screen::GetScreen()->GetPrimaryDisplay().id());
-  LoggedInAsUser();
-  UpdateDisplay("800x600,1200x800");
-  display_manager()->SetMirrorMode(true);
-  EXPECT_TRUE(display_manager()->IsInMirrorMode());
-  ash::TabletModeController* controller =
-      ash::Shell::Get()->tablet_mode_controller();
-  controller->EnableTabletModeWindowManager(true);
-  ASSERT_TRUE(controller->IsTabletModeWindowManagerEnabled());
-  EXPECT_TRUE(display_manager()->IsInMirrorMode());
-
-  // Exiting the tablet mode should stay in mirror mode.
-  controller->EnableTabletModeWindowManager(false);
-  ASSERT_FALSE(controller->IsTabletModeWindowManagerEnabled());
-  EXPECT_TRUE(display_manager()->IsInMirrorMode());
-}
-
 TEST_F(DisplayPreferencesTest, LegacyTouchCalibrationDataSupport) {
   UpdateDisplay("800x600,1200x800");
   LoggedInAsUser();
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index 324093a..75fd96d 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -180,9 +180,10 @@
     QuickView,
     FileManagerBrowserTest,
     ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "openQuickView"),
-                      TestParameter(NOT_IN_GUEST_MODE, "closeQuickView"),
-                      TestParameter(NOT_IN_GUEST_MODE,
-                                    "openQuickViewForFoldersAfterClose")));
+                      TestParameter(NOT_IN_GUEST_MODE, "closeQuickView")));
+// Disabled due to strong flakyness (crbug.com/798772):
+//                      TestParameter(NOT_IN_GUEST_MODE,
+//                                    "openQuickViewForFoldersAfterClose")
 
 #if defined(DISABLE_SLOW_FILESAPP_TESTS)
 #define MAYBE_DirectoryTreeContextMenu DISABLED_DirectoryTreeContextMenu
diff --git a/chrome/browser/chromeos/lock_screen_apps/state_controller.cc b/chrome/browser/chromeos/lock_screen_apps/state_controller.cc
index 1d5e41c..b74efd83 100644
--- a/chrome/browser/chromeos/lock_screen_apps/state_controller.cc
+++ b/chrome/browser/chromeos/lock_screen_apps/state_controller.cc
@@ -319,7 +319,7 @@
   // This is not needed for requests that come from the lock UI as the lock
   // screen UI sends these requests *after* the note action launch animation.
   if (origin == LockScreenNoteOrigin::kStylusEject &&
-      ash::switches::IsUsingWebUiLock()) {
+      !ash::switches::IsUsingViewsLock()) {
     app_launch_delayed_for_animation_ = true;
     return;
   }
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index 905dd65..26b8c1d 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -435,7 +435,6 @@
     // just after the UI is closed but before the new credentials were stored
     // in the profile. Therefore we have to give it some time to make sure it
     // has been updated before we copy it.
-    // TODO(pmarko): Find a better way to do this, see https://crbug.com/796512.
     VLOG(1) << "Authentication was entered manually, possibly for proxyauth.";
     scoped_refptr<net::URLRequestContextGetter> browser_process_context_getter =
         g_browser_process->system_request_context();
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.cc b/chrome/browser/chromeos/login/lock/screen_locker.cc
index 1e78a27..b4b8bcc6 100644
--- a/chrome/browser/chromeos/login/lock/screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock/screen_locker.cc
@@ -201,7 +201,7 @@
 
   authenticator_ = UserSessionManager::GetInstance()->CreateAuthenticator(this);
   extended_authenticator_ = ExtendedAuthenticator::Create(this);
-  if (ash::switches::IsUsingWebUiLock()) {
+  if (!ash::switches::IsUsingViewsLock()) {
     web_ui_.reset(new WebUIScreenLocker(this));
     delegate_ = web_ui_.get();
     web_ui_->LockScreen();
diff --git a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
index d67ddd4..314e251 100644
--- a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
@@ -54,18 +54,6 @@
 // URL which corresponds to the login WebUI.
 const char kLoginURL[] = "chrome://oobe/lock";
 
-// Disables virtual keyboard overscroll. Login UI will scroll user pods
-// into view on JS side when virtual keyboard is shown.
-void DisableKeyboardOverscroll() {
-  keyboard::SetKeyboardOverscrollOverride(
-      keyboard::KEYBOARD_OVERSCROLL_OVERRIDE_DISABLED);
-}
-
-void ResetKeyboardOverscrollOverride() {
-  keyboard::SetKeyboardOverscrollOverride(
-      keyboard::KEYBOARD_OVERSCROLL_OVERRIDE_NONE);
-}
-
 }  // namespace
 
 namespace chromeos {
@@ -85,7 +73,7 @@
 // static
 bool WebUIScreenLocker::ShouldPreloadLockScreen() {
   // Only preload webui lock screen when it is used.
-  if (!ash::switches::IsUsingWebUiLock())
+  if (ash::switches::IsUsingViewsLock())
     return false;
 
   // Bail for mash because IdleDetector/UserActivityDetector does not work
@@ -150,8 +138,6 @@
 
   ClearLockScreenAppFocusCyclerDelegate();
 
-  ResetKeyboardOverscrollOverride();
-
   RequestPreload();
 }
 
@@ -182,8 +168,6 @@
                                 login_display_.get());
 
   SetLockScreenAppFocusCyclerDelegate();
-
-  DisableKeyboardOverscroll();
 }
 
 void WebUIScreenLocker::SetPasswordInputEnabled(bool enabled) {
diff --git a/chrome/browser/chromeos/login/signin_partition_manager.cc b/chrome/browser/chromeos/login/signin_partition_manager.cc
index a1e0f85..17652f4 100644
--- a/chrome/browser/chromeos/login/signin_partition_manager.cc
+++ b/chrome/browser/chromeos/login/signin_partition_manager.cc
@@ -6,26 +6,17 @@
 
 #include "base/guid.h"
 #include "base/strings/stringprintf.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
 #include "chromeos/chromeos_switches.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.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/browser/web_contents.h"
 #include "content/public/common/url_constants.h"
 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
 #include "net/base/escape.h"
-#include "net/http/http_auth_cache.h"
-#include "net/http/http_network_session.h"
-#include "net/http/http_transaction_factory.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
 #include "url/gurl.h"
 
-using content::BrowserThread;
-
 namespace chromeos {
 namespace login {
 
@@ -55,50 +46,18 @@
       base::Time::Max(), std::move(partition_data_cleared));
 }
 
-net::URLRequestContextGetter* GetSystemURLRequestContextGetter() {
-  return g_browser_process->system_request_context();
-}
-
-// Transfers HttpAuthCache content from |main_url_request_context_getter| into
-// |signin_url_request_context_getter|.
-void PrepareSigninURLRequestContextOnIOThread(
-    net::URLRequestContextGetter* main_url_request_context_getter,
-    net::URLRequestContextGetter* signin_url_request_context_getter) {
-  // Transfer proxy auth data from the main URLRequestContext.
-  net::HttpAuthCache* main_http_auth_cache =
-      main_url_request_context_getter->GetURLRequestContext()
-          ->http_transaction_factory()
-          ->GetSession()
-          ->http_auth_cache();
-  net::HttpAuthCache* signin_http_auth_cache =
-      signin_url_request_context_getter->GetURLRequestContext()
-          ->http_transaction_factory()
-          ->GetSession()
-          ->http_auth_cache();
-  signin_http_auth_cache->UpdateAllFrom(*main_http_auth_cache);
-}
-
-void InvokeStartSigninSessionDoneCallback(
-    SigninPartitionManager::StartSigninSessionDoneCallback callback,
-    const std::string& partition_name) {
-  std::move(callback).Run(partition_name);
-}
-
 }  // namespace
 
 SigninPartitionManager::SigninPartitionManager(
     content::BrowserContext* browser_context)
     : browser_context_(browser_context),
       clear_storage_partition_task_(
-          base::BindRepeating(&ClearStoragePartition)),
-      get_system_url_request_context_getter_task_(
-          base::BindRepeating(&GetSystemURLRequestContextGetter)) {}
+          base::BindRepeating(&ClearStoragePartition)) {}
 
 SigninPartitionManager::~SigninPartitionManager() {}
 
 void SigninPartitionManager::StartSigninSession(
-    const content::WebContents* embedder_web_contents,
-    StartSigninSessionDoneCallback signin_session_started) {
+    const content::WebContents* embedder_web_contents) {
   // If we already were in a sign-in session, close it first.
   // This clears stale data from the last-used StorageParittion.
   CloseCurrentSigninSession(base::BindOnce(&base::DoNothing));
@@ -115,19 +74,6 @@
   current_storage_partition_ =
       content::BrowserContext::GetStoragePartitionForSite(browser_context_,
                                                           guest_site, true);
-
-  base::OnceClosure invoke_callback = base::BindOnce(
-      &InvokeStartSigninSessionDoneCallback, std::move(signin_session_started),
-      current_storage_partition_name_);
-
-  BrowserThread::PostTaskAndReply(
-      BrowserThread::IO, FROM_HERE,
-      base::BindOnce(
-          &PrepareSigninURLRequestContextOnIOThread,
-          base::RetainedRef(get_system_url_request_context_getter_task_.Run()),
-          base::RetainedRef(
-              current_storage_partition_->GetURLRequestContext())),
-      std::move(invoke_callback));
 }
 
 void SigninPartitionManager::CloseCurrentSigninSession(
@@ -151,13 +97,6 @@
   clear_storage_partition_task_ = clear_storage_partition_task;
 }
 
-void SigninPartitionManager::SetGetSystemURLRequestContextGetterTaskForTesting(
-    GetSystemURLRequestContextGetterTask
-        get_system_url_request_context_getter_task) {
-  get_system_url_request_context_getter_task_ =
-      get_system_url_request_context_getter_task;
-}
-
 const std::string& SigninPartitionManager::GetCurrentStoragePartitionName()
     const {
   DCHECK(IsInSigninSession());
diff --git a/chrome/browser/chromeos/login/signin_partition_manager.h b/chrome/browser/chromeos/login/signin_partition_manager.h
index 1a5478e..66e790e 100644
--- a/chrome/browser/chromeos/login/signin_partition_manager.h
+++ b/chrome/browser/chromeos/login/signin_partition_manager.h
@@ -9,7 +9,6 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/singleton.h"
 #include "components/keyed_service/content/browser_context_keyed_service_factory.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -20,10 +19,6 @@
 class WebContents;
 }  // namespace content
 
-namespace net {
-class URLRequestContextGetter;
-}
-
 namespace chromeos {
 namespace login {
 
@@ -35,12 +30,6 @@
       base::RepeatingCallback<void(content::StoragePartition* storage_partition,
                                    base::OnceClosure data_cleared)>;
 
-  using GetSystemURLRequestContextGetterTask =
-      base::RepeatingCallback<net::URLRequestContextGetter*()>;
-
-  using StartSigninSessionDoneCallback =
-      base::OnceCallback<void(const std::string& partition_name)>;
-
   explicit SigninPartitionManager(content::BrowserContext* browser_context);
   ~SigninPartitionManager() override;
 
@@ -49,11 +38,7 @@
   // closed (and cleared).
   // |embedder_web_contents| is the WebContents instance embedding the webview
   // which will display the sign-in pages.
-  // |signin_session_started| will be invoked with the partition name of the
-  // started signin session on completition.
-  void StartSigninSession(
-      const content::WebContents* embedder_web_contents,
-      StartSigninSessionDoneCallback signin_session_started);
+  void StartSigninSession(const content::WebContents* embedder_web_contents);
 
   // Closes the current StoragePartition. All cached data in the
   // StoragePartition is cleared. |partition_data_cleared| will be called when
@@ -81,9 +66,6 @@
 
   void SetClearStoragePartitionTaskForTesting(
       ClearStoragePartitionTask clear_storage_partition_task);
-  void SetGetSystemURLRequestContextGetterTaskForTesting(
-      GetSystemURLRequestContextGetterTask
-          get_system_url_request_context_getter_task);
 
   class Factory : public BrowserContextKeyedServiceFactory {
    public:
@@ -111,8 +93,6 @@
   content::BrowserContext* const browser_context_;
 
   ClearStoragePartitionTask clear_storage_partition_task_;
-  GetSystemURLRequestContextGetterTask
-      get_system_url_request_context_getter_task_;
 
   // GuestView StoragePartitions use the host of the embedder site's URL as the
   // domain of their StoragePartition.
diff --git a/chrome/browser/chromeos/login/signin_partition_manager_unittest.cc b/chrome/browser/chromeos/login/signin_partition_manager_unittest.cc
index be492f2..b5b6721 100644
--- a/chrome/browser/chromeos/login/signin_partition_manager_unittest.cc
+++ b/chrome/browser/chromeos/login/signin_partition_manager_unittest.cc
@@ -12,16 +12,13 @@
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/web_contents_tester.h"
 #include "net/cookies/cookie_store.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_getter.h"
-#include "net/url_request/url_request_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -30,39 +27,6 @@
 
 namespace {
 constexpr char kEmbedderUrl[] = "http://www.whatever.com/";
-
-void StorePartitionNameAndQuitLoop(base::RunLoop* loop,
-                                   std::string* out_partition_name,
-                                   const std::string& partition_name) {
-  *out_partition_name = partition_name;
-  loop->Quit();
-}
-
-void AddEntryToHttpAuthCache(
-    net::URLRequestContextGetter* url_request_context_getter) {
-  net::HttpAuthCache* http_auth_cache =
-      url_request_context_getter->GetURLRequestContext()
-          ->http_transaction_factory()
-          ->GetSession()
-          ->http_auth_cache();
-  http_auth_cache->Add(GURL("http://whatever.com/"), "",
-                       net::HttpAuth::AUTH_SCHEME_BASIC, "",
-                       net::AuthCredentials(), "");
-}
-
-void IsEntryInHttpAuthCache(
-    net::URLRequestContextGetter* url_request_context_getter,
-    bool* out_entry_found) {
-  net::HttpAuthCache* http_auth_cache =
-      url_request_context_getter->GetURLRequestContext()
-          ->http_transaction_factory()
-          ->GetSession()
-          ->http_auth_cache();
-  *out_entry_found =
-      http_auth_cache->Lookup(GURL("http://whatever.com/"), "",
-                              net::HttpAuth::AUTH_SCHEME_BASIC) != nullptr;
-}
-
 }  // namespace
 
 class SigninPartitionManagerTest : public ChromeRenderViewHostTestHarness {
@@ -73,10 +37,6 @@
   void SetUp() override {
     ChromeRenderViewHostTestHarness::SetUp();
 
-    system_request_context_getter_ = new net::TestURLRequestContextGetter(
-        content::BrowserThread::GetTaskRunnerForThread(
-            content::BrowserThread::IO));
-
     signin_browser_context_ = base::MakeUnique<TestingProfile>();
 
     signin_ui_web_contents_ = base::WrapUnique<content::WebContents>(
@@ -91,10 +51,6 @@
     GetSigninPartitionManager()->SetClearStoragePartitionTaskForTesting(
         base::Bind(&SigninPartitionManagerTest::ClearStoragePartitionTask,
                    base::Unretained(this)));
-    GetSigninPartitionManager()
-        ->SetGetSystemURLRequestContextGetterTaskForTesting(base::BindRepeating(
-            &SigninPartitionManagerTest::GetSystemURLRequestContextGetter,
-            base::Unretained(this)));
   }
 
   void TearDown() override {
@@ -133,29 +89,12 @@
     pending_clear_tasks_.clear();
   }
 
-  std::string RunStartSigninSesssion(content::WebContents* webcontents) {
-    std::string partition_name;
-    base::RunLoop loop;
-    GetSigninPartitionManager()->StartSigninSession(
-        webcontents,
-        base::BindOnce(&StorePartitionNameAndQuitLoop, &loop, &partition_name));
-    loop.Run();
-    return partition_name;
-  }
-
-  net::URLRequestContextGetter* GetSystemURLRequestContextGetter() {
-    return system_request_context_getter_.get();
-  }
-
  private:
   void ClearStoragePartitionTask(content::StoragePartition* partition,
                                  base::OnceClosure clear_done_closure) {
     pending_clear_tasks_.push_back({partition, std::move(clear_done_closure)});
   }
 
-  scoped_refptr<net::TestURLRequestContextGetter>
-      system_request_context_getter_;
-
   std::unique_ptr<TestingProfile> signin_browser_context_;
 
   // Web contents of the sign-in UI, embedder of the signin-frame webview.
@@ -169,22 +108,20 @@
 
 TEST_F(SigninPartitionManagerTest, TestSubsequentAttempts) {
   // First sign-in attempt
+  GetSigninPartitionManager()->StartSigninSession(signin_ui_web_contents());
   std::string signin_partition_name_1 =
-      RunStartSigninSesssion(signin_ui_web_contents());
+      GetSigninPartitionManager()->GetCurrentStoragePartitionName();
   auto* signin_partition_1 =
       GetSigninPartitionManager()->GetCurrentStoragePartition();
   EXPECT_FALSE(signin_partition_name_1.empty());
-  EXPECT_EQ(signin_partition_name_1,
-            GetSigninPartitionManager()->GetCurrentStoragePartitionName());
 
   // Second sign-in attempt
+  GetSigninPartitionManager()->StartSigninSession(signin_ui_web_contents());
   std::string signin_partition_name_2 =
-      RunStartSigninSesssion(signin_ui_web_contents());
+      GetSigninPartitionManager()->GetCurrentStoragePartitionName();
   auto* signin_partition_2 =
       GetSigninPartitionManager()->GetCurrentStoragePartition();
   EXPECT_FALSE(signin_partition_name_2.empty());
-  EXPECT_EQ(signin_partition_name_2,
-            GetSigninPartitionManager()->GetCurrentStoragePartitionName());
 
   // Make sure that the StoragePartition has not been re-used.
   EXPECT_NE(signin_partition_name_1, signin_partition_name_2);
@@ -211,32 +148,5 @@
   EXPECT_TRUE(closure_called);
 }
 
-TEST_F(SigninPartitionManagerTest, HttpAuthCacheTransferred) {
-  base::RunLoop loop_prepare;
-  content::BrowserThread::PostTaskAndReply(
-      content::BrowserThread::IO, FROM_HERE,
-      base::BindOnce(AddEntryToHttpAuthCache,
-                     base::RetainedRef(GetSystemURLRequestContextGetter())),
-      loop_prepare.QuitClosure());
-  loop_prepare.Run();
-
-  RunStartSigninSesssion(signin_ui_web_contents());
-  net::URLRequestContextGetter* signin_url_request_context_getter =
-      GetSigninPartitionManager()
-          ->GetCurrentStoragePartition()
-          ->GetURLRequestContext();
-
-  bool entry_found = false;
-  base::RunLoop loop_check;
-  content::BrowserThread::PostTaskAndReply(
-      content::BrowserThread::IO, FROM_HERE,
-      base::BindOnce(IsEntryInHttpAuthCache,
-                     base::RetainedRef(signin_url_request_context_getter),
-                     &entry_found),
-      loop_check.QuitClosure());
-  loop_check.Run();
-  EXPECT_TRUE(entry_found);
-}
-
 }  // namespace login
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_feedback.cc b/chrome/browser/chromeos/login/ui/login_feedback.cc
index e4015c2..edccb57 100644
--- a/chrome/browser/chromeos/login/ui/login_feedback.cc
+++ b/chrome/browser/chromeos/login/ui/login_feedback.cc
@@ -255,7 +255,7 @@
   extensions::FeedbackPrivateAPI* api =
       extensions::FeedbackPrivateAPI::GetFactoryInstance()->Get(profile_);
   api->RequestFeedbackForFlow(
-      description_, "Login", std::string(), GURL(),
+      description_, std::string(), "Login", std::string(), GURL(),
       extensions::api::feedback_private::FeedbackFlow::FEEDBACK_FLOW_LOGIN);
 
   // Make sure there is a feedback app window opened.
diff --git a/chrome/browser/chromeos/login/webview_login_browsertest.cc b/chrome/browser/chromeos/login/webview_login_browsertest.cc
index 2dde52f..48bce5d 100644
--- a/chrome/browser/chromeos/login/webview_login_browsertest.cc
+++ b/chrome/browser/chromeos/login/webview_login_browsertest.cc
@@ -9,7 +9,6 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/run_loop.h"
-#include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chrome_notification_types.h"
@@ -18,13 +17,8 @@
 #include "chrome/browser/chromeos/login/test/oobe_base_test.h"
 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
 #include "chrome/browser/chromeos/login/ui/login_display_webui.h"
-#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
-#include "chrome/browser/chromeos/policy/device_policy_builder.h"
 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
-#include "chrome/browser/policy/test/local_policy_test_server.h"
-#include "chrome/browser/ui/login/login_handler.h"
-#include "chrome/browser/ui/login/login_handler_test_utils.h"
 #include "chrome/browser/ui/webui/signin/signin_utils.h"
 #include "chromeos/chromeos_switches.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -33,15 +27,9 @@
 #include "components/guest_view/browser/guest_view_manager.h"
 #include "components/onc/onc_constants.h"
 #include "components/onc/onc_pref_names.h"
-#include "components/policy/core/common/cloud/device_management_service.h"
-#include "components/policy/core/common/policy_service.h"
-#include "components/policy/core/common/policy_switches.h"
-#include "components/policy/policy_constants.h"
 #include "components/policy/proto/chrome_device_policy.pb.h"
 #include "components/prefs/pref_change_registrar.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/test/browser_test_utils.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/test_utils.h"
@@ -110,12 +98,6 @@
   return cookies;
 }
 
-void PolicyChangedCallback(base::RepeatingClosure callback,
-                           const base::Value* old_value,
-                           const base::Value* new_value) {
-  callback.Run();
-}
-
 // Spins the loop until a notification is received from |prefs| that the value
 // of |pref_name| has changed. If the notification is received before Wait()
 // has been called, Wait() returns immediately and no loop is spun.
@@ -415,9 +397,6 @@
     device_policy_test_helper_.InstallOwnerKey();
     device_policy_test_helper_.MarkAsEnterpriseOwned();
 
-    fake_session_manager_client_->set_device_policy(
-        device_policy_test_helper_.device_policy()->GetBlob());
-
     WebviewLoginTest::SetUpInProcessBrowserTestFixture();
   }
 
@@ -742,141 +721,4 @@
   EXPECT_EQ("got no client cert", https_reply_content);
 }
 
-class WebviewProxyAuthLoginTest : public WebviewLoginTest {
- public:
-  WebviewProxyAuthLoginTest()
-      : auth_proxy_server_(std::make_unique<net::SpawnedTestServer>(
-            net::SpawnedTestServer::TYPE_BASIC_AUTH_PROXY,
-            base::FilePath())) {}
-
-  void SetUp() override {
-    // Start proxy server
-    auth_proxy_server_->set_redirect_connect_to_localhost(true);
-    ASSERT_TRUE(auth_proxy_server_->Start());
-
-    // Prepare device policy which will be used for two purposes:
-    // - given to |fake_session_manager_client_|, so the device appears to have
-    //   registered for policy.
-    // - the payload is given to |policy_test_server_|, so we can download fresh
-    //   policy.
-    device_policy_test_helper_.device_policy()
-        ->policy_data()
-        .set_public_key_version(1);
-    device_policy_test_helper_.device_policy()->Build();
-
-    // Start policy server. Use the DMToken and DeviceId from PolicyBuilder.
-    // These also used in |device_policy_test_helper_| and was passed to
-    // |fake_session_manager_client_| above, so the device will request policy
-    // with these identifiers.
-    policy_test_server_.RegisterClient(policy::PolicyBuilder::kFakeToken,
-                                       policy::PolicyBuilder::kFakeDeviceId);
-    UpdateServedPolicyFromDevicePolicyTestHelper();
-    ASSERT_TRUE(policy_test_server_.Start());
-
-    WebviewLoginTest::SetUp();
-  }
-
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    command_line->AppendSwitchASCII(
-        ::switches::kProxyServer,
-        auth_proxy_server_->host_port_pair().ToString());
-    command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl,
-                                    policy_test_server_.GetServiceURL().spec());
-    WebviewLoginTest::SetUpCommandLine(command_line);
-  }
-
-  void SetUpInProcessBrowserTestFixture() override {
-    WebviewLoginTest::SetUpInProcessBrowserTestFixture();
-
-    // Use a fake SessionManagerClient to be able to pretend that the device has
-    // been enrolled and registered for policy (and has a device DMToken).
-    auto fake_session_manager_client =
-        std::make_unique<FakeSessionManagerClient>();
-    fake_session_manager_client_ = fake_session_manager_client.get();
-    DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient(
-        std::move(fake_session_manager_client));
-    device_policy_test_helper_.InstallOwnerKey();
-    device_policy_test_helper_.MarkAsEnterpriseOwned();
-
-    fake_session_manager_client_->set_device_policy(
-        device_policy_test_helper_.device_policy()->GetBlob());
-
-    // Set some fake state keys to make sure they are not empty.
-    std::vector<std::string> state_keys;
-    state_keys.push_back("1");
-    fake_session_manager_client_->set_server_backed_state_keys(state_keys);
-  }
-
-  void UpdateServedPolicyFromDevicePolicyTestHelper() {
-    policy_test_server_.UpdatePolicy(
-        policy::dm_protocol::kChromeDevicePolicyType,
-        std::string() /* entity_id */,
-        device_policy_test_helper_.device_policy()
-            ->payload()
-            .SerializeAsString());
-  }
-
-  // A proxy server which requires authentication using the 'Basic'
-  // authentication method.
-  std::unique_ptr<net::SpawnedTestServer> auth_proxy_server_;
-  policy::LocalPolicyTestServer policy_test_server_;
-  policy::DevicePolicyCrosTestHelper device_policy_test_helper_;
-
-  // FakeDBusThreadManager uses FakeSessionManagerClient.
-  std::unique_ptr<chromeos::DBusThreadManagerSetter> dbus_setter_;
-  // Unowned pointer - owned by DBusThreadManager.
-  chromeos::FakeSessionManagerClient* fake_session_manager_client_;
-
-  DISALLOW_COPY_AND_ASSIGN(WebviewProxyAuthLoginTest);
-};
-
-IN_PROC_BROWSER_TEST_F(WebviewProxyAuthLoginTest, ProxyAuthTransfer) {
-  WaitForSigninScreen();
-
-  LoginPromptBrowserTestObserver observer;
-  observer.Register(content::NotificationService::AllSources());
-
-  content::WindowedNotificationObserver auth_needed_waiter(
-      chrome::NOTIFICATION_AUTH_NEEDED,
-      content::NotificationService::AllSources());
-
-  auth_needed_waiter.Wait();
-  ASSERT_FALSE(observer.handlers().empty());
-  LoginHandler* login_handler = *observer.handlers().begin();
-
-  // Before entering auth data, make |policy_test_server_| serve a policy that
-  // we can use to detect if policies have been fetched.
-  em::ChromeDeviceSettingsProto& device_policy =
-      device_policy_test_helper_.device_policy()->payload();
-  device_policy.mutable_device_login_screen_auto_select_certificate_for_urls()
-      ->add_login_screen_auto_select_certificate_rules("test_pattern");
-  UpdateServedPolicyFromDevicePolicyTestHelper();
-
-  policy::PolicyChangeRegistrar policy_change_registrar(
-      g_browser_process->platform_part()
-          ->browser_policy_connector_chromeos()
-          ->GetPolicyService(),
-      policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME,
-                              std::string() /* component_id */));
-
-  // Now enter auth data
-  login_handler->SetAuth(base::ASCIIToUTF16("foo"), base::ASCIIToUTF16("bar"));
-  WaitForGaiaPageLoad();
-
-  base::RunLoop run_loop;
-  policy_change_registrar.Observe(
-      policy::key::kDeviceLoginScreenAutoSelectCertificateForUrls,
-      base::BindRepeating(&PolicyChangedCallback, run_loop.QuitClosure()));
-  run_loop.Run();
-
-  // Press the back button at a sign-in screen without pre-existing users to
-  // start a new sign-in attempt.
-  // This will re-load gaia, rotating the StoragePartition. The new
-  // StoragePartition must also have the proxy auth details.
-  JS().Evaluate("$('signin-back-button').fire('tap')");
-  WaitForGaiaPageReload();
-  // Expect that we got back to the identifier page, as there are no known users
-  // so the sign-in screen will not display user pods.
-  ExpectIdentifierPage();
-}
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/net/network_state_notifier_unittest.cc b/chrome/browser/chromeos/net/network_state_notifier_unittest.cc
index 88c02a0..65df7db8 100644
--- a/chrome/browser/chromeos/net/network_state_notifier_unittest.cc
+++ b/chrome/browser/chromeos/net/network_state_notifier_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "base/macros.h"
 #include "base/run_loop.h"
+#include "chrome/browser/chromeos/ash_config.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/notifications/notification_display_service_tester.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
@@ -69,11 +70,15 @@
     NetworkHandler::Initialize();
     base::RunLoop().RunUntilIdle();
     network_connect_delegate_.reset(new NetworkConnectTestDelegate);
-    NetworkConnect::Initialize(network_connect_delegate_.get());
+    // In Config::MUS the WindowManager controls NetworkConnect.
+    if (GetAshConfig() != ash::Config::MUS)
+      NetworkConnect::Initialize(network_connect_delegate_.get());
   }
 
   void TearDown() override {
-    NetworkConnect::Shutdown();
+    // In Config::MUS the WindowManager controls NetworkConnect.
+    if (GetAshConfig() != ash::Config::MUS)
+      NetworkConnect::Shutdown();
     network_connect_delegate_.reset();
     LoginState::Shutdown();
     NetworkHandler::Shutdown();
diff --git a/chrome/browser/conflicts/module_event_sink_impl_win_unittest.cc b/chrome/browser/conflicts/module_event_sink_impl_win_unittest.cc
index 4f8237d..c0d05e2 100644
--- a/chrome/browser/conflicts/module_event_sink_impl_win_unittest.cc
+++ b/chrome/browser/conflicts/module_event_sink_impl_win_unittest.cc
@@ -13,6 +13,8 @@
 #include "chrome/common/conflicts/module_watcher_win.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#include <windows.h>
+
 namespace {
 
 // The address of this module in memory. The linker will take care of defining
diff --git a/chrome/browser/diagnostics/diagnostics_writer.cc b/chrome/browser/diagnostics/diagnostics_writer.cc
index a55fed6..2f62550 100644
--- a/chrome/browser/diagnostics/diagnostics_writer.cc
+++ b/chrome/browser/diagnostics/diagnostics_writer.cc
@@ -21,6 +21,8 @@
 #if defined(OS_POSIX)
 #include <stdio.h>
 #include <unistd.h>
+#elif defined(OS_WIN)
+#include <windows.h>
 #endif
 
 namespace diagnostics {
diff --git a/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc b/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc
index 3d5b2f0d..93d8bf84 100644
--- a/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc
+++ b/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc
@@ -42,15 +42,15 @@
 class Holder {
  public:
   virtual ~Holder() {}
-  virtual void OnResult(bool, bool) = 0;
+  virtual void OnResult(bool, bool, bool) = 0;
 };
 
 class MockDelegate : public Holder {
  public:
-  MOCK_METHOD2(OnResult, void(bool, bool));
+  MOCK_METHOD3(OnResult, void(bool, bool, bool));
 
-  base::Callback<void(bool, bool)> GetDelegate() {
-    return base::Bind(&MockDelegate::OnResult, base::Unretained(this));
+  base::RepeatingCallback<void(bool, bool, bool)> GetDelegate() {
+    return base::BindRepeating(&MockDelegate::OnResult, base::Unretained(this));
   }
 };
 
@@ -137,14 +137,14 @@
                        TestDelegate) {
   for (unsigned i = 0; i < sizeof(kAllPaths) / sizeof(kAllPaths[0]); ++i) {
     testing::InSequence dummy;
-    EXPECT_CALL(holder_, OnResult(true, true))
+    EXPECT_CALL(holder_, OnResult(true, true, _))
         .WillOnce(testing::InvokeWithoutArgs(QuitSoon));
     NavigateAndWait(kAllPaths[i], 0);
   }
   // Test pages that we don't care about its distillability.
   {
     testing::InSequence dummy;
-    EXPECT_CALL(holder_, OnResult(_, _)).Times(0);
+    EXPECT_CALL(holder_, OnResult(_, _, _)).Times(0);
     NavigateAndWait("about:blank", kWaitNoExpectedCallMs);
   }
 }
@@ -155,7 +155,7 @@
 
 IN_PROC_BROWSER_TEST_F(DistillablePageUtilsBrowserTestNone,
                        TestDelegate) {
-  EXPECT_CALL(holder_, OnResult(_, _)).Times(0);
+  EXPECT_CALL(holder_, OnResult(_, _, _)).Times(0);
   NavigateAndWait(kSimpleArticlePath, kWaitNoExpectedCallMs);
 }
 
@@ -167,13 +167,13 @@
                        TestDelegate) {
   {
     testing::InSequence dummy;
-    EXPECT_CALL(holder_, OnResult(true, true))
+    EXPECT_CALL(holder_, OnResult(true, true, _))
         .WillOnce(testing::InvokeWithoutArgs(QuitSoon));
     NavigateAndWait(kArticlePath, 0);
   }
   {
     testing::InSequence dummy;
-    EXPECT_CALL(holder_, OnResult(false, true))
+    EXPECT_CALL(holder_, OnResult(false, true, _))
         .WillOnce(testing::InvokeWithoutArgs(QuitSoon));
     NavigateAndWait(kNonArticlePath, 0);
   }
@@ -188,15 +188,15 @@
   const char* paths[] = {kSimpleArticlePath, kSimpleArticleIFramePath};
   for (unsigned i = 0; i < sizeof(paths)/sizeof(paths[0]); ++i) {
     testing::InSequence dummy;
-    EXPECT_CALL(holder_, OnResult(true, false)).Times(1);
-    EXPECT_CALL(holder_, OnResult(true, true))
+    EXPECT_CALL(holder_, OnResult(true, false, false)).Times(1);
+    EXPECT_CALL(holder_, OnResult(true, true, false))
         .WillOnce(testing::InvokeWithoutArgs(QuitSoon));
     NavigateAndWait(paths[i], 0);
   }
   {
     testing::InSequence dummy;
-    EXPECT_CALL(holder_, OnResult(false, false)).Times(1);
-    EXPECT_CALL(holder_, OnResult(false, true))
+    EXPECT_CALL(holder_, OnResult(false, false, false)).Times(1);
+    EXPECT_CALL(holder_, OnResult(false, true, false))
         .WillOnce(testing::InvokeWithoutArgs(QuitSoon));
     NavigateAndWait(kNonArticlePath, 0);
   }
@@ -210,15 +210,15 @@
   const char* paths[] = {kSimpleArticlePath, kSimpleArticleIFramePath};
   for (unsigned i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i) {
     testing::InSequence dummy;
-    EXPECT_CALL(holder_, OnResult(true, false)).Times(1);
-    EXPECT_CALL(holder_, OnResult(true, true))
+    EXPECT_CALL(holder_, OnResult(true, false, false)).Times(1);
+    EXPECT_CALL(holder_, OnResult(true, true, false))
         .WillOnce(testing::InvokeWithoutArgs(QuitSoon));
     NavigateAndWait(paths[i], 0);
   }
   {
     testing::InSequence dummy;
-    EXPECT_CALL(holder_, OnResult(false, false)).Times(1);
-    EXPECT_CALL(holder_, OnResult(false, true))
+    EXPECT_CALL(holder_, OnResult(false, false, false)).Times(1);
+    EXPECT_CALL(holder_, OnResult(false, true, false))
         .WillOnce(testing::InvokeWithoutArgs(QuitSoon));
     NavigateAndWait(kNonArticlePath, 0);
   }
diff --git a/chrome/browser/dom_distiller/tab_utils_android.cc b/chrome/browser/dom_distiller/tab_utils_android.cc
index 8696b85..7b541f2d 100644
--- a/chrome/browser/dom_distiller/tab_utils_android.cc
+++ b/chrome/browser/dom_distiller/tab_utils_android.cc
@@ -70,22 +70,10 @@
                                     nullptr));
 }
 
-// Returns true if the distiller experiment is set to use any heuristic other
-// than "NONE". This is used to prevent the Reader Mode panel from loading
-// when it would otherwise never be shown.
-jboolean JNI_DomDistillerTabUtils_IsDistillerHeuristicsEnabled(
+jint JNI_DomDistillerTabUtils_GetDistillerHeuristics(
     JNIEnv* env,
     const JavaParamRef<jclass>& clazz) {
-  return dom_distiller::GetDistillerHeuristicsType()
-      != dom_distiller::DistillerHeuristicsType::NONE;
-}
-
-// Returns true if distiller is reporting every page as distillable.
-jboolean JNI_DomDistillerTabUtils_IsHeuristicAlwaysTrue(
-    JNIEnv* env,
-    const JavaParamRef<jclass>& clazz) {
-  return dom_distiller::GetDistillerHeuristicsType()
-      == dom_distiller::DistillerHeuristicsType::ALWAYS_TRUE;
+  return static_cast<jint>(dom_distiller::GetDistillerHeuristicsType());
 }
 
 void JNI_DomDistillerTabUtils_SetInterceptNavigationDelegate(
diff --git a/chrome/browser/engagement/important_sites_usage_counter_unittest.cc b/chrome/browser/engagement/important_sites_usage_counter_unittest.cc
index ac43cc2..575d8cc 100644
--- a/chrome/browser/engagement/important_sites_usage_counter_unittest.cc
+++ b/chrome/browser/engagement/important_sites_usage_counter_unittest.cc
@@ -99,10 +99,10 @@
   important_sites.push_back(i2);
 
   const std::vector<content::MockOriginData> origins = {
-      {"http://example.com/", blink::StorageType::kTemporary, 1},
-      {"https://example.com/", blink::StorageType::kTemporary, 2},
-      {"https://maps.example.com/", blink::StorageType::kTemporary, 4},
-      {"http://google.com/", blink::StorageType::kPersistent, 8},
+      {"http://example.com/", blink::mojom::StorageType::kTemporary, 1},
+      {"https://example.com/", blink::mojom::StorageType::kTemporary, 2},
+      {"https://maps.example.com/", blink::mojom::StorageType::kTemporary, 4},
+      {"http://google.com/", blink::mojom::StorageType::kPersistent, 8},
   };
 
   QuotaManager* quota_manager = CreateQuotaManager();
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc b/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc
index 46690d85..05be2e1 100644
--- a/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc
+++ b/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc
@@ -79,9 +79,9 @@
     extensions::FeedbackPrivateAPI* api =
         extensions::FeedbackPrivateAPI::GetFactoryInstance()->Get(
             browser()->profile());
-    api->RequestFeedbackForFlow("Test description", "Test tag",
-                                extra_diagnostics, GURL("http://www.test.com"),
-                                flow);
+    api->RequestFeedbackForFlow("Test description", "Test placeholder",
+                                "Test tag", extra_diagnostics,
+                                GURL("http://www.test.com"), flow);
   }
 };
 
diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
index c24e6e2..fd33a52 100644
--- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
+++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
@@ -67,19 +67,19 @@
       static_cast<int>(code));
 }
 
-const char* QuotaStatusCodeToString(blink::QuotaStatusCode status) {
+const char* QuotaStatusCodeToString(blink::mojom::QuotaStatusCode status) {
   switch (status) {
-    case blink::QuotaStatusCode::kOk:
+    case blink::mojom::QuotaStatusCode::kOk:
       return "OK.";
-    case blink::QuotaStatusCode::kErrorNotSupported:
+    case blink::mojom::QuotaStatusCode::kErrorNotSupported:
       return "Operation not supported.";
-    case blink::QuotaStatusCode::kErrorInvalidModification:
+    case blink::mojom::QuotaStatusCode::kErrorInvalidModification:
       return "Invalid modification.";
-    case blink::QuotaStatusCode::kErrorInvalidAccess:
+    case blink::mojom::QuotaStatusCode::kErrorInvalidAccess:
       return "Invalid access.";
-    case blink::QuotaStatusCode::kErrorAbort:
+    case blink::mojom::QuotaStatusCode::kErrorAbort:
       return "Quota operation aborted.";
-    case blink::QuotaStatusCode::kUnknown:
+    case blink::mojom::QuotaStatusCode::kUnknown:
       return "Unknown error.";
   }
   NOTREACHED();
@@ -342,7 +342,7 @@
 }
 
 void SyncFileSystemGetUsageAndQuotaFunction::DidGetUsageAndQuota(
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     int64_t usage,
     int64_t quota) {
   // Repost to switch from IO thread to UI thread for SendResponse().
@@ -356,7 +356,7 @@
   }
 
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (status != blink::QuotaStatusCode::kOk) {
+  if (status != blink::mojom::QuotaStatusCode::kOk) {
     error_ = QuotaStatusCodeToString(status);
     SendResponse(false);
     return;
diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.h b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.h
index 902a961e..cb4ad6f 100644
--- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.h
+++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.h
@@ -15,7 +15,7 @@
 #include "chrome/browser/sync_file_system/sync_status_code.h"
 #include "chrome/common/extensions/api/sync_file_system.h"
 #include "storage/browser/fileapi/file_system_url.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace storage {
 class FileSystemContext;
@@ -93,7 +93,7 @@
   bool RunAsync() override;
 
  private:
-  void DidGetUsageAndQuota(blink::QuotaStatusCode status,
+  void DidGetUsageAndQuota(blink::mojom::QuotaStatusCode status,
                            int64_t usage,
                            int64_t quota);
 };
diff --git a/chrome/browser/extensions/api/web_view/OWNERS b/chrome/browser/extensions/api/web_view/OWNERS
index a25b3ec..74d34105 100644
--- a/chrome/browser/extensions/api/web_view/OWNERS
+++ b/chrome/browser/extensions/api/web_view/OWNERS
@@ -1,6 +1,3 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-wjmaclean@chromium.org
-paulmeyer@chromium.org
+file://components/guest_view/OWNERS
 
 # COMPONENT: Platform>Apps>BrowserTag
diff --git a/chrome/browser/extensions/extension_creator_filter_unittest.cc b/chrome/browser/extensions/extension_creator_filter_unittest.cc
index b8d9b1a..b3bfe5d9 100644
--- a/chrome/browser/extensions/extension_creator_filter_unittest.cc
+++ b/chrome/browser/extensions/extension_creator_filter_unittest.cc
@@ -15,6 +15,10 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
 namespace {
 
 class ExtensionCreatorFilterTest : public PlatformTest {
diff --git a/chrome/browser/extensions/extension_special_storage_policy.cc b/chrome/browser/extensions/extension_special_storage_policy.cc
index 21fcb37d..d9578a7 100644
--- a/chrome/browser/extensions/extension_special_storage_policy.cc
+++ b/chrome/browser/extensions/extension_special_storage_policy.cc
@@ -32,8 +32,7 @@
 #include "extensions/common/manifest_handlers/content_capabilities_handler.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "storage/browser/quota/quota_manager.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 using content::BrowserThread;
 using extensions::APIPermission;
@@ -42,10 +41,10 @@
 
 namespace {
 
-void ReportQuotaUsage(blink::QuotaStatusCode code,
+void ReportQuotaUsage(blink::mojom::QuotaStatusCode code,
                       int64_t usage,
                       int64_t quota) {
-  if (code == blink::QuotaStatusCode::kOk) {
+  if (code == blink::mojom::QuotaStatusCode::kOk) {
     // We're interested in the amount of space hosted apps are using. Record it
     // when the extension is granted the unlimited storage permission (once per
     // extension load, so on average once per run).
@@ -72,7 +71,7 @@
         FROM_HERE, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
         base::BindOnce(&storage::QuotaManager::GetUsageAndQuotaForWebApps,
                        partition->GetQuotaManager(), launch_url,
-                       blink::StorageType::kPersistent,
+                       blink::mojom::StorageType::kPersistent,
                        base::Bind(&ReportQuotaUsage)));
   }
 }
diff --git a/chrome/browser/extensions/extension_storage_monitor.cc b/chrome/browser/extensions/extension_storage_monitor.cc
index 081c710..f9731bd 100644
--- a/chrome/browser/extensions/extension_storage_monitor.cc
+++ b/chrome/browser/extensions/extension_storage_monitor.cc
@@ -36,7 +36,7 @@
 #include "extensions/common/permissions/permissions_data.h"
 #include "storage/browser/quota/quota_manager.h"
 #include "storage/browser/quota/storage_observer.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/message_center/notification.h"
 #include "ui/message_center/notifier_id.h"
@@ -124,12 +124,12 @@
         should_uma_(should_uma) {
     // We always observe persistent storage usage.
     storage::StorageObserver::MonitorParams params(
-        blink::StorageType::kPersistent, origin, rate, false);
+        blink::mojom::StorageType::kPersistent, origin, rate, false);
     quota_manager_->AddStorageObserver(this, params);
     if (should_uma) {
       // And if this is for uma, we also observe temporary storage usage.
-      MonitorParams temporary_params(blink::StorageType::kTemporary, origin,
-                                     rate, false);
+      MonitorParams temporary_params(blink::mojom::StorageType::kTemporary,
+                                     origin, rate, false);
       quota_manager_->AddStorageObserver(this, temporary_params);
     }
   }
@@ -247,7 +247,7 @@
 
 void SingleExtensionStorageObserver::OnStorageEvent(const Event& event) {
   if (should_uma_) {
-    if (event.filter.storage_type == blink::StorageType::kPersistent) {
+    if (event.filter.storage_type == blink::mojom::StorageType::kPersistent) {
       UMA_HISTOGRAM_MEMORY_KB(
           "Extensions.HostedAppUnlimitedStoragePersistentStorageUsage",
           event.usage);
diff --git a/chrome/browser/extensions/extension_storage_monitor_browsertest.cc b/chrome/browser/extensions/extension_storage_monitor_browsertest.cc
index 2b2885f9..c651e28 100644
--- a/chrome/browser/extensions/extension_storage_monitor_browsertest.cc
+++ b/chrome/browser/extensions/extension_storage_monitor_browsertest.cc
@@ -383,7 +383,9 @@
 // Exercises the case where two hosted apps are same-origin but have non-
 // overlapping extents. Disabling one should not suppress storage monitoring for
 // the other.
-IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest, TwoHostedAppsInSameOrigin) {
+// Disabled for flakiness. crbug.com/799022
+IN_PROC_BROWSER_TEST_F(ExtensionStorageMonitorTest,
+                       DISABLED_TwoHostedAppsInSameOrigin) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
   GURL url1 = embedded_test_server()->GetURL(
diff --git a/chrome/browser/feedback/show_feedback_page.cc b/chrome/browser/feedback/show_feedback_page.cc
index b1b9520..31047965e 100644
--- a/chrome/browser/feedback/show_feedback_page.cc
+++ b/chrome/browser/feedback/show_feedback_page.cc
@@ -20,6 +20,7 @@
 void ShowFeedbackPage(Browser* browser,
                       FeedbackSource source,
                       const std::string& description_template,
+                      const std::string& description_placeholder_text,
                       const std::string& category_tag,
                       const std::string& extra_diagnostics) {
   GURL page_url;
@@ -42,7 +43,8 @@
       extensions::FeedbackPrivateAPI::GetFactoryInstance()->Get(profile);
 
   api->RequestFeedbackForFlow(
-      description_template, category_tag, extra_diagnostics, page_url,
+      description_template, description_placeholder_text, category_tag,
+      extra_diagnostics, page_url,
       source == kFeedbackSourceSadTabPage
           ? feedback_private::FeedbackFlow::FEEDBACK_FLOW_SADTABCRASH
           : feedback_private::FeedbackFlow::FEEDBACK_FLOW_REGULAR);
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index de7bb89..ec6c375 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -540,6 +540,11 @@
     "Adjusts scroll position to prevent visible jumps when offscreen content "
     "changes.";
 
+const char kEnableSharedArrayBufferName[] =
+    "Experimental enabled SharedArrayBuffer support in JavaScript.";
+const char kEnableSharedArrayBufferDescription[] =
+    "Enable SharedArrayBuffer support in JavaScript.";
+
 const char kEnableWasmName[] = "WebAssembly structured cloning support.";
 const char kEnableWasmDescription[] =
     "Enable web pages to use WebAssembly structured cloning.";
@@ -821,7 +826,6 @@
 
 const char kMarkHttpAsName[] = "Mark non-secure origins as non-secure";
 const char kMarkHttpAsDescription[] = "Change the UI treatment for HTTP pages";
-const char kMarkHttpAsDangerous[] = "Always mark HTTP as actively dangerous";
 
 const char kMaterialDesignIncognitoNTPName[] = "Material Design Incognito NTP.";
 const char kMaterialDesignIncognitoNTPDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 9d4873a..ccbe29f8 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -349,6 +349,9 @@
 extern const char kEnableScrollAnchoringName[];
 extern const char kEnableScrollAnchoringDescription[];
 
+extern const char kEnableSharedArrayBufferName[];
+extern const char kEnableSharedArrayBufferDescription[];
+
 extern const char kEnableWasmName[];
 extern const char kEnableWasmDescription[];
 
@@ -516,6 +519,9 @@
 extern const char kMarkHttpAsName[];
 extern const char kMarkHttpAsDescription[];
 extern const char kMarkHttpAsDangerous[];
+extern const char kMarkHttpAsWarning[];
+extern const char kMarkHttpAsWarningAndDangerousOnFormEdits[];
+extern const char kMarkHttpAsWarningAndDangerousOnPasswordsAndCreditCards[];
 
 extern const char kMaterialDesignIncognitoNTPName[];
 extern const char kMaterialDesignIncognitoNTPDescription[];
diff --git a/chrome/browser/guest_view/OWNERS b/chrome/browser/guest_view/OWNERS
index fa9ece6d..74d34105 100644
--- a/chrome/browser/guest_view/OWNERS
+++ b/chrome/browser/guest_view/OWNERS
@@ -1,2 +1,3 @@
-fsamuel@chromium.org
-lfg@chromium.org
+file://components/guest_view/OWNERS
+
+# COMPONENT: Platform>Apps>BrowserTag
diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/chrome_network_delegate.cc
index 400e7a0..8bab721 100644
--- a/chrome/browser/net/chrome_network_delegate.cc
+++ b/chrome/browser/net/chrome_network_delegate.cc
@@ -37,6 +37,7 @@
 #include "components/domain_reliability/monitor.h"
 #include "components/prefs/pref_member.h"
 #include "components/prefs/pref_service.h"
+#include "components/variations/net/variations_http_headers.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_view_host.h"
@@ -355,6 +356,7 @@
   if (domain_reliability_monitor_)
     domain_reliability_monitor_->OnBeforeRedirect(request);
   extensions_delegate_->OnBeforeRedirect(request, new_location);
+  variations::StripVariationHeaderIfNeeded(new_location, request);
 }
 
 void ChromeNetworkDelegate::OnResponseStarted(net::URLRequest* request,
diff --git a/chrome/browser/net/errorpage_browsertest.cc b/chrome/browser/net/errorpage_browsertest.cc
index e577d73..d532a47 100644
--- a/chrome/browser/net/errorpage_browsertest.cc
+++ b/chrome/browser/net/errorpage_browsertest.cc
@@ -464,24 +464,6 @@
         base::BindRepeating(
             [](DNSErrorPageTest* owner,
                content::URLLoaderInterceptor::RequestParams* params) {
-              // Handle mock failed request. The error code is embedded in the
-              // query.  Here we strip it out, and call OnComplete with it.
-              // TODO(dougt) mock.failed.request handling can be moved into the
-              // URLLoaderInterceptor implementation so that we can share this
-              // with other tests.
-              if (params->url_request.url.GetWithEmptyPath().spec() ==
-                  "http://mock.failed.request/") {
-                std::string query = params->url_request.url.query();
-                std::string error_code = query.substr(query.find("=") + 1);
-
-                int error = 0;
-                base::StringToInt(error_code, &error);
-                network::URLLoaderCompletionStatus status;
-                status.error_code = error;
-                params->client->OnComplete(status);
-                return true;
-              }
-
               // Add an interceptor that serves LinkDoctor responses
               if (google_util::LinkDoctorBaseURL() == params->url_request.url) {
                 // Send RequestCreated so that anyone blocking on
@@ -1538,8 +1520,15 @@
     BrowserThread::PostTask(
         BrowserThread::IO, FROM_HERE,
         base::BindOnce(&ErrorPageOfflineTest::InstallMockInterceptors));
+    url_loader_interceptor_ =
+        std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
+            [](content::URLLoaderInterceptor::RequestParams* params) {
+              return false;
+            }));
   }
 
+  void TearDownOnMainThread() override { url_loader_interceptor_.reset(); }
+
  protected:
   void SetUpInProcessBrowserTestFixture() override {
 #if defined(OS_CHROMEOS)
@@ -1622,6 +1611,7 @@
 
   // Mock policy provider for both user and device policies.
   policy::MockConfigurationPolicyProvider policy_provider_;
+  std::unique_ptr<content::URLLoaderInterceptor> url_loader_interceptor_;
 };
 
 class ErrorPageOfflineTestWithAllowDinosaurTrue : public ErrorPageOfflineTest {
diff --git a/chrome/browser/net/variations_http_headers_browsertest.cc b/chrome/browser/net/variations_http_headers_browsertest.cc
new file mode 100644
index 0000000..5ae09ee
--- /dev/null
+++ b/chrome/browser/net/variations_http_headers_browsertest.cc
@@ -0,0 +1,221 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/variations/net/variations_http_headers.h"
+
+#include <map>
+
+#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/network_session_configurator/common/network_switches.h"
+#include "components/variations/variations_http_header_provider.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/test/browser_test_utils.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace {
+
+class VariationsHttpHeadersBrowserTest : public InProcessBrowserTest {
+ public:
+  VariationsHttpHeadersBrowserTest()
+      : https_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) {}
+  ~VariationsHttpHeadersBrowserTest() override = default;
+
+  void SetUpOnMainThread() override {
+    InProcessBrowserTest::SetUpOnMainThread();
+
+    host_resolver()->AddRule("*", "127.0.0.1");
+
+    server()->RegisterRequestHandler(
+        base::BindRepeating(&VariationsHttpHeadersBrowserTest::RequestHandler,
+                            base::Unretained(this)));
+
+    ASSERT_TRUE(server()->Start());
+
+    // Set up some fake variations.
+    auto* variations_provider =
+        variations::VariationsHttpHeaderProvider::GetInstance();
+    variations_provider->SetDefaultVariationIds({"12", "456", "t789"});
+  }
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    InProcessBrowserTest::SetUpCommandLine(command_line);
+
+    command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
+  }
+
+  net::EmbeddedTestServer* server() { return &https_server_; }
+
+  GURL GetGoogleRedirectUrl1() const {
+    return GURL(base::StringPrintf("https://www.google.com:%d/redirect",
+                                   https_server_.port()));
+  }
+
+  GURL GetGoogleRedirectUrl2() const {
+    return GURL(base::StringPrintf("https://www.google.com:%d/redirect2",
+                                   https_server_.port()));
+  }
+
+  GURL GetExampleUrl() const {
+    return GURL(base::StringPrintf("https://www.example.com:%d/landing.html",
+                                   https_server_.port()));
+  }
+
+  // Returns whether a given |header| has been received for a |url|. Note that
+  // false is returned if the |url| has not been observed.
+  bool HasReceivedHeader(const GURL& url, const std::string& header) const {
+    auto it = received_headers_.find(url);
+    if (it == received_headers_.end())
+      return false;
+    return it->second.find(header) != it->second.end();
+  }
+
+ private:
+  // Custom request handler that record request headers and simulates a redirect
+  // from google.com to example.com.
+  std::unique_ptr<net::test_server::HttpResponse> RequestHandler(
+      const net::test_server::HttpRequest& request);
+
+  net::EmbeddedTestServer https_server_;
+
+  // Stores the observed HTTP Request headers.
+  std::map<GURL, net::test_server::HttpRequest::HeaderMap> received_headers_;
+
+  DISALLOW_COPY_AND_ASSIGN(VariationsHttpHeadersBrowserTest);
+};
+
+class BlockingURLFetcherDelegate : public net::URLFetcherDelegate {
+ public:
+  BlockingURLFetcherDelegate() = default;
+  ~BlockingURLFetcherDelegate() override = default;
+
+  void OnURLFetchComplete(const net::URLFetcher* source) override {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                  run_loop_.QuitClosure());
+  }
+
+  void AwaitResponse() { run_loop_.Run(); }
+
+ private:
+  base::RunLoop run_loop_;
+
+  DISALLOW_COPY_AND_ASSIGN(BlockingURLFetcherDelegate);
+};
+
+std::unique_ptr<net::test_server::HttpResponse>
+VariationsHttpHeadersBrowserTest::RequestHandler(
+    const net::test_server::HttpRequest& request) {
+  // Retrieve the host name (without port) from the request headers.
+  std::string host = "";
+  if (request.headers.find("Host") != request.headers.end())
+    host = request.headers.find("Host")->second;
+  if (host.find(':') != std::string::npos)
+    host = host.substr(0, host.find(':'));
+
+  // Recover the original URL of the request by replacing the host name in
+  // request.GetURL() (which is 127.0.0.1) with the host name from the request
+  // headers.
+  url::Replacements<char> replacements;
+  replacements.SetHost(host.c_str(), url::Component(0, host.length()));
+  GURL original_url = request.GetURL().ReplaceComponents(replacements);
+
+  // Memorize the request headers for this URL for later verification.
+  received_headers_[original_url] = request.headers;
+
+  // Set up a test server that redirects according to the
+  // following redirect chain:
+  // https://www.google.com:<port>/redirect
+  // --> https://www.google.com:<port>/redirect2
+  // --> https://www.example.com:<port>/
+  auto http_response = std::make_unique<net::test_server::BasicHttpResponse>();
+  if (request.relative_url == GetGoogleRedirectUrl1().path()) {
+    http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
+    http_response->AddCustomHeader("Location", GetGoogleRedirectUrl2().spec());
+  } else if (request.relative_url == GetGoogleRedirectUrl2().path()) {
+    http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
+    http_response->AddCustomHeader("Location", GetExampleUrl().spec());
+  } else if (request.relative_url == GetExampleUrl().path()) {
+    http_response->set_code(net::HTTP_OK);
+    http_response->set_content("hello");
+    http_response->set_content_type("text/plain");
+  } else {
+    http_response->set_code(net::HTTP_NO_CONTENT);
+  }
+  return http_response;
+}
+
+}  // namespace
+
+// Verify in an integration test that the variations header (X-Client-Data) is
+// attached to network requests to Google but stripped on redirects.
+IN_PROC_BROWSER_TEST_F(VariationsHttpHeadersBrowserTest,
+                       TestStrippingHeadersFromResourceRequest) {
+  ui_test_utils::NavigateToURL(browser(), GetGoogleRedirectUrl1());
+
+  EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl1(), "X-Client-Data"));
+  EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl2(), "X-Client-Data"));
+  EXPECT_TRUE(HasReceivedHeader(GetExampleUrl(), "Host"));
+  EXPECT_FALSE(HasReceivedHeader(GetExampleUrl(), "X-Client-Data"));
+}
+
+// Verify in an integration that that the variations header (X-Client-Data) is
+// correctly attached and stripped from network requests that are triggered via
+// a URLFetcher.
+IN_PROC_BROWSER_TEST_F(VariationsHttpHeadersBrowserTest,
+                       TestStrippingHeadersFromInternalRequest) {
+  BlockingURLFetcherDelegate delegate;
+
+  GURL url = GetGoogleRedirectUrl1();
+  std::unique_ptr<net::URLFetcher> fetcher =
+      net::URLFetcher::Create(url, net::URLFetcher::GET, &delegate);
+  net::HttpRequestHeaders headers;
+  variations::AppendVariationHeaders(url, variations::InIncognito::kNo,
+                                     variations::SignedIn::kNo, &headers);
+  fetcher->SetRequestContext(browser()->profile()->GetRequestContext());
+  fetcher->SetExtraRequestHeaders(headers.ToString());
+  fetcher->Start();
+
+  delegate.AwaitResponse();
+
+  EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl1(), "X-Client-Data"));
+  EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl2(), "X-Client-Data"));
+  EXPECT_TRUE(HasReceivedHeader(GetExampleUrl(), "Host"));
+  EXPECT_FALSE(HasReceivedHeader(GetExampleUrl(), "X-Client-Data"));
+}
+
+// Verify in an integration that that the variations header (X-Client-Data) is
+// correctly attached and stripped from network requests that are triggered via
+// the network service.
+IN_PROC_BROWSER_TEST_F(VariationsHttpHeadersBrowserTest,
+                       TestStrippingHeadersFromNetworkService) {
+  content::StoragePartition* partition =
+      content::BrowserContext::GetDefaultStoragePartition(browser()->profile());
+  content::mojom::NetworkContext* network_context =
+      partition->GetNetworkContext();
+  EXPECT_EQ(net::OK, content::LoadBasicRequest(network_context,
+                                               GetGoogleRedirectUrl1()));
+
+  // TODO(crbug.com/794644) Once the network service stack starts injecting
+  // X-Client-Data headers, the following expectations should be used.
+  EXPECT_FALSE(HasReceivedHeader(GetGoogleRedirectUrl1(), "X-Client-Data"));
+  /*
+  EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl1(), "X-Client-Data"));
+  EXPECT_TRUE(HasReceivedHeader(GetGoogleRedirectUrl2(), "X-Client-Data"));
+  EXPECT_TRUE(HasReceivedHeader(GetExampleUrl(), "Host"));
+  EXPECT_FALSE(HasReceivedHeader(GetExampleUrl(), "X-Client-Data"));
+  */
+}
diff --git a/chrome/browser/obsolete_system/obsolete_system_linux.cc b/chrome/browser/obsolete_system/obsolete_system_linux.cc
index a437bfd..10d94a57 100644
--- a/chrome/browser/obsolete_system/obsolete_system_linux.cc
+++ b/chrome/browser/obsolete_system/obsolete_system_linux.cc
@@ -4,8 +4,6 @@
 
 #include "chrome/browser/obsolete_system/obsolete_system.h"
 
-#include <stdint.h>
-
 // static
 bool ObsoleteSystem::IsObsoleteNowOrSoon() {
   return false;
diff --git a/chrome/browser/obsolete_system/obsolete_system_mac.cc b/chrome/browser/obsolete_system/obsolete_system_mac.cc
index 87fc267f..c2778d5a 100644
--- a/chrome/browser/obsolete_system/obsolete_system_mac.cc
+++ b/chrome/browser/obsolete_system/obsolete_system_mac.cc
@@ -4,11 +4,6 @@
 
 #include "chrome/browser/obsolete_system/obsolete_system.h"
 
-#include "base/mac/mac_util.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/grit/chromium_strings.h"
-#include "ui/base/l10n/l10n_util.h"
-
 // static
 bool ObsoleteSystem::IsObsoleteNowOrSoon() {
   return false;
@@ -16,9 +11,7 @@
 
 // static
 base::string16 ObsoleteSystem::LocalizedObsoleteString() {
-  return l10n_util::GetStringUTF16(IsEndOfTheLine()
-                                       ? IDS_MAC_10_678_OBSOLETE_NOW
-                                       : IDS_MAC_10_678_OBSOLETE_SOON);
+  return base::string16();
 }
 
 // static
@@ -28,5 +21,5 @@
 
 // static
 const char* ObsoleteSystem::GetLinkURL() {
-  return chrome::kMac10_678_DeprecationURL;
+  return "";
 }
diff --git a/chrome/browser/obsolete_system/obsolete_system_win.cc b/chrome/browser/obsolete_system/obsolete_system_win.cc
index 168b64635a..8c84565 100644
--- a/chrome/browser/obsolete_system/obsolete_system_win.cc
+++ b/chrome/browser/obsolete_system/obsolete_system_win.cc
@@ -16,9 +16,7 @@
 
 // static
 base::string16 ObsoleteSystem::LocalizedObsoleteString() {
-  return l10n_util::GetStringUTF16(IsEndOfTheLine()
-                                       ? IDS_WIN_XP_VISTA_OBSOLETE_NOW
-                                       : IDS_WIN_XP_VISTA_OBSOLETE_SOON);
+  return l10n_util::GetStringUTF16(IDS_WIN_XP_VISTA_OBSOLETE);
 }
 
 // static
diff --git a/chrome/browser/permissions/permission_uma_util.cc b/chrome/browser/permissions/permission_uma_util.cc
index 9c3832c..7c67292 100644
--- a/chrome/browser/permissions/permission_uma_util.cc
+++ b/chrome/browser/permissions/permission_uma_util.cc
@@ -92,6 +92,8 @@
       return "AudioCapture";
     case PermissionRequestType::PERMISSION_MEDIASTREAM_CAMERA:
       return "VideoCapture";
+    case PermissionRequestType::PERMISSION_CLIPBOARD_READ:
+      return "ClipboardRead";
     default:
       NOTREACHED();
       return "";
@@ -500,9 +502,9 @@
   bool secure_origin = content::IsOriginSecure(requesting_origin);
 
   switch (permission) {
-    // Geolocation, MidiSysEx, Push, and Media permissions are disabled on
-    // insecure origins, so there's no need to record separate metrics for
-    // secure/insecure.
+    // Geolocation, MidiSysEx, Push, Media and Clipboard permissions are
+    // disabled on insecure origins, so there's no need to record separate
+    // metrics for secure/insecure.
     case CONTENT_SETTINGS_TYPE_GEOLOCATION:
       UMA_HISTOGRAM_ENUMERATION("Permissions.Action.Geolocation", action,
                                 PermissionAction::NUM);
@@ -536,6 +538,10 @@
                             "Permissions.Action.SecureOrigin.Flash",
                             "Permissions.Action.InsecureOrigin.Flash", action);
       break;
+    case CONTENT_SETTINGS_TYPE_CLIPBOARD_READ:
+      UMA_HISTOGRAM_ENUMERATION("Permissions.Action.ClipboardRead", action,
+                                PermissionAction::NUM);
+      break;
     // The user is not prompted for these permissions, thus there is no
     // permission action recorded for them.
     default:
diff --git a/chrome/browser/permissions/permission_util.cc b/chrome/browser/permissions/permission_util.cc
index 632c931..6edf0c95 100644
--- a/chrome/browser/permissions/permission_util.cc
+++ b/chrome/browser/permissions/permission_util.cc
@@ -46,6 +46,8 @@
       return "AccessibilityEvents";
     case CONTENT_SETTINGS_TYPE_CLIPBOARD_READ:
       return "ClipboardRead";
+    case CONTENT_SETTINGS_TYPE_CLIPBOARD_WRITE:
+      return "ClipboardWrite";
     default:
       break;
   }
diff --git a/chrome/browser/platform_util_win.cc b/chrome/browser/platform_util_win.cc
index 51d6374..298f750 100644
--- a/chrome/browser/platform_util_win.cc
+++ b/chrome/browser/platform_util_win.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/platform_util.h"
 
+#include <windows.h>  // Must be in front of other Windows header files.
+
 #include <commdlg.h>
 #include <dwmapi.h>
 #include <shellapi.h>
diff --git a/chrome/browser/resources/feedback/js/feedback.js b/chrome/browser/resources/feedback/js/feedback.js
index 6089c1b..a4a3768 100644
--- a/chrome/browser/resources/feedback/js/feedback.js
+++ b/chrome/browser/resources/feedback/js/feedback.js
@@ -321,6 +321,7 @@
       }
 
       $('description-text').textContent = feedbackInfo.description;
+      $('description-text').placeholder = feedbackInfo.descriptionPlaceholder;
       if (feedbackInfo.pageUrl)
         $('page-url-text').value = feedbackInfo.pageUrl;
 
diff --git a/chrome/browser/resources/md_bookmarks/dnd_chip.html b/chrome/browser/resources/md_bookmarks/dnd_chip.html
index f9d9985..2bafd23e 100644
--- a/chrome/browser/resources/md_bookmarks/dnd_chip.html
+++ b/chrome/browser/resources/md_bookmarks/dnd_chip.html
@@ -45,10 +45,7 @@
         color: white;
         flex: 1;
         font-weight: 500;
-        overflow: hidden;
         text-decoration: none;
-        text-overflow: ellipsis;
-        white-space: nowrap;
       }
 
       #icon-wrapper {
@@ -88,7 +85,7 @@
       <div id="icon-wrapper" class="centered">
         <div id="icon"></div>
       </div>
-      <div id="title"></div>
+      <div id="title" class="elided-text"></div>
     </div>
     <div id="count" class="centered" hidden$="[[!isMultiItem_]]"></div>
   </template>
diff --git a/chrome/browser/resources/md_bookmarks/folder_node.html b/chrome/browser/resources/md_bookmarks/folder_node.html
index 182b0226..1dbf675 100644
--- a/chrome/browser/resources/md_bookmarks/folder_node.html
+++ b/chrome/browser/resources/md_bookmarks/folder_node.html
@@ -26,9 +26,6 @@
         -webkit-margin-start: 16px;
         color: var(--folder-inactive-color);
         font-weight: 500;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        white-space: nowrap;
       }
 
       #container {
@@ -102,7 +99,7 @@
             open$="[[isSelectedFolder_]]"
             no-children$="[[!hasChildFolder_]]">
         </div>
-        <div class="menu-label">[[item_.title]]</div>
+        <div class="menu-label elided-text">[[item_.title]]</div>
       </div>
     </div>
     <div id="descendants" role="group">
diff --git a/chrome/browser/resources/md_bookmarks/item.html b/chrome/browser/resources/md_bookmarks/item.html
index da6943d36..8051a838 100644
--- a/chrome/browser/resources/md_bookmarks/item.html
+++ b/chrome/browser/resources/md_bookmarks/item.html
@@ -28,14 +28,31 @@
       #website-title {
         -webkit-margin-start: 20px;
         flex: 1;
-        overflow: hidden;
         text-decoration: none;
-        text-overflow: ellipsis;
-        white-space: nowrap;
+      }
+
+      :host(:focus) #website-title,
+      :host([is-selected-item_]) #website-title {
+        flex: 0 auto;
+      }
+
+      #website-url {
+        -webkit-margin-start: 20px;
+        /* Transparent version of --secondary-text-color */
+        color: rgba(0, 0, 0, 0.54);
+        display: none;
+        flex: 1;
+        min-width: 100px;
+      }
+
+      :host(:focus) #website-url,
+      :host([is-selected-item_]) #website-url {
+        display: block;
       }
 
       #icon {
         color: var(--secondary-text-color);
+        flex: none;
       }
 
       button.more-vert-button {
@@ -43,9 +60,12 @@
       }
     </style>
     <div id="icon"></div>
-    <div id="website-title">
+    <div id="website-title" class="elided-text" title="[[item_.title]]">
       [[item_.title]]
     </div>
+    <div id="website-url" class="elided-text" title="[[item_.url]]">
+      [[item_.url]]
+    </div>
     <button id="menuButton"
         is="paper-icon-button-light"
         class="more-vert-button"
diff --git a/chrome/browser/resources/md_bookmarks/shared_style.html b/chrome/browser/resources/md_bookmarks/shared_style.html
index 790386a..d19fe62f 100644
--- a/chrome/browser/resources/md_bookmarks/shared_style.html
+++ b/chrome/browser/resources/md_bookmarks/shared_style.html
@@ -77,6 +77,12 @@
         margin: 2px;
         width: 16px;
       }
+
+      .elided-text {
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
     </style>
   </template>
 </dom-module>
diff --git a/chrome/browser/resources/md_bookmarks/toast_manager.html b/chrome/browser/resources/md_bookmarks/toast_manager.html
index 0e5b0b60..f94f634 100644
--- a/chrome/browser/resources/md_bookmarks/toast_manager.html
+++ b/chrome/browser/resources/md_bookmarks/toast_manager.html
@@ -11,9 +11,6 @@
         color: #fff;
         display: flex;
         flex: 1;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        white-space: nowrap;
       }
 
       paper-button {
@@ -36,7 +33,7 @@
       }
     </style>
     <cr-toast id="toast" duration="[[duration]]">
-      <div id="content"></div>
+      <div id="content" class="elided-text"></div>
       <paper-button id="button" hidden$="[[!showUndo_]]" on-tap="onUndoTap_">
         $i18n{undo}
       </paper-button>
diff --git a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc
index 5c9f26116..13c1681 100644
--- a/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/binary_integrity_analyzer_win_unittest.cc
@@ -20,6 +20,8 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#include <windows.h>
+
 using ::testing::_;
 using ::testing::StrictMock;
 
diff --git a/chrome/browser/sessions/better_session_restore_browsertest.cc b/chrome/browser/sessions/better_session_restore_browsertest.cc
index 9d32ddd..24946e0 100644
--- a/chrome/browser/sessions/better_session_restore_browsertest.cc
+++ b/chrome/browser/sessions/better_session_restore_browsertest.cc
@@ -614,12 +614,7 @@
 }
 
 // Check that form data is restored after wrench menu quit.
-#if defined(OS_LINUX)
-#define MAYBE_PostCloseAllBrowsers DISABLED_PostCloseAllBrowsers
-#else
-#define MAYBE_PostCloseAllBrowsers PostCloseAllBrowsers
-#endif
-IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, MAYBE_PostCloseAllBrowsers) {
+IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, PostCloseAllBrowsers) {
   PostFormWithPage("post.html", false);
   Browser* new_browser = QuitBrowserAndRestore(browser(), true);
   CheckFormRestored(new_browser, true, false);
diff --git a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
index 876326d..65720469 100644
--- a/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
+++ b/chrome/browser/ssl/security_state_tab_helper_browsertest.cc
@@ -30,8 +30,8 @@
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/features.h"
 #include "components/security_state/content/ssl_status_input_event_data.h"
+#include "components/security_state/core/features.h"
 #include "components/security_state/core/security_state.h"
-#include "components/security_state/core/switches.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/interstitial_page.h"
 #include "content/public/browser/navigation_controller.h"
@@ -1455,10 +1455,11 @@
   {
     // Ensure that the security level remains Dangerous in the
     // kMarkHttpAsDangerous configuration.
-    base::test::ScopedCommandLine scoped_command_line;
-    scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII(
-        security_state::switches::kMarkHttpAs,
-        security_state::switches::kMarkHttpAsDangerous);
+    base::test::ScopedFeatureList scoped_feature_list;
+    scoped_feature_list.InitAndEnableFeatureWithParameters(
+        security_state::features::kMarkHttpAsFeature,
+        {{security_state::features::kMarkHttpAsFeatureParameterName,
+          security_state::features::kMarkHttpAsParameterDangerous}});
 
     helper->GetSecurityInfo(&security_info);
     EXPECT_EQ(security_state::DANGEROUS, security_info.security_level);
@@ -2122,10 +2123,11 @@
 // MarkHttpAsDangerous is enabled.
 IN_PROC_BROWSER_TEST_F(SecurityStateTabHelperIncognitoTest,
                        SecurityLevelDangerousWhenMarkHttpAsDangerous) {
-  base::test::ScopedCommandLine scoped_command_line;
-  scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII(
-      security_state::switches::kMarkHttpAs,
-      security_state::switches::kMarkHttpAsDangerous);
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeatureWithParameters(
+      security_state::features::kMarkHttpAsFeature,
+      {{security_state::features::kMarkHttpAsFeatureParameterName,
+        security_state::features::kMarkHttpAsParameterDangerous}});
 
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -2429,4 +2431,121 @@
   EXPECT_EQ(security_state::NONE, security_info.security_level);
 }
 
+IN_PROC_BROWSER_TEST_F(SecurityStateTabHelperTest, MarkHttpAsWarning) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeatureWithParameters(
+      security_state::features::kMarkHttpAsFeature,
+      {{security_state::features::kMarkHttpAsFeatureParameterName,
+        security_state::features::kMarkHttpAsParameterWarning}});
+
+  content::WebContents* contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  SecurityStateTabHelper* helper =
+      SecurityStateTabHelper::FromWebContents(contents);
+  ASSERT_TRUE(helper);
+
+  // Navigate to an HTTP page. Use a non-local hostname so that it is
+  // not considered secure.
+  ui_test_utils::NavigateToURL(
+      browser(),
+      GetURLWithNonLocalHostname(embedded_test_server(), "/title1.html"));
+
+  security_state::SecurityInfo security_info;
+  helper->GetSecurityInfo(&security_info);
+  EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
+}
+
+IN_PROC_BROWSER_TEST_F(SecurityStateTabHelperTest,
+                       MarkHttpAsWarningAndDangerousOnFormEdits) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeatureWithParameters(
+      security_state::features::kMarkHttpAsFeature,
+      {{security_state::features::kMarkHttpAsFeatureParameterName,
+        security_state::features::
+            kMarkHttpAsParameterWarningAndDangerousOnFormEdits}});
+
+  content::WebContents* contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  SecurityStateTabHelper* helper =
+      SecurityStateTabHelper::FromWebContents(contents);
+  ASSERT_TRUE(helper);
+
+  // Navigate to an HTTP page. Use a non-local hostname so that it is
+  // not considered secure.
+  ui_test_utils::NavigateToURL(
+      browser(),
+      GetURLWithNonLocalHostname(embedded_test_server(),
+                                 "/textinput/focus_input_on_load.html"));
+
+  security_state::SecurityInfo security_info;
+  helper->GetSecurityInfo(&security_info);
+  EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
+
+  // Type one character into the focused input control and wait for a security
+  // state change.
+  SecurityStyleTestObserver observer(contents);
+  content::SimulateKeyPress(contents, ui::DomKey::FromCharacter('A'),
+                            ui::DomCode::US_A, ui::VKEY_A, false, false, false,
+                            false);
+  observer.WaitForDidChangeVisibleSecurityState();
+
+  // Verify that the security state degrades as expected.
+  helper->GetSecurityInfo(&security_info);
+  EXPECT_EQ(security_state::DANGEROUS, security_info.security_level);
+}
+
+IN_PROC_BROWSER_TEST_F(SecurityStateTabHelperTest,
+                       MarkHttpAsWarningAndDangerousOnPasswordsAndCreditCards) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeatureWithParameters(
+      security_state::features::kMarkHttpAsFeature,
+      {{security_state::features::kMarkHttpAsFeatureParameterName,
+        security_state::features::
+            kMarkHttpAsParameterWarningAndDangerousOnPasswordsAndCreditCards}});
+
+  content::WebContents* contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  SecurityStateTabHelper* helper =
+      SecurityStateTabHelper::FromWebContents(contents);
+  ASSERT_TRUE(helper);
+
+  // Navigate to an HTTP page. Use a non-local hostname so that it is
+  // not considered secure.
+  ui_test_utils::NavigateToURL(
+      browser(),
+      GetURLWithNonLocalHostname(embedded_test_server(), "/title1.html"));
+
+  security_state::SecurityInfo security_info;
+  helper->GetSecurityInfo(&security_info);
+  EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
+
+  // Insert a password field into the page and wait for a security state change.
+  {
+    SecurityStyleTestObserver observer(contents);
+    EXPECT_TRUE(
+        content::ExecuteScript(contents,
+                               "var i = document.createElement('input');"
+                               "i.type = 'password';"
+                               "i.id = 'password-field';"
+                               "document.body.appendChild(i);"));
+    observer.WaitForDidChangeVisibleSecurityState();
+
+    // Verify that the security state degrades as expected.
+    helper->GetSecurityInfo(&security_info);
+    EXPECT_EQ(security_state::DANGEROUS, security_info.security_level);
+  }
+
+  // Remove the password field and verify that the security level returns to
+  // HTTP_SHOW_WARNING.
+  {
+    SecurityStyleTestObserver observer(contents);
+    EXPECT_TRUE(content::ExecuteScript(contents,
+                                       "document.body.removeChild(document."
+                                       "getElementById('password-field'));"));
+    observer.WaitForDidChangeVisibleSecurityState();
+    helper->GetSecurityInfo(&security_info);
+    EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
+  }
+}
+
 }  // namespace
diff --git a/chrome/browser/ssl/security_state_tab_helper_unittest.cc b/chrome/browser/ssl/security_state_tab_helper_unittest.cc
index 1e0b026..8d418bcc 100644
--- a/chrome/browser/ssl/security_state_tab_helper_unittest.cc
+++ b/chrome/browser/ssl/security_state_tab_helper_unittest.cc
@@ -10,7 +10,6 @@
 #include "base/test/histogram_tester.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "components/security_state/content/ssl_status_input_event_data.h"
-#include "components/security_state/core/switches.h"
 #include "content/public/browser/navigation_entry.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc
index 962c81e..5014079 100644
--- a/chrome/browser/ssl/ssl_browsertest.cc
+++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -84,8 +84,8 @@
 #include "components/security_interstitials/content/security_interstitial_controller_client.h"
 #include "components/security_interstitials/core/controller_client.h"
 #include "components/security_interstitials/core/metrics_helper.h"
+#include "components/security_state/core/features.h"
 #include "components/security_state/core/security_state.h"
-#include "components/security_state/core/switches.h"
 #include "components/ssl_config/ssl_config_prefs.h"
 #include "components/ssl_errors/error_classification.h"
 #include "components/strings/grit/components_strings.h"
@@ -1940,10 +1940,11 @@
 // Ensure that non-standard origins are marked as neutral when the
 // MarkNonSecureAs Dangerous flag is enabled.
 IN_PROC_BROWSER_TEST_P(SSLUITest, MarkFileAsNonSecure) {
-  base::test::ScopedCommandLine scoped_command_line;
-  scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII(
-      security_state::switches::kMarkHttpAs,
-      security_state::switches::kMarkHttpAsDangerous);
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeatureWithParameters(
+      security_state::features::kMarkHttpAsFeature,
+      {{security_state::features::kMarkHttpAsFeatureParameterName,
+        security_state::features::kMarkHttpAsParameterDangerous}});
 
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -1962,10 +1963,11 @@
 // Ensure that about-protocol origins are marked as neutral when the
 // MarkNonSecureAs Dangerous flag is enabled.
 IN_PROC_BROWSER_TEST_P(SSLUITest, MarkAboutAsNonSecure) {
-  base::test::ScopedCommandLine scoped_command_line;
-  scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII(
-      security_state::switches::kMarkHttpAs,
-      security_state::switches::kMarkHttpAsDangerous);
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeatureWithParameters(
+      security_state::features::kMarkHttpAsFeature,
+      {{security_state::features::kMarkHttpAsFeatureParameterName,
+        security_state::features::kMarkHttpAsParameterDangerous}});
 
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -2000,10 +2002,11 @@
 // Ensure that HTTP-protocol origins are marked as Dangerous when the
 // MarkNonSecureAs Dangerous flag is enabled.
 IN_PROC_BROWSER_TEST_P(SSLUITest, MarkHTTPAsDangerous) {
-  base::test::ScopedCommandLine scoped_command_line;
-  scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII(
-      security_state::switches::kMarkHttpAs,
-      security_state::switches::kMarkHttpAsDangerous);
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeatureWithParameters(
+      security_state::features::kMarkHttpAsFeature,
+      {{security_state::features::kMarkHttpAsFeatureParameterName,
+        security_state::features::kMarkHttpAsParameterDangerous}});
 
   ASSERT_TRUE(embedded_test_server()->Start());
 
@@ -2025,10 +2028,11 @@
 // Ensure that blob-protocol origins are marked as neutral when the
 // MarkNonSecureAs Dangerous flag is enabled.
 IN_PROC_BROWSER_TEST_P(SSLUITest, MarkBlobAsNonSecure) {
-  base::test::ScopedCommandLine scoped_command_line;
-  scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII(
-      security_state::switches::kMarkHttpAs,
-      security_state::switches::kMarkHttpAsDangerous);
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeatureWithParameters(
+      security_state::features::kMarkHttpAsFeature,
+      {{security_state::features::kMarkHttpAsFeatureParameterName,
+        security_state::features::kMarkHttpAsParameterDangerous}});
 
   content::WebContents* contents =
       browser()->tab_strip_model()->GetActiveWebContents();
diff --git a/chrome/browser/storage/storage_info_fetcher.cc b/chrome/browser/storage/storage_info_fetcher.cc
index 5a7ea16..0b18d77 100644
--- a/chrome/browser/storage/storage_info_fetcher.cc
+++ b/chrome/browser/storage/storage_info_fetcher.cc
@@ -36,7 +36,7 @@
 }
 
 void StorageInfoFetcher::ClearStorage(const std::string& host,
-                                      blink::StorageType type,
+                                      blink::mojom::StorageType type,
                                       const ClearCallback& clear_callback) {
   // Balanced in OnUsageCleared.
   AddRef();
@@ -79,7 +79,8 @@
   Release();
 }
 
-void StorageInfoFetcher::OnUsageClearedInternal(blink::QuotaStatusCode code) {
+void StorageInfoFetcher::OnUsageClearedInternal(
+    blink::mojom::QuotaStatusCode code) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
   quota_manager_->ResetUsageTracker(type_to_delete_);
@@ -89,7 +90,7 @@
       base::Bind(&StorageInfoFetcher::OnClearCompleted, this, code));
 }
 
-void StorageInfoFetcher::OnClearCompleted(blink::QuotaStatusCode code) {
+void StorageInfoFetcher::OnClearCompleted(blink::mojom::QuotaStatusCode code) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   clear_callback_.Run(code);
diff --git a/chrome/browser/storage/storage_info_fetcher.h b/chrome/browser/storage/storage_info_fetcher.h
index 3a738b1..a773ff95 100644
--- a/chrome/browser/storage/storage_info_fetcher.h
+++ b/chrome/browser/storage/storage_info_fetcher.h
@@ -7,7 +7,7 @@
 
 #include "base/memory/ref_counted.h"
 #include "storage/browser/quota/quota_callbacks.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace storage {
 class QuotaManager;
@@ -21,7 +21,8 @@
  public:
   using FetchCallback =
       base::Callback<void(const storage::UsageInfoEntries&)>;
-  using ClearCallback = base::Callback<void(blink::QuotaStatusCode code)>;
+  using ClearCallback =
+      base::Callback<void(blink::mojom::QuotaStatusCode code)>;
 
   explicit StorageInfoFetcher(Profile* profile);
 
@@ -30,7 +31,7 @@
 
   // Asynchronously clears storage for the given host.
   void ClearStorage(const std::string& host,
-                    blink::StorageType type,
+                    blink::mojom::StorageType type,
                     const ClearCallback& clear_callback);
 
  private:
@@ -48,10 +49,10 @@
   void OnFetchCompleted();
 
   // Called when usage has been cleared.
-  void OnUsageClearedInternal(blink::QuotaStatusCode code);
+  void OnUsageClearedInternal(blink::mojom::QuotaStatusCode code);
 
   // Reports back to all observers that storage has been deleted.
-  void OnClearCompleted(blink::QuotaStatusCode code);
+  void OnClearCompleted(blink::mojom::QuotaStatusCode code);
 
   // The quota manager to use to calculate the storage usage.
   storage::QuotaManager* quota_manager_;
@@ -60,7 +61,7 @@
   storage::UsageInfoEntries entries_;
 
   // The storage type to delete.
-  blink::StorageType type_to_delete_;
+  blink::mojom::StorageType type_to_delete_;
 
   // The callback to use when fetching is complete.
   FetchCallback fetch_callback_;
diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.cc b/chrome/browser/supervised_user/supervised_user_interstitial.cc
index ebe69ed9b..a878359 100644
--- a/chrome/browser/supervised_user/supervised_user_interstitial.cc
+++ b/chrome/browser/supervised_user/supervised_user_interstitial.cc
@@ -269,7 +269,9 @@
 #else
     chrome::ShowFeedbackPage(chrome::FindBrowserWithWebContents(web_contents_),
                              chrome::kFeedbackSourceSupervisedUserInterstitial,
-                             message, std::string() /* category_tag */,
+                             message,
+                             std::string() /* description_placeholder_text */,
+                             std::string() /* category_tag */,
                              std::string() /* extra_diagnostics */);
 #endif
     return;
diff --git a/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc b/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
index e3206a3..86e0e2b 100644
--- a/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
+++ b/chrome/browser/sync_file_system/local/canned_syncable_file_system.cc
@@ -196,7 +196,7 @@
 void DidGetUsageAndQuota(const storage::StatusCallback& callback,
                          int64_t* usage_out,
                          int64_t* quota_out,
-                         blink::QuotaStatusCode status,
+                         blink::mojom::QuotaStatusCode status,
                          int64_t usage,
                          int64_t quota) {
   *usage_out = usage;
@@ -464,10 +464,10 @@
                      origin_, type_));
 }
 
-blink::QuotaStatusCode CannedSyncableFileSystem::GetUsageAndQuota(
+blink::mojom::QuotaStatusCode CannedSyncableFileSystem::GetUsageAndQuota(
     int64_t* usage,
     int64_t* quota) {
-  return RunOnThread<blink::QuotaStatusCode>(
+  return RunOnThread<blink::mojom::QuotaStatusCode>(
       io_task_runner_.get(), FROM_HERE,
       base::BindOnce(&CannedSyncableFileSystem::DoGetUsageAndQuota,
                      base::Unretained(this), usage, quota));
diff --git a/chrome/browser/sync_file_system/local/canned_syncable_file_system.h b/chrome/browser/sync_file_system/local/canned_syncable_file_system.h
index cd3eea5..77fec33 100644
--- a/chrome/browser/sync_file_system/local/canned_syncable_file_system.h
+++ b/chrome/browser/sync_file_system/local/canned_syncable_file_system.h
@@ -24,8 +24,7 @@
 #include "storage/browser/quota/quota_callbacks.h"
 #include "storage/common/fileapi/file_system_types.h"
 #include "storage/common/fileapi/file_system_util.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace base {
 class SingleThreadTaskRunner;
@@ -110,7 +109,7 @@
   storage::QuotaManager* quota_manager() { return quota_manager_.get(); }
   GURL origin() const { return origin_; }
   storage::FileSystemType type() const { return type_; }
-  blink::StorageType storage_type() const {
+  blink::mojom::StorageType storage_type() const {
     return FileSystemTypeToQuotaStorageType(type_);
   }
 
@@ -152,7 +151,8 @@
   base::File::Error DeleteFileSystem();
 
   // Retrieves the quota and usage.
-  blink::QuotaStatusCode GetUsageAndQuota(int64_t* usage, int64_t* quota);
+  blink::mojom::QuotaStatusCode GetUsageAndQuota(int64_t* usage,
+                                                 int64_t* quota);
 
   // ChangeTracker related methods. They run on file task runner.
   void GetChangedURLsInTracker(storage::FileSystemURLSet* urls);
diff --git a/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc b/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc
index f0c1d784..5047329 100644
--- a/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc
+++ b/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc
@@ -611,7 +611,7 @@
   // Record the initial usage (likely 0).
   int64_t initial_usage = -1;
   int64_t quota = -1;
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system.GetUsageAndQuota(&initial_usage, &quota));
 
   // Create a file and directory in the file_system.
@@ -637,7 +637,7 @@
 
   // At this point the usage must be greater than the initial usage.
   int64_t new_usage = -1;
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system.GetUsageAndQuota(&new_usage, &quota));
   EXPECT_GT(new_usage, initial_usage);
 
@@ -673,7 +673,7 @@
   EXPECT_TRUE(urls.empty());
 
   // The quota usage data must have reflected the deletion.
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system.GetUsageAndQuota(&new_usage, &quota));
   EXPECT_EQ(new_usage, initial_usage);
 
@@ -699,7 +699,7 @@
   // Record the initial usage (likely 0).
   int64_t initial_usage = -1;
   int64_t quota = -1;
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system.GetUsageAndQuota(&initial_usage, &quota));
 
   // Create a file and directory in the file_system.
@@ -713,7 +713,7 @@
 
   // At this point the usage must be greater than the initial usage.
   int64_t new_usage = -1;
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system.GetUsageAndQuota(&new_usage, &quota));
   EXPECT_GT(new_usage, initial_usage);
 
@@ -740,7 +740,7 @@
   EXPECT_TRUE(urls.empty());
 
   // The quota usage data must have reflected the deletion.
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system.GetUsageAndQuota(&new_usage, &quota));
   EXPECT_EQ(new_usage, initial_usage);
 
@@ -806,7 +806,7 @@
   // Record the usage.
   int64_t usage = -1, new_usage = -1;
   int64_t quota = -1;
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system.GetUsageAndQuota(&usage, &quota));
 
   // Here in the local filesystem we have:
@@ -833,7 +833,7 @@
   // Check if the usage has been increased by (kTestFileData1 - kTestFileData0).
   const int updated_size =
       arraysize(kTestFileData1) - arraysize(kTestFileData0);
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system.GetUsageAndQuota(&new_usage, &quota));
   EXPECT_EQ(updated_size, new_usage - usage);
 
@@ -880,7 +880,7 @@
   // Creating a file/directory must have increased the usage more than
   // the size of kTestFileData2.
   new_usage = usage;
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system.GetUsageAndQuota(&new_usage, &quota));
   EXPECT_GT(new_usage,
             static_cast<int64_t>(usage + arraysize(kTestFileData2) - 1));
diff --git a/chrome/browser/sync_file_system/local/syncable_file_system_unittest.cc b/chrome/browser/sync_file_system/local/syncable_file_system_unittest.cc
index 420e039..157e15d5 100644
--- a/chrome/browser/sync_file_system/local/syncable_file_system_unittest.cc
+++ b/chrome/browser/sync_file_system/local/syncable_file_system_unittest.cc
@@ -127,7 +127,7 @@
   const int64_t kQuota = 12345 * 1024;
   QuotaManager::kSyncableStorageDefaultHostQuota = kQuota;
   int64_t usage, quota;
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system_.GetUsageAndQuota(&usage, &quota));
 
   // Returned quota must be what we overrode. Usage must be greater than 0
@@ -144,7 +144,7 @@
             file_system_.TruncateFile(URL("dir/foo"), kFileSizeToExtend));
 
   int64_t new_usage;
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system_.GetUsageAndQuota(&new_usage, &quota));
   EXPECT_EQ(kFileSizeToExtend, new_usage - usage);
 
@@ -155,7 +155,7 @@
             file_system_.TruncateFile(URL("dir/foo"), kFileSizeToExtend + 1));
 
   usage = new_usage;
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system_.GetUsageAndQuota(&new_usage, &quota));
   EXPECT_EQ(usage, new_usage);
 
@@ -164,7 +164,7 @@
             file_system_.DeleteFileSystem());
 
   // Now the usage must be zero.
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             file_system_.GetUsageAndQuota(&usage, &quota));
   EXPECT_EQ(0, usage);
 
diff --git a/chrome/browser/task_manager/sampling/task_group.cc b/chrome/browser/task_manager/sampling/task_group.cc
index 95a622f..5fb10b7d 100644
--- a/chrome/browser/task_manager/sampling/task_group.cc
+++ b/chrome/browser/task_manager/sampling/task_group.cc
@@ -18,6 +18,10 @@
 #include "content/public/common/content_features.h"
 #include "gpu/ipc/common/memory_stats.h"
 
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
 namespace task_manager {
 
 namespace {
diff --git a/chrome/browser/themes/theme_properties.cc b/chrome/browser/themes/theme_properties.cc
index 3ab2048e..58e959e 100644
--- a/chrome/browser/themes/theme_properties.cc
+++ b/chrome/browser/themes/theme_properties.cc
@@ -14,6 +14,10 @@
 #include "ui/base/material_design/material_design_controller.h"
 #include "ui/gfx/color_palette.h"
 
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
 namespace {
 
 // ----------------------------------------------------------------------------
diff --git a/chrome/browser/ui/app_list/app_list_controller_browsertest.cc b/chrome/browser/ui/app_list/app_list_controller_browsertest.cc
index 45fc5b5..2c09b1c 100644
--- a/chrome/browser/ui/app_list/app_list_controller_browsertest.cc
+++ b/chrome/browser/ui/app_list/app_list_controller_browsertest.cc
@@ -4,7 +4,6 @@
 
 #include <stddef.h>
 
-#include "ash/app_list/model/search/search_box_model.h"
 #include "ash/app_list/model/search/search_model.h"
 #include "ash/app_list/model/search/search_result.h"
 #include "ash/app_list/model/search/search_result_observer.h"
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h
index 57640c32..7b05a63 100644
--- a/chrome/browser/ui/app_list/app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -11,6 +11,8 @@
 
 #include "ash/app_list/model/app_list_folder_item.h"
 #include "ash/app_list/model/app_list_model.h"
+#include "ash/app_list/model/speech/speech_ui_model.h"
+#include "base/strings/string16.h"
 
 class ChromeAppListItem;
 
@@ -45,6 +47,14 @@
   virtual void HighlightItemInstalledFromUI(const std::string& id) {}
   // For SearchModel:
   virtual void SetSearchEngineIsGoogle(bool is_google) {}
+  virtual void SetSearchTabletAndClamshellAccessibleName(
+      const base::string16& tablet_accessible_name,
+      const base::string16& clamshell_accessible_name) {}
+  virtual void SetSearchHintText(const base::string16& hint_text) {}
+  virtual void SetSearchSpeechRecognitionButton(
+      app_list::SpeechRecognitionState state) {}
+  virtual void UpdateSearchBox(const base::string16& text,
+                               bool initiated_by_user) {}
 
   // For AppListModel:
   virtual ChromeAppListItem* FindItem(const std::string& id) = 0;
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.cc b/chrome/browser/ui/app_list/app_list_view_delegate.cc
index f635b886..daf4fdc 100644
--- a/chrome/browser/ui/app_list/app_list_view_delegate.cc
+++ b/chrome/browser/ui/app_list/app_list_view_delegate.cc
@@ -11,7 +11,6 @@
 
 #include "ash/app_list/model/app_list_model.h"
 #include "ash/app_list/model/app_list_view_state.h"
-#include "ash/app_list/model/search/search_box_model.h"
 #include "ash/app_list/model/speech/speech_ui_model.h"
 #include "ash/public/interfaces/constants.mojom.h"
 #include "base/command_line.h"
@@ -187,8 +186,8 @@
   OnTemplateURLServiceChanged();
 
   // Clear search query.
-  search_model_->search_box()->Update(base::string16(),
-                                      false /* initiated_by_user */);
+  model_updater_->UpdateSearchBox(base::string16(),
+                                  false /* initiated_by_user */);
 }
 
 void AppListViewDelegate::OnGetWallpaperColorsCallback(
@@ -208,7 +207,7 @@
                                         false);
 
   search_resource_manager_.reset(new app_list::SearchResourceManager(
-      profile_, search_model_->search_box(), speech_ui_.get()));
+      profile_, model_updater_, speech_ui_.get()));
 
   search_controller_ = CreateSearchController(profile_, model_updater_,
                                               search_model_, controller_);
@@ -240,9 +239,9 @@
   return speech_ui_.get();
 }
 
-void AppListViewDelegate::StartSearch() {
+void AppListViewDelegate::StartSearch(const base::string16& raw_query) {
   if (search_controller_) {
-    search_controller_->Start();
+    search_controller_->Start(raw_query);
     controller_->OnSearchStarted();
   }
 }
@@ -377,7 +376,7 @@
       default_provider->GetEngineType(
           template_url_service->search_terms_data()) == SEARCH_ENGINE_GOOGLE;
 
-  search_model_->SetSearchEngineIsGoogle(is_google);
+  model_updater_->SetSearchEngineIsGoogle(is_google);
 
   app_list::StartPageService* start_page_service =
       app_list::StartPageService::Get(profile_);
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.h b/chrome/browser/ui/app_list/app_list_view_delegate.h
index d577e2b2..c3b7301 100644
--- a/chrome/browser/ui/app_list/app_list_view_delegate.h
+++ b/chrome/browser/ui/app_list/app_list_view_delegate.h
@@ -69,7 +69,7 @@
   app_list::AppListModel* GetModel() override;
   app_list::SearchModel* GetSearchModel() override;
   app_list::SpeechUIModel* GetSpeechUI() override;
-  void StartSearch() override;
+  void StartSearch(const base::string16& raw_query) override;
   void OpenSearchResult(app_list::SearchResult* result,
                         int event_flags) override;
   void InvokeSearchResultAction(app_list::SearchResult* result,
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
index 5bf579031..4a14957 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -63,6 +63,28 @@
   search_model_->SetSearchEngineIsGoogle(is_google);
 }
 
+void ChromeAppListModelUpdater::SetSearchTabletAndClamshellAccessibleName(
+    const base::string16& tablet_accessible_name,
+    const base::string16& clamshell_accessible_name) {
+  search_model_->search_box()->SetTabletAndClamshellAccessibleName(
+      tablet_accessible_name, clamshell_accessible_name);
+}
+
+void ChromeAppListModelUpdater::SetSearchHintText(
+    const base::string16& hint_text) {
+  search_model_->search_box()->SetHintText(hint_text);
+}
+
+void ChromeAppListModelUpdater::SetSearchSpeechRecognitionButton(
+    app_list::SpeechRecognitionState state) {
+  search_model_->search_box()->SetSpeechRecognitionButton(state);
+}
+
+void ChromeAppListModelUpdater::UpdateSearchBox(const base::string16& text,
+                                                bool initiated_by_user) {
+  search_model_->search_box()->Update(text, initiated_by_user);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Methods only used by ChromeAppListItem that talk to ash directly.
 
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
index 7fbca14..a3dcf43 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
@@ -32,6 +32,14 @@
   void SetState(app_list::AppListModel::State state) override;
   void HighlightItemInstalledFromUI(const std::string& id) override;
   void SetSearchEngineIsGoogle(bool is_google) override;
+  void SetSearchTabletAndClamshellAccessibleName(
+      const base::string16& tablet_accessible_name,
+      const base::string16& clamshell_accessible_name) override;
+  void SetSearchHintText(const base::string16& hint_text) override;
+  void SetSearchSpeechRecognitionButton(
+      app_list::SpeechRecognitionState state) override;
+  void UpdateSearchBox(const base::string16& text,
+                       bool initiated_by_user) override;
 
   // Methods for item querying.
   ChromeAppListItem* FindItem(const std::string& id) override;
diff --git a/chrome/browser/ui/app_list/search/omnibox_provider.cc b/chrome/browser/ui/app_list/search/omnibox_provider.cc
index e4a079d..9588d7e 100644
--- a/chrome/browser/ui/app_list/search/omnibox_provider.cc
+++ b/chrome/browser/ui/app_list/search/omnibox_provider.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/ui/app_list/search/omnibox_provider.h"
 
-#include "ash/app_list/model/search/search_result.h"
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h"
 #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h"
diff --git a/chrome/browser/ui/app_list/search/search_controller_factory.cc b/chrome/browser/ui/app_list/search/search_controller_factory.cc
index 72817f17..a45df3a 100644
--- a/chrome/browser/ui/app_list/search/search_controller_factory.cc
+++ b/chrome/browser/ui/app_list/search/search_controller_factory.cc
@@ -75,7 +75,7 @@
     AppListControllerDelegate* list_controller) {
   std::unique_ptr<SearchController> controller =
       std::make_unique<SearchController>(
-          search_model->search_box(), search_model->results(),
+          search_model->results(),
           HistoryFactory::GetForBrowserContext(profile));
 
   // Add mixer groups. There are four main groups: answer card, apps, webstore
diff --git a/chrome/browser/ui/app_list/search/search_resource_manager.cc b/chrome/browser/ui/app_list/search/search_resource_manager.cc
index 30e3e1fc..987eb61b 100644
--- a/chrome/browser/ui/app_list/search/search_resource_manager.cc
+++ b/chrome/browser/ui/app_list/search/search_resource_manager.cc
@@ -6,9 +6,9 @@
 
 #include <memory>
 
-#include "ash/app_list/model/search/search_box_model.h"
 #include "ash/app_list/model/speech/speech_ui_model.h"
 #include "base/memory/ptr_util.h"
+#include "chrome/browser/ui/app_list/app_list_model_updater.h"
 #include "chrome/browser/ui/app_list/start_page_service.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/theme_resources.h"
@@ -18,27 +18,15 @@
 
 namespace app_list {
 
-namespace {
-
-std::unique_ptr<SearchBoxModel::SpeechButtonProperty> CreateNewProperty(
-    SpeechRecognitionState state) {
-  // Currently no speech support in app list.
-  // TODO(xiaohuic): when implementing speech support in new app list, we should
-  // either reuse this and related logic or delete them.
-  return nullptr;
-}
-
-}  // namespace
-
 SearchResourceManager::SearchResourceManager(Profile* profile,
-                                             SearchBoxModel* search_box,
+                                             AppListModelUpdater* model_updater,
                                              SpeechUIModel* speech_ui)
-    : search_box_(search_box),
+    : model_updater_(model_updater),
       speech_ui_(speech_ui),
       is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()) {
   speech_ui_->AddObserver(this);
   // Give |SearchBoxModel| tablet and clamshell A11y Announcements.
-  search_box_->SetTabletAndClamshellAccessibleName(
+  model_updater_->SetSearchTabletAndClamshellAccessibleName(
       l10n_util::GetStringUTF16(IDS_SEARCH_BOX_ACCESSIBILITY_NAME_TABLET),
       l10n_util::GetStringUTF16(IDS_SEARCH_BOX_ACCESSIBILITY_NAME));
   OnSpeechRecognitionStateChanged(speech_ui_->state());
@@ -51,11 +39,12 @@
 void SearchResourceManager::OnSpeechRecognitionStateChanged(
     SpeechRecognitionState new_state) {
   if (is_fullscreen_app_list_enabled_) {
-    search_box_->SetHintText(
+    model_updater_->SetSearchHintText(
         l10n_util::GetStringUTF16(IDS_SEARCH_BOX_HINT_FULLSCREEN));
   } else {
-    search_box_->SetHintText(l10n_util::GetStringUTF16(IDS_SEARCH_BOX_HINT));
-    search_box_->SetSpeechRecognitionButton(CreateNewProperty(new_state));
+    model_updater_->SetSearchHintText(
+        l10n_util::GetStringUTF16(IDS_SEARCH_BOX_HINT));
+    model_updater_->SetSearchSpeechRecognitionButton(new_state);
   }
 }
 
diff --git a/chrome/browser/ui/app_list/search/search_resource_manager.h b/chrome/browser/ui/app_list/search/search_resource_manager.h
index 28d6200..7122dfd 100644
--- a/chrome/browser/ui/app_list/search/search_resource_manager.h
+++ b/chrome/browser/ui/app_list/search/search_resource_manager.h
@@ -8,18 +8,18 @@
 #include "ash/app_list/model/speech/speech_ui_model_observer.h"
 #include "base/macros.h"
 
+class AppListModelUpdater;
 class Profile;
 
 namespace app_list {
 
-class SearchBoxModel;
 class SpeechUIModel;
 
 // Manages the strings and assets of the app-list search box.
 class SearchResourceManager : public SpeechUIModelObserver {
  public:
   SearchResourceManager(Profile* profile,
-                        SearchBoxModel* search_box,
+                        AppListModelUpdater* model_updater,
                         SpeechUIModel* speech_ui);
   ~SearchResourceManager() override;
 
@@ -28,7 +28,7 @@
   void OnSpeechRecognitionStateChanged(
       SpeechRecognitionState new_state) override;
 
-  SearchBoxModel* search_box_;
+  AppListModelUpdater* model_updater_;
   SpeechUIModel* speech_ui_;
 
   const bool is_fullscreen_app_list_enabled_;
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 928bcaf..ee4755a 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -1095,6 +1095,7 @@
   base::RecordAction(UserMetricsAction("Feedback"));
   chrome::ShowFeedbackPage(
       browser, source, std::string() /* description_template */,
+      std::string() /* description_placeholder_text */,
       std::string() /* category_tag */, std::string() /* extra_diagnostics */);
 }
 
diff --git a/chrome/browser/ui/chrome_pages.h b/chrome/browser/ui/chrome_pages.h
index 89e40057..2709102 100644
--- a/chrome/browser/ui/chrome_pages.h
+++ b/chrome/browser/ui/chrome_pages.h
@@ -66,6 +66,7 @@
 void ShowFeedbackPage(Browser* browser,
                       FeedbackSource source,
                       const std::string& description_template,
+                      const std::string& description_placeholder_text,
                       const std::string& category_tag,
                       const std::string& extra_diagnostics);
 
diff --git a/chrome/browser/ui/cocoa/infobars/confirm_infobar_controller.mm b/chrome/browser/ui/cocoa/infobars/confirm_infobar_controller.mm
index 3417cb5..aa10f6b 100644
--- a/chrome/browser/ui/cocoa/infobars/confirm_infobar_controller.mm
+++ b/chrome/browser/ui/cocoa/infobars/confirm_infobar_controller.mm
@@ -127,8 +127,11 @@
   if (linkLength != 0) {
     NSColor* linkColor =
         skia::SkColorToCalibratedNSColor(chrome_style::GetLinkColor());
+    GURL linkUrl = delegate->GetLinkURL();
+    NSString* urlString =
+        linkUrl.is_valid() ? base::SysUTF8ToNSString(linkUrl.spec()) : nil;
     [view addLinkRange:NSMakeRange(linkOffset, linkLength)
-               withURL:base::SysUTF8ToNSString(delegate->GetLinkURL().spec())
+               withURL:urlString
              linkColor:linkColor];
   }
 }
diff --git a/chrome/browser/ui/cocoa/tabs/tab_controller.h b/chrome/browser/ui/cocoa/tabs/tab_controller.h
index e28817d..8674cca 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_controller.h
+++ b/chrome/browser/ui/cocoa/tabs/tab_controller.h
@@ -42,9 +42,14 @@
 
 @interface TabController : NSViewController<TabDraggingEventTarget>
 
-@property(assign, nonatomic) TabLoadingState loadingState;
+@property(readonly, nonatomic) TabLoadingState loadingState;
 
 @property(assign, nonatomic) SEL action;
+// showIcon is YES when the tab should display a favicon (e.g. has an icon, is
+// not the NTP, etc.), and is equivalent to the data.show_icon flag in Views.
+// Actual favicon visibility depends on other factors such as available space,
+// and is reflected in the iconView's isHidden state.
+@property(readonly, nonatomic) BOOL showIcon;
 @property(assign, nonatomic) BOOL pinned;
 @property(assign, nonatomic) BOOL blocked;
 @property(assign, nonatomic) NSString* toolTip;
@@ -55,7 +60,6 @@
 @property(assign, nonatomic) BOOL selected;
 @property(assign, nonatomic) id target;
 @property(assign, nonatomic) GURL url;
-@property(readonly, nonatomic) NSView* iconView;
 @property(readonly, nonatomic) AlertIndicatorButton* alertIndicatorButton;
 @property(readonly, nonatomic) HoverCloseButton* closeButton;
 
@@ -75,11 +79,10 @@
 
 // Sets the tab's icon image.
 // |image| must be 16x16 in size.
-// |image| can be a horizontal strip of image sprites which will be animated.
-// Setting |animate| to YES will animate away the old image before animating
-// the new image back to position.
-- (void)setIconImage:(NSImage*)image;
-- (void)setIconImage:(NSImage*)image withToastAnimation:(BOOL)animate;
+// |showIcon| is YES when the tab should show its favicon.
+- (void)setIconImage:(NSImage*)image
+     forLoadingState:(TabLoadingState)loadingState
+            showIcon:(BOOL)showIcon;
 
 // Sets the current tab alert state and updates the views.
 - (void)setAlertState:(TabAlertState)alertState;
@@ -118,6 +121,7 @@
 @end
 
 @interface TabController(TestingAPI)
+- (NSView*)iconView;
 - (int)iconCapacity;
 - (BOOL)shouldShowIcon;
 - (BOOL)shouldShowAlertIndicator;
diff --git a/chrome/browser/ui/cocoa/tabs/tab_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_controller.mm
index b254c19..d83f7e4 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_controller.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_controller.mm
@@ -22,12 +22,15 @@
 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h"
 #import "chrome/browser/ui/cocoa/tabs/tab_view.h"
 #import "chrome/browser/ui/cocoa/themed_window.h"
+#include "chrome/grit/theme_resources.h"
+#include "components/grit/components_scaled_resources.h"
 #import "extensions/common/extension.h"
 #include "skia/ext/skia_utils_mac.h"
 #import "ui/base/cocoa/menu_controller.h"
-#include "ui/base/material_design/material_design_controller.h"
+#include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/favicon_size.h"
 #include "ui/native_theme/native_theme.h"
+#include "ui/resources/grit/ui_resources.h"
 
 namespace {
 
@@ -67,8 +70,6 @@
   base::scoped_nsobject<AlertIndicatorButton> alertIndicatorButton_;
   base::scoped_nsobject<HoverCloseButton> closeButton_;
 
-  BOOL isIconShowing_;  // last state of iconView_ in updateVisibility
-
   BOOL active_;
   BOOL selected_;
   std::unique_ptr<ui::SimpleMenuModel> contextMenuModel_;
@@ -94,6 +95,7 @@
 @synthesize action = action_;
 @synthesize currentAttentionTypes = currentAttentionTypes_;
 @synthesize loadingState = loadingState_;
+@synthesize showIcon = showIcon_;
 @synthesize pinned = pinned_;
 @synthesize target = target_;
 @synthesize url = url_;
@@ -169,7 +171,6 @@
                                          : NSViewMaxXMargin | NSViewMinYMargin];
     [self updateIconViewFrameWithAnimation:NO];
     [tabView addSubview:iconView_];
-    isIconShowing_ = YES;
 
     // Set up the title.
     const CGFloat titleXOrigin =
@@ -326,18 +327,11 @@
   CGFloat leadingPadding =
       [self pinned] ? kPinnedTabLeadingPadding : kTabLeadingPadding;
 
-  NSRect iconViewFrame;
+  NSRect iconViewFrame = [iconView_ frame];
   iconViewFrame.origin.x = isRTL ? NSWidth([[self tabView] frame]) -
                                        leadingPadding - gfx::kFaviconSize
                                  : leadingPadding;
 
-  // As long as the iconView gets repeatedly created and destroyed we have to
-  // initialize the other struct values. Once the iconView gets created a single
-  // time per tab we can rely on the values that get set in -init (and remove
-  // these lines).
-  iconViewFrame.origin.y = kTabElementYOrigin;
-  iconViewFrame.size = NSMakeSize(gfx::kFaviconSize, gfx::kFaviconSize);
-
   // The iconView animation looks funky in RTL so don't allow it.
   if (shouldAnimate && !isRTL) {
     // Animate at the same rate as the tab changes shape.
@@ -349,20 +343,6 @@
   }
 }
 
-- (SpriteView*)iconView {
-  return iconView_;
-}
-
-- (void)setIconView:(SpriteView*)iconView {
-  [iconView_ removeFromSuperview];
-  iconView_.reset([iconView retain]);
-
-  if (iconView_) {
-    [[self view] addSubview:iconView_];
-    [self updateAttentionIndicator];
-  }
-}
-
 - (AlertIndicatorButton*)alertIndicatorButton {
   return alertIndicatorButton_;
 }
@@ -423,6 +403,10 @@
   [[self tabView] setToolTipText:toolTip];
 }
 
+- (NSView*)iconView {
+  return iconView_;
+}
+
 // Return a rough approximation of the number of icons we could fit in the
 // tab. We never actually do this, but it's a helpful guide for determining
 // how much space we have available.
@@ -441,16 +425,16 @@
 
 - (BOOL)shouldShowIcon {
   return chrome::ShouldTabShowFavicon(
-      [self iconCapacity], [self pinned], [self active], iconView_ != nil,
-      !alertIndicatorButton_ ? TabAlertState::NONE :
-          [alertIndicatorButton_ showingAlertState]);
+      [self iconCapacity], [self pinned], [self active], [self showIcon],
+      !alertIndicatorButton_ ? TabAlertState::NONE
+                             : [alertIndicatorButton_ showingAlertState]);
 }
 
 - (BOOL)shouldShowAlertIndicator {
   return chrome::ShouldTabShowAlertIndicator(
-      [self iconCapacity], [self pinned], [self active], iconView_ != nil,
-      !alertIndicatorButton_ ? TabAlertState::NONE :
-          [alertIndicatorButton_ showingAlertState]);
+      [self iconCapacity], [self pinned], [self active], [self showIcon],
+      !alertIndicatorButton_ ? TabAlertState::NONE
+                             : [alertIndicatorButton_ showingAlertState]);
 }
 
 - (BOOL)shouldShowCloseButton {
@@ -458,29 +442,65 @@
       [self iconCapacity], [self pinned], [self active]);
 }
 
-- (void)setIconImage:(NSImage*)image {
-  [self setIconImage:image withToastAnimation:NO];
-}
+- (void)setIconImage:(NSImage*)image
+     forLoadingState:(TabLoadingState)newLoadingState
+            showIcon:(BOOL)showIcon {
+  // Update the favicon's visbility state. Note that TabStripController calls
+  // -updateVisibility immediately after calling this method, so we don't need
+  // to act on a change in this state.
+  showIcon_ = showIcon;
 
-- (void)setIconImage:(NSImage*)image withToastAnimation:(BOOL)animate {
-  if (image == nil) {
-    [self setIconView:nil];
-  } else {
-    BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout();
-    if (iconView_.get() == nil) {
-      base::scoped_nsobject<SpriteView> iconView([[SpriteView alloc] init]);
-      [iconView setAutoresizingMask:isRTL
-                                        ? NSViewMinXMargin | NSViewMinYMargin
-                                        : NSViewMaxXMargin | NSViewMinYMargin];
-      [self setIconView:iconView];
+  // Always draw the favicon when the state is already kTabDone because the site
+  // may have sent an updated favicon.
+  if (newLoadingState == loadingState_ && newLoadingState != kTabDone) {
+    return;
+  }
+  loadingState_ = newLoadingState;
+
+  // The Material Design spinner handles sad tab icon display, etc. directly
+  // based on the loading state. Handle it here until the new spinner code
+  // lands.
+  if (newLoadingState == kTabCrashed) {
+    static NSImage* sadFaviconImage =
+        ui::ResourceBundle::GetSharedInstance()
+            .GetNativeImageNamed(IDR_CRASH_SAD_FAVICON)
+            .CopyNSImage();
+
+    image = sadFaviconImage;
+  } else if (newLoadingState == kTabWaiting) {
+    static NSImage* throbberWaitingImage =
+        ui::ResourceBundle::GetSharedInstance()
+            .GetNativeImageNamed(IDR_THROBBER_WAITING)
+            .CopyNSImage();
+    static NSImage* throbberWaitingIncognitoImage =
+        ui::ResourceBundle::GetSharedInstance()
+            .GetNativeImageNamed(IDR_THROBBER_WAITING_INCOGNITO)
+            .CopyNSImage();
+
+    if ([[iconView_ window] hasDarkTheme]) {
+      image = throbberWaitingIncognitoImage;
+    } else {
+      image = throbberWaitingImage;
     }
+  } else if (newLoadingState == kTabLoading) {
+    static NSImage* throbberLoadingImage =
+        ui::ResourceBundle::GetSharedInstance()
+            .GetNativeImageNamed(IDR_THROBBER)
+            .CopyNSImage();
+    static NSImage* throbberLoadingIncognitoImage =
+        ui::ResourceBundle::GetSharedInstance()
+            .GetNativeImageNamed(IDR_THROBBER_INCOGNITO)
+            .CopyNSImage();
 
-    [iconView_ setImage:image withToastAnimation:animate];
-
-    [self updateIconViewFrameWithAnimation:NO];
+    if ([[iconView_ window] hasDarkTheme]) {
+      image = throbberLoadingIncognitoImage;
+    } else {
+      image = throbberLoadingImage;
+    }
   }
 
-  [self updateAttentionIndicator];
+  [iconView_ setImage:image
+      withToastAnimation:(newLoadingState == kTabCrashed)];
 }
 
 - (void)updateAttentionIndicator {
@@ -490,7 +510,7 @@
   if ([self active])
     actualAttentionTypes &= ~AttentionType::kBlockedWebContents;
 
-  if (actualAttentionTypes != 0 && iconView_ && isIconShowing_) {
+  if (actualAttentionTypes != 0 && ![iconView_ isHidden]) {
     // The attention indicator consists of two parts:
     // . a wedge cut out of the bottom right (or left in rtl) of the favicon.
     // . a circle in the bottom right (or left in rtl) of the favicon.
@@ -551,13 +571,9 @@
 }
 
 - (void)updateVisibility {
-  // iconView_ may have been replaced or it may be nil, so [iconView_ isHidden]
-  // won't work.  Instead, the state of the icon is tracked separately in
-  // isIconShowing_.
   BOOL newShowIcon = [self shouldShowIcon];
 
   [iconView_ setHidden:!newShowIcon];
-  isIconShowing_ = newShowIcon;
 
   // If the tab is a pinned-tab, hide the title.
   TabView* tabView = [self tabView];
diff --git a/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm b/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
index 43606ed..c25abb4 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_controller_unittest.mm
@@ -150,7 +150,9 @@
           // TabController state.
           [controller setPinned:(isPinnedTab ? YES : NO)];
           [controller setActive:(isActiveTab ? YES : NO)];
-          [controller setIconImage:favicon];
+          [controller setIconImage:favicon
+                   forLoadingState:kTabDone
+                          showIcon:YES];
           [controller setAlertState:alertState];
           [controller updateVisibility];
 
@@ -383,11 +385,15 @@
   [[window contentView] addSubview:[controller view]];
 
   EXPECT_EQ(kTabDone, [controller loadingState]);
-  [controller setLoadingState:kTabWaiting];
+  [controller setIconImage:nil forLoadingState:kTabWaiting showIcon:YES];
   EXPECT_EQ(kTabWaiting, [controller loadingState]);
-  [controller setLoadingState:kTabLoading];
+  [controller setIconImage:nil forLoadingState:kTabLoading showIcon:YES];
   EXPECT_EQ(kTabLoading, [controller loadingState]);
-  [controller setLoadingState:kTabDone];
+  // Create favicon.
+  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  base::scoped_nsobject<NSImage> favicon(
+      rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).CopyNSImage());
+  [controller setIconImage:favicon forLoadingState:kTabDone showIcon:YES];
   EXPECT_EQ(kTabDone, [controller loadingState]);
 
   [[controller view] removeFromSuperview];
@@ -474,9 +480,10 @@
 
   // Setting the icon when tab is at min width should not show icon (bug 18359).
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-  base::scoped_nsobject<NSImage> image(
+  base::scoped_nsobject<NSImage> favicon(
       rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).CopyNSImage());
-  [controller setIconImage:image];
+  [controller setIconImage:favicon forLoadingState:kTabDone showIcon:YES];
+  [controller updateVisibility];
   NSView* newIcon = [controller iconView];
   EXPECT_TRUE([newIcon isHidden]);
 
@@ -561,6 +568,13 @@
   tabFrame.size.width = [TabController maxTabWidth];
   [[controller view] setFrame:tabFrame];
 
+  // Set up the favicon in the tabview.
+  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+  base::scoped_nsobject<NSImage> favicon(
+      rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).CopyNSImage());
+  [controller setIconImage:favicon forLoadingState:kTabDone showIcon:YES];
+  [controller updateVisibility];
+
   const NSRect originalTabFrame = [[controller view] frame];
   const NSRect originalIconFrame = [[controller iconView] frame];
   const NSRect originalCloseFrame = [[controller closeButton] frame];
@@ -577,7 +591,7 @@
   [[controller view] setFrame:tabFrame];
 
   // The icon view and close button should be hidden and the title view should
-  // be resize to take up their space.
+  // resize to take up their space.
   EXPECT_TRUE([[controller iconView] isHidden]);
   EXPECT_TRUE([[controller closeButton] isHidden]);
   EXPECT_GT(NSWidth([[controller view] frame]),
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
index 7e528bf..8f0fc0a5 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
@@ -1578,61 +1578,26 @@
   if (!contents)
     return;
 
-  static NSImage* throbberWaitingImage =
-      ui::ResourceBundle::GetSharedInstance()
-          .GetNativeImageNamed(IDR_THROBBER_WAITING)
-          .CopyNSImage();
-  static NSImage* throbberWaitingIncognitoImage =
-      ui::ResourceBundle::GetSharedInstance()
-          .GetNativeImageNamed(IDR_THROBBER_WAITING_INCOGNITO)
-          .CopyNSImage();
-  static NSImage* throbberLoadingImage = ui::ResourceBundle::GetSharedInstance()
-                                             .GetNativeImageNamed(IDR_THROBBER)
-                                             .CopyNSImage();
-  static NSImage* throbberLoadingIncognitoImage =
-      ui::ResourceBundle::GetSharedInstance()
-          .GetNativeImageNamed(IDR_THROBBER_INCOGNITO)
-          .CopyNSImage();
-  static NSImage* sadFaviconImage =
-      ui::ResourceBundle::GetSharedInstance()
-          .GetNativeImageNamed(IDR_CRASH_SAD_FAVICON)
-          .CopyNSImage();
-
   // Take closing tabs into account.
   NSInteger index = [self indexFromModelIndex:modelIndex];
   TabController* tabController = [tabArray_ objectAtIndex:index];
   TabUIHelper* tabUIHelper = TabUIHelper::FromWebContents(contents);
 
-  bool oldHasIcon = [tabController iconView] != nil;
-  bool newHasIcon =
-      favicon::ShouldDisplayFavicon(contents) ||
-      tabStripModel_->IsTabPinned(modelIndex);  // Always show icon if pinned.
+  bool oldShowIcon = [tabController showIcon];
+  bool tabIsCrashed = contents->IsCrashed();
+  bool showIcon = favicon::ShouldDisplayFavicon(contents) || tabIsCrashed ||
+                  tabStripModel_->IsTabPinned(modelIndex);
 
-  TabLoadingState oldState = [tabController loadingState];
-  TabLoadingState newState = kTabDone;
-  NSImage* throbberImage = nil;
-  if (contents->IsCrashed()) {
-    newState = kTabCrashed;
-    newHasIcon = true;
+  TabLoadingState oldLoadingState = [tabController loadingState];
+  TabLoadingState newLoadingState = kTabDone;
+  if (tabIsCrashed) {
+    newLoadingState = kTabCrashed;
   } else if (contents->IsWaitingForResponse()) {
-    newState = kTabWaiting;
-    if ([[[tabController view] window] hasDarkTheme]) {
-      throbberImage = throbberWaitingIncognitoImage;
-    } else {
-      throbberImage = throbberWaitingImage;
-    }
+    newLoadingState = kTabWaiting;
   } else if (contents->IsLoadingToDifferentDocument()) {
-    newState = kTabLoading;
-    if ([[[tabController view] window] hasDarkTheme]) {
-      throbberImage = throbberLoadingIncognitoImage;
-    } else {
-      throbberImage = throbberLoadingImage;
-    }
+    newLoadingState = kTabLoading;
   }
 
-  if (oldState != newState)
-    [tabController setLoadingState:newState];
-
   // Use TabUIHelper to determine if we would like to hide the throbber and
   // override the favicon. We want to hide the throbber for 2 cases. 1) when a
   // new tab is opened in the background and its initial navigation is delayed,
@@ -1641,39 +1606,28 @@
   // So TabUIHelper will fetch the favicon from history if available and use
   // that. For the 2nd case, TabUIhelper will return an empty favicon, so the
   // WebContents' favicon is used.
-  //
-  // When the throbber should be shown, only make changes when the state is
-  // actually changing, to avoid expensive unnecessary view manipulation.
-  // Because while loading, this function is called repeatedly with the same
-  // state. When loading is complete (kTabDone), every call to this function is
-  // significant.
+  NSImage* newImage = nil;
   if (tabUIHelper->ShouldHideThrobber()) {
-    gfx::Image favicon = tabUIHelper->GetFavicon();
-    if (!favicon.IsEmpty()) {
-      [tabController setIconImage:favicon.AsNSImage()];
-    } else {
-      [tabController
-          setIconImage:[self iconImageForContents:contents atIndex:modelIndex]];
-    }
     wasHidingThrobberSet_.insert(contents);
+
+    gfx::Image favicon = tabUIHelper->GetFavicon();
+    newImage = favicon.IsEmpty()
+                   ? [self iconImageForContents:contents atIndex:modelIndex]
+                   : favicon.AsNSImage();
   } else if (base::ContainsKey(wasHidingThrobberSet_, contents) ||
-             newState == kTabDone || oldState != newState ||
-             oldHasIcon != newHasIcon) {
+             newLoadingState == kTabDone ||
+             oldLoadingState != newLoadingState || oldShowIcon != showIcon) {
     wasHidingThrobberSet_.erase(contents);
-    if (newHasIcon) {
-      if (newState == kTabDone) {
-        [tabController setIconImage:[self iconImageForContents:contents
-                                                       atIndex:modelIndex]];
-      } else if (newState == kTabCrashed) {
-        [tabController setIconImage:sadFaviconImage withToastAnimation:YES];
-      } else {
-        [tabController setIconImage:throbberImage];
-      }
-    } else {
-      [tabController setIconImage:nil];
+
+    if (showIcon && newLoadingState == kTabDone) {
+      newImage = [self iconImageForContents:contents atIndex:modelIndex];
     }
   }
 
+  [tabController setIconImage:newImage
+              forLoadingState:newLoadingState
+                     showIcon:showIcon];
+
   TabAlertState alertState = [self alertStateForContents:contents];
   [self updateWindowAlertState:alertState forWebContents:contents];
   [tabController setAlertState:alertState];
diff --git a/chrome/browser/ui/libgtkui/gtk_util.cc b/chrome/browser/ui/libgtkui/gtk_util.cc
index 5c8fd3f..a925139 100644
--- a/chrome/browser/ui/libgtkui/gtk_util.cc
+++ b/chrome/browser/ui/libgtkui/gtk_util.cc
@@ -54,11 +54,6 @@
   }
 }
 
-float GetDeviceScaleFactor() {
-  views::LinuxUI* linux_ui = views::LinuxUI::instance();
-  return linux_ui ? linux_ui->GetDeviceScaleFactor() : 1;
-}
-
 }  // namespace
 
 namespace libgtkui {
@@ -233,6 +228,15 @@
 }
 
 #if GTK_MAJOR_VERSION > 2
+namespace {
+
+float GetDeviceScaleFactor() {
+  views::LinuxUI* linux_ui = views::LinuxUI::instance();
+  return linux_ui ? linux_ui->GetDeviceScaleFactor() : 1;
+}
+
+}  // namespace
+
 void* GetGdkSharedLibrary() {
   std::string lib_name =
       "libgdk-" + std::to_string(GTK_MAJOR_VERSION) + ".so.0";
diff --git a/chrome/browser/ui/libgtkui/native_theme_gtk2.cc b/chrome/browser/ui/libgtkui/native_theme_gtk2.cc
index af67e834..83fce01 100644
--- a/chrome/browser/ui/libgtkui/native_theme_gtk2.cc
+++ b/chrome/browser/ui/libgtkui/native_theme_gtk2.cc
@@ -219,6 +219,14 @@
     case kColorId_ButtonPressedShade:
       return SK_ColorTRANSPARENT;
 
+    // TabbedPane
+    case ui::NativeTheme::kColorId_TabTitleColorActive:
+      return GetTextColor(GetEntry(), NORMAL);
+    case ui::NativeTheme::kColorId_TabTitleColorInactive:
+      return GetTextColor(GetLabel(), INSENSITIVE);
+    case ui::NativeTheme::kColorId_TabBottomBorder:
+      return GetTextColor(GetEntry(), NORMAL);
+
     // Textfield
     case kColorId_TextfieldDefaultColor:
       return GetTextColor(GetEntry(), NORMAL);
diff --git a/chrome/browser/ui/profile_error_dialog.cc b/chrome/browser/ui/profile_error_dialog.cc
index e6a63f03..b2ab4162 100644
--- a/chrome/browser/ui/profile_error_dialog.cc
+++ b/chrome/browser/ui/profile_error_dialog.cc
@@ -32,8 +32,9 @@
       l10n_util::GetStringUTF8(IDS_PROFILE_ERROR_FEEDBACK_DESCRIPTION);
 
   chrome::ShowFeedbackPage(nullptr, chrome::kFeedbackSourceProfileErrorDialog,
-                           feedback_description, kProfileErrorFeedbackCategory,
-                           diagnostics);
+                           feedback_description,
+                           std::string() /* description_placeholder_text */,
+                           kProfileErrorFeedbackCategory, diagnostics);
 }
 #endif  // !defined(OS_ANDROID)
 
diff --git a/chrome/browser/ui/sad_tab.cc b/chrome/browser/ui/sad_tab.cc
index ec4cfc62..ff830f5c 100644
--- a/chrome/browser/ui/sad_tab.cc
+++ b/chrome/browser/ui/sad_tab.cc
@@ -228,6 +228,7 @@
         ShowFeedbackPage(
             chrome::FindBrowserWithWebContents(web_contents_),
             chrome::kFeedbackSourceSadTabPage,
+            std::string() /* description_template */,
             l10n_util::GetStringUTF8(kind_ == SAD_TAB_KIND_CRASHED
                                          ? IDS_CRASHED_TAB_FEEDBACK_MESSAGE
                                          : IDS_KILLED_TAB_FEEDBACK_MESSAGE),
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 71ed5e2..d493122 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -82,7 +82,6 @@
 #include "chrome/browser/ui/views/infobars/infobar_container_view.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/browser/ui/views/location_bar/star_view.h"
-#include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h"
 #include "chrome/browser/ui/views/new_back_shortcut_bubble.h"
 #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
 #include "chrome/browser/ui/views/profiles/profile_indicator_icon.h"
@@ -796,7 +795,6 @@
   UpdateTitleBar();
 
   TranslateBubbleView::CloseCurrentBubble();
-  ZoomBubbleView::CloseCurrentBubble();
 }
 
 void BrowserView::ZoomChangedForActiveTab(bool can_show_bubble) {
diff --git a/chrome/browser/ui/views/harmony/harmony_layout_provider.cc b/chrome/browser/ui/views/harmony/harmony_layout_provider.cc
index 0f1da5f..bc16751c 100644
--- a/chrome/browser/ui/views/harmony/harmony_layout_provider.cc
+++ b/chrome/browser/ui/views/harmony/harmony_layout_provider.cc
@@ -34,6 +34,8 @@
 int HarmonyLayoutProvider::GetDistanceMetric(int metric) const {
   DCHECK_GE(metric, views::VIEWS_INSETS_MAX);
   switch (metric) {
+    case views::DISTANCE_BUTTON_IMAGE_LABEL_PADDING:
+      return kHarmonyLayoutUnit * 3 / 4;
     case DISTANCE_CONTENT_LIST_VERTICAL_SINGLE:
       return kHarmonyLayoutUnit / 4;
     case DISTANCE_CONTENT_LIST_VERTICAL_MULTI:
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
index b602e61..047572c59 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -153,7 +153,7 @@
   // initiated by an extension, then the bubble can be reused and only the label
   // text needs to be updated.
   if (zoom_bubble_ && zoom_bubble_->GetAnchorView() == anchor_view && !client) {
-    DCHECK_EQ(web_contents, zoom_bubble_->web_contents_);
+    DCHECK_EQ(web_contents, zoom_bubble_->web_contents());
     zoom_bubble_->Refresh();
     return;
   }
@@ -224,13 +224,13 @@
     DisplayReason reason,
     ImmersiveModeController* immersive_mode_controller)
     : LocationBarBubbleDelegateView(anchor_view, anchor_point, web_contents),
+      WebContentsObserver(web_contents),
       auto_close_duration_(kBubbleCloseDelayDefault),
       image_button_(nullptr),
       label_(nullptr),
       zoom_out_button_(nullptr),
       zoom_in_button_(nullptr),
       reset_button_(nullptr),
-      web_contents_(web_contents),
       auto_close_(reason == AUTOMATIC),
       ignore_close_bubble_(false),
       immersive_mode_controller_(immersive_mode_controller) {
@@ -313,7 +313,7 @@
   }
 
   // Add zoom label with the new zoom percent.
-  label_ = new ZoomValue(web_contents_);
+  label_ = new ZoomValue(web_contents());
   UpdateZoomPercent();
   label_->SetProperty(views::kMarginsKey,
                       new gfx::Insets(label_vertical_margin));
@@ -358,9 +358,8 @@
   bool this_bubble = zoom_bubble_ == this;
   if (this_bubble)
     zoom_bubble_ = nullptr;
+
   UpdateZoomIconVisibility();
-  if (this_bubble)
-    web_contents_ = nullptr;
 }
 
 void ZoomBubbleView::CloseBubble() {
@@ -368,7 +367,7 @@
     return;
 
   // Widget's Close() is async, but we don't want to use zoom_bubble_ after
-  // this. Additionally web_contents_ may have been destroyed.
+  // this. Additionally web_contents() may have been destroyed.
   zoom_bubble_ = nullptr;
   LocationBarBubbleDelegateView::CloseBubble();
 }
@@ -385,17 +384,17 @@
 
   if (sender == image_button_) {
     DCHECK(extension_info_.icon_image) << "Invalid button press.";
-    Browser* browser = chrome::FindBrowserWithWebContents(web_contents_);
+    Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
     chrome::AddSelectedTabWithURL(
         browser, GURL(base::StringPrintf("chrome://extensions?id=%s",
                                          extension_info_.id.c_str())),
         ui::PAGE_TRANSITION_FROM_API);
   } else if (sender == zoom_out_button_) {
-    zoom::PageZoom::Zoom(web_contents_, content::PAGE_ZOOM_OUT);
+    zoom::PageZoom::Zoom(web_contents(), content::PAGE_ZOOM_OUT);
   } else if (sender == zoom_in_button_) {
-    zoom::PageZoom::Zoom(web_contents_, content::PAGE_ZOOM_IN);
+    zoom::PageZoom::Zoom(web_contents(), content::PAGE_ZOOM_IN);
   } else if (sender == reset_button_) {
-    zoom::PageZoom::Zoom(web_contents_, content::PAGE_ZOOM_RESET);
+    zoom::PageZoom::Zoom(web_contents(), content::PAGE_ZOOM_RESET);
   } else {
     NOTREACHED();
   }
@@ -416,6 +415,14 @@
   image_button_->SchedulePaint();
 }
 
+void ZoomBubbleView::WasHidden() {
+  CloseBubble();
+}
+
+void ZoomBubbleView::WebContentsDestroyed() {
+  CloseBubble();
+}
+
 void ZoomBubbleView::SetExtensionInfo(const extensions::Extension* extension) {
   DCHECK(extension);
   extension_info_.id = extension->id();
@@ -435,13 +442,9 @@
   bool has_default_sized_icon =
       !icons.Get(gfx::kFaviconSize, ExtensionIconSet::MATCH_EXACTLY).empty();
   if (has_default_sized_icon) {
-    extension_info_.icon_image.reset(
-        new extensions::IconImage(web_contents_->GetBrowserContext(),
-                                  extension,
-                                  icons,
-                                  icon_size,
-                                  default_extension_icon_image,
-                                  this));
+    extension_info_.icon_image.reset(new extensions::IconImage(
+        web_contents()->GetBrowserContext(), extension, icons, icon_size,
+        default_extension_icon_image, this));
     return;
   }
 
@@ -452,22 +455,22 @@
 
   icon_size = browser_action->default_icon.map().begin()->first;
   extension_info_.icon_image.reset(
-      new extensions::IconImage(web_contents_->GetBrowserContext(),
-                                extension,
-                                browser_action->default_icon,
-                                icon_size,
-                                default_extension_icon_image,
-                                this));
+      new extensions::IconImage(web_contents()->GetBrowserContext(), extension,
+                                browser_action->default_icon, icon_size,
+                                default_extension_icon_image, this));
 }
 
 void ZoomBubbleView::UpdateZoomPercent() {
   label_->SetText(base::FormatPercent(
-      zoom::ZoomController::FromWebContents(web_contents_)->GetZoomPercent()));
+      zoom::ZoomController::FromWebContents(web_contents())->GetZoomPercent()));
   label_->NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true);
 }
 
 void ZoomBubbleView::UpdateZoomIconVisibility() {
-  Browser* browser = chrome::FindBrowserWithWebContents(web_contents_);
+  // Note that we can't rely on web_contents() here, as it may have been
+  // destroyed by the time we get this call.
+  Browser* browser = chrome::FindBrowserWithWindow(
+      platform_util::GetTopLevel(parent_window()));
   if (browser && browser->window() && browser->window()->GetLocationBar())
     browser->window()->GetLocationBar()->UpdateZoomViewVisibility();
 }
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
index 4597bb1..9e7e2cb2 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
@@ -12,6 +12,7 @@
 #include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
+#include "content/public/browser/web_contents_observer.h"
 #include "extensions/browser/extension_icon_image.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/label.h"
@@ -28,7 +29,8 @@
 class ZoomBubbleView : public LocationBarBubbleDelegateView,
                        public views::ButtonListener,
                        public ImmersiveModeController::Observer,
-                       public extensions::IconImage::Observer {
+                       public extensions::IconImage::Observer,
+                       public content::WebContentsObserver {
  public:
   // Shows the bubble and automatically closes it after a short time period if
   // |reason| is AUTOMATIC.
@@ -99,6 +101,10 @@
   // extensions::IconImage::Observer:
   void OnExtensionIconImageChanged(extensions::IconImage* /* image */) override;
 
+  // content::WebContentsObserver:
+  void WasHidden() override;
+  void WebContentsDestroyed() override;
+
   // Sets information about the extension that initiated the zoom change.
   // Calling this method asserts that the extension |extension| did initiate
   // the zoom change.
@@ -142,9 +148,6 @@
   views::Button* zoom_in_button_;
   views::Button* reset_button_;
 
-  // The WebContents for the page whose zoom has changed.
-  content::WebContents* web_contents_;
-
   // Whether the currently displayed bubble will automatically close.
   bool auto_close_;
 
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
index 530eafe..4fe32ec 100644
--- a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
@@ -5,13 +5,20 @@
 #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h"
 
 #include "build/build_config.h"
+#include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
 #include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/test/test_browser_dialog.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "ui/base/ui_features.h"
+#include "ui/views/test/test_widget_observer.h"
+
+#if !defined(OS_MACOSX) || BUILDFLAG(MAC_VIEWS_BROWSER)
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
-#include "chrome/test/base/in_process_browser_test.h"
+#endif
 
 #if defined(OS_CHROMEOS)
 #include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h"
@@ -21,12 +28,25 @@
 
 using ZoomBubbleBrowserTest = InProcessBrowserTest;
 
+namespace {
+
+void ShowInActiveTab(Browser* browser) {
+  content::WebContents* web_contents =
+      browser->tab_strip_model()->GetActiveWebContents();
+  ZoomBubbleView::ShowBubble(web_contents, gfx::Point(),
+                             ZoomBubbleView::USER_GESTURE);
+  EXPECT_TRUE(ZoomBubbleView::GetZoomBubble());
+}
+
+}  // namespace
+
 // TODO(linux_aura) http://crbug.com/163931
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
 #define MAYBE_NonImmersiveFullscreen DISABLED_NonImmersiveFullscreen
 #else
 #define MAYBE_NonImmersiveFullscreen NonImmersiveFullscreen
 #endif
+#if !defined(OS_MACOSX) || BUILDFLAG(MAC_VIEWS_BROWSER)
 // Test whether the zoom bubble is anchored and whether it is visible when in
 // non-immersive fullscreen.
 IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, MAYBE_NonImmersiveFullscreen) {
@@ -72,6 +92,7 @@
     waiter->Wait();
   }
 }
+#endif  // !defined(OS_MACOSX) || BUILDFLAG(MAC_VIEWS_BROWSER)
 
 #if defined(OS_CHROMEOS)
 // Test whether the zoom bubble is anchored and whether it is visible when in
@@ -144,12 +165,11 @@
 
 // Tests that trying to open zoom bubble with stale WebContents is safe.
 IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, NoWebContentsIsSafe) {
-  BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
-  content::WebContents* web_contents = browser_view->GetActiveWebContents();
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
 
   ZoomBubbleView::ShowBubble(web_contents, gfx::Point(),
                              ZoomBubbleView::AUTOMATIC);
-
   // Close the current tab and try opening the zoom bubble with stale
   // |web_contents|.
   chrome::CloseTab(browser());
@@ -157,17 +177,44 @@
                              ZoomBubbleView::AUTOMATIC);
 }
 
+// Ensure a tab switch closes the bubble.
+IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, TabSwitchCloses) {
+  AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_LINK);
+  ShowInActiveTab(browser());
+  chrome::SelectNextTab(browser());
+  EXPECT_FALSE(ZoomBubbleView::GetZoomBubble());
+}
+
+// Ensure the bubble is dismissed on tab closure and doesn't reference a
+// destroyed WebContents.
+IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, DestroyedWebContents) {
+  AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_LINK);
+  ShowInActiveTab(browser());
+
+  ZoomBubbleView* bubble = ZoomBubbleView::GetZoomBubble();
+  EXPECT_TRUE(bubble);
+
+  views::test::TestWidgetObserver observer(bubble->GetWidget());
+  EXPECT_FALSE(bubble->GetWidget()->IsClosed());
+
+  chrome::CloseTab(browser());
+  EXPECT_FALSE(ZoomBubbleView::GetZoomBubble());
+
+  // Widget::Close() completes asynchronously, so it's still safe to access
+  // |bubble| here, even though GetZoomBubble() returned null.
+  EXPECT_FALSE(observer.widget_closed());
+  EXPECT_TRUE(bubble->GetWidget()->IsClosed());
+
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(observer.widget_closed());
+}
+
 class ZoomBubbleDialogTest : public DialogBrowserTest {
  public:
   ZoomBubbleDialogTest() {}
 
   // DialogBrowserTest:
-  void ShowUi(const std::string& name) override {
-    BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
-    content::WebContents* web_contents = browser_view->GetActiveWebContents();
-    ZoomBubbleView::ShowBubble(web_contents, gfx::Point(),
-                               ZoomBubbleView::USER_GESTURE);
-  }
+  void ShowUi(const std::string& name) override { ShowInActiveTab(browser()); }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ZoomBubbleDialogTest);
diff --git a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
index 2e7d630..d1b97dae 100644
--- a/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
+++ b/chrome/browser/ui/views/payments/shipping_address_editor_view_controller_browsertest.cc
@@ -239,8 +239,9 @@
                                /*accept_empty_phone_number=*/false);
 }
 
+// Disabled for flakyness: crbug.com/799028
 IN_PROC_BROWSER_TEST_F(PaymentRequestShippingAddressEditorTest,
-                       EnterAcceleratorSyncData) {
+                       DISABLED_EnterAcceleratorSyncData) {
   NavigateTo("/payment_request_dynamic_shipping_test.html");
   InvokePaymentRequestUI();
   SetRegionDataLoader(&test_region_data_loader_);
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
index aaca6ca..492913c 100644
--- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
@@ -707,16 +707,13 @@
   login::SigninPartitionManager* signin_partition_manager =
       login::SigninPartitionManager::Factory::GetForBrowserContext(
           Profile::FromWebUI(web_ui()));
-  signin_partition_manager->StartSigninSession(
-      web_ui()->GetWebContents(),
-      base::BindOnce(&EnrollmentScreenHandler::DoShowWithPartition,
-                     weak_ptr_factory_.GetWeakPtr()));
-}
+  signin_partition_manager->StartSigninSession(web_ui()->GetWebContents());
 
-void EnrollmentScreenHandler::DoShowWithPartition(
-    const std::string& partition_name) {
+  // Then leave it running forever.
   base::DictionaryValue screen_data;
-  screen_data.SetString("webviewPartitionName", partition_name);
+  screen_data.SetString(
+      "webviewPartitionName",
+      signin_partition_manager->GetCurrentStoragePartitionName());
   screen_data.SetString("gaiaUrl", GaiaUrls::GetInstance()->gaia_url().spec());
   screen_data.SetString("clientId",
                         GaiaUrls::GetInstance()->oauth2_chrome_client_id());
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
index e97c73e..23b7d798 100644
--- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.h
@@ -118,9 +118,6 @@
   // Shows the screen.
   void DoShow();
 
-  // Shows the screen.
-  void DoShowWithPartition(const std::string& partition_name);
-
   // Returns true if current visible screen is the enrollment sign-in page.
   bool IsOnEnrollmentScreen() const;
 
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index f9d8266..a27ea28 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -300,39 +300,31 @@
 }
 
 void GaiaScreenHandler::LoadGaia(const GaiaContext& context) {
-  // Start a new session with SigninPartitionManager, generating a unique
-  // StoragePartition.
-  login::SigninPartitionManager* signin_partition_manager =
-      login::SigninPartitionManager::Factory::GetForBrowserContext(
-          Profile::FromWebUI(web_ui()));
-  signin_partition_manager->StartSigninSession(
-      web_ui()->GetWebContents(),
-      base::BindOnce(&GaiaScreenHandler::LoadGaiaWithPartition,
-                     weak_factory_.GetWeakPtr(), context));
-}
-
-void GaiaScreenHandler::LoadGaiaWithPartition(
-    const GaiaContext& context,
-    const std::string& partition_name) {
   std::unique_ptr<std::string> version = std::make_unique<std::string>();
   std::unique_ptr<bool> consent = std::make_unique<bool>();
   base::OnceClosure get_version_and_consent =
       base::BindOnce(&GetVersionAndConsent, base::Unretained(version.get()),
                      base::Unretained(consent.get()));
   base::OnceClosure load_gaia = base::BindOnce(
-      &GaiaScreenHandler::LoadGaiaWithPartitionAndVersionAndConsent,
-      weak_factory_.GetWeakPtr(), context, partition_name,
-      base::Owned(version.release()), base::Owned(consent.release()));
+      &GaiaScreenHandler::LoadGaiaWithVersionAndConsent,
+      weak_factory_.GetWeakPtr(), context, base::Owned(version.release()),
+      base::Owned(consent.release()));
   base::PostTaskWithTraitsAndReply(
       FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
       std::move(get_version_and_consent), std::move(load_gaia));
 }
 
-void GaiaScreenHandler::LoadGaiaWithPartitionAndVersionAndConsent(
+void GaiaScreenHandler::LoadGaiaWithVersionAndConsent(
     const GaiaContext& context,
-    const std::string& partition_name,
     const std::string* platform_version,
     const bool* collect_stats_consent) {
+  // Start a new session with SigninPartitionManager, generating a a unique
+  // StoragePartition.
+  login::SigninPartitionManager* signin_partition_manager =
+      login::SigninPartitionManager::Factory::GetForBrowserContext(
+          Profile::FromWebUI(web_ui()));
+  signin_partition_manager->StartSigninSession(web_ui()->GetWebContents());
+
   base::DictionaryValue params;
 
   params.SetBoolean("forceReload", context.force_reload);
@@ -408,8 +400,8 @@
   // sending device statistics.
   if (*collect_stats_consent)
     params.SetString("lsbReleaseBoard", base::SysInfo::GetLsbReleaseBoard());
-
-  params.SetString("webviewPartitionName", partition_name);
+  params.SetString("webviewPartitionName",
+                   signin_partition_manager->GetCurrentStoragePartitionName());
 
   frame_state_ = FRAME_STATE_LOADING;
   CallJS("loadAuthExtension", params);
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
index 749c2de03..7e91022e 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h
@@ -64,16 +64,9 @@
 
   // Callback that loads GAIA after version and stat consent information has
   // been retrieved.
-  void LoadGaiaWithPartition(const GaiaContext& context,
-                             const std::string& partition_name);
-
-  // Callback that loads GAIA after version and stat consent information has
-  // been retrieved.
-  void LoadGaiaWithPartitionAndVersionAndConsent(
-      const GaiaContext& context,
-      const std::string& partition_name,
-      const std::string* platform_version,
-      const bool* collect_stats_consent);
+  void LoadGaiaWithVersionAndConsent(const GaiaContext& context,
+                                     const std::string* platform_version,
+                                     const bool* collect_stats_consent);
 
   // Sends request to reload Gaia. If |force_reload| is true, request
   // will be sent in any case, otherwise it will be sent only when Gaia is
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
index e003100..4b2ccea6 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -550,7 +550,9 @@
                                ? "off"
                                : "on");
   localized_strings->SetString(
-      "showMdLogin", ash::switches::IsUsingWebUiLock() ? "off" : "on");
+      "showViewsLock", ash::switches::IsUsingViewsLock() ? "on" : "off");
+  localized_strings->SetString(
+      "showViewsLogin", ash::switches::IsUsingViewsLogin() ? "on" : "off");
   localized_strings->SetBoolean(
       "changePictureVideoModeEnabled",
       base::FeatureList::IsEnabled(features::kChangePictureVideoMode));
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 4f2118f..af4dfdc 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -685,8 +685,7 @@
   // Skip "update" notification about OFFLINE state from
   // NetworkStateInformer if previous notification already was
   // delayed.
-  if ((state == NetworkStateInformer::OFFLINE ||
-       network_state_ignored_until_proxy_auth_) &&
+  if ((state == NetworkStateInformer::OFFLINE || has_pending_auth_ui_) &&
       !force_update && !update_state_closure_.IsCancelled()) {
     return;
   }
@@ -694,7 +693,7 @@
   update_state_closure_.Cancel();
 
   if ((state == NetworkStateInformer::OFFLINE && !force_update) ||
-      network_state_ignored_until_proxy_auth_) {
+      has_pending_auth_ui_) {
     update_state_closure_.Reset(
         base::Bind(&SigninScreenHandler::UpdateStateInternal,
                    weak_factory_.GetWeakPtr(),
@@ -790,6 +789,7 @@
 
   if (is_gaia_loading_timeout) {
     LOG(WARNING) << "Retry frame load due to loading timeout.";
+    LOG(ERROR) << "UpdateStateInternal reload 4";
     reload_gaia.ScheduleCall();
   }
 
@@ -1082,33 +1082,20 @@
                                   const content::NotificationDetails& details) {
   switch (type) {
     case chrome::NOTIFICATION_AUTH_NEEDED: {
-      network_state_ignored_until_proxy_auth_ = true;
+      has_pending_auth_ui_ = true;
       break;
     }
-    case chrome::NOTIFICATION_AUTH_SUPPLIED: {
-      if (IsGaiaHiddenByError()) {
-        // Start listening to network state notifications immediately, hoping
-        // that the network will switch to ONLINE soon.
-        update_state_closure_.Cancel();
-        ReenableNetworkStateUpdatesAfterProxyAuth();
-      } else {
-        // Gaia is not hidden behind an error yet. Discard last cached network
-        // state notification and wait for |kOfflineTimeoutSec| before
-        // considering network update notifications again (hoping the network
-        // will become ONLINE by then).
-        update_state_closure_.Cancel();
-        base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-            FROM_HERE,
-            base::BindOnce(
-                &SigninScreenHandler::ReenableNetworkStateUpdatesAfterProxyAuth,
-                weak_factory_.GetWeakPtr()),
-            base::TimeDelta::FromSeconds(kOfflineTimeoutSec));
-      }
-      break;
-    }
-    case chrome::NOTIFICATION_AUTH_CANCELLED: {
+    case chrome::NOTIFICATION_AUTH_SUPPLIED:
+      has_pending_auth_ui_ = false;
+      // Reload auth extension as proxy credentials are supplied.
+      if (!IsSigninScreenHiddenByError() && ui_state_ == UI_STATE_GAIA_SIGNIN)
+        ReloadGaia(true);
       update_state_closure_.Cancel();
-      ReenableNetworkStateUpdatesAfterProxyAuth();
+      break;
+    case chrome::NOTIFICATION_AUTH_CANCELLED: {
+      // Don't reload auth extension if proxy auth dialog was cancelled.
+      has_pending_auth_ui_ = false;
+      update_state_closure_.Cancel();
       break;
     }
     default:
@@ -1116,10 +1103,6 @@
   }
 }
 
-void SigninScreenHandler::ReenableNetworkStateUpdatesAfterProxyAuth() {
-  network_state_ignored_until_proxy_auth_ = false;
-}
-
 void SigninScreenHandler::SuspendDone(const base::TimeDelta& sleep_duration) {
   for (user_manager::User* user :
        user_manager::UserManager::Get()->GetUnlockUsers()) {
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
index d63b0652f..680ab51 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
@@ -483,10 +483,6 @@
   // Called when the cros property controlling allowed input methods changes.
   void OnAllowedInputMethodsChanged();
 
-  // After proxy auth information has been supplied, this function re-enables
-  // responding to network state notifications.
-  void ReenableNetworkStateUpdatesAfterProxyAuth();
-
   // Current UI state of the signin screen.
   UIState ui_state_ = UI_STATE_UNKNOWN;
 
@@ -526,10 +522,10 @@
   std::unique_ptr<CrosSettings::ObserverSubscription>
       allowed_input_methods_subscription_;
 
-  // Whether we're currently ignoring network state updates because a proxy auth
-  // UI pending (or we're waiting for a grace period after the proxy auth UI is
-  // finished for the network to switch into the ONLINE state).
-  bool network_state_ignored_until_proxy_auth_ = false;
+  // Whether there is an auth UI pending. This flag is set on receiving
+  // NOTIFICATION_AUTH_NEEDED and reset on either NOTIFICATION_AUTH_SUPPLIED or
+  // NOTIFICATION_AUTH_CANCELLED.
+  bool has_pending_auth_ui_ = false;
 
   // Used for pending GAIA reloads.
   NetworkError::ErrorReason gaia_reload_reason_ =
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc b/chrome/browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc
index 07f3e9b..7d96c06 100644
--- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc
@@ -4,8 +4,9 @@
 
 #include "chrome/browser/ui/webui/print_preview/pdf_printer_handler.h"
 
+#include <windows.h>  // Must be in front of other Windows header files.
+
 #include <commdlg.h>
-#include <windows.h>
 
 #include "base/memory/ref_counted.h"
 #include "base/memory/ref_counted_memory.h"
diff --git a/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.cc b/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.cc
index bf3dd34..a5648eea 100644
--- a/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.cc
+++ b/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.cc
@@ -13,7 +13,7 @@
 #include "chrome/browser/ui/webui/quota_internals/quota_internals_types.h"
 #include "net/base/url_util.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 using content::BrowserThread;
 
 namespace quota_internals {
diff --git a/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.h b/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.h
index 139f0c9..0c1fc6e 100644
--- a/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.h
+++ b/chrome/browser/ui/webui/quota_internals/quota_internals_proxy.h
@@ -18,7 +18,7 @@
 #include "base/sequenced_task_runner_helpers.h"
 #include "content/public/browser/browser_thread.h"
 #include "storage/browser/quota/quota_manager.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace quota_internals {
 
@@ -60,26 +60,26 @@
   // Called on IO Thread by QuotaManager as callback.
   void DidGetSettings(const storage::QuotaSettings& settings);
   void DidGetCapacity(int64_t total_space, int64_t available_space);
-  void DidGetGlobalUsage(blink::StorageType type,
+  void DidGetGlobalUsage(blink::mojom::StorageType type,
                          int64_t usage,
                          int64_t unlimited_usage);
   void DidDumpQuotaTable(const QuotaTableEntries& entries);
   void DidDumpOriginInfoTable(const OriginInfoTableEntries& entries);
   void DidGetHostUsage(const std::string& host,
-                       blink::StorageType type,
+                       blink::mojom::StorageType type,
                        int64_t usage);
 
   // Helper. Called on IO Thread.
-  void RequestPerOriginInfo(blink::StorageType type);
-  void VisitHost(const std::string& host, blink::StorageType type);
-  void GetHostUsage(const std::string& host, blink::StorageType type);
+  void RequestPerOriginInfo(blink::mojom::StorageType type);
+  void VisitHost(const std::string& host, blink::mojom::StorageType type);
+  void GetHostUsage(const std::string& host, blink::mojom::StorageType type);
 
   // Used on UI Thread.
   QuotaInternalsHandler* handler_;
 
   // Used on IO Thread.
   scoped_refptr<storage::QuotaManager> quota_manager_;
-  std::set<std::pair<std::string, blink::StorageType>> hosts_visited_,
+  std::set<std::pair<std::string, blink::mojom::StorageType>> hosts_visited_,
       hosts_pending_;
   std::vector<PerHostStorageInfo> report_pending_;
   base::WeakPtrFactory<QuotaInternalsProxy> weak_factory_;
diff --git a/chrome/browser/ui/webui/quota_internals/quota_internals_types.cc b/chrome/browser/ui/webui/quota_internals/quota_internals_types.cc
index 04f4a3a..d9bd312 100644
--- a/chrome/browser/ui/webui/quota_internals/quota_internals_types.cc
+++ b/chrome/browser/ui/webui/quota_internals/quota_internals_types.cc
@@ -12,17 +12,17 @@
 
 namespace {
 
-std::string StorageTypeToString(blink::StorageType type) {
+std::string StorageTypeToString(blink::mojom::StorageType type) {
   switch (type) {
-    case blink::StorageType::kTemporary:
+    case blink::mojom::StorageType::kTemporary:
       return "temporary";
-    case blink::StorageType::kPersistent:
+    case blink::mojom::StorageType::kPersistent:
       return "persistent";
-    case blink::StorageType::kSyncable:
+    case blink::mojom::StorageType::kSyncable:
       return "syncable";
-    case blink::StorageType::kQuotaNotManaged:
+    case blink::mojom::StorageType::kQuotaNotManaged:
       return "quota not managed";
-    case blink::StorageType::kUnknown:
+    case blink::mojom::StorageType::kUnknown:
       return "unknown";
   }
   return "unknown";
@@ -32,7 +32,7 @@
 
 namespace quota_internals {
 
-GlobalStorageInfo::GlobalStorageInfo(blink::StorageType type)
+GlobalStorageInfo::GlobalStorageInfo(blink::mojom::StorageType type)
     : type_(type), usage_(-1), unlimited_usage_(-1), quota_(-1) {}
 
 GlobalStorageInfo::~GlobalStorageInfo() {}
@@ -52,7 +52,7 @@
 }
 
 PerHostStorageInfo::PerHostStorageInfo(const std::string& host,
-                                       blink::StorageType type)
+                                       blink::mojom::StorageType type)
     : host_(host), type_(type), usage_(-1), quota_(-1) {}
 
 PerHostStorageInfo::~PerHostStorageInfo() {}
@@ -70,7 +70,7 @@
 }
 
 PerOriginStorageInfo::PerOriginStorageInfo(const GURL& origin,
-                                           blink::StorageType type)
+                                           blink::mojom::StorageType type)
     : origin_(origin),
       type_(type),
       host_(net::GetHostOrSpecFromURL(origin)),
diff --git a/chrome/browser/ui/webui/quota_internals/quota_internals_types.h b/chrome/browser/ui/webui/quota_internals/quota_internals_types.h
index 0b18c0b..c9b5c7a 100644
--- a/chrome/browser/ui/webui/quota_internals/quota_internals_types.h
+++ b/chrome/browser/ui/webui/quota_internals/quota_internals_types.h
@@ -12,7 +12,7 @@
 #include <string>
 
 #include "base/time/time.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 namespace base {
@@ -24,7 +24,7 @@
 // Represends global usage and quota information for specific type of storage.
 class GlobalStorageInfo {
  public:
-  explicit GlobalStorageInfo(blink::StorageType type);
+  explicit GlobalStorageInfo(blink::mojom::StorageType type);
   ~GlobalStorageInfo();
 
   void set_usage(int64_t usage) { usage_ = usage; }
@@ -39,7 +39,7 @@
   std::unique_ptr<base::Value> NewValue() const;
 
  private:
-  blink::StorageType type_;
+  blink::mojom::StorageType type_;
 
   int64_t usage_;
   int64_t unlimited_usage_;
@@ -49,7 +49,7 @@
 // Represents per host usage and quota information for the storage.
 class PerHostStorageInfo {
  public:
-  PerHostStorageInfo(const std::string& host, blink::StorageType type);
+  PerHostStorageInfo(const std::string& host, blink::mojom::StorageType type);
   ~PerHostStorageInfo();
 
   void set_usage(int64_t usage) { usage_ = usage; }
@@ -61,7 +61,7 @@
 
  private:
   std::string host_;
-  blink::StorageType type_;
+  blink::mojom::StorageType type_;
 
   int64_t usage_;
   int64_t quota_;
@@ -70,7 +70,7 @@
 // Represendts per origin usage and access time information.
 class PerOriginStorageInfo {
  public:
-  PerOriginStorageInfo(const GURL& origin, blink::StorageType type);
+  PerOriginStorageInfo(const GURL& origin, blink::mojom::StorageType type);
   PerOriginStorageInfo(const PerOriginStorageInfo& other);
   ~PerOriginStorageInfo();
 
@@ -95,7 +95,7 @@
 
  private:
   GURL origin_;
-  blink::StorageType type_;
+  blink::mojom::StorageType type_;
   std::string host_;
 
   int in_use_;
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc
index 4fb215a4..ecaced9 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -45,7 +45,7 @@
 #include "extensions/common/permissions/api_permission.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "storage/browser/quota/quota_manager.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/text/bytes_formatting.h"
 
@@ -248,8 +248,9 @@
   }
 }
 
-void SiteSettingsHandler::OnUsageInfoCleared(blink::QuotaStatusCode code) {
-  if (code == blink::QuotaStatusCode::kOk) {
+void SiteSettingsHandler::OnUsageInfoCleared(
+    blink::mojom::QuotaStatusCode code) {
+  if (code == blink::mojom::QuotaStatusCode::kOk) {
     CallJavascriptFunction("settings.WebsiteUsagePrivateApi.onUsageCleared",
                            base::Value(clearing_origin_));
   }
@@ -359,7 +360,7 @@
         = new StorageInfoFetcher(profile_);
     storage_info_fetcher->ClearStorage(
         url.host(),
-        static_cast<blink::StorageType>(static_cast<int>(storage_type)),
+        static_cast<blink::mojom::StorageType>(static_cast<int>(storage_type)),
         base::Bind(&SiteSettingsHandler::OnUsageInfoCleared,
                    base::Unretained(this)));
 
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.h b/chrome/browser/ui/webui/settings/site_settings_handler.h
index 457223f..63fa495c 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.h
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.h
@@ -16,7 +16,7 @@
 #include "content/public/browser/host_zoom_map.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 class HostContentSettingsMap;
 class Profile;
@@ -46,7 +46,7 @@
 
   // Usage info.
   void OnGetUsageInfo(const storage::UsageInfoEntries& entries);
-  void OnUsageInfoCleared(blink::QuotaStatusCode code);
+  void OnUsageInfoCleared(blink::mojom::QuotaStatusCode code);
 
 #if defined(OS_CHROMEOS)
   // Alert the Javascript that the |kEnableDRM| pref has changed.
diff --git a/chrome/browser/vr/assets.cc b/chrome/browser/vr/assets.cc
index 047f2ad..30cb1ba0 100644
--- a/chrome/browser/vr/assets.cc
+++ b/chrome/browser/vr/assets.cc
@@ -73,6 +73,12 @@
   return component_ready_;
 }
 
+void Assets::SetOnComponentReadyCallback(
+    const base::RepeatingCallback<void()>& on_component_ready) {
+  DCHECK(main_thread_task_runner_->BelongsToCurrentThread());
+  on_component_ready_callback_ = on_component_ready;
+}
+
 // static
 void Assets::LoadAssetsTask(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
@@ -150,6 +156,9 @@
   component_version_ = version;
   component_install_dir_ = install_dir;
   component_ready_ = true;
+  if (on_component_ready_callback_) {
+    on_component_ready_callback_.Run();
+  }
   GetMetricsHelper()->OnComponentReady(version);
 }
 
diff --git a/chrome/browser/vr/assets.h b/chrome/browser/vr/assets.h
index 25542f1..352ad82 100644
--- a/chrome/browser/vr/assets.h
+++ b/chrome/browser/vr/assets.h
@@ -42,6 +42,7 @@
                                   std::unique_ptr<SkBitmap> background_image,
                                   const base::Version& component_version)>
       OnAssetsLoadedCallback;
+  typedef base::RepeatingCallback<void()> OnComponentReadyCallback;
 
   // Returns the single assets instance and creates it on first call.
   static Assets* GetInstance();
@@ -62,6 +63,11 @@
   // Must be called on the main thread.
   bool ComponentReady();
 
+  // |on_component_ready| is called on main thread when assets component becomes
+  // ready to use or got updated. Must be called on the main thread.
+  void SetOnComponentReadyCallback(
+      const OnComponentReadyCallback& on_component_ready);
+
  private:
   static void LoadAssetsTask(
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
@@ -81,6 +87,7 @@
   base::FilePath component_install_dir_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
   std::unique_ptr<MetricsHelper> metrics_helper_;
+  OnComponentReadyCallback on_component_ready_callback_;
 
   base::WeakPtrFactory<Assets> weak_ptr_factory_;
 
diff --git a/chrome/browser/vr/browser_ui_interface.h b/chrome/browser/vr/browser_ui_interface.h
index 51bd1ee..5375121 100644
--- a/chrome/browser/vr/browser_ui_interface.h
+++ b/chrome/browser/vr/browser_ui_interface.h
@@ -39,6 +39,7 @@
   virtual void OnSpeechRecognitionStateChanged(int new_state) = 0;
   virtual void SetOmniboxSuggestions(
       std::unique_ptr<OmniboxSuggestions> suggestions) = 0;
+  virtual void OnAssetsComponentReady() = 0;
 
   // Tab handling.
   virtual void AppendToTabList(bool incognito,
diff --git a/chrome/browser/vr/elements/text.cc b/chrome/browser/vr/elements/text.cc
index 31550499..084414ad0 100644
--- a/chrome/browser/vr/elements/text.cc
+++ b/chrome/browser/vr/elements/text.cc
@@ -52,7 +52,7 @@
     SetAndDirty(&alignment_, alignment);
   }
 
-  void SetTextLayoutMode(TextLayoutMode mode) {
+  void SetLayoutMode(TextLayoutMode mode) {
     SetAndDirty(&text_layout_mode_, mode);
   }
 
@@ -123,13 +123,13 @@
   texture_->SetColor(color);
 }
 
-void Text::SetTextAlignment(UiTexture::TextAlignment alignment) {
+void Text::SetAlignment(UiTexture::TextAlignment alignment) {
   texture_->SetAlignment(alignment);
 }
 
-void Text::SetTextLayoutMode(TextLayoutMode mode) {
+void Text::SetLayoutMode(TextLayoutMode mode) {
   text_layout_mode_ = mode;
-  texture_->SetTextLayoutMode(mode);
+  texture_->SetLayoutMode(mode);
 }
 
 void Text::SetCursorEnabled(bool enabled) {
diff --git a/chrome/browser/vr/elements/text.h b/chrome/browser/vr/elements/text.h
index 80d03f8..aa9e504b 100644
--- a/chrome/browser/vr/elements/text.h
+++ b/chrome/browser/vr/elements/text.h
@@ -33,10 +33,12 @@
 
   void SetFontHeightInDmm(float font_height_dmms);
   void SetText(const base::string16& text);
+
+  // TODO(vollick): should use TexturedElement::SetForegroundColor
   void SetColor(SkColor color);
 
-  void SetTextAlignment(UiTexture::TextAlignment alignment);
-  void SetTextLayoutMode(TextLayoutMode mode);
+  void SetAlignment(UiTexture::TextAlignment alignment);
+  void SetLayoutMode(TextLayoutMode mode);
 
   // This text element does not typically feature a cursor, but since the cursor
   // position is deterined while laying out text, a parent may wish to supply
diff --git a/chrome/browser/vr/elements/text_input.cc b/chrome/browser/vr/elements/text_input.cc
index ac7ebd9..a8747a3 100644
--- a/chrome/browser/vr/elements/text_input.cc
+++ b/chrome/browser/vr/elements/text_input.cc
@@ -29,8 +29,8 @@
   text->set_x_anchoring(LEFT);
   text->set_x_centering(LEFT);
   text->SetSize(1, 1);
-  text->SetTextLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
-  text->SetTextAlignment(UiTexture::kTextAlignmentLeft);
+  text->SetLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
+  text->SetAlignment(UiTexture::kTextAlignmentLeft);
   hint_element_ = text.get();
   this->AddChild(std::move(text));
 
@@ -43,8 +43,8 @@
   text->set_x_centering(LEFT);
   text->set_bubble_events(true);
   text->SetSize(1, 1);
-  text->SetTextLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
-  text->SetTextAlignment(UiTexture::kTextAlignmentLeft);
+  text->SetLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
+  text->SetAlignment(UiTexture::kTextAlignmentLeft);
   text->SetCursorEnabled(true);
   text_element_ = text.get();
   this->AddChild(std::move(text));
diff --git a/chrome/browser/vr/elements/text_unittest.cc b/chrome/browser/vr/elements/text_unittest.cc
index a931c5d..18c0052 100644
--- a/chrome/browser/vr/elements/text_unittest.cc
+++ b/chrome/browser/vr/elements/text_unittest.cc
@@ -32,7 +32,7 @@
   EXPECT_GT(text->GetTextureSizeForTest().height(), initial_size.height());
 
   // Enforce single-line rendering.
-  text->SetTextLayoutMode(kSingleLineFixedWidth);
+  text->SetLayoutMode(kSingleLineFixedWidth);
   EXPECT_EQ(text->LayOutTextForTest().size(), 1u);
   EXPECT_LT(text->GetTextureSizeForTest().height(), initial_size.height());
 }
diff --git a/chrome/browser/vr/elements/toast.cc b/chrome/browser/vr/elements/toast.cc
index 44c5f6c8..eebca43 100644
--- a/chrome/browser/vr/elements/toast.cc
+++ b/chrome/browser/vr/elements/toast.cc
@@ -64,7 +64,7 @@
   text_element->set_hit_testable(false);
   text_element->SetDrawPhase(draw_phase());
   text_element->SetText(text);
-  text_element->SetTextLayoutMode(text_layout_mode);
+  text_element->SetLayoutMode(text_layout_mode);
   text_element->set_owner_name_for_test(name());
   text_element->SetVisible(true);
   text_ = text_element.get();
diff --git a/chrome/browser/vr/elements/ui_element.h b/chrome/browser/vr/elements/ui_element.h
index a0c104a0..e3fb5eb 100644
--- a/chrome/browser/vr/elements/ui_element.h
+++ b/chrome/browser/vr/elements/ui_element.h
@@ -430,15 +430,15 @@
                      bool include_bindings) const;
   virtual void DumpGeometry(std::ostringstream* os) const;
 
+  // This is to be used only during the texture / size updated phase (i.e., to
+  // change your size based on your old size).
+  gfx::SizeF stale_size() const;
+
  protected:
   AnimationPlayer& animation_player() { return animation_player_; }
 
   base::TimeTicks last_frame_time() const { return last_frame_time_; }
 
-  // This is to be used only during the texture / size updated phase (i.e., to
-  // change your size based on your old size).
-  gfx::SizeF stale_size() const;
-
  private:
   virtual void OnUpdatedWorldSpaceTransform();
 
diff --git a/chrome/browser/vr/elements/ui_element_name.cc b/chrome/browser/vr/elements/ui_element_name.cc
index 04238af..3687101 100644
--- a/chrome/browser/vr/elements/ui_element_name.cc
+++ b/chrome/browser/vr/elements/ui_element_name.cc
@@ -106,6 +106,7 @@
     "kSpeechRecognitionListening",
     "kSpeechRecognitionListeningGrowingCircle",
     "kSpeechRecognitionListeningCloseButton",
+    "kDownloadedSnackbar",
 };
 
 static_assert(
diff --git a/chrome/browser/vr/elements/ui_element_name.h b/chrome/browser/vr/elements/ui_element_name.h
index 51b4987..b0ef1ff 100644
--- a/chrome/browser/vr/elements/ui_element_name.h
+++ b/chrome/browser/vr/elements/ui_element_name.h
@@ -105,6 +105,7 @@
   kSpeechRecognitionListening,
   kSpeechRecognitionListeningGrowingCircle,
   kSpeechRecognitionListeningCloseButton,
+  kDownloadedSnackbar,
 
   // This must be last.
   kNumUiElementNames,
diff --git a/chrome/browser/vr/elements/ui_element_type.cc b/chrome/browser/vr/elements/ui_element_type.cc
index 9f0ca1ca..bfc6294 100644
--- a/chrome/browser/vr/elements/ui_element_type.cc
+++ b/chrome/browser/vr/elements/ui_element_type.cc
@@ -32,6 +32,8 @@
     "kTypeToastContainer",
     "kTypeToastIcon",
     "kTypeToastText",
+    "kTypeSnackbarButton",
+    "kTypeSnackbarDescription",
 };
 
 static_assert(
diff --git a/chrome/browser/vr/elements/ui_element_type.h b/chrome/browser/vr/elements/ui_element_type.h
index 3ad5f93..2874f70 100644
--- a/chrome/browser/vr/elements/ui_element_type.h
+++ b/chrome/browser/vr/elements/ui_element_type.h
@@ -32,6 +32,8 @@
   kTypeToastContainer,
   kTypeToastIcon,
   kTypeToastText,
+  kTypeSnackbarButton,
+  kTypeSnackbarDescription,
 
   // This must be last.
   kNumUiElementTypes,
diff --git a/chrome/browser/vr/elements/vector_icon.h b/chrome/browser/vr/elements/vector_icon.h
index 2e79e34..d0f3a7d 100644
--- a/chrome/browser/vr/elements/vector_icon.h
+++ b/chrome/browser/vr/elements/vector_icon.h
@@ -24,6 +24,7 @@
   explicit VectorIcon(int maximum_width_pixels);
   ~VectorIcon() override;
 
+  // TODO(vollick): should just use TexturedElement::SetForegroundColor.
   void SetColor(SkColor color);
   SkColor GetColor() const;
   void SetIcon(const gfx::VectorIcon& icon);
diff --git a/chrome/browser/vr/model/color_scheme.cc b/chrome/browser/vr/model/color_scheme.cc
index 4c8cf62cb..f651d48 100644
--- a/chrome/browser/vr/model/color_scheme.cc
+++ b/chrome/browser/vr/model/color_scheme.cc
@@ -133,6 +133,14 @@
   normal_scheme.omnibox_voice_search_button_colors.background_down = 0xFFFAFAFA;
   normal_scheme.cursor = 0xFF5595FE;
 
+  normal_scheme.snackbar_foreground = 0xFFEEEEEE;
+  normal_scheme.snackbar_background = 0xDD212121;
+  normal_scheme.snackbar_button_colors.background =
+      normal_scheme.snackbar_background;
+  normal_scheme.snackbar_button_colors.foreground = 0xFFFFD500;
+  normal_scheme.snackbar_button_colors.background_hover = 0xDD2D2D2D;
+  normal_scheme.snackbar_button_colors.background_down = 0xDD2D2D2D;
+
   g_fullscreen_scheme.Get() = normal_scheme;
   ColorScheme& fullscreen_scheme = g_fullscreen_scheme.Get();
   fullscreen_scheme.world_background = 0xFF000714;
diff --git a/chrome/browser/vr/model/color_scheme.h b/chrome/browser/vr/model/color_scheme.h
index 17b0eef..684a07d6 100644
--- a/chrome/browser/vr/model/color_scheme.h
+++ b/chrome/browser/vr/model/color_scheme.h
@@ -110,6 +110,10 @@
   ButtonColors omnibox_voice_search_button_colors;
   ButtonColors suggestion_button_colors;
 
+  SkColor snackbar_background;
+  SkColor snackbar_foreground;
+  ButtonColors snackbar_button_colors;
+
   SkColor cursor;
 };
 
diff --git a/chrome/browser/vr/model/model.h b/chrome/browser/vr/model/model.h
index f914046..90b1065 100644
--- a/chrome/browser/vr/model/model.h
+++ b/chrome/browser/vr/model/model.h
@@ -41,6 +41,7 @@
   UiElementRenderer::TextureLocation content_location =
       UiElementRenderer::kTextureLocationLocal;
   bool background_available = false;
+  bool can_apply_new_background = false;
   bool background_loaded = false;
 
   // WebVR state.
diff --git a/chrome/browser/vr/test/mock_browser_ui_interface.h b/chrome/browser/vr/test/mock_browser_ui_interface.h
index 331051f..224a7990 100644
--- a/chrome/browser/vr/test/mock_browser_ui_interface.h
+++ b/chrome/browser/vr/test/mock_browser_ui_interface.h
@@ -38,6 +38,7 @@
   MOCK_METHOD1(SetRecognitionResult, void(const base::string16& result));
   MOCK_METHOD1(OnSpeechRecognitionStateChanged, void(int new_state));
   void SetOmniboxSuggestions(std::unique_ptr<OmniboxSuggestions> suggestions) {}
+  MOCK_METHOD0(OnAssetsComponentReady, void());
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockBrowserUiInterface);
diff --git a/chrome/browser/vr/test/mock_ui_browser_interface.h b/chrome/browser/vr/test/mock_ui_browser_interface.h
index 8411b23..3f92da2 100644
--- a/chrome/browser/vr/test/mock_ui_browser_interface.h
+++ b/chrome/browser/vr/test/mock_ui_browser_interface.h
@@ -29,6 +29,7 @@
   MOCK_METHOD1(SetVoiceSearchActive, void(bool active));
   MOCK_METHOD1(StartAutocomplete, void(const base::string16& string));
   MOCK_METHOD0(StopAutocomplete, void());
+  MOCK_METHOD0(LoadAssets, void());
 
  private:
   DISALLOW_COPY_AND_ASSIGN(MockUiBrowserInterface);
diff --git a/chrome/browser/vr/testapp/vr_test_context.cc b/chrome/browser/vr/testapp/vr_test_context.cc
index aa720a71..c36ba5b3 100644
--- a/chrome/browser/vr/testapp/vr_test_context.cc
+++ b/chrome/browser/vr/testapp/vr_test_context.cc
@@ -180,6 +180,9 @@
       case ui::DomCode::US_O:
         CycleOrigin();
         break;
+      case ui::DomCode::US_C:
+        model_->can_apply_new_background = true;
+        break;
       default:
         break;
     }
@@ -495,4 +498,9 @@
   state = (state + 1) % states.size();
 }
 
+void VrTestContext::LoadAssets() {
+  // TODO(793380): Load asset files once they are available for development.
+  model_->can_apply_new_background = false;
+}
+
 }  // namespace vr
diff --git a/chrome/browser/vr/testapp/vr_test_context.h b/chrome/browser/vr/testapp/vr_test_context.h
index b6fd1d11..6edbfa8c 100644
--- a/chrome/browser/vr/testapp/vr_test_context.h
+++ b/chrome/browser/vr/testapp/vr_test_context.h
@@ -51,6 +51,7 @@
   void StartAutocomplete(const base::string16& string) override;
   void StopAutocomplete() override;
   void Navigate(GURL gurl) override;
+  void LoadAssets() override;
 
   void set_window_size(const gfx::Size& size) { window_size_ = size; }
 
diff --git a/chrome/browser/vr/ui.cc b/chrome/browser/vr/ui.cc
index bc2e19a..08872e92 100644
--- a/chrome/browser/vr/ui.cc
+++ b/chrome/browser/vr/ui.cc
@@ -201,6 +201,10 @@
   model_->omnibox_suggestions = suggestions->suggestions;
 }
 
+void Ui::OnAssetsComponentReady() {
+  model_->can_apply_new_background = true;
+}
+
 bool Ui::ShouldRenderWebVr() {
   return model_->web_vr.has_produced_frames();
 }
@@ -323,6 +327,7 @@
   DCHECK(background);
   background->SetImage(std::move(bitmap));
   model_->background_loaded = true;
+  model_->can_apply_new_background = false;
 }
 
 void Ui::ReinitializeForTest(const UiInitialState& ui_initial_state) {
diff --git a/chrome/browser/vr/ui.h b/chrome/browser/vr/ui.h
index 3bbd4a4..86d011b7 100644
--- a/chrome/browser/vr/ui.h
+++ b/chrome/browser/vr/ui.h
@@ -88,6 +88,7 @@
   void OnSpeechRecognitionStateChanged(int new_state) override;
   void SetOmniboxSuggestions(
       std::unique_ptr<OmniboxSuggestions> suggestions) override;
+  void OnAssetsComponentReady() override;
 
   bool ShouldRenderWebVr();
   void OnGlInitialized(unsigned int content_texture_id,
diff --git a/chrome/browser/vr/ui_browser_interface.h b/chrome/browser/vr/ui_browser_interface.h
index 09202cf..90ccaf5 100644
--- a/chrome/browser/vr/ui_browser_interface.h
+++ b/chrome/browser/vr/ui_browser_interface.h
@@ -30,6 +30,7 @@
   virtual void SetVoiceSearchActive(bool active) = 0;
   virtual void StartAutocomplete(const base::string16& string) = 0;
   virtual void StopAutocomplete() = 0;
+  virtual void LoadAssets() = 0;
 };
 
 }  // namespace vr
diff --git a/chrome/browser/vr/ui_scene_constants.h b/chrome/browser/vr/ui_scene_constants.h
index 21a224b57..3ef4d5b 100644
--- a/chrome/browser/vr/ui_scene_constants.h
+++ b/chrome/browser/vr/ui_scene_constants.h
@@ -5,13 +5,13 @@
 #ifndef CHROME_BROWSER_VR_UI_SCENE_CONSTANTS_H_
 #define CHROME_BROWSER_VR_UI_SCENE_CONSTANTS_H_
 
-#include "base/numerics/math_constants.h"
+#include "ui/gfx/geometry/angle_conversions.h"
 
 namespace vr {
 
 static constexpr int kWarningTimeoutSeconds = 30;
 static constexpr float kWarningDistance = 1.0;
-static constexpr float kWarningAngleRadians = 16.3f * base::kPiFloat / 180;
+static constexpr float kWarningAngleRadians = gfx::DegToRad(16.3f);
 static constexpr float kPermanentWarningHeightDMM = 0.049f;
 static constexpr float kPermanentWarningWidthDMM = 0.1568f;
 static constexpr float kTransientWarningHeightDMM = 0.160f;
@@ -85,7 +85,7 @@
     kWebVrUrlToastHeightDMM * kWebVrUrlToastDistance;
 static constexpr int kWebVrUrlToastTimeoutSeconds = 6;
 static constexpr float kWebVrUrlToastOpacity = 0.8f;
-static constexpr float kWebVrUrlToastRotationRad = 14 * base::kPiFloat / 180;
+static constexpr float kWebVrUrlToastRotationRad = gfx::DegToRad(14.0f);
 
 static constexpr float kWebVrToastDistance = 1.0;
 static constexpr float kFullscreenToastDistance = kFullscreenDistance;
@@ -101,7 +101,7 @@
 static constexpr float kExclusiveScreenToastTextFontHeightDMM = 0.023f;
 // When changing the value here, make sure it doesn't collide with
 // kWarningAngleRadians.
-static constexpr float kWebVrAngleRadians = 9.88f * base::kPiFloat / 180;
+static constexpr float kWebVrAngleRadians = gfx::DegToRad(9.88f);
 static constexpr int kToastTimeoutSeconds = kWebVrUrlToastTimeoutSeconds;
 
 static constexpr float kSplashScreenTextDistance = 2.5f;
@@ -244,6 +244,15 @@
 static constexpr float kKeyboardVerticalOffsetDMM = -0.45f;
 static constexpr float kKeyboardRotationRadians = -0.14f;
 
+static constexpr float kSnackbarDistance = 1.5f;
+static constexpr float kSnackbarAngle = -gfx::DegToRad(34.0f);
+static constexpr float kSnackbarPaddingDMM = 0.032f;
+static constexpr float kSnackbarIconWidthDMM = 0.034f;
+static constexpr float kSnackbarFontHeightDMM = 0.024f;
+static constexpr float kSnackbarHeightDMM = 0.08f;
+static constexpr float kSnackbarMoveInAngle = -base::kPiFloat / 10;
+static constexpr int kSnackbarTransitionDurationMs = 300;
+
 }  // namespace vr
 
 #endif  // CHROME_BROWSER_VR_UI_SCENE_CONSTANTS_H_
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc
index a911c8f6..9cdfaa7 100644
--- a/chrome/browser/vr/ui_scene_creator.cc
+++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/i18n/case_conversion.h"
 #include "base/memory/ptr_util.h"
 #include "base/numerics/math_constants.h"
 #include "chrome/browser/vr/databinding/binding.h"
@@ -140,9 +141,9 @@
   content_text->SetDrawPhase(kPhaseForeground);
   content_text->SetType(kTypeOmniboxSuggestionContentText);
   content_text->set_hit_testable(false);
-  content_text->SetTextLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
+  content_text->SetLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
   content_text->SetSize(kSuggestionTextFieldWidthDMM, 0);
-  content_text->SetTextAlignment(UiTexture::kTextAlignmentLeft);
+  content_text->SetAlignment(UiTexture::kTextAlignmentLeft);
   VR_BIND_COLOR(model, content_text.get(),
                 &ColorScheme::omnibox_suggestion_content, &Text::SetColor);
   Text* p_content_text = content_text.get();
@@ -152,9 +153,9 @@
   description_text->SetDrawPhase(kPhaseForeground);
   description_text->SetType(kTypeOmniboxSuggestionDescriptionText);
   description_text->set_hit_testable(false);
-  description_text->SetTextLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
+  description_text->SetLayoutMode(TextLayoutMode::kSingleLineFixedWidth);
   description_text->SetSize(kSuggestionTextFieldWidthDMM, 0);
-  description_text->SetTextAlignment(UiTexture::kTextAlignmentLeft);
+  description_text->SetAlignment(UiTexture::kTextAlignmentLeft);
   VR_BIND_COLOR(model, description_text.get(),
                 &ColorScheme::omnibox_suggestion_description, &Text::SetColor);
   Text* p_description_text = description_text.get();
@@ -277,6 +278,111 @@
                         const bool& value) { control->SetVisible(value); }, \
                      base::Unretained(control_element))))
 
+std::unique_ptr<UiElement> CreateSpacer(float width, float height) {
+  auto spacer = Create<UiElement>(kNone, kPhaseNone);
+  spacer->SetSize(width, height);
+  spacer->set_hit_testable(false);
+  return spacer;
+}
+
+std::unique_ptr<UiElement> CreateSnackbar(
+    UiElementName name,
+    Model* model,
+    const gfx::VectorIcon& vector_icon,
+    const base::string16& label,
+    const base::string16& button_label,
+    base::RepeatingCallback<void()> callback) {
+  auto scaler = base::MakeUnique<ScaledDepthAdjuster>(kSnackbarDistance);
+  scaler->set_hit_testable(false);
+
+  auto snackbar_layout =
+      Create<LinearLayout>(name, kPhaseNone, LinearLayout::kRight);
+  snackbar_layout->SetTranslate(0, kSnackbarDistance * sin(kSnackbarAngle), 0);
+  snackbar_layout->SetRotate(1, 0, 0, kSnackbarAngle);
+  snackbar_layout->set_hit_testable(false);
+
+  float radius = 0.5f * kSnackbarHeightDMM;
+  auto snackbar_oval_left = Create<Rect>(kNone, kPhaseForeground);
+  snackbar_oval_left->SetType(kTypeSnackbarDescription);
+  snackbar_oval_left->SetSize(0, kSnackbarHeightDMM);
+  snackbar_oval_left->SetCornerRadii({radius, 0, radius, 0});
+  snackbar_oval_left->set_owner_name_for_test(name);
+  VR_BIND_COLOR(model, snackbar_oval_left.get(),
+                &ColorScheme::snackbar_background, &Rect::SetColor);
+
+  auto snackbar_inner_layout =
+      Create<LinearLayout>(kNone, kPhaseNone, LinearLayout::kRight);
+  snackbar_inner_layout->set_margin(kSnackbarPaddingDMM * 0.5f);
+  snackbar_inner_layout->set_hit_testable(false);
+  snackbar_oval_left->AddBinding(
+      VR_BIND(float, UiElement, snackbar_inner_layout.get(),
+              stale_size().width() + kSnackbarPaddingDMM, UiElement,
+              snackbar_oval_left.get(), SetSize(value, kSnackbarHeightDMM)));
+
+  auto icon = Create<VectorIcon>(kNone, kPhaseForeground, 256);
+  icon->SetSize(kSnackbarIconWidthDMM, kSnackbarIconWidthDMM);
+  icon->SetBackgroundColor(SK_ColorTRANSPARENT);
+  icon->SetIcon(vector_icon);
+  icon->set_hit_testable(false);
+  VR_BIND_COLOR(model, icon.get(), &ColorScheme::snackbar_foreground,
+                &VectorIcon::SetColor);
+
+  auto text = Create<Text>(kNone, kPhaseForeground, kSnackbarFontHeightDMM);
+  text->SetText(label);
+  text->SetLayoutMode(TextLayoutMode::kSingleLineFixedHeight);
+  text->set_hit_testable(false);
+  VR_BIND_COLOR(model, text.get(), &ColorScheme::snackbar_foreground,
+                &Text::SetColor);
+
+  auto button = Create<Button>(kNone, kPhaseForeground, callback);
+  button->SetType(kTypeSnackbarButton);
+  VR_BIND_BUTTON_COLORS(model, button.get(),
+                        &ColorScheme::snackbar_button_colors,
+                        &Button::SetButtonColors);
+  button->set_hover_offset(0.0f);
+  button->SetCornerRadii({0, radius, 0, radius});
+  button->SetSize(0, kSnackbarHeightDMM);
+  button->set_owner_name_for_test(name);
+  button->set_hit_testable(true);
+
+  auto button_layout =
+      Create<LinearLayout>(kNone, kPhaseNone, LinearLayout::kRight);
+  button_layout->set_hit_testable(false);
+
+  auto button_text =
+      Create<Text>(kNone, kPhaseForeground, kSnackbarFontHeightDMM);
+  button_text->SetText(button_label);
+  button_text->SetLayoutMode(TextLayoutMode::kSingleLineFixedHeight);
+  button_text->set_hit_testable(false);
+  button_text->AddBinding(VR_BIND_FUNC(
+      SkColor, Model, model, color_scheme().snackbar_button_colors.foreground,
+      Text, button_text.get(), SetColor));
+
+  button->AddBinding(VR_BIND(float, UiElement, button_layout.get(),
+                             stale_size().width() + kSnackbarPaddingDMM,
+                             UiElement, button.get(),
+                             SetSize(value, kSnackbarHeightDMM)));
+
+  button_layout->AddChild(std::move(button_text));
+  button_layout->AddChild(CreateSpacer(0.5f * kSnackbarPaddingDMM, 0.0f));
+
+  button->AddChild(std::move(button_layout));
+
+  snackbar_inner_layout->AddChild(CreateSpacer(0.0f, 0.0f));
+  snackbar_inner_layout->AddChild(std::move(icon));
+  snackbar_inner_layout->AddChild(std::move(text));
+  snackbar_oval_left->AddChild(std::move(snackbar_inner_layout));
+
+  snackbar_layout->AddChild(std::move(snackbar_oval_left));
+  snackbar_layout->AddChild(std::move(button));
+
+  scaler->AddChild(std::move(snackbar_layout));
+  auto snackbar_root = Create<UiElement>(kNone, kPhaseNone);
+  snackbar_root->set_hit_testable(false);
+  snackbar_root->AddChild(std::move(scaler));
+  return snackbar_root;
+}
+
 }  // namespace
 
 UiSceneCreator::UiSceneCreator(UiBrowserInterface* browser,
@@ -306,6 +412,7 @@
   CreateAudioPermissionPrompt();
   CreateSystemIndicators();
   CreateUrlBar();
+  CreateSnackbars();
   CreateOmnibox();
   CreateCloseButton();
   CreateFullscreenToast();
@@ -677,7 +784,7 @@
       l10n_util::GetStringUTF16(IDS_VR_WEB_VR_TIMEOUT_MESSAGE));
   timeout_text->SetColor(
       model_->color_scheme().web_vr_timeout_message_foreground);
-  timeout_text->SetTextAlignment(UiTexture::kTextAlignmentLeft);
+  timeout_text->SetAlignment(UiTexture::kTextAlignmentLeft);
   timeout_text->SetSize(kTimeoutMessageTextWidthDMM,
                         kTimeoutMessageTextHeightDMM);
 
@@ -747,11 +854,8 @@
       Create<Background>(k2dBrowsingTexturedBackground, kPhaseBackground);
   background->SetVisible(false);
   background->AddBinding(base::MakeUnique<Binding<bool>>(
-      VR_BIND_LAMBDA(
-          [](Model* m) {
-            return m->background_available && m->background_loaded;
-          },
-          base::Unretained(model_)),
+      VR_BIND_LAMBDA([](Model* m) { return m->background_loaded; },
+                     base::Unretained(model_)),
       VR_BIND_LAMBDA([](UiElement* e, const bool& v) { e->SetVisible(v); },
                      base::Unretained(background.get()))));
   scene_->AddUiElement(k2dBrowsingBackground, std::move(background));
@@ -759,7 +863,7 @@
   auto element = Create<UiElement>(k2dBrowsingDefaultBackground, kPhaseNone);
   element->set_hit_testable(false);
   element->AddBinding(VR_BIND_FUNC(bool, Model, model_,
-                                   background_available == false, UiElement,
+                                   background_loaded == false, UiElement,
                                    element.get(), SetVisible));
   scene_->AddUiElement(k2dBrowsingBackground, std::move(element));
 
@@ -923,7 +1027,7 @@
   speech_result->SetTranslate(0.f, kSpeechRecognitionResultTextYOffset, 0.f);
   speech_result->set_hit_testable(false);
   speech_result->SetSize(kVoiceSearchRecognitionResultTextWidth, 0);
-  speech_result->SetTextAlignment(UiTexture::kTextAlignmentCenter);
+  speech_result->SetAlignment(UiTexture::kTextAlignmentCenter);
   VR_BIND_COLOR(model_, speech_result.get(), &ColorScheme::prompt_foreground,
                 &Text::SetColor);
   speech_result->AddBinding(VR_BIND_FUNC(base::string16, Model, model_,
@@ -1213,6 +1317,31 @@
   scene_->AddUiElement(kLoadingIndicator, std::move(indicator_fg));
 }
 
+void UiSceneCreator::CreateSnackbars() {
+  auto snackbar = CreateSnackbar(
+      kDownloadedSnackbar, model_, kFileDownloadDoneIcon,
+      l10n_util::GetStringUTF16(IDS_VR_COMPONENT_UPDATE_READY),
+      base::i18n::ToUpper(l10n_util::GetStringUTF16(IDS_VR_COMPONENT_APPLY)),
+      base::BindRepeating(
+          [](UiBrowserInterface* browser) { browser->LoadAssets(); },
+          base::Unretained(browser_)));
+  snackbar->AddBinding(base::MakeUnique<Binding<bool>>(
+      VR_BIND_LAMBDA([](Model* m) { return m->can_apply_new_background; },
+                     base::Unretained(model_)),
+      VR_BIND_LAMBDA(
+          [](UiElement* s, const bool& value) {
+            s->SetVisible(value);
+            s->SetRotate(1, 0, 0, value ? 0 : kSnackbarMoveInAngle);
+          },
+          base::Unretained(snackbar.get()))));
+  snackbar->SetVisible(false);
+  snackbar->SetRotate(1, 0, 0, kSnackbarMoveInAngle);
+  snackbar->SetTransitionedProperties({OPACITY, TRANSFORM});
+  snackbar->SetTransitionDuration(
+      base::TimeDelta::FromMilliseconds(kSnackbarTransitionDurationMs));
+  scene_->AddUiElement(k2dBrowsingRoot, std::move(snackbar));
+}
+
 void UiSceneCreator::CreateOmnibox() {
   auto visibility_control_root =
       Create<UiElement>(kOmniboxVisibiltyControlForVoice, kPhaseNone);
diff --git a/chrome/browser/vr/ui_scene_creator.h b/chrome/browser/vr/ui_scene_creator.h
index e0619f9..5c2e424 100644
--- a/chrome/browser/vr/ui_scene_creator.h
+++ b/chrome/browser/vr/ui_scene_creator.h
@@ -47,6 +47,7 @@
   void CreateBackground();
   void CreateViewportAwareRoot();
   void CreateUrlBar();
+  void CreateSnackbars();
   void CreateOmnibox();
   void CreateCloseButton();
   void CreateExitPrompt();
diff --git a/chrome/browser/vr/ui_unittest.cc b/chrome/browser/vr/ui_unittest.cc
index 07fb0396..14cd2b2 100644
--- a/chrome/browser/vr/ui_unittest.cc
+++ b/chrome/browser/vr/ui_unittest.cc
@@ -77,7 +77,9 @@
     kSpeechRecognitionResultBackplane,
 };
 const std::set<UiElementType> kHitTestableElementTypes = {
-    kTypeButtonHitTarget, kTypeTextInputText, kTypeOmniboxSuggestionSpacer,
+    kTypeButtonHitTarget,         kTypeTextInputText,
+    kTypeOmniboxSuggestionSpacer, kTypeSnackbarButton,
+    kTypeSnackbarDescription,
 };
 const std::set<UiElementName> kElementsVisibleWithExitWarning = {
     kScreenDimmer, kExitWarningBackground, kExitWarningText};
diff --git a/chrome/browser/vr/vector_icons/BUILD.gn b/chrome/browser/vr/vector_icons/BUILD.gn
index 4e55130..55685ab 100644
--- a/chrome/browser/vr/vector_icons/BUILD.gn
+++ b/chrome/browser/vr/vector_icons/BUILD.gn
@@ -7,7 +7,10 @@
 aggregate_vector_icons("vr_vector_icons") {
   icon_directory = "."
 
-  icons = [ "sad_tab.icon" ]
+  icons = [
+    "sad_tab.icon",
+    "file_download_done.icon",
+  ]
 }
 
 source_set("vector_icons") {
diff --git a/chrome/browser/vr/vector_icons/file_download_done.icon b/chrome/browser/vr/vector_icons/file_download_done.icon
new file mode 100644
index 0000000..d5c94e4
--- /dev/null
+++ b/chrome/browser/vr/vector_icons/file_download_done.icon
@@ -0,0 +1,20 @@
+// 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.
+
+CANVAS_DIMENSIONS, 24,
+MOVE_TO, 5, 18,
+R_H_LINE_TO, 14,
+R_V_LINE_TO, 2,
+H_LINE_TO, 5,
+R_V_LINE_TO, -2,
+CLOSE,
+R_MOVE_TO, 4.6f, -2.7f,
+LINE_TO, 5, 10.7f,
+R_LINE_TO, 2, -1.9f,
+R_LINE_TO, 2.6f, 2.6f,
+LINE_TO, 17, 4,
+R_LINE_TO, 2, 2,
+R_LINE_TO, -9.4f, 9.3f,
+CLOSE,
+END
\ No newline at end of file
diff --git a/chrome/browser/win/enumerate_modules_model.cc b/chrome/browser/win/enumerate_modules_model.cc
index 56e55df..ecfbe05 100644
--- a/chrome/browser/win/enumerate_modules_model.cc
+++ b/chrome/browser/win/enumerate_modules_model.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/win/enumerate_modules_model.h"
 
+#include <windows.h>
+
 #include <softpub.h>
 #include <stddef.h>
 #include <stdint.h>
diff --git a/chrome/common/conflicts/module_watcher_win_unittest.cc b/chrome/common/conflicts/module_watcher_win_unittest.cc
index 87937cb..84d6f3f 100644
--- a/chrome/common/conflicts/module_watcher_win_unittest.cc
+++ b/chrome/common/conflicts/module_watcher_win_unittest.cc
@@ -10,6 +10,8 @@
 #include "base/test/scoped_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#include <windows.h>
+
 class ModuleWatcherTest : public testing::Test {
  protected:
   ModuleWatcherTest()
diff --git a/chrome/common/extensions/api/OWNERS b/chrome/common/extensions/api/OWNERS
index 1a183d1..503d523e 100644
--- a/chrome/common/extensions/api/OWNERS
+++ b/chrome/common/extensions/api/OWNERS
@@ -5,8 +5,7 @@
 per-file *.idl=file://extensions/common/api/API_OWNERS
 
 per-file input_method_private.json=shuchen@chromium.org
-per-file webview*.json=paulmeyer@chromium.org
-per-file webview*.json=fsamuel@chromium.org
+per-file webview*.json=file://components/guest_view/OWNERS
 
 # For trivial changes only, like adding a new enum value or attribute.
 # New APIs or changes to existing APIs should be approved by an
diff --git a/chrome/common/extensions/docs/OWNERS b/chrome/common/extensions/docs/OWNERS
index 3c933bc..c51025e 100644
--- a/chrome/common/extensions/docs/OWNERS
+++ b/chrome/common/extensions/docs/OWNERS
@@ -2,8 +2,7 @@
 mkearney@chromium.org
 
 # For webview documentation.
-paulmeyer@chromium.org
-fsamuel@chromium.org
+file://components/guest_view/OWNERS
 
 # For devtools documentation.
 paulirish@chromium.org
diff --git a/chrome/common/multi_process_lock_win.cc b/chrome/common/multi_process_lock_win.cc
index 7ba4507..875709a 100644
--- a/chrome/common/multi_process_lock_win.cc
+++ b/chrome/common/multi_process_lock_win.cc
@@ -9,6 +9,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/scoped_handle.h"
 
+#include <windows.h>
+
 class MultiProcessLockWin : public MultiProcessLock {
  public:
   explicit MultiProcessLockWin(const std::string& name) : name_(name) { }
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 552f2fe..c33d558 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -304,13 +304,6 @@
     "https://support.google.com/chrome/topic/1678461";
 #endif
 
-#if defined(OS_MACOSX)
-// TODO(mark): Change to a Help Center URL when one is available.
-// https://crbug.com/555044
-const char kMac10_678_DeprecationURL[] =
-    "https://chrome.blogspot.com/2015/11/updates-to-chrome-platform-support.html";
-#endif
-
 #if defined(OS_WIN)
 const char kWindowsXPVistaDeprecationURL[] =
     "https://chrome.blogspot.com/2015/11/updates-to-chrome-platform-support.html";
diff --git a/chrome/installer/util/lzma_file_allocator.cc b/chrome/installer/util/lzma_file_allocator.cc
index 9dcd3ec..4c54818d 100644
--- a/chrome/installer/util/lzma_file_allocator.cc
+++ b/chrome/installer/util/lzma_file_allocator.cc
@@ -7,6 +7,8 @@
 #include "base/files/file_util.h"
 #include "base/logging.h"
 
+#include <windows.h>
+
 extern "C" {
 #include "third_party/lzma_sdk/7zAlloc.h"
 }
diff --git a/chrome/installer/util/lzma_file_allocator_unittest.cc b/chrome/installer/util/lzma_file_allocator_unittest.cc
index 6a5ceda..dcd5710 100644
--- a/chrome/installer/util/lzma_file_allocator_unittest.cc
+++ b/chrome/installer/util/lzma_file_allocator_unittest.cc
@@ -14,6 +14,8 @@
 #include "base/memory/ptr_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#include <windows.h>
+
 class LzmaFileAllocatorTest : public testing::Test {
  protected:
   void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
diff --git a/chrome/renderer/chrome_render_frame_observer.cc b/chrome/renderer/chrome_render_frame_observer.cc
index 1884521..915b5290 100644
--- a/chrome/renderer/chrome_render_frame_observer.cc
+++ b/chrome/renderer/chrome_render_frame_observer.cc
@@ -213,7 +213,8 @@
   SkBitmap thumbnail;
   gfx::Size original_size;
   if (!context_node.IsNull() && context_node.IsElementNode()) {
-    blink::WebImage image = context_node.To<WebElement>().ImageContents();
+    blink::WebImage image =
+        context_node.To<WebElement>().ImageContents();
     original_size = image.Size();
     thumbnail = Downscale(image,
                           thumbnail_min_area_pixels,
diff --git a/chrome/renderer/resources/extensions/web_view/OWNERS b/chrome/renderer/resources/extensions/web_view/OWNERS
index a7c62782..74d34105 100644
--- a/chrome/renderer/resources/extensions/web_view/OWNERS
+++ b/chrome/renderer/resources/extensions/web_view/OWNERS
@@ -1,4 +1,3 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
+file://components/guest_view/OWNERS
 
 # COMPONENT: Platform>Apps>BrowserTag
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index c7f72a21..cd79274d 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -597,6 +597,7 @@
       "../browser/net/predictor_browsertest.cc",
       "../browser/net/profile_network_context_service_browsertest.cc",
       "../browser/net/proxy_browsertest.cc",
+      "../browser/net/variations_http_headers_browsertest.cc",
       "../browser/net/websocket_browsertest.cc",
       "../browser/ntp_snippets/content_suggestions_service_factory_browsertest.cc",
       "../browser/ntp_tiles/ntp_tiles_browsertest.cc",
@@ -1353,6 +1354,7 @@
         "../browser/ui/views/frame/browser_window_property_manager_browsertest_win.cc",
         "../browser/ui/views/importer/import_lock_dialog_view_browsertest.cc",
         "../browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc",
+        "../browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc",
         "../browser/ui/views/passwords/manage_passwords_bubble_view_browsertest.cc",
         "../browser/ui/views/payments/contact_info_editor_view_controller_browsertest.cc",
         "../browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc",
@@ -1419,7 +1421,6 @@
           "../browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc",
           "../browser/ui/views/frame/browser_view_browsertest.cc",
           "../browser/ui/views/location_bar/location_icon_view_browsertest.cc",
-          "../browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc",
           "../browser/ui/views/media_router/media_router_ui_browsertest.cc",
           "../browser/ui/views/page_info/page_info_bubble_view_browsertest.cc",
           "../browser/ui/views/passwords/password_dialog_view_browsertest.cc",
@@ -4856,7 +4857,6 @@
       "//chrome/child",
       "//components/crash/core/common",
       "//components/flags_ui:switches",
-      "//gpu/config:crash_keys",
     ]
     if (!is_fuchsia) {
       # TODO(crbug.com/753619): Enable crash reporting on Fuchsia.
diff --git a/chrome/test/data/extensions/platform_apps/web_view/OWNERS b/chrome/test/data/extensions/platform_apps/web_view/OWNERS
index cf8fef33..74d34105 100644
--- a/chrome/test/data/extensions/platform_apps/web_view/OWNERS
+++ b/chrome/test/data/extensions/platform_apps/web_view/OWNERS
@@ -1,5 +1,3 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-wjmaclean@chromium.org
+file://components/guest_view/OWNERS
 
 # COMPONENT: Platform>Apps>BrowserTag
diff --git a/chrome/utility/safe_browsing/mac/hfs.cc b/chrome/utility/safe_browsing/mac/hfs.cc
index 563b71a7..30dcb93 100644
--- a/chrome/utility/safe_browsing/mac/hfs.cc
+++ b/chrome/utility/safe_browsing/mac/hfs.cc
@@ -501,8 +501,8 @@
   }
   ConvertBigEndian(&header_);
 
-  if (header_.nodeSize == 0) {
-    DLOG(ERROR) << "Invalid header: zero node size";
+  if (header_.nodeSize < sizeof(BTNodeDescriptor)) {
+    DLOG(ERROR) << "Invalid header: node size smaller than BTNodeDescriptor";
     return false;
   }
 
diff --git a/chromecast/browser/android/BUILD.gn b/chromecast/browser/android/BUILD.gn
index 54077e51..a72a708 100644
--- a/chromecast/browser/android/BUILD.gn
+++ b/chromecast/browser/android/BUILD.gn
@@ -72,7 +72,7 @@
     "$java_src_dir/org/chromium/chromecast/shell/LogcatExtractor.java",
   ]
 
-  android_manifest = cast_shell_android_manifest
+  android_manifest_for_lint = cast_shell_android_manifest
 
   srcjar_deps = [ ":cast_shell_build_config_gen" ]
 
diff --git a/components/autofill/core/browser/autofill_ie_toolbar_import_win_unittest.cc b/components/autofill/core/browser/autofill_ie_toolbar_import_win_unittest.cc
index 2bf3e457..aba32f1 100644
--- a/components/autofill/core/browser/autofill_ie_toolbar_import_win_unittest.cc
+++ b/components/autofill/core/browser/autofill_ie_toolbar_import_win_unittest.cc
@@ -15,6 +15,8 @@
 #include "components/os_crypt/os_crypt.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#include <windows.h>
+
 using base::win::RegKey;
 
 namespace autofill {
diff --git a/components/autofill/ios/browser/BUILD.gn b/components/autofill/ios/browser/BUILD.gn
index d160cc86..a02d9c0 100644
--- a/components/autofill/ios/browser/BUILD.gn
+++ b/components/autofill/ios/browser/BUILD.gn
@@ -61,7 +61,6 @@
 js_compile_checked("injected_js") {
   visibility = [ ":browser" ]
   sources = [
-    "resources/autofill_controller.js",
     "resources/suggestion_controller.js",
   ]
 }
diff --git a/components/autofill/ios/browser/autofill_agent.mm b/components/autofill/ios/browser/autofill_agent.mm
index edc0f7c..bfdf303 100644
--- a/components/autofill/ios/browser/autofill_agent.mm
+++ b/components/autofill/ios/browser/autofill_agent.mm
@@ -136,6 +136,10 @@
                                     type:(const std::string&)type
                                 webState:(web::WebState*)webState;
 
+// Returns whether Autofill is enabled by checking if Autofill is turned on and
+// if the current URL has a web scheme and the page content is HTML.
+- (BOOL)isAutofillEnabled;
+
 // Sends a request to AutofillManager to retrieve suggestions for the specified
 // form and field.
 - (void)queryAutofillWithForms:(const FormDataVector&)forms
@@ -157,8 +161,8 @@
 @end
 
 @implementation AutofillAgent {
-  // Timestamp of the first time forms are seen.
-  base::TimeTicks formsSeenTimestamp_;
+  // Whether page is scanned for forms.
+  BOOL pageProcessed_;
 
   // The WebState this instance is observing. Will be null after
   // -webStateDestroyed: has been called.
@@ -213,9 +217,8 @@
     webStateObserverBridge_ =
         std::make_unique<web::WebStateObserverBridge>(self);
     webState_->AddObserver(webStateObserverBridge_.get());
-    jsAutofillManager_ = base::mac::ObjCCastStrict<JsAutofillManager>(
-        [webState_->GetJSInjectionReceiver()
-            instanceOfClass:[JsAutofillManager class]]);
+    jsAutofillManager_ = [[JsAutofillManager alloc]
+        initWithReceiver:webState_->GetJSInjectionReceiver()];
   }
   return self;
 }
@@ -328,7 +331,7 @@
   DCHECK(autofillManager);
   DCHECK(!forms.empty());
   autofillManager->Reset();
-  autofillManager->OnFormsSeen(forms, formsSeenTimestamp_);
+  autofillManager->OnFormsSeen(forms, base::TimeTicks::Now());
 }
 
 - (void)notifyAutofillManager:(autofill::AutofillManager*)autofillManager
@@ -353,17 +356,6 @@
              completionHandler:(FetchFormsCompletionHandler)completionHandler {
   DCHECK(completionHandler);
 
-  // TODO(crbug.com/418827): Early-inject the script and replace the following
-  // if statement with a DCHECK if a race condition between the script injection
-  // and the call to the this function continues to happen.
-  // Return if the script has not been injected.
-  if (![jsAutofillManager_ hasBeenInjected]) {
-    dispatch_async(dispatch_get_main_queue(), ^{
-      completionHandler(NO, FormDataVector());
-    });
-    return;
-  }
-
   // Necessary so the values can be used inside a block.
   base::string16 formNameCopy = formName;
   GURL pageURLCopy = pageURL;
@@ -569,13 +561,18 @@
                                   webState:(web::WebState*)webState
                          completionHandler:
                              (SuggestionsAvailableCompletion)completion {
+  DCHECK_EQ(webState_, webState);
+
   if (!isMainFrame) {
     // Filling in iframes is not implemented.
     completion(NO);
     return;
   }
-  web::URLVerificationTrustLevel trustLevel;
-  const GURL pageURL(webState->GetCurrentURL(&trustLevel));
+
+  if (![self isAutofillEnabled]) {
+    completion(NO);
+    return;
+  }
 
   // Once the active form and field are extracted, send a query to the
   // AutofillManager for suggestions.
@@ -591,6 +588,9 @@
     }
   };
 
+  web::URLVerificationTrustLevel trustLevel;
+  const GURL pageURL(webState->GetCurrentURL(&trustLevel));
+
   // Re-extract the active form and field only. All forms with at least one
   // input element are considered because key/value suggestions are offered
   // even on short forms.
@@ -670,16 +670,9 @@
     // Saving from iframes is not implemented.
     return;
   }
-  DCHECK_EQ(webState_, webState);
-  if (!prefService_->GetBoolean(autofill::prefs::kAutofillEnabled))
-    return;
 
-  web::URLVerificationTrustLevel trustLevel;
-  const GURL pageURL(webState->GetCurrentURL(&trustLevel));
-  if (trustLevel != web::URLVerificationTrustLevel::kAbsolute) {
-    DLOG(WARNING) << "Form submit not handled on untrusted page";
+  if (![self isAutofillEnabled])
     return;
-  }
 
   __weak AutofillAgent* weakSelf = self;
   id completionHandler = ^(BOOL success, const FormDataVector& forms) {
@@ -699,6 +692,10 @@
                         userInitiated:userInitiated];
 
   };
+
+  web::URLVerificationTrustLevel trustLevel;
+  const GURL pageURL(webState->GetCurrentURL(&trustLevel));
+
   // This code is racing against the new page loading and will not get the
   // password form data if the page has changed. In most cases this code wins
   // the race.
@@ -711,29 +708,18 @@
 }
 
 - (void)webState:(web::WebState*)webState didLoadPageWithSuccess:(BOOL)success {
-  DCHECK_EQ(webState_, webState);
-  if (!prefService_->GetBoolean(autofill::prefs::kAutofillEnabled) ||
-      !webState->ContentIsHTML()) {
+  if (![self isAutofillEnabled])
     return;
-  }
+
+  pageProcessed_ = NO;
   [self processPage:webState];
 }
 
 - (void)processPage:(web::WebState*)webState {
-  DCHECK_EQ(webState_, webState);
-  web::URLVerificationTrustLevel trustLevel;
-  const GURL pageURL(webState->GetCurrentURL(&trustLevel));
-  if (trustLevel != web::URLVerificationTrustLevel::kAbsolute) {
-    DLOG(WARNING) << "Page load not handled on untrusted page";
-    return;
-  }
-
-  if (!web::UrlHasWebScheme(pageURL))
-    return;
-
   // This process is only done once.
-  if ([jsAutofillManager_ hasBeenInjected])
+  if (pageProcessed_)
     return;
+  pageProcessed_ = YES;
 
   popupDelegate_.reset();
   suggestionsAvailableCompletion_ = nil;
@@ -741,7 +727,8 @@
   mostRecentSuggestions_ = nil;
   typedValue_ = nil;
 
-  [jsAutofillManager_ inject];
+  web::URLVerificationTrustLevel trustLevel;
+  const GURL pageURL(webState->GetCurrentURL(&trustLevel));
 
   __weak AutofillAgent* weakSelf = self;
   id completionHandler = ^(BOOL success, const FormDataVector& forms) {
@@ -768,18 +755,7 @@
 
 - (void)webState:(web::WebState*)webState
     didRegisterFormActivity:(const web::FormActivityParams&)params {
-  DCHECK_EQ(webState_, webState);
-  if (!prefService_->GetBoolean(autofill::prefs::kAutofillEnabled))
-    return;
-  web::URLVerificationTrustLevel trustLevel;
-  const GURL pageURL(webState->GetCurrentURL(&trustLevel));
-  if (trustLevel != web::URLVerificationTrustLevel::kAbsolute) {
-    DLOG(WARNING) << "Form activity not handled on untrusted page";
-    return;
-  }
-
-  // Autofill and suggestion scripts are only injected for web URLs.
-  if (!web::UrlHasWebScheme(pageURL) || !webState->ContentIsHTML())
+  if (![self isAutofillEnabled])
     return;
 
   // Returns early and reset the suggestion state if an error occurs.
@@ -812,6 +788,9 @@
     }
   };
 
+  web::URLVerificationTrustLevel trustLevel;
+  const GURL pageURL(webState->GetCurrentURL(&trustLevel));
+
   // Re-extract the active form and field only. There is no minimum field
   // requirement because key/value suggestions are offered even on short forms.
   [self fetchFormsFiltered:YES
@@ -845,6 +824,17 @@
   }
 }
 
+- (BOOL)isAutofillEnabled {
+  if (!prefService_->GetBoolean(autofill::prefs::kAutofillEnabled))
+    return NO;
+
+  web::URLVerificationTrustLevel trustLevel;
+  const GURL pageURL(webState_->GetCurrentURL(&trustLevel));
+
+  // Only web URLs are supported by Autofill.
+  return web::UrlHasWebScheme(pageURL) && webState_->ContentIsHTML();
+}
+
 #pragma mark -
 #pragma mark AutofillViewClient
 
diff --git a/components/autofill/ios/browser/autofill_agent_unittests.mm b/components/autofill/ios/browser/autofill_agent_unittests.mm
index 5d8a1ef6..e15077b 100644
--- a/components/autofill/ios/browser/autofill_agent_unittests.mm
+++ b/components/autofill/ios/browser/autofill_agent_unittests.mm
@@ -22,23 +22,6 @@
 #error "This file requires ARC support."
 #endif
 
-class MockWebState : public web::TestWebState {
- public:
-  MockWebState() : js_injection_receiver_(nullptr) {}
-  ~MockWebState() override {}
-
-  CRWJSInjectionReceiver* GetJSInjectionReceiver() const override {
-    return js_injection_receiver_;
-  }
-
-  void SetJSInjectionReceiver(CRWJSInjectionReceiver* receiver) {
-    js_injection_receiver_ = receiver;
-  }
-
- private:
-  CRWJSInjectionReceiver* js_injection_receiver_;
-};
-
 // Test fixture for AutofillAgent testing.
 class AutofillAgentTests : public PlatformTest {
  public:
@@ -46,32 +29,22 @@
 
   void SetUp() override {
     PlatformTest::SetUp();
-    // Mock out the JsAutofillManager.
-    mock_js_autofill_manager_ =
-        [OCMockObject mockForClass:[JsAutofillManager class]];
-    mock_web_state_ = std::make_unique<MockWebState>();
-    id mock_js_injection_receiver =
+
+    // Mock CRWJSInjectionReceiver for verifying interactions.
+    mock_js_injection_receiver_ =
         [OCMockObject mockForClass:[CRWJSInjectionReceiver class]];
-
-    mock_web_state_->SetJSInjectionReceiver(mock_js_injection_receiver);
-
-    // Set expectations for setting the JsCastSenderManager instance.
-    [[[mock_js_autofill_manager_ stub] andReturnValue:@YES]
-        isKindOfClass:[JsAutofillManager class]];
-    [[[mock_js_injection_receiver expect] andReturn:mock_js_autofill_manager_]
-        instanceOfClass:[JsAutofillManager class]];
+    test_web_state_.SetJSInjectionReceiver(mock_js_injection_receiver_);
 
     prefs_ = autofill::test::PrefServiceForTesting();
     autofill_agent_ =
         [[AutofillAgent alloc] initWithPrefService:prefs_.get()
-                                          webState:mock_web_state_.get()];
+                                          webState:&test_web_state_];
   }
 
-  std::unique_ptr<MockWebState> mock_web_state_;
+  web::TestWebState test_web_state_;
   AutofillAgent* autofill_agent_;
   std::unique_ptr<PrefService> prefs_;
-  // Mock JsSuggestionManager for verifying interactions.
-  id mock_js_autofill_manager_;
+  id mock_js_injection_receiver_;
 
   DISALLOW_COPY_AND_ASSIGN(AutofillAgentTests);
 };
@@ -96,17 +69,16 @@
   field.value = base::ASCIIToUTF16("");
   form.fields.push_back(field);
   // Fields are in alphabetical order.
-  [[mock_js_autofill_manager_ expect] fillForm:
-                                          @"{\"fields\":{"
-                                           "\"name\":\"name_value\","
-                                           "\"number\":\"number_value\","
-                                           "\"unknown\":\"\""
-                                           "},\"formName\":\"\"}"
-                            forceFillFieldName:@""
-                             completionHandler:[OCMArg any]];
+  [[mock_js_injection_receiver_ expect]
+      executeJavaScript:
+          @"__gCrWeb.autofill.fillForm({\"fields\":{\"name\":\"name_value\","
+          @"\"number\":\"number_value\",\"unknown\":\"\"},\"formName\":\"\"}, "
+          @"\"\");"
+      completionHandler:[OCMArg any]];
   [autofill_agent_ onFormDataFilled:form];
-  mock_web_state_->WasShown();
-  EXPECT_OCMOCK_VERIFY(mock_js_autofill_manager_);
+  test_web_state_.WasShown();
+
+  EXPECT_OCMOCK_VERIFY(mock_js_injection_receiver_);
 }
 
 TEST_F(AutofillAgentTests, OnFormDataFilledWithNameCollisionTest) {
@@ -134,15 +106,13 @@
   field.value = base::ASCIIToUTF16("value 2");
   form.fields.push_back(field);
   // Fields are in alphabetical order.
-  [[mock_js_autofill_manager_ expect] fillForm:
-                                          @"{\"fields\":{"
-                                           "\"field1\":\"value 2\","
-                                           "\"region\":\"California\""
-                                           "},\"formName\":\"\"}"
-                            forceFillFieldName:@""
-                             completionHandler:[OCMArg any]];
+  [[mock_js_injection_receiver_ expect]
+      executeJavaScript:
+          @"__gCrWeb.autofill.fillForm({\"fields\":{\"field1\":\"value "
+          @"2\",\"region\":\"California\"},\"formName\":\"\"}, \"\");"
+      completionHandler:[OCMArg any]];
   [autofill_agent_ onFormDataFilled:form];
-  mock_web_state_->WasShown();
+  test_web_state_.WasShown();
 
-  EXPECT_OCMOCK_VERIFY(mock_js_autofill_manager_);
+  EXPECT_OCMOCK_VERIFY(mock_js_injection_receiver_);
 }
diff --git a/components/autofill/ios/browser/js_autofill_manager.h b/components/autofill/ios/browser/js_autofill_manager.h
index 6b957ca..74182625 100644
--- a/components/autofill/ios/browser/js_autofill_manager.h
+++ b/components/autofill/ios/browser/js_autofill_manager.h
@@ -7,13 +7,11 @@
 
 #include "base/ios/block_types.h"
 #include "components/autofill/core/common/autofill_constants.h"
-#import "ios/web/public/web_state/js/crw_js_injection_manager.h"
-
-@class CRWJSInjectionReceiver;
+#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 
 // Loads the JavaScript file, autofill_controller.js, which contains form
 // parsing and autofill functions.
-@interface JsAutofillManager : CRWJSInjectionManager
+@interface JsAutofillManager : NSObject
 
 // Extracts forms from a web page. Only forms with at least |requiredFields|
 // fields are extracted.
@@ -51,6 +49,12 @@
 // Marks up the form with autofill field prediction data (diagnostic tool).
 - (void)fillPredictionData:(NSString*)dataString;
 
+// Designated initializer. |receiver| should not be nil.
+- (instancetype)initWithReceiver:(CRWJSInjectionReceiver*)receiver
+    NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)init NS_UNAVAILABLE;
+
 @end
 
 #endif  // COMPONENTS_AUTOFILL_IOS_BROWSER_JS_AUTOFILL_MANAGER_H_
diff --git a/components/autofill/ios/browser/js_autofill_manager.mm b/components/autofill/ios/browser/js_autofill_manager.mm
index 7131576..ea192bc 100644
--- a/components/autofill/ios/browser/js_autofill_manager.mm
+++ b/components/autofill/ios/browser/js_autofill_manager.mm
@@ -13,7 +13,19 @@
 #error "This file requires ARC support."
 #endif
 
-@implementation JsAutofillManager
+@implementation JsAutofillManager {
+  // The injection receiver used to evaluate JavaScript.
+  CRWJSInjectionReceiver* _receiver;
+}
+
+- (instancetype)initWithReceiver:(CRWJSInjectionReceiver*)receiver {
+  DCHECK(receiver);
+  self = [super init];
+  if (self) {
+    _receiver = receiver;
+  }
+  return self;
+}
 
 - (void)fetchFormsWithMinimumRequiredFieldsCount:(NSUInteger)requiredFieldsCount
                                completionHandler:
@@ -22,27 +34,24 @@
   NSString* extractFormsJS = [NSString
       stringWithFormat:@"__gCrWeb.autofill.extractForms(%" PRIuNS ");",
                        requiredFieldsCount];
-  [self executeJavaScript:extractFormsJS
-        completionHandler:^(id result, NSError*) {
-          completionHandler(base::mac::ObjCCastStrict<NSString>(result));
-        }];
+  [_receiver executeJavaScript:extractFormsJS
+             completionHandler:^(id result, NSError*) {
+               completionHandler(base::mac::ObjCCastStrict<NSString>(result));
+             }];
 }
 
 #pragma mark -
 #pragma mark ProtectedMethods
 
-- (NSString*)scriptPath {
-  return @"autofill_controller";
-}
-
 - (void)fillActiveFormField:(NSString*)dataString
           completionHandler:(ProceduralBlock)completionHandler {
   NSString* script =
       [NSString stringWithFormat:@"__gCrWeb.autofill.fillActiveFormField(%@);",
                                  dataString];
-  [self executeJavaScript:script completionHandler:^(id, NSError*) {
-    completionHandler();
-  }];
+  [_receiver executeJavaScript:script
+             completionHandler:^(id, NSError*) {
+               completionHandler();
+             }];
 }
 
 - (void)fillForm:(NSString*)dataString
@@ -56,9 +65,10 @@
   NSString* fillFormJS =
       [NSString stringWithFormat:@"__gCrWeb.autofill.fillForm(%@, %s);",
                                  dataString, fieldName.c_str()];
-  [self executeJavaScript:fillFormJS completionHandler:^(id, NSError*) {
-    completionHandler();
-  }];
+  [_receiver executeJavaScript:fillFormJS
+             completionHandler:^(id, NSError*) {
+               completionHandler();
+             }];
 }
 
 - (void)clearAutofilledFieldsForFormNamed:(NSString*)formName
@@ -68,16 +78,17 @@
       [NSString stringWithFormat:
                     @"__gCrWeb.autofill.clearAutofilledFields(%s);",
                     base::GetQuotedJSONString([formName UTF8String]).c_str()];
-  [self executeJavaScript:script completionHandler:^(id, NSError*) {
-    completionHandler();
-  }];
+  [_receiver executeJavaScript:script
+             completionHandler:^(id, NSError*) {
+               completionHandler();
+             }];
 }
 
 - (void)fillPredictionData:(NSString*)dataString {
   NSString* script =
       [NSString stringWithFormat:@"__gCrWeb.autofill.fillPredictionData(%@);",
                                  dataString];
-  [self executeJavaScript:script completionHandler:nil];
+  [_receiver executeJavaScript:script completionHandler:nil];
 }
 
 @end
diff --git a/components/autofill/ios/browser/resources/autofill_controller.js b/components/autofill/ios/browser/resources/autofill_controller.js
index a38aeff9..1dc9f17 100644
--- a/components/autofill/ios/browser/resources/autofill_controller.js
+++ b/components/autofill/ios/browser/resources/autofill_controller.js
@@ -15,6 +15,7 @@
   * TODO(crbug.com/647084): Enable checkTypes error for this file.
   * @suppress {checkTypes}
   */
+goog.provide('__crWeb.autofill');
 
 /**
   * @typedef {{
diff --git a/components/browser_watcher/exit_code_watcher_win.cc b/components/browser_watcher/exit_code_watcher_win.cc
index 3d762ed..d5af475 100644
--- a/components/browser_watcher/exit_code_watcher_win.cc
+++ b/components/browser_watcher/exit_code_watcher_win.cc
@@ -11,6 +11,8 @@
 #include "base/strings/stringprintf.h"
 #include "base/win/registry.h"
 
+#include <windows.h>
+
 namespace browser_watcher {
 
 namespace {
diff --git a/components/consent_auditor/consent_auditor.cc b/components/consent_auditor/consent_auditor.cc
index d2fba70..d86c85f 100644
--- a/components/consent_auditor/consent_auditor.cc
+++ b/components/consent_auditor/consent_auditor.cc
@@ -36,7 +36,7 @@
       return UserEventSpecifics::UserConsent::GIVEN;
   }
   NOTREACHED();
-  return UserEventSpecifics::UserConsent::GIVEN;
+  return UserEventSpecifics::UserConsent::UNSPECIFIED;
 }
 
 }  // namespace
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index f4613c4..7909990 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -844,7 +844,7 @@
 
 android_library("cronet_perf_test_apk_java") {
   testonly = true
-  android_manifest = "test/javaperftests/AndroidManifest.xml"
+  android_manifest_for_lint = "test/javaperftests/AndroidManifest.xml"
   java_files =
       [ "test/javaperftests/src/org/chromium/net/CronetPerfTestActivity.java" ]
 
diff --git a/components/dom_distiller/content/browser/android/java/src/org/chromium/components/dom_distiller/content/DistillablePageUtils.java b/components/dom_distiller/content/browser/android/java/src/org/chromium/components/dom_distiller/content/DistillablePageUtils.java
index ad1d87fc..9b7e411 100644
--- a/components/dom_distiller/content/browser/android/java/src/org/chromium/components/dom_distiller/content/DistillablePageUtils.java
+++ b/components/dom_distiller/content/browser/android/java/src/org/chromium/components/dom_distiller/content/DistillablePageUtils.java
@@ -37,13 +37,16 @@
     /**
      * Delegate to receive distillability updates.
      */
-    public static interface PageDistillableDelegate {
+    public interface PageDistillableDelegate {
         /**
          * Called when the distillability status changes.
          * @param isDistillable Whether the page is distillable.
          * @param isLast Whether the update is the last one for this page.
+         * @param isMobileOptimized Whether the page is optimized for mobile. Only valid when
+         *                         the heuristics is ADABOOST_MODEL or ALL_ARTICLES.
          */
-        public void onIsPageDistillableResult(boolean isDistillable, boolean isLast);
+        void onIsPageDistillableResult(
+                boolean isDistillable, boolean isLast, boolean isMobileOptimized);
     }
 
     public static void setDelegate(WebContents webContents,
@@ -52,10 +55,10 @@
     }
 
     @CalledByNative
-    private static void callOnIsPageDistillableUpdate(
-            PageDistillableDelegate delegate, boolean isDistillable, boolean isLast) {
+    private static void callOnIsPageDistillableUpdate(PageDistillableDelegate delegate,
+            boolean isDistillable, boolean isLast, boolean isMobileOptimized) {
         if (delegate != null) {
-            delegate.onIsPageDistillableResult(isDistillable, isLast);
+            delegate.onIsPageDistillableResult(isDistillable, isLast, isMobileOptimized);
         }
     }
 
diff --git a/components/dom_distiller/content/browser/distillability_driver.cc b/components/dom_distiller/content/browser/distillability_driver.cc
index f4c9d30..0ec73fb 100644
--- a/components/dom_distiller/content/browser/distillability_driver.cc
+++ b/components/dom_distiller/content/browser/distillability_driver.cc
@@ -28,9 +28,12 @@
   ~DistillabilityServiceImpl() override {
   }
 
-  void NotifyIsDistillable(bool is_distillable, bool is_last_update) override {
+  void NotifyIsDistillable(bool is_distillable,
+                           bool is_last_update,
+                           bool is_mobile_friendly) override {
     if (!distillability_driver_) return;
-    distillability_driver_->OnDistillability(is_distillable, is_last_update);
+    distillability_driver_->OnDistillability(is_distillable, is_last_update,
+                                             is_mobile_friendly);
   }
 
  private:
@@ -43,8 +46,8 @@
       weak_factory_(this) {
   if (!web_contents) return;
   frame_interfaces_.AddInterface(
-      base::Bind(&DistillabilityDriver::CreateDistillabilityService,
-                 base::Unretained(this)));
+      base::BindRepeating(&DistillabilityDriver::CreateDistillabilityService,
+                          base::Unretained(this)));
 }
 
 DistillabilityDriver::~DistillabilityDriver() {
@@ -59,14 +62,16 @@
 }
 
 void DistillabilityDriver::SetDelegate(
-    const base::Callback<void(bool, bool)>& delegate) {
+    const base::RepeatingCallback<void(bool, bool, bool)>& delegate) {
   m_delegate_ = delegate;
 }
 
-void DistillabilityDriver::OnDistillability(bool distillable, bool is_last) {
+void DistillabilityDriver::OnDistillability(bool distillable,
+                                            bool is_last,
+                                            bool is_mobile_friendly) {
   if (m_delegate_.is_null()) return;
 
-  m_delegate_.Run(distillable, is_last);
+  m_delegate_.Run(distillable, is_last, is_mobile_friendly);
 }
 
 void DistillabilityDriver::OnInterfaceRequestFromFrame(
diff --git a/components/dom_distiller/content/browser/distillability_driver.h b/components/dom_distiller/content/browser/distillability_driver.h
index ebfd4b0..85dea22 100644
--- a/components/dom_distiller/content/browser/distillability_driver.h
+++ b/components/dom_distiller/content/browser/distillability_driver.h
@@ -7,6 +7,7 @@
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "components/dom_distiller/content/browser/distillable_page_utils.h"
 #include "components/dom_distiller/content/common/distillability_service.mojom.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
@@ -24,7 +25,7 @@
   void CreateDistillabilityService(
       mojom::DistillabilityServiceRequest request);
 
-  void SetDelegate(const base::Callback<void(bool, bool)>& delegate);
+  void SetDelegate(const DistillabilityDelegate& delegate);
 
   // content::WebContentsObserver implementation.
   void OnInterfaceRequestFromFrame(
@@ -37,9 +38,11 @@
   friend class content::WebContentsUserData<DistillabilityDriver>;
   friend class DistillabilityServiceImpl;
 
-  void OnDistillability(bool distillable, bool is_last);
+  void OnDistillability(bool distillable,
+                        bool is_last,
+                        bool is_mobile_friendly);
 
-  base::Callback<void(bool, bool)> m_delegate_;
+  DistillabilityDelegate m_delegate_;
 
   service_manager::BinderRegistry frame_interfaces_;
 
diff --git a/components/dom_distiller/content/browser/distillable_page_utils.h b/components/dom_distiller/content/browser/distillable_page_utils.h
index dd3e00a..d2805d6 100644
--- a/components/dom_distiller/content/browser/distillable_page_utils.h
+++ b/components/dom_distiller/content/browser/distillable_page_utils.h
@@ -29,7 +29,7 @@
                                   const DistillablePageDetector* detector,
                                   base::Callback<void(bool)> callback);
 
-typedef base::Callback<void(bool, bool)> DistillabilityDelegate;
+typedef base::RepeatingCallback<void(bool, bool, bool)> DistillabilityDelegate;
 
 // Set the delegate to receive the result of whether the page is distillable.
 void setDelegate(content::WebContents* web_contents,
diff --git a/components/dom_distiller/content/browser/distillable_page_utils_android.cc b/components/dom_distiller/content/browser/distillable_page_utils_android.cc
index 5a7133b8..69a880e 100644
--- a/components/dom_distiller/content/browser/distillable_page_utils_android.cc
+++ b/components/dom_distiller/content/browser/distillable_page_utils_android.cc
@@ -27,9 +27,11 @@
 
 void OnIsPageDistillableUpdate(const JavaRef<jobject>& callback,
                                bool isDistillable,
-                               bool isLast) {
+                               bool isLast,
+                               bool isMobileFriendly) {
   Java_DistillablePageUtils_callOnIsPageDistillableUpdate(
-      base::android::AttachCurrentThread(), callback, isDistillable, isLast);
+      base::android::AttachCurrentThread(), callback, isDistillable, isLast,
+      isMobileFriendly);
 }
 }  // namespace
 
diff --git a/components/dom_distiller/content/common/distillability_service.mojom b/components/dom_distiller/content/common/distillability_service.mojom
index 7c2475f..0323f06 100644
--- a/components/dom_distiller/content/common/distillability_service.mojom
+++ b/components/dom_distiller/content/common/distillability_service.mojom
@@ -5,7 +5,10 @@
 module dom_distiller.mojom;
 
 // This service is implemented in the browser process and is used by the
-// renderer to notify the Reader Mode UI if a page is distillable.
+// renderer to notify the Reader Mode UI whether a page is distillable.
+// |is_mobile_friendly| is only valid when the heuristics is ADABOOST_MODEL
+// or ALL_ARTICLES.
 interface DistillabilityService {
-  NotifyIsDistillable(bool page_is_distillable, bool is_last_update);
+  NotifyIsDistillable(bool page_is_distillable, bool is_last_update,
+      bool is_mobile_friendly);
 };
diff --git a/components/dom_distiller/content/renderer/distillability_agent.cc b/components/dom_distiller/content/renderer/distillability_agent.cc
index e69378f..fd587b0e 100644
--- a/components/dom_distiller/content/renderer/distillability_agent.cc
+++ b/components/dom_distiller/content/renderer/distillability_agent.cc
@@ -78,12 +78,13 @@
                                const DistillablePageDetector* detector,
                                const DistillablePageDetector* long_page,
                                bool is_last,
-                               bool exclude_mobile) {
-  WebDistillabilityFeatures features = doc.DistillabilityFeatures();
+                               bool& is_mobile_friendly) {
   GURL parsed_url(doc.Url());
   if (!parsed_url.is_valid()) {
     return false;
   }
+  WebDistillabilityFeatures features = doc.DistillabilityFeatures();
+  is_mobile_friendly = features.is_mobile_friendly;
   std::vector<double> derived = CalculateDerivedFeatures(
       features.open_graph, parsed_url, features.element_count,
       features.anchor_count, features.form_count, features.moz_score,
@@ -147,26 +148,23 @@
   if (blacklisted) {
     return false;
   }
-  if (exclude_mobile && features.is_mobile_friendly) {
-    return false;
-  }
   return distillable && long_article;
 }
 
-bool IsDistillablePage(WebDocument& doc, bool is_last) {
+bool IsDistillablePage(WebDocument& doc,
+                       bool is_last,
+                       bool& is_mobile_friendly) {
   switch (GetDistillerHeuristicsType()) {
     case DistillerHeuristicsType::ALWAYS_TRUE:
       return true;
     case DistillerHeuristicsType::OG_ARTICLE:
       return doc.DistillabilityFeatures().open_graph;
     case DistillerHeuristicsType::ADABOOST_MODEL:
-      return IsDistillablePageAdaboost(
-          doc, DistillablePageDetector::GetNewModel(),
-          DistillablePageDetector::GetLongPageModel(), is_last, true);
     case DistillerHeuristicsType::ALL_ARTICLES:
       return IsDistillablePageAdaboost(
           doc, DistillablePageDetector::GetNewModel(),
-          DistillablePageDetector::GetLongPageModel(), is_last, false);
+          DistillablePageDetector::GetLongPageModel(), is_last,
+          is_mobile_friendly);
     case DistillerHeuristicsType::NONE:
     default:
       return false;
@@ -206,8 +204,10 @@
       &distillability_service);
   DCHECK(distillability_service);
   if (!distillability_service.is_bound()) return;
-  distillability_service->NotifyIsDistillable(
-      IsDistillablePage(doc, is_last), is_last);
+  bool is_mobile_friendly = false;
+  bool is_distillable = IsDistillablePage(doc, is_last, is_mobile_friendly);
+  distillability_service->NotifyIsDistillable(is_distillable, is_last,
+                                              is_mobile_friendly);
 }
 
 DistillabilityAgent::~DistillabilityAgent() {}
diff --git a/components/dom_distiller/core/BUILD.gn b/components/dom_distiller/core/BUILD.gn
index 1c0059eb..f190917d 100644
--- a/components/dom_distiller/core/BUILD.gn
+++ b/components/dom_distiller/core/BUILD.gn
@@ -172,4 +172,10 @@
     ]
     jni_package = "dom_distiller_core"
   }
+
+  java_cpp_enum("distiller_type_java") {
+    sources = [
+      "experiments.h",
+    ]
+  }
 }
diff --git a/components/dom_distiller/core/experiments.h b/components/dom_distiller/core/experiments.h
index 80d02fa8..da2fab4 100644
--- a/components/dom_distiller/core/experiments.h
+++ b/components/dom_distiller/core/experiments.h
@@ -6,6 +6,7 @@
 #define COMPONENTS_DOM_DISTILLER_CORE_EXPERIMENTS_H_
 
 namespace dom_distiller {
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.dom_distiller
 enum class DistillerHeuristicsType {
   NONE,
   OG_ARTICLE,
diff --git a/components/guest_view/OWNERS b/components/guest_view/OWNERS
index 728baf502..439b190 100644
--- a/components/guest_view/OWNERS
+++ b/components/guest_view/OWNERS
@@ -5,5 +5,6 @@
 wjmaclean@chromium.org
 paulmeyer@chromium.org
 ekaramad@chromium.org
+mcnee@chromium.org
 
 # COMPONENT: Platform>Apps>BrowserTag
diff --git a/components/guest_view/common/OWNERS b/components/guest_view/common/OWNERS
index 465e847..fad6e24f 100644
--- a/components/guest_view/common/OWNERS
+++ b/components/guest_view/common/OWNERS
@@ -1,7 +1,3 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-wjmaclean@chromium.org
-
 per-file *_messages*.h=set noparent
 per-file *_messages*.h=file://ipc/SECURITY_OWNERS
 
diff --git a/components/guest_view/renderer/OWNERS b/components/guest_view/renderer/OWNERS
deleted file mode 100644
index 7c8b9591..0000000
--- a/components/guest_view/renderer/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-hanxi@chromium.org
-wjmaclean@chromium.org
-
-# COMPONENT: Platform>Apps>BrowserTag
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc
index b197453..0135a82 100644
--- a/components/history/core/browser/history_backend.cc
+++ b/components/history/core/browser/history_backend.cc
@@ -2529,7 +2529,8 @@
 
     // Notify SyncBridge about storage error. It will report failure to sync
     // engine and stop accepting remote updates.
-    typed_url_sync_bridge_->OnDatabaseError();
+    if (typed_url_sync_bridge_)
+      typed_url_sync_bridge_->OnDatabaseError();
 
     // Don't just do the close/delete here, as we are being called by |db| and
     // that seems dangerous.
diff --git a/components/history/core/browser/history_backend_unittest.cc b/components/history/core/browser/history_backend_unittest.cc
index cabba58e..5ee081b7 100644
--- a/components/history/core/browser/history_backend_unittest.cc
+++ b/components/history/core/browser/history_backend_unittest.cc
@@ -51,6 +51,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/sqlite/sqlite3.h"
 #include "ui/gfx/codec/png_codec.h"
 #include "url/gurl.h"
 
@@ -3839,6 +3840,15 @@
   EXPECT_TRUE(base::PathExists(db2_actual));  // Symlinks shouldn't be followed.
 }
 
+// Tests that calling DatabaseErrorCallback doesn't cause crash. (Regression
+// test for https://crbug.com/796138)
+TEST_F(HistoryBackendTest, DatabaseError) {
+  EXPECT_EQ(nullptr, backend_->GetTypedURLSyncBridge());
+  backend_->DatabaseErrorCallback(SQLITE_CORRUPT, nullptr);
+  // Run loop to let any posted callbacks run before TearDown().
+  base::RunLoop().RunUntilIdle();
+}
+
 // Common implementation for the two tests below, given that the only difference
 // between them is the type of the notification sent out.
 void InMemoryHistoryBackendTest::TestAddingAndChangingURLRows(
diff --git a/components/metrics/clean_exit_beacon.cc b/components/metrics/clean_exit_beacon.cc
index 4bca5d1c..a73ddde 100644
--- a/components/metrics/clean_exit_beacon.cc
+++ b/components/metrics/clean_exit_beacon.cc
@@ -11,6 +11,7 @@
 #include "components/prefs/pref_service.h"
 
 #if defined(OS_WIN)
+#include <windows.h>
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/registry.h"
diff --git a/components/metrics/metrics_log.cc b/components/metrics/metrics_log.cc
index df760be..78012521 100644
--- a/components/metrics/metrics_log.cc
+++ b/components/metrics/metrics_log.cc
@@ -38,6 +38,7 @@
 #endif
 
 #if defined(OS_WIN)
+#include <windows.h>
 #include "base/win/current_module.h"
 #endif
 
diff --git a/components/metrics/ui/screen_info_metrics_provider.cc b/components/metrics/ui/screen_info_metrics_provider.cc
index 25e8952..d551863 100644
--- a/components/metrics/ui/screen_info_metrics_provider.cc
+++ b/components/metrics/ui/screen_info_metrics_provider.cc
@@ -9,12 +9,14 @@
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
 
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
 namespace metrics {
 
 #if defined(OS_WIN)
 
-#include <windows.h>
-
 namespace {
 
 struct ScreenDPIInformation {
diff --git a/components/offline_pages/content/renovations/test/page_renovator_browsertest.cc b/components/offline_pages/content/renovations/test/page_renovator_browsertest.cc
index 8e3a8a4..256b606 100644
--- a/components/offline_pages/content/renovations/test/page_renovator_browsertest.cc
+++ b/components/offline_pages/content/renovations/test/page_renovator_browsertest.cc
@@ -161,16 +161,16 @@
   ASSERT_TRUE(render_frame_) << "Navigate should have been called.";
 
   std::vector<std::unique_ptr<PageRenovation>> renovations;
-  renovations.push_back(base::MakeUnique<FooPageRenovation>());
-  renovations.push_back(base::MakeUnique<BarPageRenovation>());
-  renovations.push_back(base::MakeUnique<AlwaysRenovation>());
+  renovations.push_back(std::make_unique<FooPageRenovation>());
+  renovations.push_back(std::make_unique<BarPageRenovation>());
+  renovations.push_back(std::make_unique<AlwaysRenovation>());
 
   page_renovation_loader_.reset(new PageRenovationLoader);
   page_renovation_loader_->SetSourceForTest(
       base::ASCIIToUTF16(kTestRenovationScript));
   page_renovation_loader_->SetRenovationsForTest(std::move(renovations));
 
-  auto script_injector = base::MakeUnique<RenderFrameScriptInjector>(
+  auto script_injector = std::make_unique<RenderFrameScriptInjector>(
       render_frame_, content::ISOLATED_WORLD_ID_CONTENT_END);
   page_renovator_.reset(new PageRenovator(
       page_renovation_loader_.get(), std::move(script_injector), fake_url));
@@ -182,7 +182,7 @@
 
   page_renovation_loader_.reset(new PageRenovationLoader);
 
-  auto script_injector = base::MakeUnique<RenderFrameScriptInjector>(
+  auto script_injector = std::make_unique<RenderFrameScriptInjector>(
       render_frame_, content::ISOLATED_WORLD_ID_CONTENT_END);
   page_renovator_.reset(new PageRenovator(
       page_renovation_loader_.get(), std::move(script_injector), fake_url));
diff --git a/components/offline_pages/core/background/request_coordinator.cc b/components/offline_pages/core/background/request_coordinator.cc
index 314ad2a..b5eb604 100644
--- a/components/offline_pages/core/background/request_coordinator.cc
+++ b/components/offline_pages/core/background/request_coordinator.cc
@@ -713,7 +713,7 @@
   if (use_test_device_conditions_)
     return;
 
-  current_conditions_ = base::MakeUnique<DeviceConditions>(
+  current_conditions_ = std::make_unique<DeviceConditions>(
       scheduler_->GetCurrentDeviceConditions());
 }
 
diff --git a/components/offline_pages/core/background/request_coordinator_stub_taco.cc b/components/offline_pages/core/background/request_coordinator_stub_taco.cc
index acc4453..3e90426 100644
--- a/components/offline_pages/core/background/request_coordinator_stub_taco.cc
+++ b/components/offline_pages/core/background/request_coordinator_stub_taco.cc
@@ -4,7 +4,6 @@
 
 #include "components/offline_pages/core/background/request_coordinator_stub_taco.h"
 
-#include "base/memory/ptr_util.h"
 #include "components/offline_pages/core/background/network_quality_provider_stub.h"
 #include "components/offline_pages/core/background/offliner_stub.h"
 #include "components/offline_pages/core/background/request_queue.h"
@@ -17,13 +16,13 @@
 namespace offline_pages {
 
 RequestCoordinatorStubTaco::RequestCoordinatorStubTaco() {
-  policy_ = base::MakeUnique<OfflinerPolicy>();
-  queue_ = base::MakeUnique<RequestQueue>(
-      base::MakeUnique<RequestQueueInMemoryStore>());
-  offliner_ = base::MakeUnique<OfflinerStub>();
-  scheduler_ = base::MakeUnique<SchedulerStub>();
-  network_quality_provider_ = base::MakeUnique<NetworkQualityProviderStub>();
-  ukm_reporter_ = base::MakeUnique<OfflinePagesUkmReporterStub>();
+  policy_ = std::make_unique<OfflinerPolicy>();
+  queue_ = std::make_unique<RequestQueue>(
+      std::make_unique<RequestQueueInMemoryStore>());
+  offliner_ = std::make_unique<OfflinerStub>();
+  scheduler_ = std::make_unique<SchedulerStub>();
+  network_quality_provider_ = std::make_unique<NetworkQualityProviderStub>();
+  ukm_reporter_ = std::make_unique<OfflinePagesUkmReporterStub>();
 }
 
 RequestCoordinatorStubTaco::~RequestCoordinatorStubTaco() {
@@ -39,7 +38,7 @@
     std::unique_ptr<RequestQueueStore> store) {
   CHECK(!request_coordinator_ && !queue_overridden_);
   store_overridden_ = true;
-  queue_ = base::MakeUnique<RequestQueue>(std::move(store));
+  queue_ = std::make_unique<RequestQueue>(std::move(store));
 }
 
 void RequestCoordinatorStubTaco::SetRequestQueue(
@@ -74,7 +73,7 @@
 }
 
 void RequestCoordinatorStubTaco::CreateRequestCoordinator() {
-  request_coordinator_ = base::MakeUnique<RequestCoordinator>(
+  request_coordinator_ = std::make_unique<RequestCoordinator>(
       std::move(policy_), std::move(offliner_), std::move(queue_),
       std::move(scheduler_), network_quality_provider_.get(),
       std::move(ukm_reporter_));
diff --git a/components/offline_pages/core/background/request_coordinator_unittest.cc b/components/offline_pages/core/background/request_coordinator_unittest.cc
index 9ce255bc..d3c6dfd 100644
--- a/components/offline_pages/core/background/request_coordinator_unittest.cc
+++ b/components/offline_pages/core/background/request_coordinator_unittest.cc
@@ -353,7 +353,7 @@
 RequestCoordinatorTest::~RequestCoordinatorTest() {}
 
 void RequestCoordinatorTest::SetUp() {
-  coordinator_taco_ = base::MakeUnique<RequestCoordinatorStubTaco>();
+  coordinator_taco_ = std::make_unique<RequestCoordinatorStubTaco>();
 
   std::unique_ptr<OfflinerStub> offliner(new OfflinerStub());
   // Save raw pointer for use by the tests.
@@ -361,7 +361,7 @@
   coordinator_taco_->SetOffliner(std::move(offliner));
 
   std::unique_ptr<NetworkQualityProviderStub> network_quality_provider =
-      base::MakeUnique<NetworkQualityProviderStub>();
+      std::make_unique<NetworkQualityProviderStub>();
   // Save raw pointer for use by the tests.
   network_quality_provider_ = network_quality_provider.get();
   coordinator_taco_->SetNetworkQualityProvider(
diff --git a/components/offline_pages/core/client_policy_controller.cc b/components/offline_pages/core/client_policy_controller.cc
index dc243100..4f7b57ba 100644
--- a/components/offline_pages/core/client_policy_controller.cc
+++ b/components/offline_pages/core/client_policy_controller.cc
@@ -6,7 +6,6 @@
 
 #include <utility>
 
-#include "base/memory/ptr_util.h"
 #include "base/time/time.h"
 #include "components/offline_pages/core/client_namespace_constants.h"
 #include "components/offline_pages/core/offline_page_feature.h"
@@ -132,7 +131,7 @@
   if (cache_reset_namespace_cache_)
     return *cache_reset_namespace_cache_;
 
-  cache_reset_namespace_cache_ = base::MakeUnique<std::vector<std::string>>();
+  cache_reset_namespace_cache_ = std::make_unique<std::vector<std::string>>();
   for (const auto& policy_item : policies_) {
     if (policy_item.second.feature_policy.is_removed_on_cache_reset)
       cache_reset_namespace_cache_->emplace_back(policy_item.first);
@@ -145,7 +144,7 @@
   if (download_namespace_cache_)
     return *download_namespace_cache_;
 
-  download_namespace_cache_ = base::MakeUnique<std::vector<std::string>>();
+  download_namespace_cache_ = std::make_unique<std::vector<std::string>>();
   for (const auto& policy_item : policies_) {
     if (policy_item.second.feature_policy.is_supported_by_download)
       download_namespace_cache_->emplace_back(policy_item.first);
@@ -163,7 +162,7 @@
   if (recent_tab_namespace_cache_)
     return *recent_tab_namespace_cache_;
 
-  recent_tab_namespace_cache_ = base::MakeUnique<std::vector<std::string>>();
+  recent_tab_namespace_cache_ = std::make_unique<std::vector<std::string>>();
   for (const auto& policy_item : policies_) {
     if (policy_item.second.feature_policy.is_supported_by_recent_tabs)
       recent_tab_namespace_cache_->emplace_back(policy_item.first);
@@ -182,7 +181,7 @@
   if (show_in_original_tab_cache_)
     return *show_in_original_tab_cache_;
 
-  show_in_original_tab_cache_ = base::MakeUnique<std::vector<std::string>>();
+  show_in_original_tab_cache_ = std::make_unique<std::vector<std::string>>();
   for (const auto& policy_item : policies_) {
     if (policy_item.second.feature_policy.only_shown_in_original_tab)
       show_in_original_tab_cache_->emplace_back(policy_item.first);
@@ -202,7 +201,7 @@
     return *disabled_when_prefetch_disabled_cache_;
 
   disabled_when_prefetch_disabled_cache_ =
-      base::MakeUnique<std::vector<std::string>>();
+      std::make_unique<std::vector<std::string>>();
   for (const auto& policy_item : policies_) {
     if (policy_item.second.feature_policy.disabled_when_prefetch_disabled)
       disabled_when_prefetch_disabled_cache_->emplace_back(policy_item.first);
diff --git a/components/offline_pages/core/downloads/download_ui_adapter.cc b/components/offline_pages/core/downloads/download_ui_adapter.cc
index 9418a42..3d9be479 100644
--- a/components/offline_pages/core/downloads/download_ui_adapter.cc
+++ b/components/offline_pages/core/downloads/download_ui_adapter.cc
@@ -7,7 +7,6 @@
 #include "base/bind.h"
 #include "base/guid.h"
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/offline_pages/core/background/request_coordinator.h"
 #include "components/offline_pages/core/background/save_page_request.h"
@@ -62,7 +61,7 @@
 DownloadUIAdapter::ItemInfo::ItemInfo(const OfflinePageItem& page,
                                       bool temporarily_hidden,
                                       bool is_suggested)
-    : ui_item(base::MakeUnique<OfflineItem>(
+    : ui_item(std::make_unique<OfflineItem>(
           OfflineItemConversions::CreateOfflineItem(page, is_suggested))),
       is_request(false),
       offline_id(page.offline_id),
@@ -71,7 +70,7 @@
 
 DownloadUIAdapter::ItemInfo::ItemInfo(const SavePageRequest& request,
                                       bool temporarily_hidden)
-    : ui_item(base::MakeUnique<OfflineItem>(
+    : ui_item(std::make_unique<OfflineItem>(
           OfflineItemConversions::CreateOfflineItem(request))),
       is_request(true),
       offline_id(request.request_id()),
@@ -147,7 +146,7 @@
   bool is_suggested = model->GetPolicyController()->IsSuggested(
       added_page.client_id.name_space);
   AddItemHelper(
-      base::MakeUnique<ItemInfo>(added_page, temporarily_hidden, is_suggested));
+      std::make_unique<ItemInfo>(added_page, temporarily_hidden, is_suggested));
 }
 
 void DownloadUIAdapter::OfflinePageDeleted(
@@ -164,7 +163,7 @@
 
   bool temporarily_hidden =
       delegate_->IsTemporarilyHiddenInUI(added_request.client_id());
-  AddItemHelper(base::MakeUnique<ItemInfo>(added_request, temporarily_hidden));
+  AddItemHelper(std::make_unique<ItemInfo>(added_request, temporarily_hidden));
 }
 
 // RequestCoordinator::Observer
@@ -198,7 +197,7 @@
 
   bool temporarily_hidden =
       delegate_->IsTemporarilyHiddenInUI(request.client_id());
-  items_[guid] = base::MakeUnique<ItemInfo>(request, temporarily_hidden);
+  items_[guid] = std::make_unique<ItemInfo>(request, temporarily_hidden);
 
   if (state_ != State::LOADED)
     return;
@@ -398,7 +397,7 @@
       bool is_suggested =
           model_->GetPolicyController()->IsSuggested(page.client_id.name_space);
       std::unique_ptr<ItemInfo> item =
-          base::MakeUnique<ItemInfo>(page, temporarily_hidden, is_suggested);
+          std::make_unique<ItemInfo>(page, temporarily_hidden, is_suggested);
       items_[guid] = std::move(item);
     }
   }
@@ -424,7 +423,7 @@
       bool temporarily_hidden =
           delegate_->IsTemporarilyHiddenInUI(request->client_id());
       std::unique_ptr<ItemInfo> item =
-          base::MakeUnique<ItemInfo>(*request.get(), temporarily_hidden);
+          std::make_unique<ItemInfo>(*request.get(), temporarily_hidden);
       items_[guid] = std::move(item);
     }
   }
diff --git a/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc b/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc
index 7de8794..a5adafdb 100644
--- a/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc
+++ b/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc
@@ -216,18 +216,18 @@
 DownloadUIAdapterTest::~DownloadUIAdapterTest() {}
 
 void DownloadUIAdapterTest::SetUp() {
-  model = base::MakeUnique<MockOfflinePageModel>(task_runner_.get());
+  model = std::make_unique<MockOfflinePageModel>(task_runner_.get());
   std::unique_ptr<DownloadUIAdapterDelegate> delegate =
-      base::MakeUnique<DownloadUIAdapterDelegate>();
+      std::make_unique<DownloadUIAdapterDelegate>();
   adapter_delegate = delegate.get();
-  request_coordinator_taco_ = base::MakeUnique<RequestCoordinatorStubTaco>();
+  request_coordinator_taco_ = std::make_unique<RequestCoordinatorStubTaco>();
 
-  std::unique_ptr<OfflinerStub> offliner = base::MakeUnique<OfflinerStub>();
+  std::unique_ptr<OfflinerStub> offliner = std::make_unique<OfflinerStub>();
   offliner_stub = offliner.get();
   request_coordinator_taco_->SetOffliner(std::move(offliner));
 
   request_coordinator_taco_->CreateRequestCoordinator();
-  adapter = base::MakeUnique<DownloadUIAdapter>(
+  adapter = std::make_unique<DownloadUIAdapter>(
       nullptr, model.get(), request_coordinator_taco_->request_coordinator(),
       std::move(delegate));
 
diff --git a/components/offline_pages/core/model/add_page_task_unittest.cc b/components/offline_pages/core/model/add_page_task_unittest.cc
index 99491783..4747082b 100644
--- a/components/offline_pages/core/model/add_page_task_unittest.cc
+++ b/components/offline_pages/core/model/add_page_task_unittest.cc
@@ -109,7 +109,7 @@
 }
 
 void AddPageTaskTest::AddPage(const OfflinePageItem& page) {
-  auto task = base::MakeUnique<AddPageTask>(store(), page, add_page_callback());
+  auto task = std::make_unique<AddPageTask>(store(), page, add_page_callback());
   runner()->RunTask(std::move(task));
 }
 
@@ -188,7 +188,7 @@
 TEST_F(AddPageTaskTest, AddPageWithInvalidStore) {
   generator()->SetNamespace(kTestNamespace);
   OfflinePageItem page = generator()->CreateItem();
-  auto task = base::MakeUnique<AddPageTask>(nullptr, page, add_page_callback());
+  auto task = std::make_unique<AddPageTask>(nullptr, page, add_page_callback());
   runner()->RunTask(std::move(task));
 
   // Start checking if the page is added into the store.
diff --git a/components/offline_pages/core/model/clear_digest_task_unittest.cc b/components/offline_pages/core/model/clear_digest_task_unittest.cc
index b02992c..9b2fb33 100644
--- a/components/offline_pages/core/model/clear_digest_task_unittest.cc
+++ b/components/offline_pages/core/model/clear_digest_task_unittest.cc
@@ -4,7 +4,8 @@
 
 #include "components/offline_pages/core/model/clear_digest_task.h"
 
-#include "base/memory/ptr_util.h"
+#include <memory>
+
 #include "base/test/test_mock_time_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/offline_pages/core/model/offline_page_item_generator.h"
@@ -62,7 +63,7 @@
   page.digest = kTestDigest;
   store_test_util()->InsertItem(page);
 
-  auto task = base::MakeUnique<ClearDigestTask>(store(), page.offline_id);
+  auto task = std::make_unique<ClearDigestTask>(store(), page.offline_id);
   runner()->RunTask(std::move(task));
 
   // Check the digest of the page is cleared.
diff --git a/components/offline_pages/core/model/clear_legacy_temporary_pages_task_unittest.cc b/components/offline_pages/core/model/clear_legacy_temporary_pages_task_unittest.cc
index 57e3497..410a78a4 100644
--- a/components/offline_pages/core/model/clear_legacy_temporary_pages_task_unittest.cc
+++ b/components/offline_pages/core/model/clear_legacy_temporary_pages_task_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "components/offline_pages/core/model/clear_legacy_temporary_pages_task.h"
 
+#include <memory>
+
 #include "base/bind.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
@@ -68,7 +70,7 @@
 void ClearLegacyTemporaryPagesTaskTest::SetUp() {
   store_test_util_.BuildStoreInMemory();
   ASSERT_TRUE(legacy_archives_dir_.CreateUniqueTempDir());
-  policy_controller_ = base::MakeUnique<ClientPolicyController>();
+  policy_controller_ = std::make_unique<ClientPolicyController>();
 }
 
 void ClearLegacyTemporaryPagesTaskTest::TearDown() {
@@ -104,7 +106,7 @@
   EXPECT_EQ(2LL, store_test_util()->GetPageCount());
   EXPECT_EQ(2UL, test_utils::GetFileCountInDirectory(legacy_archives_dir()));
 
-  auto task = base::MakeUnique<ClearLegacyTemporaryPagesTask>(
+  auto task = std::make_unique<ClearLegacyTemporaryPagesTask>(
       store(), policy_controller(), legacy_archives_dir());
   runner()->RunTask(std::move(task));
 
diff --git a/components/offline_pages/core/model/clear_storage_task.cc b/components/offline_pages/core/model/clear_storage_task.cc
index 5729bc0..a494369 100644
--- a/components/offline_pages/core/model/clear_storage_task.cc
+++ b/components/offline_pages/core/model/clear_storage_task.cc
@@ -6,13 +6,13 @@
 
 #include <algorithm>
 #include <map>
+#include <memory>
 #include <utility>
 #include <vector>
 
 #include "base/bind.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
-#include "base/memory/ptr_util.h"
 #include "base/time/clock.h"
 #include "base/time/default_clock.h"
 #include "base/time/time.h"
@@ -72,7 +72,7 @@
 std::unique_ptr<std::vector<PageInfo>> GetAllTemporaryPageInfos(
     const std::map<std::string, LifetimePolicy>& temp_namespace_policy_map,
     sql::Connection* db) {
-  auto result = base::MakeUnique<std::vector<PageInfo>>();
+  auto result = std::make_unique<std::vector<PageInfo>>();
 
   const char kSql[] = "SELECT " PAGE_INFO_PROJECTION
                       " FROM offlinepages_v1"
@@ -100,7 +100,7 @@
     const ArchiveManager::StorageStats& stats,
     sql::Connection* db) {
   std::map<std::string, int> namespace_page_count;
-  auto page_infos_to_delete = base::MakeUnique<std::vector<PageInfo>>();
+  auto page_infos_to_delete = std::make_unique<std::vector<PageInfo>>();
   std::vector<PageInfo> pages_remaining;
   int64_t remaining_size = 0;
 
diff --git a/components/offline_pages/core/model/clear_storage_task_unittest.cc b/components/offline_pages/core/model/clear_storage_task_unittest.cc
index 4d0a0e3..d129e7f 100644
--- a/components/offline_pages/core/model/clear_storage_task_unittest.cc
+++ b/components/offline_pages/core/model/clear_storage_task_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "components/offline_pages/core/model/clear_storage_task.h"
 
+#include <memory>
+
 #include "base/bind.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
@@ -134,7 +136,7 @@
   store_test_util_.BuildStoreInMemory();
   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
   // Setting up policies for testing.
-  policy_controller_ = base::MakeUnique<ClientPolicyController>();
+  policy_controller_ = std::make_unique<ClientPolicyController>();
 }
 
 void ClearStorageTaskTest::TearDown() {
@@ -185,7 +187,7 @@
 }
 
 void ClearStorageTaskTest::RunClearStorageTask(const base::Time& start_time) {
-  auto task = base::MakeUnique<ClearStorageTask>(
+  auto task = std::make_unique<ClearStorageTask>(
       store(), archive_manager(), policy_controller(), start_time,
       base::Bind(&ClearStorageTaskTest::OnClearStorageDone, AsWeakPtr()));
 
@@ -193,7 +195,7 @@
 }
 
 TEST_F(ClearStorageTaskTest, ClearPagesLessThanLimit) {
-  auto clock = base::MakeUnique<base::SimpleTestClock>();
+  auto clock = std::make_unique<base::SimpleTestClock>();
   clock->SetNow(base::Time::Now());
   Initialize({{kBookmarkNamespace, 1, 1}, {kLastNNamespace, 1, 1}},
              clock.get());
@@ -214,7 +216,7 @@
 }
 
 TEST_F(ClearStorageTaskTest, ClearPagesMoreFreshPages) {
-  auto clock = base::MakeUnique<base::SimpleTestClock>();
+  auto clock = std::make_unique<base::SimpleTestClock>();
   clock->SetNow(base::Time::Now());
   Initialize({{kBookmarkNamespace, 30, 0}, {kLastNNamespace, 100, 1}},
              clock.get());
@@ -235,7 +237,7 @@
 }
 
 TEST_F(ClearStorageTaskTest, TryClearPersistentPages) {
-  auto clock = base::MakeUnique<base::SimpleTestClock>();
+  auto clock = std::make_unique<base::SimpleTestClock>();
   clock->SetNow(base::Time::Now());
   Initialize({{kDownloadNamespace, 20, 0}}, clock.get());
 
@@ -254,7 +256,7 @@
 }
 
 TEST_F(ClearStorageTaskTest, TryClearPersistentPagesWithStoragePressure) {
-  auto clock = base::MakeUnique<base::SimpleTestClock>();
+  auto clock = std::make_unique<base::SimpleTestClock>();
   clock->SetNow(base::Time::Now());
   // Sets the free space with 1KB.
   Initialize({{kDownloadNamespace, 20, 0}}, clock.get());
@@ -275,7 +277,7 @@
 }
 
 TEST_F(ClearStorageTaskTest, ClearMultipleTimes) {
-  auto clock = base::MakeUnique<base::SimpleTestClock>();
+  auto clock = std::make_unique<base::SimpleTestClock>();
   clock->SetNow(base::Time::Now());
   // Initializing with 20 unexpired and 0 expired pages in bookmark namespace,
   // 30 unexpired and 1 expired pages in last_n namespace, and 40 persistent
diff --git a/components/offline_pages/core/model/complete_offline_page_upgrade_task_unittest.cc b/components/offline_pages/core/model/complete_offline_page_upgrade_task_unittest.cc
index f8015a5..b407b427 100644
--- a/components/offline_pages/core/model/complete_offline_page_upgrade_task_unittest.cc
+++ b/components/offline_pages/core/model/complete_offline_page_upgrade_task_unittest.cc
@@ -4,9 +4,10 @@
 
 #include "components/offline_pages/core/model/complete_offline_page_upgrade_task.h"
 
+#include <memory>
+
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
-#include "base/memory/ptr_util.h"
 #include "base/test/test_mock_time_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/offline_pages/core/model/offline_page_item_generator.h"
@@ -115,7 +116,7 @@
 TEST_F(CompleteOfflinePageUpgradeTaskTest, Success) {
   OfflinePageItem original_page = CreateOfflinePage();
 
-  auto task = base::MakeUnique<CompleteOfflinePageUpgradeTask>(
+  auto task = std::make_unique<CompleteOfflinePageUpgradeTask>(
       store(), original_page.offline_id, temporary_file_path(),
       target_file_path(), kDummyDigest, sizeof(kContentsOfTempFile),
       callback());
@@ -138,7 +139,7 @@
 }
 
 TEST_F(CompleteOfflinePageUpgradeTaskTest, ItemMissing) {
-  auto task = base::MakeUnique<CompleteOfflinePageUpgradeTask>(
+  auto task = std::make_unique<CompleteOfflinePageUpgradeTask>(
       store(), 42, temporary_file_path(), target_file_path(), kDummyDigest,
       sizeof(kContentsOfTempFile), callback());
   runner()->RunTask(std::move(task));
@@ -155,7 +156,7 @@
   // This ensures the temporary file won't be there.
   EXPECT_TRUE(base::DeleteFile(temporary_file_path(), false));
 
-  auto task = base::MakeUnique<CompleteOfflinePageUpgradeTask>(
+  auto task = std::make_unique<CompleteOfflinePageUpgradeTask>(
       store(), original_page.offline_id, temporary_file_path(),
       target_file_path(), kDummyDigest, sizeof(kContentsOfTempFile),
       callback());
@@ -179,7 +180,7 @@
   // This ensures target name is taken.
   EXPECT_TRUE(base::CopyFile(temporary_file_path(), target_file_path()));
 
-  auto task = base::MakeUnique<CompleteOfflinePageUpgradeTask>(
+  auto task = std::make_unique<CompleteOfflinePageUpgradeTask>(
       store(), original_page.offline_id, temporary_file_path(),
       target_file_path(), kDummyDigest, sizeof(kContentsOfTempFile),
       callback());
diff --git a/components/offline_pages/core/model/delete_page_task_unittest.cc b/components/offline_pages/core/model/delete_page_task_unittest.cc
index 8df7352d..75974ae5 100644
--- a/components/offline_pages/core/model/delete_page_task_unittest.cc
+++ b/components/offline_pages/core/model/delete_page_task_unittest.cc
@@ -104,9 +104,9 @@
 void DeletePageTaskTest::SetUp() {
   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
   store_test_util_.BuildStoreInMemory();
-  policy_controller_ = base::MakeUnique<ClientPolicyController>();
+  policy_controller_ = std::make_unique<ClientPolicyController>();
   generator()->SetArchiveDirectory(temp_dir());
-  histogram_tester_ = base::MakeUnique<base::HistogramTester>();
+  histogram_tester_ = std::make_unique<base::HistogramTester>();
 }
 
 void DeletePageTaskTest::TearDown() {
diff --git a/components/offline_pages/core/model/mark_page_accessed_task_unittest.cc b/components/offline_pages/core/model/mark_page_accessed_task_unittest.cc
index ea8bbe4c..d307c75b 100644
--- a/components/offline_pages/core/model/mark_page_accessed_task_unittest.cc
+++ b/components/offline_pages/core/model/mark_page_accessed_task_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "components/offline_pages/core/model/mark_page_accessed_task.h"
 
+#include <memory>
 #include <vector>
 
-#include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/test/histogram_tester.h"
 #include "base/test/test_mock_time_task_runner.h"
@@ -61,7 +61,7 @@
 
 void MarkPageAccessedTaskTest::SetUp() {
   store_test_util_.BuildStoreInMemory();
-  histogram_tester_ = base::MakeUnique<base::HistogramTester>();
+  histogram_tester_ = std::make_unique<base::HistogramTester>();
 }
 
 void MarkPageAccessedTaskTest::TearDown() {
@@ -74,7 +74,7 @@
   store_test_util()->InsertItem(page);
 
   base::Time current_time = base::Time::Now();
-  auto task = base::MakeUnique<MarkPageAccessedTask>(store(), kTestOfflineId,
+  auto task = std::make_unique<MarkPageAccessedTask>(store(), kTestOfflineId,
                                                      current_time);
   runner()->RunTask(std::move(task));
 
@@ -96,7 +96,7 @@
   store_test_util()->InsertItem(page);
 
   base::Time current_time = base::Time::Now();
-  auto task = base::MakeUnique<MarkPageAccessedTask>(store(), kTestOfflineId,
+  auto task = std::make_unique<MarkPageAccessedTask>(store(), kTestOfflineId,
                                                      current_time);
   runner()->RunTask(std::move(task));
 
@@ -112,7 +112,7 @@
       static_cast<int>(model_utils::ToNamespaceEnum(kTestClientId.name_space)),
       1);
 
-  task = base::MakeUnique<MarkPageAccessedTask>(store(), kTestOfflineId,
+  task = std::make_unique<MarkPageAccessedTask>(store(), kTestOfflineId,
                                                 base::Time::Now());
   runner()->RunTask(std::move(task));
 
diff --git a/components/offline_pages/core/model/offline_page_model_taskified.cc b/components/offline_pages/core/model/offline_page_model_taskified.cc
index 2b94dde..adcb2f054 100644
--- a/components/offline_pages/core/model/offline_page_model_taskified.cc
+++ b/components/offline_pages/core/model/offline_page_model_taskified.cc
@@ -190,7 +190,7 @@
 
 void OfflinePageModelTaskified::AddPage(const OfflinePageItem& page,
                                         const AddPageCallback& callback) {
-  auto task = base::MakeUnique<AddPageTask>(
+  auto task = std::make_unique<AddPageTask>(
       store_.get(), page,
       base::BindOnce(&OfflinePageModelTaskified::OnAddPageDone,
                      weak_ptr_factory_.GetWeakPtr(), page, callback));
@@ -198,7 +198,7 @@
 }
 
 void OfflinePageModelTaskified::MarkPageAccessed(int64_t offline_id) {
-  auto task = base::MakeUnique<MarkPageAccessedTask>(store_.get(), offline_id,
+  auto task = std::make_unique<MarkPageAccessedTask>(store_.get(), offline_id,
                                                      GetCurrentTime());
   task_queue_.AddTask(std::move(task));
 }
@@ -466,7 +466,7 @@
 void OfflinePageModelTaskified::ClearLegacyTemporaryPages() {
   // TODO(romax): When we have external directory, adding the support of getting
   // 'legacy' directory and replace the persistent one here.
-  auto task = base::MakeUnique<ClearLegacyTemporaryPagesTask>(
+  auto task = std::make_unique<ClearLegacyTemporaryPagesTask>(
       store_.get(), policy_controller_.get(),
       archive_manager_->GetPersistentArchivesDir());
   task_queue_.AddTask(std::move(task));
@@ -491,7 +491,7 @@
 }
 
 void OfflinePageModelTaskified::ClearCachedPages() {
-  auto task = base::MakeUnique<ClearStorageTask>(
+  auto task = std::make_unique<ClearStorageTask>(
       store_.get(), archive_manager_.get(), policy_controller_.get(),
       GetCurrentTime(),
       base::BindOnce(&OfflinePageModelTaskified::OnClearCachedPagesDone,
@@ -522,14 +522,14 @@
 }
 
 void OfflinePageModelTaskified::CheckTemporaryPagesConsistency() {
-  auto task = base::MakeUnique<TemporaryPagesConsistencyCheckTask>(
+  auto task = std::make_unique<TemporaryPagesConsistencyCheckTask>(
       store_.get(), policy_controller_.get(),
       archive_manager_->GetTemporaryArchivesDir());
   task_queue_.AddTask(std::move(task));
 }
 
 void OfflinePageModelTaskified::CheckPersistentPagesConsistency() {
-  auto task = base::MakeUnique<PersistentPagesConsistencyCheckTask>(
+  auto task = std::make_unique<PersistentPagesConsistencyCheckTask>(
       store_.get(), policy_controller_.get(),
       archive_manager_->GetPersistentArchivesDir());
   task_queue_.AddTask(std::move(task));
diff --git a/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc b/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
index b130277..b2eb51b 100644
--- a/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
+++ b/components/offline_pages/core/model/offline_page_model_taskified_unittest.cc
@@ -5,6 +5,7 @@
 #include "components/offline_pages/core/model/offline_page_model_taskified.h"
 
 #include <stdint.h>
+#include <memory>
 
 #include "base/bind.h"
 #include "base/files/file_enumerator.h"
@@ -181,7 +182,7 @@
   BuildModel();
   PumpLoop();
   CheckTaskQueueIdle();
-  histogram_tester_ = base::MakeUnique<base::HistogramTester>();
+  histogram_tester_ = std::make_unique<base::HistogramTester>();
 }
 
 void OfflinePageModelTaskifiedTest::TearDown() {
@@ -207,14 +208,14 @@
 
 void OfflinePageModelTaskifiedTest::BuildModel() {
   ASSERT_TRUE(store_test_util_.store());
-  auto archive_manager = base::MakeUnique<ArchiveManager>(
+  auto archive_manager = std::make_unique<ArchiveManager>(
       temporary_dir_path(), persistent_dir_path(),
       base::ThreadTaskRunnerHandle::Get());
-  model_ = base::MakeUnique<OfflinePageModelTaskified>(
+  model_ = std::make_unique<OfflinePageModelTaskified>(
       store_test_util()->ReleaseStore(), std::move(archive_manager),
       base::ThreadTaskRunnerHandle::Get(), task_runner_->GetMockClock());
   model_->AddObserver(this);
-  histogram_tester_ = base::MakeUnique<base::HistogramTester>();
+  histogram_tester_ = std::make_unique<base::HistogramTester>();
   ResetResults();
   EXPECT_EQ(0UL, model_->pending_archivers_.size());
 }
@@ -295,7 +296,7 @@
 std::unique_ptr<OfflinePageTestArchiver>
 OfflinePageModelTaskifiedTest::BuildArchiver(const GURL& url,
                                              ArchiverResult result) {
-  return base::MakeUnique<OfflinePageTestArchiver>(
+  return std::make_unique<OfflinePageTestArchiver>(
       this, url, result, kTestTitle, kTestFileSize, kTestDigest,
       base::ThreadTaskRunnerHandle::Get());
 }
diff --git a/components/offline_pages/core/model/persistent_pages_consistency_check_task_unittest.cc b/components/offline_pages/core/model/persistent_pages_consistency_check_task_unittest.cc
index 261d41e4..7f34d30d 100644
--- a/components/offline_pages/core/model/persistent_pages_consistency_check_task_unittest.cc
+++ b/components/offline_pages/core/model/persistent_pages_consistency_check_task_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "components/offline_pages/core/model/persistent_pages_consistency_check_task.h"
 
+#include <memory>
+
 #include "base/bind.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
@@ -77,8 +79,8 @@
 void PersistentPagesConsistencyCheckTaskTest::SetUp() {
   store_test_util_.BuildStoreInMemory();
   ASSERT_TRUE(persistent_dir_.CreateUniqueTempDir());
-  policy_controller_ = base::MakeUnique<ClientPolicyController>();
-  histogram_tester_ = base::MakeUnique<base::HistogramTester>();
+  policy_controller_ = std::make_unique<ClientPolicyController>();
+  histogram_tester_ = std::make_unique<base::HistogramTester>();
 }
 
 void PersistentPagesConsistencyCheckTaskTest::TearDown() {
@@ -138,7 +140,7 @@
   EXPECT_EQ(1LL, store_test_util()->GetPageCount());
   EXPECT_EQ(2UL, test_utils::GetFileCountInDirectory(persistent_dir()));
 
-  auto task = base::MakeUnique<PersistentPagesConsistencyCheckTask>(
+  auto task = std::make_unique<PersistentPagesConsistencyCheckTask>(
       store(), policy_controller(), persistent_dir());
   runner()->RunTask(std::move(task));
 
@@ -178,7 +180,7 @@
   EXPECT_EQ(2LL, store_test_util()->GetPageCount());
   EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(persistent_dir()));
 
-  auto task = base::MakeUnique<PersistentPagesConsistencyCheckTask>(
+  auto task = std::make_unique<PersistentPagesConsistencyCheckTask>(
       store(), policy_controller(), persistent_dir());
   runner()->RunTask(std::move(task));
 
@@ -219,7 +221,7 @@
   EXPECT_EQ(2LL, store_test_util()->GetPageCount());
   EXPECT_EQ(2UL, test_utils::GetFileCountInDirectory(persistent_dir()));
 
-  auto task = base::MakeUnique<PersistentPagesConsistencyCheckTask>(
+  auto task = std::make_unique<PersistentPagesConsistencyCheckTask>(
       store(), policy_controller(), persistent_dir());
   runner()->RunTask(std::move(task));
 
@@ -253,7 +255,7 @@
   EXPECT_EQ(0LL, store_test_util()->GetPageCount());
   EXPECT_EQ(2UL, test_utils::GetFileCountInDirectory(persistent_dir()));
 
-  auto task = base::MakeUnique<PersistentPagesConsistencyCheckTask>(
+  auto task = std::make_unique<PersistentPagesConsistencyCheckTask>(
       store(), policy_controller(), persistent_dir());
   runner()->RunTask(std::move(task));
 
diff --git a/components/offline_pages/core/model/start_offline_page_upgrade_task_unittest.cc b/components/offline_pages/core/model/start_offline_page_upgrade_task_unittest.cc
index ec676ba..6a87c36 100644
--- a/components/offline_pages/core/model/start_offline_page_upgrade_task_unittest.cc
+++ b/components/offline_pages/core/model/start_offline_page_upgrade_task_unittest.cc
@@ -4,8 +4,9 @@
 
 #include "components/offline_pages/core/model/start_offline_page_upgrade_task.h"
 
+#include <memory>
+
 #include "base/files/scoped_temp_dir.h"
-#include "base/memory/ptr_util.h"
 #include "base/test/test_mock_time_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/offline_pages/core/model/offline_page_item_generator.h"
@@ -84,7 +85,7 @@
   original_page.digest = kTestDigest;
   store_test_util()->InsertItem(original_page);
 
-  auto task = base::MakeUnique<StartOfflinePageUpgradeTask>(
+  auto task = std::make_unique<StartOfflinePageUpgradeTask>(
       store(), original_page.offline_id, temp_dir.GetPath(), callback());
   runner()->RunTask(std::move(task));
 
@@ -99,7 +100,7 @@
 }
 
 TEST_F(StartOfflinePageUpgradeTaskTest, StartUpgradeItemMissing) {
-  auto task = base::MakeUnique<StartOfflinePageUpgradeTask>(
+  auto task = std::make_unique<StartOfflinePageUpgradeTask>(
       store(), 42, base::FilePath(), callback());
   runner()->RunTask(std::move(task));
 
@@ -113,7 +114,7 @@
   original_page.upgrade_attempt = 3;
   store_test_util()->InsertItem(original_page);
 
-  auto task = base::MakeUnique<StartOfflinePageUpgradeTask>(
+  auto task = std::make_unique<StartOfflinePageUpgradeTask>(
       store(), original_page.offline_id, base::FilePath(), callback());
   runner()->RunTask(std::move(task));
 
@@ -136,7 +137,7 @@
   original_page.upgrade_attempt = 3;
   store_test_util()->InsertItem(original_page);
 
-  auto task = base::MakeUnique<StartOfflinePageUpgradeTask>(
+  auto task = std::make_unique<StartOfflinePageUpgradeTask>(
       store(), original_page.offline_id, base::FilePath(), callback());
   runner()->RunTask(std::move(task));
 
diff --git a/components/offline_pages/core/model/temporary_pages_consistency_check_task_unittest.cc b/components/offline_pages/core/model/temporary_pages_consistency_check_task_unittest.cc
index 8c87f8c..321201b 100644
--- a/components/offline_pages/core/model/temporary_pages_consistency_check_task_unittest.cc
+++ b/components/offline_pages/core/model/temporary_pages_consistency_check_task_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "components/offline_pages/core/model/temporary_pages_consistency_check_task.h"
 
+#include <memory>
+
 #include "base/bind.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
@@ -76,8 +78,8 @@
 void TemporaryPagesConsistencyCheckTaskTest::SetUp() {
   store_test_util_.BuildStoreInMemory();
   ASSERT_TRUE(temporary_dir_.CreateUniqueTempDir());
-  policy_controller_ = base::MakeUnique<ClientPolicyController>();
-  histogram_tester_ = base::MakeUnique<base::HistogramTester>();
+  policy_controller_ = std::make_unique<ClientPolicyController>();
+  histogram_tester_ = std::make_unique<base::HistogramTester>();
 }
 
 void TemporaryPagesConsistencyCheckTaskTest::TearDown() {
@@ -136,7 +138,7 @@
   EXPECT_EQ(1LL, store_test_util()->GetPageCount());
   EXPECT_EQ(2UL, test_utils::GetFileCountInDirectory(temporary_dir()));
 
-  auto task = base::MakeUnique<TemporaryPagesConsistencyCheckTask>(
+  auto task = std::make_unique<TemporaryPagesConsistencyCheckTask>(
       store(), policy_controller(), temporary_dir());
   runner()->RunTask(std::move(task));
 
@@ -175,7 +177,7 @@
   EXPECT_EQ(2LL, store_test_util()->GetPageCount());
   EXPECT_EQ(1UL, test_utils::GetFileCountInDirectory(temporary_dir()));
 
-  auto task = base::MakeUnique<TemporaryPagesConsistencyCheckTask>(
+  auto task = std::make_unique<TemporaryPagesConsistencyCheckTask>(
       store(), policy_controller(), temporary_dir());
   runner()->RunTask(std::move(task));
 
@@ -216,7 +218,7 @@
   EXPECT_EQ(2LL, store_test_util()->GetPageCount());
   EXPECT_EQ(2UL, test_utils::GetFileCountInDirectory(temporary_dir()));
 
-  auto task = base::MakeUnique<TemporaryPagesConsistencyCheckTask>(
+  auto task = std::make_unique<TemporaryPagesConsistencyCheckTask>(
       store(), policy_controller(), temporary_dir());
   runner()->RunTask(std::move(task));
 
diff --git a/components/offline_pages/core/offline_page_metadata_store_test_util.cc b/components/offline_pages/core/offline_page_metadata_store_test_util.cc
index c6d81ce..6a7e7e5 100644
--- a/components/offline_pages/core/offline_page_metadata_store_test_util.cc
+++ b/components/offline_pages/core/offline_page_metadata_store_test_util.cc
@@ -64,7 +64,7 @@
 
 void OfflinePageMetadataStoreTestUtil::InsertItem(const OfflinePageItem& page) {
   AddPageResult result;
-  auto task = base::MakeUnique<AddPageTask>(
+  auto task = std::make_unique<AddPageTask>(
       store(), page,
       base::Bind([](AddPageResult* out_result,
                     AddPageResult cb_result) { *out_result = cb_result; },
diff --git a/components/offline_pages/core/offline_page_model_impl_unittest.cc b/components/offline_pages/core/offline_page_model_impl_unittest.cc
index abed698..285cee3 100644
--- a/components/offline_pages/core/offline_page_model_impl_unittest.cc
+++ b/components/offline_pages/core/offline_page_model_impl_unittest.cc
@@ -13,7 +13,6 @@
 #include "base/feature_list.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/rand_util.h"
 #include "base/run_loop.h"
@@ -344,7 +343,7 @@
 std::unique_ptr<OfflinePageModelImpl> OfflinePageModelImplTest::BuildModel(
     std::unique_ptr<OfflinePageMetadataStore> store) {
   std::unique_ptr<ArchiveManager> archive_manager = nullptr;
-  archive_manager = base::MakeUnique<ArchiveManager>(
+  archive_manager = std::make_unique<ArchiveManager>(
       temporary_dir_path(), persistent_dir_path(),
       base::ThreadTaskRunnerHandle::Get());
   return std::unique_ptr<OfflinePageModelImpl>(
@@ -525,7 +524,7 @@
     return;
   }
 
-  *storage = base::MakeUnique<OfflinePageItem>(*result);
+  *storage = std::make_unique<OfflinePageItem>(*result);
 }
 
 void OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult(
diff --git a/components/offline_pages/core/offline_page_model_query.cc b/components/offline_pages/core/offline_page_model_query.cc
index dd737ad..a7b0ab4 100644
--- a/components/offline_pages/core/offline_page_model_query.cc
+++ b/components/offline_pages/core/offline_page_model_query.cc
@@ -5,10 +5,9 @@
 #include "components/offline_pages/core/offline_page_model_query.h"
 
 #include <algorithm>
+#include <memory>
 #include <unordered_set>
 
-#include "base/memory/ptr_util.h"
-
 namespace offline_pages {
 
 namespace {
@@ -119,7 +118,7 @@
 
 OfflinePageModelQueryBuilder& OfflinePageModelQueryBuilder::RequireNamespace(
     const std::string& name_space) {
-  name_space_ = base::MakeUnique<std::string>(name_space);
+  name_space_ = std::make_unique<std::string>(name_space);
   return *this;
 }
 
@@ -127,7 +126,7 @@
     ClientPolicyController* controller) {
   DCHECK(controller);
 
-  auto query = base::MakeUnique<OfflinePageModelQuery>();
+  auto query = std::make_unique<OfflinePageModelQuery>();
 
   query->urls_ = urls_;
   urls_ = std::make_pair(
@@ -197,7 +196,7 @@
   restricted_to_original_tab_ = Requirement::UNSET;
 
   if (uses_namespace_restrictions) {
-    query->restricted_to_namespaces_ = base::MakeUnique<std::set<std::string>>(
+    query->restricted_to_namespaces_ = std::make_unique<std::set<std::string>>(
         allowed_namespaces.begin(), allowed_namespaces.end());
   }
 
diff --git a/components/offline_pages/core/offline_page_storage_manager_unittest.cc b/components/offline_pages/core/offline_page_storage_manager_unittest.cc
index e561222d..4faa2ad 100644
--- a/components/offline_pages/core/offline_page_storage_manager_unittest.cc
+++ b/components/offline_pages/core/offline_page_storage_manager_unittest.cc
@@ -11,7 +11,6 @@
 
 #include "base/bind.h"
 #include "base/files/file_path.h"
-#include "base/memory/ptr_util.h"
 #include "base/test/histogram_tester.h"
 #include "base/test/simple_test_clock.h"
 #include "base/time/time.h"
@@ -271,7 +270,7 @@
       model_.get(), policy_controller(), archive_manager_.get()));
   manager_->SetClockForTesting(std::move(clock));
 
-  histogram_tester_ = base::MakeUnique<base::HistogramTester>();
+  histogram_tester_ = std::make_unique<base::HistogramTester>();
 }
 
 void OfflinePageStorageManagerTest::TryClearPages() {
diff --git a/components/offline_pages/core/prefetch/download_archives_task.cc b/components/offline_pages/core/prefetch/download_archives_task.cc
index 6401a01..fb6077a 100644
--- a/components/offline_pages/core/prefetch/download_archives_task.cc
+++ b/components/offline_pages/core/prefetch/download_archives_task.cc
@@ -6,7 +6,6 @@
 
 #include "base/bind.h"
 #include "base/guid.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/time/default_clock.h"
 #include "base/time/time.h"
@@ -53,7 +52,7 @@
   statement.BindInt(0, static_cast<int>(PrefetchItemState::DOWNLOADING));
   if (!statement.Step())
     return nullptr;
-  return base::MakeUnique<int>(statement.ColumnInt(0));
+  return std::make_unique<int>(statement.ColumnInt(0));
 }
 
 bool MarkItemAsDownloading(sql::Connection* db,
@@ -118,7 +117,7 @@
   // Below implementation is a greedy algorithm that selects the next item we
   // can download without quota violation and maximum concurrent downloads
   // violation, as ordered by the |FindItemsReadyForDownload| function.
-  auto items_to_download = base::MakeUnique<ItemsToDownload>();
+  auto items_to_download = std::make_unique<ItemsToDownload>();
   for (auto& ready_item : ready_items) {
     // Concurrent downloads check.
     if (*concurrent_downloads >= max_concurrent_downloads)
diff --git a/components/offline_pages/core/prefetch/generate_page_bundle_reconcile_task_unittest.cc b/components/offline_pages/core/prefetch/generate_page_bundle_reconcile_task_unittest.cc
index 1102924c..ab1ceff1 100644
--- a/components/offline_pages/core/prefetch/generate_page_bundle_reconcile_task_unittest.cc
+++ b/components/offline_pages/core/prefetch/generate_page_bundle_reconcile_task_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "components/offline_pages/core/prefetch/generate_page_bundle_reconcile_task.h"
 
+#include <memory>
 #include <string>
 
 #include "base/time/time.h"
@@ -22,7 +23,7 @@
 class FakePrefetchNetworkRequestFactory : public PrefetchNetworkRequestFactory {
  public:
   FakePrefetchNetworkRequestFactory() {
-    requested_urls_ = base::MakeUnique<std::set<std::string>>();
+    requested_urls_ = std::make_unique<std::set<std::string>>();
   }
   ~FakePrefetchNetworkRequestFactory() override = default;
 
@@ -33,7 +34,7 @@
       const std::string& gcm_registration_id,
       const PrefetchRequestFinishedCallback& callback) override {}
   std::unique_ptr<std::set<std::string>> GetAllUrlsRequested() const override {
-    return base::MakeUnique<std::set<std::string>>(*requested_urls_);
+    return std::make_unique<std::set<std::string>>(*requested_urls_);
   }
   void MakeGetOperationRequest(
       const std::string& operation_name,
@@ -72,7 +73,7 @@
 };
 
 GeneratePageBundleReconcileTaskTest::GeneratePageBundleReconcileTaskTest()
-    : request_factory_(base::MakeUnique<FakePrefetchNetworkRequestFactory>()) {}
+    : request_factory_(std::make_unique<FakePrefetchNetworkRequestFactory>()) {}
 
 PrefetchItem GeneratePageBundleReconcileTaskTest::InsertItem(
     PrefetchItemState state,
diff --git a/components/offline_pages/core/prefetch/generate_page_bundle_task.cc b/components/offline_pages/core/prefetch/generate_page_bundle_task.cc
index 31a2744..5c38f5a 100644
--- a/components/offline_pages/core/prefetch/generate_page_bundle_task.cc
+++ b/components/offline_pages/core/prefetch/generate_page_bundle_task.cc
@@ -8,7 +8,6 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/memory/ptr_util.h"
 #include "base/time/default_clock.h"
 #include "components/offline_pages/core/offline_store_utils.h"
 #include "components/offline_pages/core/prefetch/prefetch_gcm_handler.h"
@@ -66,7 +65,7 @@
   sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
   statement.BindInt(0, static_cast<int>(PrefetchItemState::NEW_REQUEST));
 
-  auto urls = base::MakeUnique<std::vector<FetchedUrl>>();
+  auto urls = std::make_unique<std::vector<FetchedUrl>>();
   while (statement.Step()) {
     urls->push_back(
         FetchedUrl(statement.ColumnInt64(0),   // offline_id
@@ -113,7 +112,7 @@
     urls->resize(kMaxUrlsToSend);
   }
 
-  auto url_specs = base::MakeUnique<std::vector<std::string>>();
+  auto url_specs = std::make_unique<std::vector<std::string>>();
   for (const auto& url : *urls) {
     if (!UpdateStateSync(db, url.offline_id, clock))
       return nullptr;
diff --git a/components/offline_pages/core/prefetch/get_operation_task.cc b/components/offline_pages/core/prefetch/get_operation_task.cc
index e8befc93..6d73ff5 100644
--- a/components/offline_pages/core/prefetch/get_operation_task.cc
+++ b/components/offline_pages/core/prefetch/get_operation_task.cc
@@ -9,7 +9,6 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/memory/ptr_util.h"
 #include "components/offline_pages/core/prefetch/prefetch_dispatcher.h"
 #include "components/offline_pages/core/prefetch/prefetch_network_request_factory.h"
 #include "components/offline_pages/core/prefetch/store/prefetch_store.h"
@@ -49,7 +48,7 @@
   sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
   statement.BindInt(0, static_cast<int>(PrefetchItemState::RECEIVED_GCM));
 
-  auto operations = base::MakeUnique<std::vector<std::string>>();
+  auto operations = std::make_unique<std::vector<std::string>>();
   while (statement.Step()) {
     operations->push_back(statement.ColumnString(0));  // operation_name
   }
diff --git a/components/offline_pages/core/prefetch/import_archives_task.cc b/components/offline_pages/core/prefetch/import_archives_task.cc
index 15760f6..7ebacfc 100644
--- a/components/offline_pages/core/prefetch/import_archives_task.cc
+++ b/components/offline_pages/core/prefetch/import_archives_task.cc
@@ -4,11 +4,12 @@
 
 #include "components/offline_pages/core/prefetch/import_archives_task.h"
 
+#include <memory>
+
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "components/offline_pages/core/offline_store_utils.h"
 #include "components/offline_pages/core/prefetch/prefetch_types.h"
 #include "components/offline_pages/core/prefetch/store/prefetch_store.h"
@@ -45,7 +46,7 @@
         store_utils::FromDatabaseFilePath(statement.ColumnString(6));
     archive.file_size = statement.ColumnInt64(7);
     if (!archives)
-      archives = base::MakeUnique<std::vector<PrefetchArchiveInfo>>();
+      archives = std::make_unique<std::vector<PrefetchArchiveInfo>>();
     archives->push_back(archive);
   }
 
diff --git a/components/offline_pages/core/prefetch/metrics_finalization_task_unittest.cc b/components/offline_pages/core/prefetch/metrics_finalization_task_unittest.cc
index 51933b4..9c006f6 100644
--- a/components/offline_pages/core/prefetch/metrics_finalization_task_unittest.cc
+++ b/components/offline_pages/core/prefetch/metrics_finalization_task_unittest.cc
@@ -4,9 +4,9 @@
 
 #include "components/offline_pages/core/prefetch/metrics_finalization_task.h"
 
+#include <memory>
 #include <set>
 
-#include "base/memory/ptr_util.h"
 #include "base/test/histogram_tester.h"
 #include "components/offline_pages/core/prefetch/mock_prefetch_item_generator.h"
 #include "components/offline_pages/core/prefetch/prefetch_item.h"
@@ -32,7 +32,7 @@
 void MetricsFinalizationTaskTest::SetUp() {
   TaskTestBase::SetUp();
   metrics_finalization_task_ =
-      base::MakeUnique<MetricsFinalizationTask>(store());
+      std::make_unique<MetricsFinalizationTask>(store());
 }
 
 void MetricsFinalizationTaskTest::TearDown() {
diff --git a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc
index 70016d5..7b0f609b 100644
--- a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc
+++ b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc
@@ -8,7 +8,6 @@
 
 #include "base/bind.h"
 #include "base/guid.h"
-#include "base/memory/ptr_util.h"
 #include "base/task_runner.h"
 #include "base/task_scheduler/post_task.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -94,14 +93,14 @@
   // example, if the user is never on WiFi with enough battery charge).
   // First, detect stale entries and move them to FINISHED.
   task_queue_.AddTask(
-      base::MakeUnique<StaleEntryFinalizerTask>(this, prefetch_store));
+      std::make_unique<StaleEntryFinalizerTask>(this, prefetch_store));
 
   // Second, move FINISHED to ZOMBIE.
   task_queue_.AddTask(
-      base::MakeUnique<MetricsFinalizationTask>(prefetch_store));
+      std::make_unique<MetricsFinalizationTask>(prefetch_store));
 
   // Third, add new unique URLs and remove unneeded ZOMBIEs.
-  std::unique_ptr<Task> add_task = base::MakeUnique<AddUniqueUrlsTask>(
+  std::unique_ptr<Task> add_task = std::make_unique<AddUniqueUrlsTask>(
       this, prefetch_store, name_space, prefetch_urls);
   task_queue_.AddTask(std::move(add_task));
 
@@ -152,14 +151,14 @@
   // other reconciler tasks that deal with external systems so that entries
   // finalized by it will promptly effect any external processing they relate
   // to.
-  task_queue_.AddTask(base::MakeUnique<StaleEntryFinalizerTask>(
+  task_queue_.AddTask(std::make_unique<StaleEntryFinalizerTask>(
       this, service_->GetPrefetchStore()));
 
-  task_queue_.AddTask(base::MakeUnique<GeneratePageBundleReconcileTask>(
+  task_queue_.AddTask(std::make_unique<GeneratePageBundleReconcileTask>(
       service_->GetPrefetchStore(),
       service_->GetPrefetchNetworkRequestFactory()));
 
-  task_queue_.AddTask(base::MakeUnique<SentGetOperationCleanupTask>(
+  task_queue_.AddTask(std::make_unique<SentGetOperationCleanupTask>(
       service_->GetPrefetchStore(),
       service_->GetPrefetchNetworkRequestFactory()));
 
@@ -169,7 +168,7 @@
   // should only kick in when both services are ready.
   service_->GetPrefetchDownloader()->CleanupDownloadsWhenReady();
 
-  task_queue_.AddTask(base::MakeUnique<ImportCleanupTask>(
+  task_queue_.AddTask(std::make_unique<ImportCleanupTask>(
       service_->GetPrefetchStore(), service_->GetPrefetchImporter()));
 
   // This task should be last, because it is least important for correct
@@ -177,7 +176,7 @@
   // generate more entries in the FINISHED state that the finalization task
   // could pick up.
   task_queue_.AddTask(
-      base::MakeUnique<MetricsFinalizationTask>(service_->GetPrefetchStore()));
+      std::make_unique<MetricsFinalizationTask>(service_->GetPrefetchStore()));
 }
 
 void PrefetchDispatcherImpl::QueueActionTasks() {
@@ -186,12 +185,12 @@
   // Import should be run first to minimize time to import after download
   // finishes, during the download background task.
   std::unique_ptr<Task> import_archives_task =
-      base::MakeUnique<ImportArchivesTask>(service_->GetPrefetchStore(),
+      std::make_unique<ImportArchivesTask>(service_->GetPrefetchStore(),
                                            service_->GetPrefetchImporter());
   task_queue_.AddTask(std::move(import_archives_task));
 
   std::unique_ptr<Task> download_archives_task =
-      base::MakeUnique<DownloadArchivesTask>(service_->GetPrefetchStore(),
+      std::make_unique<DownloadArchivesTask>(service_->GetPrefetchStore(),
                                              service_->GetPrefetchDownloader());
   task_queue_.AddTask(std::move(download_archives_task));
 
@@ -201,7 +200,7 @@
   if (!background_task_ && !offline_pages::IsLimitlessPrefetchingEnabled())
     return;
 
-  std::unique_ptr<Task> get_operation_task = base::MakeUnique<GetOperationTask>(
+  std::unique_ptr<Task> get_operation_task = std::make_unique<GetOperationTask>(
       service_->GetPrefetchStore(),
       service_->GetPrefetchNetworkRequestFactory(),
       base::Bind(
@@ -210,7 +209,7 @@
   task_queue_.AddTask(std::move(get_operation_task));
 
   std::unique_ptr<Task> generate_page_bundle_task =
-      base::MakeUnique<GeneratePageBundleTask>(
+      std::make_unique<GeneratePageBundleTask>(
           service_->GetPrefetchStore(), service_->GetPrefetchGCMHandler(),
           service_->GetPrefetchNetworkRequestFactory(),
           base::Bind(
@@ -260,7 +259,7 @@
   service_->GetLogger()->RecordActivity("Dispatcher: Received GCM message.");
 
   PrefetchStore* prefetch_store = service_->GetPrefetchStore();
-  task_queue_.AddTask(base::MakeUnique<MarkOperationDoneTask>(
+  task_queue_.AddTask(std::make_unique<MarkOperationDoneTask>(
       this, prefetch_store, operation_name));
 }
 
@@ -276,7 +275,7 @@
   // the empty task queue and no outstanding request in order to decide whether
   // to dispose th background task upon the completion of a task.
   PrefetchStore* prefetch_store = service_->GetPrefetchStore();
-  task_queue_.AddTask(base::MakeUnique<PageBundleUpdateTask>(
+  task_queue_.AddTask(std::make_unique<PageBundleUpdateTask>(
       prefetch_store, this, operation_name, pages));
 
   if (background_task_ && status != PrefetchRequestStatus::SUCCESS) {
@@ -309,7 +308,7 @@
     const std::set<std::string>& outstanding_download_ids,
     const std::map<std::string, std::pair<base::FilePath, int64_t>>&
         success_downloads) {
-  task_queue_.AddTask(base::MakeUnique<DownloadCleanupTask>(
+  task_queue_.AddTask(std::make_unique<DownloadCleanupTask>(
       this, service_->GetPrefetchStore(), outstanding_download_ids,
       success_downloads));
 }
@@ -327,9 +326,9 @@
         "Download size: " + std::to_string(download_result.file_size));
   }
 
-  task_queue_.AddTask(base::MakeUnique<DownloadCompletedTask>(
+  task_queue_.AddTask(std::make_unique<DownloadCompletedTask>(
       this, service_->GetPrefetchStore(), download_result));
-  task_queue_.AddTask(base::MakeUnique<ImportArchivesTask>(
+  task_queue_.AddTask(std::make_unique<ImportArchivesTask>(
       service_->GetPrefetchStore(), service_->GetPrefetchImporter()));
 }
 
@@ -346,7 +345,7 @@
   if (success)
     service_->GetOfflineMetricsCollector()->OnSuccessfulPagePrefetch();
 
-  task_queue_.AddTask(base::MakeUnique<ImportCompletedTask>(
+  task_queue_.AddTask(std::make_unique<ImportCompletedTask>(
       this, service_->GetPrefetchStore(), service_->GetPrefetchImporter(),
       offline_id, success));
 }
diff --git a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc
index c3e3ee1d9..b681a337 100644
--- a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc
+++ b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl_unittest.cc
@@ -143,7 +143,7 @@
   taco_->SetPrefetchNetworkRequestFactory(
       base::WrapUnique(network_request_factory_));
   taco_->SetPrefetchConfiguration(
-      base::MakeUnique<TestPrefetchConfiguration>());
+      std::make_unique<TestPrefetchConfiguration>());
   taco_->CreatePrefetchService();
 
   ASSERT_TRUE(test_urls_.empty());
@@ -163,7 +163,7 @@
 }
 
 void PrefetchDispatcherTest::BeginBackgroundTask() {
-  dispatcher_->BeginBackgroundTask(base::MakeUnique<TestPrefetchBackgroundTask>(
+  dispatcher_->BeginBackgroundTask(std::make_unique<TestPrefetchBackgroundTask>(
       taco_->prefetch_service(),
       base::BindRepeating(&PrefetchDispatcherTest::SetReschedule,
                           base::Unretained(this))));
diff --git a/components/offline_pages/core/prefetch/prefetch_download_flow_unittest.cc b/components/offline_pages/core/prefetch/prefetch_download_flow_unittest.cc
index 2eadd4be..504eb3a 100644
--- a/components/offline_pages/core/prefetch/prefetch_download_flow_unittest.cc
+++ b/components/offline_pages/core/prefetch/prefetch_download_flow_unittest.cc
@@ -40,12 +40,12 @@
     TaskTestBase::SetUp();
 
     prefetch_service_taco_.reset(new PrefetchServiceTestTaco);
-    auto downloader = base::MakeUnique<PrefetchDownloaderImpl>(
+    auto downloader = std::make_unique<PrefetchDownloaderImpl>(
         &download_service_, kTestChannel);
-    download_client_ = base::MakeUnique<TestDownloadClient>(downloader.get());
+    download_client_ = std::make_unique<TestDownloadClient>(downloader.get());
     download_service_.set_client(download_client_.get());
     prefetch_service_taco_->SetPrefetchDispatcher(
-        base::MakeUnique<PrefetchDispatcherImpl>());
+        std::make_unique<PrefetchDispatcherImpl>());
     prefetch_service_taco_->SetPrefetchStore(store_util()->ReleaseStore());
     prefetch_service_taco_->SetPrefetchDownloader(std::move(downloader));
     prefetch_service_taco_->CreatePrefetchService();
@@ -75,7 +75,7 @@
 
   void BeginBackgroundTask() {
     prefetch_dispatcher()->BeginBackgroundTask(
-        base::MakeUnique<PrefetchBackgroundTask>(
+        std::make_unique<PrefetchBackgroundTask>(
             prefetch_service_taco_->prefetch_service()));
     RunUntilIdle();
   }
diff --git a/components/offline_pages/core/prefetch/prefetch_downloader_impl_unittest.cc b/components/offline_pages/core/prefetch/prefetch_downloader_impl_unittest.cc
index 5fc63a6..963464c 100644
--- a/components/offline_pages/core/prefetch/prefetch_downloader_impl_unittest.cc
+++ b/components/offline_pages/core/prefetch/prefetch_downloader_impl_unittest.cc
@@ -44,12 +44,12 @@
 
     prefetch_service_taco_.reset(new PrefetchServiceTestTaco);
 
-    auto downloader = base::MakeUnique<PrefetchDownloaderImpl>(
+    auto downloader = std::make_unique<PrefetchDownloaderImpl>(
         &download_service_, kTestChannel);
     downloader->SetClockForTesting(base::WrapUnique(clock_));
     download_service_.SetFailedDownload(kFailedDownloadId, false);
     download_service_.SetIsReady(true);
-    download_client_ = base::MakeUnique<TestDownloadClient>(downloader.get());
+    download_client_ = std::make_unique<TestDownloadClient>(downloader.get());
     download_service_.set_client(download_client_.get());
     prefetch_service_taco_->SetPrefetchDownloader(std::move(downloader));
     prefetch_service_taco_->CreatePrefetchService();
diff --git a/components/offline_pages/core/prefetch/prefetch_gcm_app_handler_unittest.cc b/components/offline_pages/core/prefetch/prefetch_gcm_app_handler_unittest.cc
index fe969a8..b124dc1 100644
--- a/components/offline_pages/core/prefetch/prefetch_gcm_app_handler_unittest.cc
+++ b/components/offline_pages/core/prefetch/prefetch_gcm_app_handler_unittest.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/memory/ptr_util.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/gcm_driver/instance_id/instance_id.h"
@@ -41,14 +40,14 @@
         task_runner_handle_(task_runner_) {}
 
   void SetUp() override {
-    auto dispatcher = base::MakeUnique<TestPrefetchDispatcher>();
+    auto dispatcher = std::make_unique<TestPrefetchDispatcher>();
     test_dispatcher_ = dispatcher.get();
 
-    auto token_factory = base::MakeUnique<TestTokenFactory>();
+    auto token_factory = std::make_unique<TestTokenFactory>();
     token_factory_ = token_factory.get();
 
     auto gcm_app_handler =
-        base::MakeUnique<PrefetchGCMAppHandler>(std::move(token_factory));
+        std::make_unique<PrefetchGCMAppHandler>(std::move(token_factory));
     handler_ = gcm_app_handler.get();
 
     prefetch_service_taco_.reset(new PrefetchServiceTestTaco);
diff --git a/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl.cc b/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl.cc
index ec2bd54..6de2d9d5 100644
--- a/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl.cc
+++ b/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl.cc
@@ -5,7 +5,6 @@
 #include "components/offline_pages/core/prefetch/prefetch_network_request_factory_impl.h"
 
 #include "base/bind.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "components/offline_pages/core/prefetch/generate_page_bundle_request.h"
 #include "components/offline_pages/core/prefetch/get_operation_request.h"
@@ -58,7 +57,7 @@
     return;
   uint64_t request_id = GetNextRequestId();
   generate_page_bundle_requests_[request_id] =
-      base::MakeUnique<GeneratePageBundleRequest>(
+      std::make_unique<GeneratePageBundleRequest>(
           user_agent_, gcm_registration_id, kMaxBundleSizeBytes, url_strings,
           channel_, request_context_.get(),
           base::Bind(
@@ -68,7 +67,7 @@
 
 std::unique_ptr<std::set<std::string>>
 PrefetchNetworkRequestFactoryImpl::GetAllUrlsRequested() const {
-  auto result = base::MakeUnique<std::set<std::string>>();
+  auto result = std::make_unique<std::set<std::string>>();
   for (const auto& request_pair : generate_page_bundle_requests_) {
     for (const auto& url : request_pair.second->requested_urls())
       result->insert(url);
@@ -82,7 +81,7 @@
   if (!AddConcurrentRequest())
     return;
   get_operation_requests_[operation_name] =
-      base::MakeUnique<GetOperationRequest>(
+      std::make_unique<GetOperationRequest>(
           operation_name, channel_, request_context_.get(),
           base::Bind(
               &PrefetchNetworkRequestFactoryImpl::GetOperationRequestDone,
@@ -131,7 +130,7 @@
 
 std::unique_ptr<std::set<std::string>>
 PrefetchNetworkRequestFactoryImpl::GetAllOperationNamesRequested() const {
-  auto result = base::MakeUnique<std::set<std::string>>();
+  auto result = std::make_unique<std::set<std::string>>();
   for (const auto& request_pair : get_operation_requests_)
     result->insert(request_pair.first);
   return result;
diff --git a/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl_unittest.cc b/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl_unittest.cc
index d73e201..68b01909 100644
--- a/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl_unittest.cc
+++ b/components/offline_pages/core/prefetch/prefetch_network_request_factory_impl_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "components/offline_pages/core/prefetch/prefetch_network_request_factory_impl.h"
 
-#include "base/memory/ptr_util.h"
 #include "base/test/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "base/test/test_simple_task_runner.h"
@@ -41,7 +40,7 @@
 
 PrefetchNetworkRequestFactoryTest::PrefetchNetworkRequestFactoryTest()
     : request_context_(new net::TestURLRequestContextGetter(task_runner())) {
-  request_factory_ = base::MakeUnique<PrefetchNetworkRequestFactoryImpl>(
+  request_factory_ = std::make_unique<PrefetchNetworkRequestFactoryImpl>(
       request_context_.get(), version_info::Channel::UNKNOWN, "a user agent");
 }
 
diff --git a/components/offline_pages/core/prefetch/prefetch_request_test_base.cc b/components/offline_pages/core/prefetch/prefetch_request_test_base.cc
index 1afcf048..8f4aa36 100644
--- a/components/offline_pages/core/prefetch/prefetch_request_test_base.cc
+++ b/components/offline_pages/core/prefetch/prefetch_request_test_base.cc
@@ -4,6 +4,8 @@
 
 #include "components/offline_pages/core/prefetch/prefetch_request_test_base.h"
 
+#include <memory>
+
 #include "base/feature_list.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/test/mock_entropy_provider.h"
@@ -26,8 +28,8 @@
 PrefetchRequestTestBase::~PrefetchRequestTestBase() {}
 
 void PrefetchRequestTestBase::SetUp() {
-  field_trial_list_ = base::MakeUnique<base::FieldTrialList>(
-      base::MakeUnique<base::MockEntropyProvider>());
+  field_trial_list_ = std::make_unique<base::FieldTrialList>(
+      std::make_unique<base::MockEntropyProvider>());
 }
 
 void PrefetchRequestTestBase::SetUpExperimentOption() {
@@ -43,7 +45,7 @@
   base::AssociateFieldTrialParams(kTrialName, kGroupName, params);
 
   std::unique_ptr<base::FeatureList> feature_list =
-      base::MakeUnique<base::FeatureList>();
+      std::make_unique<base::FeatureList>();
   feature_list->RegisterFieldTrialOverride(
       kPrefetchingOfflinePagesFeature.name,
       base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial.get());
diff --git a/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc b/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc
index b026e983..b15e1d2 100644
--- a/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc
+++ b/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc
@@ -63,23 +63,23 @@
 }  // namespace
 
 PrefetchServiceTestTaco::PrefetchServiceTestTaco() {
-  dispatcher_ = base::MakeUnique<TestPrefetchDispatcher>();
-  metrics_collector_ = base::MakeUnique<TestOfflineMetricsCollector>(nullptr);
-  gcm_handler_ = base::MakeUnique<TestPrefetchGCMHandler>();
+  dispatcher_ = std::make_unique<TestPrefetchDispatcher>();
+  metrics_collector_ = std::make_unique<TestOfflineMetricsCollector>(nullptr);
+  gcm_handler_ = std::make_unique<TestPrefetchGCMHandler>();
   network_request_factory_ =
-      base::MakeUnique<TestPrefetchNetworkRequestFactory>();
+      std::make_unique<TestPrefetchNetworkRequestFactory>();
   prefetch_store_ =
-      base::MakeUnique<PrefetchStore>(base::ThreadTaskRunnerHandle::Get());
-  suggested_articles_observer_ = base::MakeUnique<SuggestedArticlesObserver>();
+      std::make_unique<PrefetchStore>(base::ThreadTaskRunnerHandle::Get());
+  suggested_articles_observer_ = std::make_unique<SuggestedArticlesObserver>();
   prefetch_downloader_ =
       base::WrapUnique(new PrefetchDownloaderImpl(kTestChannel));
-  prefetch_importer_ = base::MakeUnique<TestPrefetchImporter>();
+  prefetch_importer_ = std::make_unique<TestPrefetchImporter>();
   // This sets up the testing articles as an empty vector, we can ignore the
   // result here.  This allows us to not create a ContentSuggestionsService.
   suggested_articles_observer_->GetTestingArticles();
   prefetch_background_task_handler_ =
-      base::MakeUnique<StubPrefetchBackgroundTaskHandler>();
-  prefetch_configuration_ = base::MakeUnique<StubPrefetchConfiguration>();
+      std::make_unique<StubPrefetchBackgroundTaskHandler>();
+  prefetch_configuration_ = std::make_unique<StubPrefetchConfiguration>();
 }
 
 PrefetchServiceTestTaco::~PrefetchServiceTestTaco() = default;
@@ -151,7 +151,7 @@
         network_request_factory_ && prefetch_store_ &&
         suggested_articles_observer_ && prefetch_downloader_);
 
-  prefetch_service_ = base::MakeUnique<PrefetchServiceImpl>(
+  prefetch_service_ = std::make_unique<PrefetchServiceImpl>(
       std::move(metrics_collector_), std::move(dispatcher_),
       std::move(gcm_handler_), std::move(network_request_factory_),
       std::move(prefetch_store_), std::move(suggested_articles_observer_),
diff --git a/components/offline_pages/core/prefetch/sent_get_operation_cleanup_task.cc b/components/offline_pages/core/prefetch/sent_get_operation_cleanup_task.cc
index 6bd9064a..1ad8d5f 100644
--- a/components/offline_pages/core/prefetch/sent_get_operation_cleanup_task.cc
+++ b/components/offline_pages/core/prefetch/sent_get_operation_cleanup_task.cc
@@ -4,13 +4,13 @@
 
 #include "components/offline_pages/core/prefetch/sent_get_operation_cleanup_task.h"
 
+#include <memory>
 #include <set>
 #include <vector>
 
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "components/offline_pages/core/prefetch/prefetch_network_request_factory.h"
 #include "components/offline_pages/core/prefetch/prefetch_types.h"
 #include "components/offline_pages/core/prefetch/store/prefetch_store.h"
@@ -35,7 +35,7 @@
   std::unique_ptr<std::vector<std::string>> operation_names;
   while (statement.Step()) {
     if (!operation_names)
-      operation_names = base::MakeUnique<std::vector<std::string>>();
+      operation_names = std::make_unique<std::vector<std::string>>();
     operation_names->push_back(statement.ColumnString(0));
   }
   return operation_names;
diff --git a/components/offline_pages/core/prefetch/sent_get_operation_cleanup_task_unittest.cc b/components/offline_pages/core/prefetch/sent_get_operation_cleanup_task_unittest.cc
index c1f6a4a..43507efa 100644
--- a/components/offline_pages/core/prefetch/sent_get_operation_cleanup_task_unittest.cc
+++ b/components/offline_pages/core/prefetch/sent_get_operation_cleanup_task_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "components/offline_pages/core/prefetch/sent_get_operation_cleanup_task.h"
 
+#include <memory>
 #include <string>
 
 #include "base/time/time.h"
@@ -24,7 +25,7 @@
     : public PrefetchNetworkRequestFactory {
  public:
   TestingPrefetchNetworkRequestFactory() {
-    ongoing_operation_names_ = base::MakeUnique<std::set<std::string>>();
+    ongoing_operation_names_ = std::make_unique<std::set<std::string>>();
   }
   ~TestingPrefetchNetworkRequestFactory() override = default;
 
@@ -46,7 +47,7 @@
   }
   std::unique_ptr<std::set<std::string>> GetAllOperationNamesRequested()
       const override {
-    return base::MakeUnique<std::set<std::string>>(*ongoing_operation_names_);
+    return std::make_unique<std::set<std::string>>(*ongoing_operation_names_);
   }
 
   void AddOngoingOperation(const std::string& operation_name) {
@@ -100,7 +101,7 @@
   ASSERT_TRUE(store_util()->InsertPrefetchItem(item));
 
   std::unique_ptr<TestingPrefetchNetworkRequestFactory> request_factory =
-      base::MakeUnique<TestingPrefetchNetworkRequestFactory>();
+      std::make_unique<TestingPrefetchNetworkRequestFactory>();
   request_factory->AddOngoingOperation(item.operation_name);
 
   SentGetOperationCleanupTask task(store(), request_factory.get());
@@ -143,7 +144,7 @@
   ASSERT_TRUE(store_util()->InsertPrefetchItem(item));
 
   std::unique_ptr<TestingPrefetchNetworkRequestFactory> request_factory =
-      base::MakeUnique<TestingPrefetchNetworkRequestFactory>();
+      std::make_unique<TestingPrefetchNetworkRequestFactory>();
   request_factory->AddOngoingOperation(item.operation_name);
 
   SentGetOperationCleanupTask task(store(), request_factory.get());
diff --git a/components/offline_pages/core/prefetch/stale_entry_finalizer_task_unittest.cc b/components/offline_pages/core/prefetch/stale_entry_finalizer_task_unittest.cc
index 7f0295dc..93030a07 100644
--- a/components/offline_pages/core/prefetch/stale_entry_finalizer_task_unittest.cc
+++ b/components/offline_pages/core/prefetch/stale_entry_finalizer_task_unittest.cc
@@ -4,10 +4,10 @@
 
 #include "components/offline_pages/core/prefetch/stale_entry_finalizer_task.h"
 
+#include <memory>
 #include <set>
 
 #include "base/bind.h"
-#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/histogram_tester.h"
 #include "base/test/test_simple_task_runner.h"
@@ -56,7 +56,7 @@
 void StaleEntryFinalizerTaskTest::SetUp() {
   TaskTestBase::SetUp();
   stale_finalizer_task_ =
-      base::MakeUnique<StaleEntryFinalizerTask>(dispatcher(), store());
+      std::make_unique<StaleEntryFinalizerTask>(dispatcher(), store());
   fake_now_ = base::Time() + base::TimeDelta::FromDays(100);
   stale_finalizer_task_->SetNowGetterForTesting(base::BindRepeating(
       [](base::Time t) -> base::Time { return t; }, fake_now_));
diff --git a/components/offline_pages/core/prefetch/store/prefetch_store_schema_unittest.cc b/components/offline_pages/core/prefetch/store/prefetch_store_schema_unittest.cc
index a7a383a..3cbe717 100644
--- a/components/offline_pages/core/prefetch/store/prefetch_store_schema_unittest.cc
+++ b/components/offline_pages/core/prefetch/store/prefetch_store_schema_unittest.cc
@@ -5,8 +5,8 @@
 #include "components/offline_pages/core/prefetch/store/prefetch_store_schema.h"
 
 #include <limits>
+#include <memory>
 
-#include "base/memory/ptr_util.h"
 #include "sql/connection.h"
 #include "sql/meta_table.h"
 #include "sql/statement.h"
@@ -96,7 +96,7 @@
   ~PrefetchStoreSchemaTest() override = default;
 
   void SetUp() override {
-    db_ = base::MakeUnique<sql::Connection>();
+    db_ = std::make_unique<sql::Connection>();
     ASSERT_TRUE(db_->OpenInMemory());
     ASSERT_FALSE(sql::MetaTable::DoesTableExist(db_.get()));
   }
diff --git a/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc b/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc
index 4c37ad3..2246e610 100644
--- a/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc
+++ b/components/offline_pages/core/prefetch/store/prefetch_store_test_util.cc
@@ -128,7 +128,7 @@
   if (!statement.Step())
     return nullptr;
 
-  auto item = base::MakeUnique<PrefetchItem>();
+  auto item = std::make_unique<PrefetchItem>();
   PopulatePrefetchItem(statement, item.get());
   return item;
 }
diff --git a/components/offline_pages/core/prefetch/suggested_articles_observer.cc b/components/offline_pages/core/prefetch/suggested_articles_observer.cc
index e325ebf0..34b8956e 100644
--- a/components/offline_pages/core/prefetch/suggested_articles_observer.cc
+++ b/components/offline_pages/core/prefetch/suggested_articles_observer.cc
@@ -6,7 +6,6 @@
 
 #include <unordered_set>
 
-#include "base/memory/ptr_util.h"
 #include "components/ntp_snippets/category.h"
 #include "components/ntp_snippets/category_status.h"
 #include "components/offline_pages/core/client_namespace_constants.h"
@@ -129,7 +128,7 @@
 SuggestedArticlesObserver::GetTestingArticles() {
   if (!test_articles_) {
     test_articles_ =
-        base::MakeUnique<std::vector<ntp_snippets::ContentSuggestion>>();
+        std::make_unique<std::vector<ntp_snippets::ContentSuggestion>>();
   }
   return test_articles_.get();
 }
diff --git a/components/offline_pages/core/prefetch/suggested_articles_observer_unittest.cc b/components/offline_pages/core/prefetch/suggested_articles_observer_unittest.cc
index ea86549..f9dd052 100644
--- a/components/offline_pages/core/prefetch/suggested_articles_observer_unittest.cc
+++ b/components/offline_pages/core/prefetch/suggested_articles_observer_unittest.cc
@@ -45,12 +45,12 @@
         task_runner_handle_(task_runner_) {}
 
   void SetUp() override {
-    prefetch_service_test_taco_ = base::MakeUnique<PrefetchServiceTestTaco>();
+    prefetch_service_test_taco_ = std::make_unique<PrefetchServiceTestTaco>();
     test_prefetch_dispatcher_ = new TestPrefetchDispatcher();
     prefetch_service_test_taco_->SetPrefetchDispatcher(
         base::WrapUnique(test_prefetch_dispatcher_));
     prefetch_service_test_taco_->SetSuggestedArticlesObserver(
-        base::MakeUnique<SuggestedArticlesObserver>());
+        std::make_unique<SuggestedArticlesObserver>());
     prefetch_service_test_taco_->CreatePrefetchService();
   }
 
diff --git a/components/offline_pages/core/prefetch/task_test_base.cc b/components/offline_pages/core/prefetch/task_test_base.cc
index a67fcf36e..69d3a3f 100644
--- a/components/offline_pages/core/prefetch/task_test_base.cc
+++ b/components/offline_pages/core/prefetch/task_test_base.cc
@@ -4,7 +4,6 @@
 
 #include "components/offline_pages/core/prefetch/task_test_base.h"
 
-#include "base/memory/ptr_util.h"
 #include "base/test/mock_callback.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/offline_pages/core/offline_store_utils.h"
@@ -67,7 +66,7 @@
 
 void TaskTestBase::ExpectTaskCompletes(Task* task) {
   completion_callbacks_.push_back(
-      base::MakeUnique<base::MockCallback<Task::TaskCompletionCallback>>());
+      std::make_unique<base::MockCallback<Task::TaskCompletionCallback>>());
   EXPECT_CALL(*completion_callbacks_.back(), Run(_));
 
   task->SetTaskCompletionCallbackForTesting(
diff --git a/components/offline_pages/core/prefetch/test_prefetch_dispatcher.cc b/components/offline_pages/core/prefetch/test_prefetch_dispatcher.cc
index 0191f10..19482d1 100644
--- a/components/offline_pages/core/prefetch/test_prefetch_dispatcher.cc
+++ b/components/offline_pages/core/prefetch/test_prefetch_dispatcher.cc
@@ -4,7 +4,6 @@
 
 #include "components/offline_pages/core/prefetch/test_prefetch_dispatcher.h"
 
-#include "base/memory/ptr_util.h"
 #include "components/offline_pages/core/offline_page_item.h"
 #include "components/offline_pages/core/prefetch/prefetch_background_task.h"
 
@@ -30,7 +29,7 @@
 void TestPrefetchDispatcher::RemovePrefetchURLsByClientId(
     const ClientId& client_id) {
   remove_by_client_id_count++;
-  last_removed_client_id = base::MakeUnique<ClientId>(client_id);
+  last_removed_client_id = std::make_unique<ClientId>(client_id);
 }
 
 void TestPrefetchDispatcher::BeginBackgroundTask(
diff --git a/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate.cc b/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate.cc
index a4501adc..edf7661d 100644
--- a/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate.cc
+++ b/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate.cc
@@ -33,7 +33,7 @@
 
   if (!recent_tabs_ui_adapter) {
     auto delegate =
-        base::MakeUnique<RecentTabsUIAdapterDelegate>(offline_page_model);
+        std::make_unique<RecentTabsUIAdapterDelegate>(offline_page_model);
     recent_tabs_ui_adapter = new DownloadUIAdapter(
         nullptr, offline_page_model, request_coordinator, std::move(delegate));
     offline_page_model->SetUserData(kRecentTabsUIAdapterKey,
diff --git a/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate_unittest.cc b/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate_unittest.cc
index fd2b8fb..992e529e 100644
--- a/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate_unittest.cc
+++ b/components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate_unittest.cc
@@ -71,13 +71,13 @@
 RecentTabsUIAdapterDelegateTest::RecentTabsUIAdapterDelegateTest()
     : task_runner_(new base::TestMockTimeTaskRunner()),
       task_runner_handle_(task_runner_) {
-  request_coordinator_taco_ = base::MakeUnique<RequestCoordinatorStubTaco>();
+  request_coordinator_taco_ = std::make_unique<RequestCoordinatorStubTaco>();
   request_coordinator_taco_->CreateRequestCoordinator();
 
-  auto delegate = base::MakeUnique<RecentTabsUIAdapterDelegate>(&model);
+  auto delegate = std::make_unique<RecentTabsUIAdapterDelegate>(&model);
   adapter_delegate = delegate.get();
 
-  adapter = base::MakeUnique<DownloadUIAdapter>(
+  adapter = std::make_unique<DownloadUIAdapter>(
       nullptr, &model, request_coordinator_taco_->request_coordinator(),
       std::move(delegate));
 }
diff --git a/components/offline_pages/core/renovations/page_renovator_unittest.cc b/components/offline_pages/core/renovations/page_renovator_unittest.cc
index 7e9b2c8..000adcc1 100644
--- a/components/offline_pages/core/renovations/page_renovator_unittest.cc
+++ b/components/offline_pages/core/renovations/page_renovator_unittest.cc
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/memory/ptr_util.h"
 #include "base/test/mock_callback.h"
 #include "base/values.h"
 #include "components/offline_pages/core/renovations/script_injector.h"
@@ -66,8 +65,8 @@
   page_renovation_loader_.SetRenovationsForTest(
       std::vector<std::unique_ptr<PageRenovation>>());
 
-  page_renovator_ = base::MakeUnique<PageRenovator>(
-      &page_renovation_loader_, base::MakeUnique<FakeScriptInjector>(this),
+  page_renovator_ = std::make_unique<PageRenovator>(
+      &page_renovation_loader_, std::make_unique<FakeScriptInjector>(this),
       GURL("example.com"));
 }
 
diff --git a/components/payments/mojom/BUILD.gn b/components/payments/mojom/BUILD.gn
new file mode 100644
index 0000000..3ad1d93
--- /dev/null
+++ b/components/payments/mojom/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright (c) 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+java_group("mojom_java") {
+  # This is a temporary empty target. It is needed to enable prerequisite
+  # downstream changes to be landed without breaking the Android build. It will
+  # be replaced with an actual mojom target once the downstream changes are in
+  # place.
+}
diff --git a/components/search_engines/default_search_manager_unittest.cc b/components/search_engines/default_search_manager_unittest.cc
index 713a1bf..5277c192 100644
--- a/components/search_engines/default_search_manager_unittest.cc
+++ b/components/search_engines/default_search_manager_unittest.cc
@@ -11,7 +11,6 @@
 
 #include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -32,9 +31,9 @@
 void SetOverrides(sync_preferences::TestingPrefServiceSyncable* prefs,
                   bool update) {
   prefs->SetUserPref(prefs::kSearchProviderOverridesVersion,
-                     base::MakeUnique<base::Value>(1));
-  auto overrides = base::MakeUnique<base::ListValue>();
-  auto entry = base::MakeUnique<base::DictionaryValue>();
+                     std::make_unique<base::Value>(1));
+  auto overrides = std::make_unique<base::ListValue>();
+  auto entry = std::make_unique<base::DictionaryValue>();
 
   entry->SetString("name", update ? "new_foo" : "foo");
   entry->SetString("keyword", update ? "new_fook" : "fook");
@@ -43,17 +42,17 @@
   entry->SetString("encoding", "UTF-8");
   entry->SetInteger("id", 1001);
   entry->SetString("suggest_url", "http://foo.com/suggest?q={searchTerms}");
-  auto alternate_urls = base::MakeUnique<base::ListValue>();
+  auto alternate_urls = std::make_unique<base::ListValue>();
   alternate_urls->AppendString("http://foo.com/alternate?q={searchTerms}");
   entry->Set("alternate_urls", std::move(alternate_urls));
   overrides->Append(std::move(entry));
 
-  entry = base::MakeUnique<base::DictionaryValue>();
+  entry = std::make_unique<base::DictionaryValue>();
   entry->SetInteger("id", 1002);
   entry->SetString("name", update ? "new_bar" : "bar");
   entry->SetString("keyword", update ? "new_bark" : "bark");
   entry->SetString("encoding", std::string());
-  overrides->Append(base::MakeUnique<base::Value>(entry->Clone()));
+  overrides->Append(std::make_unique<base::Value>(entry->Clone()));
   entry->SetInteger("id", 1003);
   entry->SetString("name", "baz");
   entry->SetString("keyword", "bazk");
diff --git a/components/search_engines/default_search_policy_handler.cc b/components/search_engines/default_search_policy_handler.cc
index 6ef34eb..7bd0d8d9 100644
--- a/components/search_engines/default_search_policy_handler.cc
+++ b/components/search_engines/default_search_policy_handler.cc
@@ -9,7 +9,6 @@
 #include <utility>
 
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "components/policy/core/browser/policy_error_map.h"
 #include "components/policy/core/common/policy_map.h"
@@ -37,8 +36,8 @@
     DCHECK(is_list);
   }
   dict->Set(key, policy_list
-                     ? base::MakeUnique<base::Value>(policy_list->Clone())
-                     : base::MakeUnique<base::Value>(base::Value::Type::LIST));
+                     ? std::make_unique<base::Value>(policy_list->Clone())
+                     : std::make_unique<base::Value>(base::Value::Type::LIST));
 }
 
 // Extracts a string from a policy value and adds it to a pref dictionary.
@@ -280,7 +279,7 @@
   base::Value* value;
   base::ListValue* list_value;
   if (!prefs->GetValue(path, &value) || !value->GetAsList(&list_value))
-    prefs->SetValue(path, base::MakeUnique<base::ListValue>());
+    prefs->SetValue(path, std::make_unique<base::ListValue>());
 }
 
 }  // namespace policy
diff --git a/components/search_engines/default_search_policy_handler_unittest.cc b/components/search_engines/default_search_policy_handler_unittest.cc
index f8ccdf7b..a5610ff 100644
--- a/components/search_engines/default_search_policy_handler_unittest.cc
+++ b/components/search_engines/default_search_policy_handler_unittest.cc
@@ -79,22 +79,22 @@
   encodings->AppendString("UTF-8");
   policy->Set(key::kDefaultSearchProviderEnabled, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::Value>(true), nullptr);
+              std::make_unique<base::Value>(true), nullptr);
   policy->Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::Value>(kSearchURL), nullptr);
+              std::make_unique<base::Value>(kSearchURL), nullptr);
   policy->Set(key::kDefaultSearchProviderName, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::Value>(kName), nullptr);
+              std::make_unique<base::Value>(kName), nullptr);
   policy->Set(key::kDefaultSearchProviderKeyword, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::Value>(kKeyword), nullptr);
+              std::make_unique<base::Value>(kKeyword), nullptr);
   policy->Set(key::kDefaultSearchProviderSuggestURL, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::Value>(kSuggestURL), nullptr);
+              std::make_unique<base::Value>(kSuggestURL), nullptr);
   policy->Set(key::kDefaultSearchProviderIconURL, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::Value>(kIconURL), nullptr);
+              std::make_unique<base::Value>(kIconURL), nullptr);
   policy->Set(key::kDefaultSearchProviderEncodings, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
               base::WrapUnique(encodings), nullptr);
@@ -103,13 +103,13 @@
               default_alternate_urls_.CreateDeepCopy(), nullptr);
   policy->Set(key::kDefaultSearchProviderImageURL, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::Value>(kImageURL), nullptr);
+              std::make_unique<base::Value>(kImageURL), nullptr);
   policy->Set(key::kDefaultSearchProviderImageURLPostParams,
               POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::Value>(kImageParams), nullptr);
+              std::make_unique<base::Value>(kImageParams), nullptr);
   policy->Set(key::kDefaultSearchProviderNewTabURL, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::Value>(kNewTabURL), nullptr);
+              std::make_unique<base::Value>(kNewTabURL), nullptr);
 }
 
 // Checks that if the default search policy is missing, that no elements of the
@@ -174,7 +174,7 @@
     // invalid.
     policy.Set(policy_name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                POLICY_SOURCE_CLOUD,
-               base::MakeUnique<base::Value>(base::Value::Type::BINARY),
+               std::make_unique<base::Value>(base::Value::Type::BINARY),
                nullptr);
     UpdateProviderPolicy(policy);
 
diff --git a/components/search_engines/search_engine_data_type_controller_unittest.cc b/components/search_engines/search_engine_data_type_controller_unittest.cc
index cfa6c15..e71aa92 100644
--- a/components/search_engines/search_engine_data_type_controller_unittest.cc
+++ b/components/search_engines/search_engine_data_type_controller_unittest.cc
@@ -64,7 +64,7 @@
     search_engine_dtc_.SetGenericChangeProcessorFactoryForTest(
         base::WrapUnique<syncer::GenericChangeProcessorFactory>(
             new syncer::FakeGenericChangeProcessorFactory(
-                base::MakeUnique<syncer::FakeGenericChangeProcessor>(
+                std::make_unique<syncer::FakeGenericChangeProcessor>(
                     syncer::SEARCH_ENGINES, this))));
     EXPECT_CALL(model_load_callback_, Run(_, _));
   }
diff --git a/components/search_engines/search_engines_test_util.cc b/components/search_engines/search_engines_test_util.cc
index 93a3686..4d6239f 100644
--- a/components/search_engines/search_engines_test_util.cc
+++ b/components/search_engines/search_engines_test_util.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/search_engines/default_search_manager.h"
 #include "components/search_engines/template_url.h"
@@ -18,7 +17,7 @@
 
 std::unique_ptr<TemplateURLData> GenerateDummyTemplateURLData(
     const std::string& keyword) {
-  auto data = base::MakeUnique<TemplateURLData>();
+  auto data = std::make_unique<TemplateURLData>();
   data->SetShortName(base::UTF8ToUTF16(keyword + "name"));
   data->SetKeyword(base::UTF8ToUTF16(keyword));
   data->SetURL(std::string("http://") + keyword + "foo/{searchTerms}");
diff --git a/components/search_engines/search_host_to_urls_map_unittest.cc b/components/search_engines/search_host_to_urls_map_unittest.cc
index 18916fe..301a89b 100644
--- a/components/search_engines/search_host_to_urls_map_unittest.cc
+++ b/components/search_engines/search_host_to_urls_map_unittest.cc
@@ -9,7 +9,6 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "components/search_engines/search_terms_data.h"
 #include "components/search_engines/template_url.h"
 #include "components/search_engines/template_url_service.h"
@@ -37,9 +36,9 @@
   host_ = "www.unittest.com";
   TemplateURLData data;
   data.SetURL("http://" + host_ + "/path1");
-  template_urls_.push_back(base::MakeUnique<TemplateURL>(data));
+  template_urls_.push_back(std::make_unique<TemplateURL>(data));
   data.SetURL("http://" + host_ + "/path2");
-  template_urls_.push_back(base::MakeUnique<TemplateURL>(data));
+  template_urls_.push_back(std::make_unique<TemplateURL>(data));
 
   provider_map_.reset(new SearchHostToURLsMap);
   provider_map_->Init(template_urls_, SearchTermsData());
diff --git a/components/search_engines/template_url.cc b/components/search_engines/template_url.cc
index bf15ae03..3cdecf9c 100644
--- a/components/search_engines/template_url.cc
+++ b/components/search_engines/template_url.cc
@@ -1176,7 +1176,7 @@
   // Omnibox keywords may not be set as default.
   DCHECK(!wants_to_be_default_engine || type != OMNIBOX_API_EXTENSION) << type;
   DCHECK_EQ(kInvalidTemplateURLID, data.id);
-  extension_info_ = base::MakeUnique<AssociatedExtensionInfo>(
+  extension_info_ = std::make_unique<AssociatedExtensionInfo>(
       extension_id, install_time, wants_to_be_default_engine);
 }
 
diff --git a/components/search_engines/template_url_data_util.cc b/components/search_engines/template_url_data_util.cc
index f283cce..91bdafe 100644
--- a/components/search_engines/template_url_data_util.cc
+++ b/components/search_engines/template_url_data_util.cc
@@ -6,7 +6,6 @@
 
 #include <string>
 
-#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
@@ -27,7 +26,7 @@
   if (search_url.empty() || keyword.empty() || short_name.empty())
     return std::unique_ptr<TemplateURLData>();
 
-  auto result = base::MakeUnique<TemplateURLData>();
+  auto result = std::make_unique<TemplateURLData>();
   result->SetKeyword(keyword);
   result->SetURL(search_url);
 
@@ -114,7 +113,7 @@
 
 std::unique_ptr<base::DictionaryValue> TemplateURLDataToDictionary(
     const TemplateURLData& data) {
-  auto url_dict = base::MakeUnique<base::DictionaryValue>();
+  auto url_dict = std::make_unique<base::DictionaryValue>();
   url_dict->SetString(DefaultSearchManager::kID, base::Int64ToString(data.id));
   url_dict->SetString(DefaultSearchManager::kShortName, data.short_name());
   url_dict->SetString(DefaultSearchManager::kKeyword, data.keyword());
@@ -156,14 +155,14 @@
       base::Int64ToString(data.last_visited.ToInternalValue()));
   url_dict->SetInteger(DefaultSearchManager::kUsageCount, data.usage_count);
 
-  auto alternate_urls = base::MakeUnique<base::ListValue>();
+  auto alternate_urls = std::make_unique<base::ListValue>();
   for (const auto& alternate_url : data.alternate_urls)
     alternate_urls->AppendString(alternate_url);
 
   url_dict->Set(DefaultSearchManager::kAlternateURLs,
                 std::move(alternate_urls));
 
-  auto encodings = base::MakeUnique<base::ListValue>();
+  auto encodings = std::make_unique<base::ListValue>();
   for (const auto& input_encoding : data.input_encodings)
     encodings->AppendString(input_encoding);
   url_dict->Set(DefaultSearchManager::kInputEncodings, std::move(encodings));
@@ -181,7 +180,7 @@
       alternate_urls.AppendString(std::string(engine.alternate_urls[i]));
   }
 
-  return base::MakeUnique<TemplateURLData>(
+  return std::make_unique<TemplateURLData>(
       base::WideToUTF16(engine.name), base::WideToUTF16(engine.keyword),
       engine.search_url, engine.suggest_url, engine.image_url,
       engine.new_tab_url, engine.contextual_search_url, engine.logo_url,
@@ -227,7 +226,7 @@
     engine.GetString("suggest_url_post_params", &suggest_url_post_params);
     engine.GetString("image_url_post_params", &image_url_post_params);
     engine.GetList("alternate_urls", &alternate_urls);
-    return base::MakeUnique<TemplateURLData>(
+    return std::make_unique<TemplateURLData>(
         name, keyword, search_url, suggest_url, image_url, new_tab_url,
         contextual_search_url, logo_url, doodle_url, search_url_post_params,
         suggest_url_post_params, image_url_post_params, favicon_url, encoding,
diff --git a/components/search_engines/template_url_fetcher.cc b/components/search_engines/template_url_fetcher.cc
index 5c1ce91..a48af4c9 100644
--- a/components/search_engines/template_url_fetcher.cc
+++ b/components/search_engines/template_url_fetcher.cc
@@ -5,7 +5,6 @@
 #include "components/search_engines/template_url_fetcher.h"
 
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
@@ -201,7 +200,7 @@
 
   // Mark the keyword as replaceable so it can be removed if necessary.
   data.safe_for_autoreplace = true;
-  model->Add(base::MakeUnique<TemplateURL>(data));
+  model->Add(std::make_unique<TemplateURL>(data));
 
   fetcher_->RequestCompleted(this);
   // WARNING: RequestCompleted deletes us.
@@ -246,7 +245,7 @@
       return;
   }
 
-  requests_.push_back(base::MakeUnique<RequestDelegate>(
+  requests_.push_back(std::make_unique<RequestDelegate>(
       this, keyword, osdd_url, favicon_url, url_fetcher_customize_callback));
 }
 
diff --git a/components/search_engines/template_url_parser.cc b/components/search_engines/template_url_parser.cc
index c51fd6c..08c56f8b 100644
--- a/components/search_engines/template_url_parser.cc
+++ b/components/search_engines/template_url_parser.cc
@@ -13,7 +13,6 @@
 
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -328,7 +327,7 @@
 
   // Bail if the search URL is empty or if either TemplateURLRef is invalid.
   std::unique_ptr<TemplateURL> template_url =
-      base::MakeUnique<TemplateURL>(data_);
+      std::make_unique<TemplateURL>(data_);
   if (template_url->url().empty() ||
       !template_url->url_ref().IsValid(search_terms_data) ||
       (!template_url->suggestions_url().empty() &&
diff --git a/components/search_engines/template_url_prepopulate_data.cc b/components/search_engines/template_url_prepopulate_data.cc
index 6be17ee..0c686f6e 100644
--- a/components/search_engines/template_url_prepopulate_data.cc
+++ b/components/search_engines/template_url_prepopulate_data.cc
@@ -26,6 +26,7 @@
 #include "url/gurl.h"
 
 #if defined(OS_WIN)
+#include <windows.h>
 #undef IN  // On Windows, windef.h defines this, which screws up "India" cases.
 #elif defined(OS_MACOSX)
 #include "base/mac/scoped_cftyperef.h"
diff --git a/components/search_engines/template_url_prepopulate_data_unittest.cc b/components/search_engines/template_url_prepopulate_data_unittest.cc
index 3690b5bf..27de40b7 100644
--- a/components/search_engines/template_url_prepopulate_data_unittest.cc
+++ b/components/search_engines/template_url_prepopulate_data_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/command_line.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
-#include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "components/google/core/browser/google_switches.h"
@@ -123,8 +122,8 @@
 // override the built-in ones.
 TEST_F(TemplateURLPrepopulateDataTest, ProvidersFromPrefs) {
   prefs_.SetUserPref(prefs::kSearchProviderOverridesVersion,
-                     base::MakeUnique<base::Value>(1));
-  auto overrides = base::MakeUnique<base::ListValue>();
+                     std::make_unique<base::Value>(1));
+  auto overrides = std::make_unique<base::ListValue>();
   std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
   // Set only the minimal required settings for a search provider configuration.
   entry->SetString("name", "foo");
@@ -159,10 +158,10 @@
 
   // Test the optional settings too.
   entry->SetString("suggest_url", "http://foo.com/suggest?q={searchTerms}");
-  auto alternate_urls = base::MakeUnique<base::ListValue>();
+  auto alternate_urls = std::make_unique<base::ListValue>();
   alternate_urls->AppendString("http://foo.com/alternate?q={searchTerms}");
   entry->Set("alternate_urls", std::move(alternate_urls));
-  overrides = base::MakeUnique<base::ListValue>();
+  overrides = std::make_unique<base::ListValue>();
   overrides->Append(entry->CreateDeepCopy());
   prefs_.SetUserPref(prefs::kSearchProviderOverrides, std::move(overrides));
 
@@ -183,7 +182,7 @@
 
   // Test that subsequent providers are loaded even if an intermediate
   // provider has an incomplete configuration.
-  overrides = base::MakeUnique<base::ListValue>();
+  overrides = std::make_unique<base::ListValue>();
   overrides->Append(entry->CreateDeepCopy());
   entry->SetInteger("id", 1002);
   entry->SetString("name", "bar");
@@ -205,8 +204,8 @@
 
 TEST_F(TemplateURLPrepopulateDataTest, ClearProvidersFromPrefs) {
   prefs_.SetUserPref(prefs::kSearchProviderOverridesVersion,
-                     base::MakeUnique<base::Value>(1));
-  auto overrides = base::MakeUnique<base::ListValue>();
+                     std::make_unique<base::Value>(1));
+  auto overrides = std::make_unique<base::ListValue>();
   std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
   // Set only the minimal required settings for a search provider configuration.
   entry->SetString("name", "foo");
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc
index fd94cad..c85d04d 100644
--- a/components/search_engines/template_url_service.cc
+++ b/components/search_engines/template_url_service.cc
@@ -14,7 +14,6 @@
 #include "base/debug/crash_logging.h"
 #include "base/format_macros.h"
 #include "base/guid.h"
-#include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
@@ -509,7 +508,7 @@
   data.SetShortName(base::UTF8ToUTF16(extension_name));
   data.SetKeyword(base::UTF8ToUTF16(keyword));
   data.SetURL(template_url_string);
-  Add(base::MakeUnique<TemplateURL>(data, TemplateURL::OMNIBOX_API_EXTENSION,
+  Add(std::make_unique<TemplateURL>(data, TemplateURL::OMNIBOX_API_EXTENSION,
                                     extension_id, extension_install_time,
                                     false));
 }
@@ -630,7 +629,7 @@
            actions.added_engines.begin();
        i < actions.added_engines.end();
        ++i) {
-    AddNoNotify(base::MakeUnique<TemplateURL>(*i), true);
+    AddNoNotify(std::make_unique<TemplateURL>(*i), true);
   }
 
   base::AutoReset<DefaultSearchChangeOrigin> change_origin(
@@ -713,7 +712,7 @@
   }
 
   std::unique_ptr<OwnedTemplateURLVector> template_urls =
-      base::MakeUnique<OwnedTemplateURLVector>();
+      std::make_unique<OwnedTemplateURLVector>();
   int new_resource_keyword_version = 0;
   {
     GetSearchProvidersUsingKeywordResult(
@@ -921,7 +920,7 @@
       TemplateURLData data(turl->data());
       data.id = kInvalidTemplateURLID;
       std::unique_ptr<TemplateURL> added_ptr =
-          base::MakeUnique<TemplateURL>(data);
+          std::make_unique<TemplateURL>(data);
       TemplateURL* added = added_ptr.get();
       if (AddNoNotify(std::move(added_ptr), true)) {
         should_notify = true;
@@ -1328,7 +1327,7 @@
       data.SetShortName(base::UTF8ToUTF16(initializers[i].content));
       data.SetKeyword(base::UTF8ToUTF16(initializers[i].keyword));
       data.SetURL(initializers[i].url);
-      AddNoNotify(base::MakeUnique<TemplateURL>(data), true);
+      AddNoNotify(std::make_unique<TemplateURL>(data), true);
 
       // Set the first provided identifier to be the default.
       if (i == 0)
@@ -1810,7 +1809,7 @@
             ? TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION
             : TemplateURL::NORMAL;
     initial_default_search_provider_ =
-        data ? base::MakeUnique<TemplateURL>(*data, initial_engine_type)
+        data ? std::make_unique<TemplateURL>(*data, initial_engine_type)
              : nullptr;
     default_search_provider_source_ = source;
     return changed;
@@ -1868,7 +1867,7 @@
       // (2) If the user deleted the pre-populated default and we subsequently
       // lost their user-selected value.
       default_search_provider_ =
-          AddNoNotify(base::MakeUnique<TemplateURL>(*data), true);
+          AddNoNotify(std::make_unique<TemplateURL>(*data), true);
     }
   } else if (source == DefaultSearchManager::FROM_USER) {
     default_search_provider_ = GetTemplateURLForGUID(data->sync_guid);
@@ -1882,7 +1881,7 @@
     } else {
       new_data.id = kInvalidTemplateURLID;
       default_search_provider_ =
-          AddNoNotify(base::MakeUnique<TemplateURL>(new_data), true);
+          AddNoNotify(std::make_unique<TemplateURL>(new_data), true);
     }
     if (default_search_provider_ && prefs_) {
       prefs_->SetString(prefs::kSyncedDefaultSearchProviderGUID,
@@ -2064,7 +2063,7 @@
       new_data.sync_guid = base::GenerateGUID();
     new_data.created_by_policy = true;
     std::unique_ptr<TemplateURL> new_dse_ptr =
-        base::MakeUnique<TemplateURL>(new_data);
+        std::make_unique<TemplateURL>(new_data);
     TemplateURL* new_dse = new_dse_ptr.get();
     if (AddNoNotify(std::move(new_dse_ptr), true))
       default_search_provider_ = new_dse;
@@ -2269,7 +2268,7 @@
     TemplateURLData data(sync_turl->data());
     data.id = kInvalidTemplateURLID;
     std::unique_ptr<TemplateURL> added_ptr =
-        base::MakeUnique<TemplateURL>(data);
+        std::make_unique<TemplateURL>(data);
     TemplateURL* added = added_ptr.get();
     base::AutoReset<DefaultSearchChangeOrigin> change_origin(
         &dsp_change_origin_, DSP_CHANGE_SYNC_ADD);
diff --git a/components/search_engines/template_url_service_util_unittest.cc b/components/search_engines/template_url_service_util_unittest.cc
index 4321d56..527d8d57 100644
--- a/components/search_engines/template_url_service_util_unittest.cc
+++ b/components/search_engines/template_url_service_util_unittest.cc
@@ -4,7 +4,8 @@
 
 #include <stddef.h>
 
-#include "base/memory/ptr_util.h"
+#include <memory>
+
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/search_engines/search_terms_data.h"
@@ -33,7 +34,7 @@
     int prepopulate_id,
     const std::string& keyword,
     TemplateURLID id) {
-  return base::MakeUnique<TemplateURL>(
+  return std::make_unique<TemplateURL>(
       *CreatePrepopulateTemplateURLData(prepopulate_id, keyword, id));
 }
 
diff --git a/components/search_engines/util.cc b/components/search_engines/util.cc
index 60ab571..35b976aa 100644
--- a/components/search_engines/util.cc
+++ b/components/search_engines/util.cc
@@ -14,7 +14,6 @@
 #include <vector>
 
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/time/time.h"
 #include "components/prefs/pref_service.h"
 #include "components/search_engines/template_url.h"
@@ -219,12 +218,12 @@
 
     // Replace the entry in |template_urls| with the updated one.
     auto j = FindTemplateURL(template_urls, edited_engine.first);
-    *j = base::MakeUnique<TemplateURL>(data);
+    *j = std::make_unique<TemplateURL>(data);
   }
 
   // Add items.
   for (const auto& added_engine : actions.added_engines)
-    template_urls->push_back(base::MakeUnique<TemplateURL>(added_engine));
+    template_urls->push_back(std::make_unique<TemplateURL>(added_engine));
 }
 
 ActionsFromPrepopulateData CreateActionsFromCurrentPrepopulateData(
@@ -315,7 +314,7 @@
     // search engine sync, since in that case that code will never be reached.
     if (DeDupeEncodings(&keyword.input_encodings) && service)
       service->UpdateKeyword(keyword);
-    template_urls->push_back(base::MakeUnique<TemplateURL>(keyword));
+    template_urls->push_back(std::make_unique<TemplateURL>(keyword));
   }
 
   *new_resource_keyword_version = keyword_result.builtin_keyword_version;
diff --git a/components/security_state/content/content_utils_unittest.cc b/components/security_state/content/content_utils_unittest.cc
index 24b783ca..b544ee1 100644
--- a/components/security_state/content/content_utils_unittest.cc
+++ b/components/security_state/content/content_utils_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/histogram_tester.h"
 #include "components/security_state/core/security_state.h"
-#include "components/security_state/core/switches.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/security_style_explanation.h"
 #include "content/public/browser/security_style_explanations.h"
diff --git a/components/security_state/core/BUILD.gn b/components/security_state/core/BUILD.gn
index 27648f60..38906ad 100644
--- a/components/security_state/core/BUILD.gn
+++ b/components/security_state/core/BUILD.gn
@@ -9,13 +9,13 @@
 
 static_library("core") {
   sources = [
+    "features.cc",
+    "features.h",
     "insecure_input_event_data.h",
     "security_state.cc",
     "security_state.h",
     "security_state_ui.cc",
     "security_state_ui.h",
-    "switches.cc",
-    "switches.h",
   ]
 
   public_deps = [
diff --git a/components/security_state/core/features.cc b/components/security_state/core/features.cc
new file mode 100644
index 0000000..c7fa7c82
--- /dev/null
+++ b/components/security_state/core/features.cc
@@ -0,0 +1,21 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/security_state/core/features.h"
+
+namespace security_state {
+namespace features {
+
+const base::Feature kMarkHttpAsFeature{"MarkHttpAs",
+                                       base::FEATURE_DISABLED_BY_DEFAULT};
+const char kMarkHttpAsFeatureParameterName[] = "treatment";
+const char kMarkHttpAsParameterWarning[] = "warning";
+const char kMarkHttpAsParameterDangerous[] = "dangerous";
+const char kMarkHttpAsParameterWarningAndDangerousOnFormEdits[] =
+    "warning-and-dangerous-on-form-edits";
+const char kMarkHttpAsParameterWarningAndDangerousOnPasswordsAndCreditCards[] =
+    "warning-and-dangerous-on-passwords-and-credit-cards";
+
+}  // namespace features
+}  // namespace security_state
diff --git a/components/security_state/core/features.h b/components/security_state/core/features.h
new file mode 100644
index 0000000..4a0e4b78f
--- /dev/null
+++ b/components/security_state/core/features.h
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SECURITY_STATE_FEATURES_H_
+#define COMPONENTS_SECURITY_STATE_FEATURES_H_
+
+#include "base/feature_list.h"
+
+namespace security_state {
+namespace features {
+
+// This feature enables more aggressive warnings for nonsecure http:// pages.
+// The exact warning treatment is dependent on the parameter 'treatment' which
+// can have the following values:
+// - 'warning': Show a Not Secure warning on all http:// pages
+// - 'dangerous': Treat all http:// pages as actively dangerous
+// - 'warning-and-dangerous-on-form-edits': Show a Not Secure warning on all
+//   http:// pages, and treat them as actively dangerous when the user edits
+//   form fields
+// - 'warning-and-dangerous-on-passwords-and-credit-cards': Show a Not Secure
+//   warning on all http:// pages, and treat them as actively dangerous when
+//   there is a sensitive field
+extern const base::Feature kMarkHttpAsFeature;
+
+// The parameter name which controls the warning treatment.
+extern const char kMarkHttpAsFeatureParameterName[];
+
+// The different parameter values, described above.
+extern const char kMarkHttpAsParameterWarning[];
+extern const char kMarkHttpAsParameterDangerous[];
+extern const char kMarkHttpAsParameterWarningAndDangerousOnFormEdits[];
+extern const char
+    kMarkHttpAsParameterWarningAndDangerousOnPasswordsAndCreditCards[];
+
+}  // namespace features
+}  // namespace security_state
+
+#endif  // COMPONENTS_SECURITY_STATE_FEATURES_H_
diff --git a/components/security_state/core/security_state.cc b/components/security_state/core/security_state.cc
index d045093..67684ce 100644
--- a/components/security_state/core/security_state.cc
+++ b/components/security_state/core/security_state.cc
@@ -9,8 +9,9 @@
 
 #include "base/command_line.h"
 #include "base/metrics/field_trial.h"
+#include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_macros.h"
-#include "components/security_state/core/switches.h"
+#include "components/security_state/core/features.h"
 #include "net/ssl/ssl_cipher_suite_names.h"
 #include "net/ssl/ssl_connection_status_flags.h"
 
@@ -18,68 +19,67 @@
 
 namespace {
 
-// These values are written to logs. New enum values can be added, but existing
-// enums must never be renumbered or deleted and reused.
-enum MarkHttpStatus {
-  NEUTRAL = 0,  // Deprecated
-  NON_SECURE = 1,
-  HTTP_SHOW_WARNING_ON_SENSITIVE_FIELDS = 2,  // Deprecated as of Chrome 64
-  NON_SECURE_AFTER_EDITING = 3,               // Deprecated as of Chrome 64
-  NON_SECURE_WHILE_INCOGNITO = 4,             // Deprecated as of Chrome 64
-  NON_SECURE_WHILE_INCOGNITO_OR_EDITING = 5,
-  LAST_STATUS
-};
-
-// If |switch_or_field_trial_group| corresponds to a valid
-// MarkHttpAs setting, sets |*level| and |*histogram_status| to the
-// appropriate values and returns true. Otherwise, returns false.
-bool GetSecurityLevelAndHistogramValueForNonSecureFieldTrial(
-    std::string switch_or_field_trial_group,
+// For nonsecure pages, sets |security_level| in |*security_info| based on the
+// provided information and the kMarkHttpAsFeature field trial. Also sets the
+// explanatory fields |incognito_downgraded_security_level| and
+// |field_edit_downgraded_security_level|.
+void SetSecurityLevelAndRelatedFieldsForNonSecureFieldTrial(
     bool is_incognito,
+    bool is_error_page,
     const InsecureInputEventData& input_events,
-    SecurityLevel* level,
-    MarkHttpStatus* mark_http_as) {
-  if (switch_or_field_trial_group == switches::kMarkHttpAsDangerous) {
-    *mark_http_as = NON_SECURE;
-    *level = DANGEROUS;
-    return true;
-  }
+    SecurityInfo* security_info) {
+  if (base::FeatureList::IsEnabled(features::kMarkHttpAsFeature)) {
+    std::string parameter = base::GetFieldTrialParamValueByFeature(
+        features::kMarkHttpAsFeature,
+        features::kMarkHttpAsFeatureParameterName);
 
-  return false;
-}
+    if (parameter == features::kMarkHttpAsParameterDangerous) {
+      security_info->security_level = DANGEROUS;
+      return;
+    }
 
-SecurityLevel GetSecurityLevelForNonSecureFieldTrial(
-    bool is_incognito,
-    const InsecureInputEventData& input_events,
-    MarkHttpStatus* mark_http_as) {
-  std::string choice =
-      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-          switches::kMarkHttpAs);
-  std::string group = base::FieldTrialList::FindFullName("MarkNonSecureAs");
+    if (parameter == features::kMarkHttpAsParameterWarning) {
+      security_info->security_level = HTTP_SHOW_WARNING;
+      return;
+    }
 
-  const char kEnumeration[] = "SSL.MarkHttpAsStatus";
+    if (parameter ==
+        features::kMarkHttpAsParameterWarningAndDangerousOnFormEdits) {
+      security_info->security_level =
+          input_events.insecure_field_edited ? DANGEROUS : HTTP_SHOW_WARNING;
+      // Do not set |field_edit_downgraded_security_level| here because that
+      // field is for specifically for when the security level was downgraded
+      // from NONE to HTTP_SHOW_WARNING, not from HTTP_SHOW_WARNING to DANGEROUS
+      // as in this case.
+      return;
+    }
 
-  SecurityLevel level = NONE;
-
-  // If the command-line switch is set, then it takes precedence over
-  // the field trial group.
-  if (!GetSecurityLevelAndHistogramValueForNonSecureFieldTrial(
-          choice, is_incognito, input_events, &level, mark_http_as)) {
-    if (!GetSecurityLevelAndHistogramValueForNonSecureFieldTrial(
-            group, is_incognito, input_events, &level, mark_http_as)) {
-      // No command-line switch or field trial is in effect.
-      // Default to warning on incognito or editing or sensitive form fields.
-      *mark_http_as = NON_SECURE_WHILE_INCOGNITO_OR_EDITING;
-      level = (is_incognito || input_events.insecure_field_edited ||
-               input_events.password_field_shown ||
-               input_events.credit_card_field_edited)
-                  ? security_state::HTTP_SHOW_WARNING
-                  : NONE;
+    if (parameter ==
+        features::
+            kMarkHttpAsParameterWarningAndDangerousOnPasswordsAndCreditCards) {
+      security_info->security_level = (input_events.password_field_shown ||
+                                       input_events.credit_card_field_edited)
+                                          ? DANGEROUS
+                                          : HTTP_SHOW_WARNING;
+      return;
     }
   }
 
-  UMA_HISTOGRAM_ENUMERATION(kEnumeration, *mark_http_as, LAST_STATUS);
-  return level;
+  // No warning treatment is configured via field trial. Default to warning on
+  // incognito or editing or sensitive form fields.
+  security_info->security_level =
+      (is_incognito || input_events.insecure_field_edited ||
+       input_events.password_field_shown ||
+       input_events.credit_card_field_edited)
+          ? HTTP_SHOW_WARNING
+          : NONE;
+  security_info->incognito_downgraded_security_level =
+      (is_incognito && !is_error_page &&
+       security_info->security_level == HTTP_SHOW_WARNING);
+
+  security_info->field_edit_downgraded_security_level =
+      (security_info->security_level == HTTP_SHOW_WARNING &&
+       input_events.insecure_field_edited);
 }
 
 ContentStatus GetContentStatus(bool displayed, bool ran) {
@@ -92,23 +92,33 @@
   return CONTENT_STATUS_NONE;
 }
 
-SecurityLevel GetSecurityLevelForRequest(
+// Sets |security_level| in |*security_info| based on the provided information,
+// as well as the explanatory fields |incognito_downgraded_security_level| and
+// |field_edit_downgraded_security_level|.
+void SetSecurityLevelAndRelatedFields(
     const VisibleSecurityState& visible_security_state,
     bool used_policy_installed_certificate,
     const IsOriginSecureCallback& is_origin_secure_callback,
     bool sha1_in_chain,
     ContentStatus mixed_content_status,
     ContentStatus content_with_cert_errors_status,
-    MarkHttpStatus* mark_http_as) {
+    SecurityInfo* security_info) {
   DCHECK(visible_security_state.connection_info_initialized ||
          visible_security_state.malicious_content_status !=
              MALICIOUS_CONTENT_STATUS_NONE);
 
+  // Initialize the related fields; they'll be set to true in
+  // SetSecurityLevelAndRelatedFieldsForNonSecureFieldTrial() below if
+  // necessary.
+  security_info->incognito_downgraded_security_level = false;
+  security_info->field_edit_downgraded_security_level = false;
+
   // Override the connection security information if the website failed the
   // browser's malware checks.
   if (visible_security_state.malicious_content_status !=
       MALICIOUS_CONTENT_STATUS_NONE) {
-    return DANGEROUS;
+    security_info->security_level = DANGEROUS;
+    return;
   }
 
   const GURL url = visible_security_state.url;
@@ -120,7 +130,8 @@
   if (is_cryptographic_with_certificate &&
       net::IsCertStatusError(visible_security_state.cert_status) &&
       !net::IsCertStatusMinorError(visible_security_state.cert_status)) {
-    return DANGEROUS;
+    security_info->security_level = DANGEROUS;
+    return;
   }
 
   // data: URLs don't define a secure context, and are a vector for spoofing.
@@ -129,8 +140,10 @@
   //
   // Display a "Not secure" badge for all these URLs, regardless of whether
   // they show a password or credit card field.
-  if (url.SchemeIs(url::kDataScheme) || url.SchemeIs(url::kFtpScheme))
-    return SecurityLevel::HTTP_SHOW_WARNING;
+  if (url.SchemeIs(url::kDataScheme) || url.SchemeIs(url::kFtpScheme)) {
+    security_info->security_level = SecurityLevel::HTTP_SHOW_WARNING;
+    return;
+  }
 
   // Choose the appropriate security level for requests to HTTP and remaining
   // pseudo URLs (blob:, filesystem:). filesystem: is a standard scheme so does
@@ -140,11 +153,14 @@
     if (!visible_security_state.is_error_page &&
         !is_origin_secure_callback.Run(url) &&
         (url.IsStandard() || url.SchemeIs(url::kBlobScheme))) {
-      return GetSecurityLevelForNonSecureFieldTrial(
+      SetSecurityLevelAndRelatedFieldsForNonSecureFieldTrial(
           visible_security_state.is_incognito,
-          visible_security_state.insecure_input_events, mark_http_as);
+          visible_security_state.is_error_page,
+          visible_security_state.insecure_input_events, security_info);
+      return;
     }
-    return NONE;
+    security_info->security_level = NONE;
+    return;
   }
 
   // Downgrade the security level for active insecure subresources.
@@ -152,14 +168,17 @@
       mixed_content_status == CONTENT_STATUS_DISPLAYED_AND_RAN ||
       content_with_cert_errors_status == CONTENT_STATUS_RAN ||
       content_with_cert_errors_status == CONTENT_STATUS_DISPLAYED_AND_RAN) {
-    return kRanInsecureContentLevel;
+    security_info->security_level = kRanInsecureContentLevel;
+    return;
   }
 
   // In most cases, SHA1 use is treated as a certificate error, in which case
   // DANGEROUS will have been returned above. If SHA1 was permitted by policy,
   // downgrade the security level to Neutral.
-  if (sha1_in_chain)
-    return NONE;
+  if (sha1_in_chain) {
+    security_info->security_level = NONE;
+    return;
+  }
 
   // Active mixed content is handled above.
   DCHECK_NE(CONTENT_STATUS_RAN, mixed_content_status);
@@ -168,30 +187,36 @@
   if (visible_security_state.contained_mixed_form ||
       mixed_content_status == CONTENT_STATUS_DISPLAYED ||
       content_with_cert_errors_status == CONTENT_STATUS_DISPLAYED) {
-    return kDisplayedInsecureContentLevel;
+    security_info->security_level = kDisplayedInsecureContentLevel;
+    return;
   }
 
   if (net::IsCertStatusError(visible_security_state.cert_status)) {
     // Major cert errors are handled above.
     DCHECK(net::IsCertStatusMinorError(visible_security_state.cert_status));
-    return NONE;
+    security_info->security_level = NONE;
+    return;
   }
 
   if (visible_security_state.is_view_source) {
-    return NONE;
+    security_info->security_level = NONE;
+    return;
   }
 
   // Any prior observation of a policy-installed cert is a strong indicator
   // of a MITM being present (the enterprise), so a "secure-but-inspected"
   // security level is returned.
-  if (used_policy_installed_certificate)
-    return SECURE_WITH_POLICY_INSTALLED_CERT;
+  if (used_policy_installed_certificate) {
+    security_info->security_level = SECURE_WITH_POLICY_INSTALLED_CERT;
+    return;
+  }
 
   if ((visible_security_state.cert_status & net::CERT_STATUS_IS_EV) &&
       visible_security_state.certificate) {
-    return EV_SECURE;
+    security_info->security_level = EV_SECURE;
+    return;
   }
-  return SECURE;
+  security_info->security_level = SECURE;
 }
 
 void SecurityInfoForRequest(
@@ -199,21 +224,16 @@
     bool used_policy_installed_certificate,
     const IsOriginSecureCallback& is_origin_secure_callback,
     SecurityInfo* security_info) {
-  // |mark_http_as| will be updated to the value specified by the
-  // field trial or command-line in |GetSecurityLevelForNonSecureFieldTrial|
-  // if that function is reached.
-  MarkHttpStatus mark_http_as = NON_SECURE_WHILE_INCOGNITO_OR_EDITING;
-
   if (!visible_security_state.connection_info_initialized) {
     *security_info = SecurityInfo();
     security_info->malicious_content_status =
         visible_security_state.malicious_content_status;
     if (security_info->malicious_content_status !=
         MALICIOUS_CONTENT_STATUS_NONE) {
-      security_info->security_level = GetSecurityLevelForRequest(
+      SetSecurityLevelAndRelatedFields(
           visible_security_state, used_policy_installed_certificate,
           is_origin_secure_callback, false, CONTENT_STATUS_UNKNOWN,
-          CONTENT_STATUS_UNKNOWN, &mark_http_as);
+          CONTENT_STATUS_UNKNOWN, security_info);
     }
     return;
   }
@@ -248,22 +268,11 @@
   security_info->contained_mixed_form =
       visible_security_state.contained_mixed_form;
 
-  security_info->security_level = GetSecurityLevelForRequest(
+  SetSecurityLevelAndRelatedFields(
       visible_security_state, used_policy_installed_certificate,
       is_origin_secure_callback, security_info->sha1_in_chain,
       security_info->mixed_content_status,
-      security_info->content_with_cert_errors_status, &mark_http_as);
-
-  security_info->incognito_downgraded_security_level =
-      (visible_security_state.is_incognito &&
-       !visible_security_state.is_error_page &&
-       security_info->security_level == HTTP_SHOW_WARNING &&
-       (mark_http_as == NON_SECURE_WHILE_INCOGNITO_OR_EDITING));
-
-  security_info->field_edit_downgraded_security_level =
-      (security_info->security_level == HTTP_SHOW_WARNING &&
-       visible_security_state.insecure_input_events.insecure_field_edited &&
-       (mark_http_as == NON_SECURE_WHILE_INCOGNITO_OR_EDITING));
+      security_info->content_with_cert_errors_status, security_info);
 
   security_info->insecure_input_events =
       visible_security_state.insecure_input_events;
@@ -336,10 +345,9 @@
          (net::IsLocalhost(url.HostNoBracketsPiece()) || url.SchemeIsFile());
 }
 
-bool IsSslCertificateValid(security_state::SecurityLevel security_level) {
-  return security_level == security_state::SECURE ||
-         security_level == security_state::EV_SECURE ||
-         security_level == security_state::SECURE_WITH_POLICY_INSTALLED_CERT;
+bool IsSslCertificateValid(SecurityLevel security_level) {
+  return security_level == SECURE || security_level == EV_SECURE ||
+         security_level == SECURE_WITH_POLICY_INSTALLED_CERT;
 }
 
 }  // namespace security_state
diff --git a/components/security_state/core/security_state_unittest.cc b/components/security_state/core/security_state_unittest.cc
index cf4ad1b..511670e61 100644
--- a/components/security_state/core/security_state_unittest.cc
+++ b/components/security_state/core/security_state_unittest.cc
@@ -11,9 +11,9 @@
 #include "base/command_line.h"
 #include "base/memory/ptr_util.h"
 #include "base/test/histogram_tester.h"
-#include "base/test/scoped_command_line.h"
+#include "base/test/scoped_feature_list.h"
+#include "components/security_state/core/features.h"
 #include "components/security_state/core/insecure_input_event_data.h"
-#include "components/security_state/core/switches.h"
 #include "net/cert/x509_certificate.h"
 #include "net/ssl/ssl_cipher_suite_names.h"
 #include "net/ssl/ssl_connection_status_flags.h"
@@ -453,10 +453,11 @@
 
   {
     // Disable the "non-secure-while-incognito" configuration.
-    base::test::ScopedCommandLine scoped_command_line;
-    scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII(
-        security_state::switches::kMarkHttpAs,
-        security_state::switches::kMarkHttpAsDangerous);
+    base::test::ScopedFeatureList scoped_feature_list;
+    scoped_feature_list.InitAndEnableFeatureWithParameters(
+        security_state::features::kMarkHttpAsFeature,
+        {{security_state::features::kMarkHttpAsFeatureParameterName,
+          security_state::features::kMarkHttpAsParameterDangerous}});
     helper.set_is_incognito(false);
     helper.GetSecurityInfo(&security_info);
     EXPECT_FALSE(security_info.incognito_downgraded_security_level);
@@ -467,72 +468,6 @@
   }
 }
 
-// Tests that SSL.MarkHttpAsStatus histogram is updated when security state is
-// computed for a page.
-TEST(SecurityStateTest, MarkHttpAsStatusHistogram) {
-  const char* kHistogramName = "SSL.MarkHttpAsStatus";
-  base::HistogramTester histograms;
-  TestSecurityStateHelper helper;
-  helper.SetUrl(GURL(kHttpUrl));
-
-  // Ensure histogram recorded correctly when a non-secure password input is
-  // found on the page.
-  helper.set_password_field_shown(true);
-  SecurityInfo security_info;
-  histograms.ExpectTotalCount(kHistogramName, 0);
-  helper.GetSecurityInfo(&security_info);
-  histograms.ExpectUniqueSample(
-      kHistogramName, 5 /* NON_SECURE_WHILE_INCOGNITO_OR_EDITING */, 1);
-
-  // Ensure histogram recorded correctly even without a password input.
-  helper.set_password_field_shown(false);
-  helper.GetSecurityInfo(&security_info);
-  histograms.ExpectUniqueSample(
-      kHistogramName, 5 /* NON_SECURE_WHILE_INCOGNITO_OR_EDITING */, 2);
-
-  // Ensure histogram recorded correctly when the Incognito flag is present.
-  helper.set_is_incognito(true);
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_TRUE(security_info.incognito_downgraded_security_level);
-  histograms.ExpectUniqueSample(
-      kHistogramName, 5 /* NON_SECURE_WHILE_INCOGNITO_OR_EDITING */, 3);
-
-  // Ensure histogram recorded correctly when the Insecure Field Edit flag
-  // is set.
-  helper.set_is_incognito(false);
-  helper.set_insecure_field_edit(true);
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_FALSE(security_info.incognito_downgraded_security_level);
-  histograms.ExpectUniqueSample(
-      kHistogramName, 5 /* NON_SECURE_WHILE_INCOGNITO_OR_EDITING */, 4);
-
-  // Ensure histogram recorded correctly even when neither flag is set.
-  helper.set_is_incognito(false);
-  helper.set_insecure_field_edit(false);
-  helper.GetSecurityInfo(&security_info);
-  EXPECT_FALSE(security_info.incognito_downgraded_security_level);
-  histograms.ExpectUniqueSample(
-      kHistogramName, 5 /* NON_SECURE_WHILE_INCOGNITO_OR_EDITING */, 5);
-
-  {
-    // Test the "dangerous" configuration.
-    base::test::ScopedCommandLine scoped_command_line;
-    scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII(
-        security_state::switches::kMarkHttpAs,
-        security_state::switches::kMarkHttpAsDangerous);
-
-    base::HistogramTester histograms;
-    TestSecurityStateHelper helper;
-    helper.SetUrl(GURL(kHttpUrl));
-
-    // Ensure histogram recorded correctly.
-    SecurityInfo security_info;
-    histograms.ExpectTotalCount(kHistogramName, 0);
-    helper.GetSecurityInfo(&security_info);
-    histograms.ExpectUniqueSample(kHistogramName, 1 /* NON_SECURE */, 1);
-  }
-}
-
 TEST(SecurityStateTest, DetectSubjectAltName) {
   TestSecurityStateHelper helper;
 
@@ -658,10 +593,11 @@
 
   {
     // Test the "dangerous" configuration.
-    base::test::ScopedCommandLine scoped_command_line;
-    scoped_command_line.GetProcessCommandLine()->AppendSwitchASCII(
-        security_state::switches::kMarkHttpAs,
-        security_state::switches::kMarkHttpAsDangerous);
+    base::test::ScopedFeatureList scoped_feature_list;
+    scoped_feature_list.InitAndEnableFeatureWithParameters(
+        security_state::features::kMarkHttpAsFeature,
+        {{security_state::features::kMarkHttpAsFeatureParameterName,
+          security_state::features::kMarkHttpAsParameterDangerous}});
 
     helper.GetSecurityInfo(&security_info);
     EXPECT_TRUE(security_info.insecure_input_events.insecure_field_edited);
@@ -722,4 +658,122 @@
   EXPECT_TRUE(security_info.incognito_downgraded_security_level);
 }
 
+// Tests that HTTP_SHOW_WARNING is set when the 'warning' field trial
+// configuration is enabled.
+TEST(SecurityStateTest, AlwaysShowWarning) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeatureWithParameters(
+      security_state::features::kMarkHttpAsFeature,
+      {{security_state::features::kMarkHttpAsFeatureParameterName,
+        security_state::features::kMarkHttpAsParameterWarning}});
+
+  TestSecurityStateHelper helper;
+  helper.SetUrl(GURL(kHttpUrl));
+
+  {
+    SecurityInfo security_info;
+    helper.GetSecurityInfo(&security_info);
+    EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
+  }
+
+  {
+    // Use a fresh SecurityInfo to make sure to check the output of this
+    // GetSecurityInfo() call, not the previous one (e.g. to catch a
+    // hypothetical bug where GetSecurityInfo() doesn't set a |security_level|).
+    SecurityInfo security_info;
+    helper.set_insecure_field_edit(true);
+    helper.GetSecurityInfo(&security_info);
+    EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
+  }
+
+  {
+    SecurityInfo security_info;
+    helper.set_insecure_field_edit(true);
+    helper.set_password_field_shown(true);
+    helper.GetSecurityInfo(&security_info);
+    EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
+  }
+}
+
+// Tests that HTTP_SHOW_WARNING is set on normal http pages but DANGEROUS on
+// form edits when the 'warning-and-dangerous-on-form-edits' field trial
+// configuration is enabled.
+TEST(SecurityStateTest, WarningAndDangerousOnFormEdits) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeatureWithParameters(
+      security_state::features::kMarkHttpAsFeature,
+      {{security_state::features::kMarkHttpAsFeatureParameterName,
+        security_state::features::
+            kMarkHttpAsParameterWarningAndDangerousOnFormEdits}});
+
+  TestSecurityStateHelper helper;
+  helper.SetUrl(GURL(kHttpUrl));
+
+  {
+    SecurityInfo security_info;
+    helper.GetSecurityInfo(&security_info);
+    EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
+  }
+
+  {
+    SecurityInfo security_info;
+    helper.set_insecure_field_edit(true);
+    helper.GetSecurityInfo(&security_info);
+    EXPECT_EQ(security_state::DANGEROUS, security_info.security_level);
+  }
+
+  {
+    SecurityInfo security_info;
+    helper.set_insecure_field_edit(false);
+    helper.set_password_field_shown(true);
+    helper.GetSecurityInfo(&security_info);
+    EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
+  }
+}
+
+// Tests that HTTP_SHOW_WARNING is set on normal http pages but DANGEROUS on
+// sensitive fields when the
+// 'warning-and-dangerous-on-passwords-and-credit-cards' field trial
+// configuration is enabled.
+TEST(SecurityStateTest, WarningAndDangerousOnSensitiveFields) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeatureWithParameters(
+      security_state::features::kMarkHttpAsFeature,
+      {{security_state::features::kMarkHttpAsFeatureParameterName,
+        security_state::features::
+            kMarkHttpAsParameterWarningAndDangerousOnPasswordsAndCreditCards}});
+
+  TestSecurityStateHelper helper;
+  helper.SetUrl(GURL(kHttpUrl));
+
+  {
+    SecurityInfo security_info;
+    helper.GetSecurityInfo(&security_info);
+    EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
+  }
+
+  {
+    SecurityInfo security_info;
+    helper.set_insecure_field_edit(true);
+    helper.GetSecurityInfo(&security_info);
+    EXPECT_EQ(security_state::HTTP_SHOW_WARNING, security_info.security_level);
+  }
+
+  {
+    SecurityInfo security_info;
+    helper.set_insecure_field_edit(false);
+    helper.set_password_field_shown(true);
+    helper.GetSecurityInfo(&security_info);
+    EXPECT_EQ(security_state::DANGEROUS, security_info.security_level);
+  }
+
+  {
+    SecurityInfo security_info;
+    helper.set_password_field_shown(false);
+    helper.set_credit_card_field_edited(true);
+    helper.GetSecurityInfo(&security_info);
+    EXPECT_EQ(security_state::DANGEROUS, security_info.security_level);
+  }
+}
+
 }  // namespace security_state
diff --git a/components/security_state/core/switches.cc b/components/security_state/core/switches.cc
deleted file mode 100644
index cdda1cb0..0000000
--- a/components/security_state/core/switches.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/security_state/core/switches.h"
-
-namespace security_state {
-namespace switches {
-
-// Use to opt-in to marking HTTP as non-secure.
-const char kMarkHttpAs[] = "mark-non-secure-as";
-const char kMarkHttpAsDangerous[] = "non-secure";
-}  // namespace switches
-}  // namespace security_state
diff --git a/components/security_state/core/switches.h b/components/security_state/core/switches.h
deleted file mode 100644
index 4216cd2..0000000
--- a/components/security_state/core/switches.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_SECURITY_STATE_SWITCHES_H_
-#define COMPONENTS_SECURITY_STATE_SWITCHES_H_
-
-namespace security_state {
-namespace switches {
-
-extern const char kMarkHttpAs[];
-extern const char kMarkHttpAsDangerous[];
-}
-}  // namespace security_state
-
-#endif  // COMPONENTS_SECURITY_STATE_SWITCHES_H_
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java
index 8a301678..6ba0455 100644
--- a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java
+++ b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java
@@ -27,7 +27,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
@@ -110,7 +110,7 @@
     /** Use {@link FakeProfileDataSource}. */
     public static final int ENABLE_PROFILE_DATA_SOURCE = 1;
 
-    private final Set<AccountHolder> mAccounts = new HashSet<>();
+    private final Set<AccountHolder> mAccounts = new LinkedHashSet<>();
     private final ObserverList<AccountsChangeObserver> mObservers = new ObserverList<>();
     private boolean mRegisterObserversCalled;
     private FakeProfileDataSource mFakeProfileDataSource;
diff --git a/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java b/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java
index 497fc17..225382d 100644
--- a/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java
+++ b/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java
@@ -15,6 +15,7 @@
 import org.junit.runner.RunWith;
 import org.robolectric.annotation.Config;
 
+import org.chromium.components.signin.AccountManagerDelegateException;
 import org.chromium.components.signin.AccountManagerFacade;
 import org.chromium.components.signin.ProfileDataSource;
 import org.chromium.components.signin.test.util.AccountHolder;
@@ -89,6 +90,25 @@
         });
     }
 
+    @Test
+    @SmallTest
+    public void testGetAccounts() throws AccountManagerDelegateException {
+        Assert.assertArrayEquals(new Account[] {}, mFacade.getGoogleAccounts());
+
+        Account account = addTestAccount("test@gmail.com");
+        Assert.assertArrayEquals(new Account[] {account}, mFacade.getGoogleAccounts());
+
+        Account account2 = addTestAccount("test2@gmail.com");
+        Assert.assertArrayEquals(new Account[] {account, account2}, mFacade.getGoogleAccounts());
+
+        Account account3 = addTestAccount("test3@gmail.com");
+        Assert.assertArrayEquals(
+                new Account[] {account, account2, account3}, mFacade.getGoogleAccounts());
+
+        removeTestAccount(account2);
+        Assert.assertArrayEquals(new Account[] {account, account3}, mFacade.getGoogleAccounts());
+    }
+
     private Account addTestAccount(String accountName) {
         Account account = AccountManagerFacade.createAccountFromName(accountName);
         AccountHolder holder = AccountHolder.builder(account).alwaysAccept(true).build();
@@ -96,4 +116,8 @@
         Assert.assertFalse(AccountManagerFacade.get().isUpdatePending());
         return account;
     }
+
+    private void removeTestAccount(Account account) {
+        mDelegate.removeAccountHolderExplicitly(AccountHolder.builder(account).build());
+    }
 }
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.cc b/components/startup_metric_utils/browser/startup_metric_utils.cc
index 7ac6044..7952fe04 100644
--- a/components/startup_metric_utils/browser/startup_metric_utils.cc
+++ b/components/startup_metric_utils/browser/startup_metric_utils.cc
@@ -29,6 +29,7 @@
 #include "components/version_info/version_info.h"
 
 #if defined(OS_WIN)
+#include <windows.h>
 #include <winternl.h>
 #include "base/win/win_util.h"
 #endif
diff --git a/components/storage_monitor/storage_monitor_win.h b/components/storage_monitor/storage_monitor_win.h
index 2d74f2c..53a170f1 100644
--- a/components/storage_monitor/storage_monitor_win.h
+++ b/components/storage_monitor/storage_monitor_win.h
@@ -11,6 +11,8 @@
 #include "base/memory/ref_counted.h"
 #include "components/storage_monitor/storage_monitor.h"
 
+#include <windows.h>
+
 namespace base {
 class FilePath;
 }
diff --git a/components/storage_monitor/volume_mount_watcher_win.h b/components/storage_monitor/volume_mount_watcher_win.h
index ca164af..c8eafb2 100644
--- a/components/storage_monitor/volume_mount_watcher_win.h
+++ b/components/storage_monitor/volume_mount_watcher_win.h
@@ -19,6 +19,8 @@
 #include "components/storage_monitor/storage_info.h"
 #include "components/storage_monitor/storage_monitor.h"
 
+#include <windows.h>
+
 namespace storage_monitor {
 
 class TestVolumeMountWatcherWin;
diff --git a/components/sync/protocol/proto_enum_conversions.cc b/components/sync/protocol/proto_enum_conversions.cc
index e3271e5..0952e086 100644
--- a/components/sync/protocol/proto_enum_conversions.cc
+++ b/components/sync/protocol/proto_enum_conversions.cc
@@ -319,8 +319,9 @@
 const char* ProtoEnumToString(
     sync_pb::UserEventSpecifics::UserConsent::ConsentStatus status) {
   ASSERT_ENUM_BOUNDS(sync_pb::UserEventSpecifics::UserConsent, ConsentStatus,
-                     REVOKED, GIVEN);
+                     UNSPECIFIED, GIVEN);
   switch (status) {
+    ENUM_CASE(sync_pb::UserEventSpecifics::UserConsent, UNSPECIFIED);
     ENUM_CASE(sync_pb::UserEventSpecifics::UserConsent, REVOKED);
     ENUM_CASE(sync_pb::UserEventSpecifics::UserConsent, GIVEN);
   }
diff --git a/components/sync/protocol/user_event_specifics.proto b/components/sync/protocol/user_event_specifics.proto
index ca68019..8002d27 100644
--- a/components/sync/protocol/user_event_specifics.proto
+++ b/components/sync/protocol/user_event_specifics.proto
@@ -99,8 +99,9 @@
     optional string locale = 4;
     // Was the consent for |feature| given or revoked?
     enum ConsentStatus {
-      REVOKED = 0;
-      GIVEN = 1;
+      UNSPECIFIED = 0;
+      REVOKED = 1;
+      GIVEN = 2;
     }
     optional ConsentStatus status = 5;
   }
diff --git a/components/update_client/updater_state_win.cc b/components/update_client/updater_state_win.cc
index a1660132..9b81183 100644
--- a/components/update_client/updater_state_win.cc
+++ b/components/update_client/updater_state_win.cc
@@ -15,6 +15,8 @@
 #include "base/win/registry.h"
 #include "base/win/win_util.h"
 
+#include <windows.h>
+
 // TODO(sorin): implement this in terms of
 // chrome/installer/util/google_update_settings (crbug.com/615187).
 
diff --git a/components/variations/net/variations_http_headers.cc b/components/variations/net/variations_http_headers.cc
index 50c3429..3eb28d0 100644
--- a/components/variations/net/variations_http_headers.cc
+++ b/components/variations/net/variations_http_headers.cc
@@ -12,6 +12,7 @@
 #include "components/google/core/browser/google_util.h"
 #include "components/variations/variations_http_header_provider.h"
 #include "net/http/http_request_headers.h"
+#include "net/url_request/url_request.h"
 #include "url/gurl.h"
 
 namespace variations {
@@ -118,6 +119,14 @@
   return headers;
 }
 
+void StripVariationHeaderIfNeeded(const GURL& new_location,
+                                  net::URLRequest* request) {
+  if (!internal::ShouldAppendVariationHeaders(new_location)) {
+    for (const std::string& header : GetVariationHeaderNames())
+      request->RemoveRequestHeaderByName(header);
+  }
+}
+
 namespace internal {
 
 // static
diff --git a/components/variations/net/variations_http_headers.h b/components/variations/net/variations_http_headers.h
index 12c626e1..d174788 100644
--- a/components/variations/net/variations_http_headers.h
+++ b/components/variations/net/variations_http_headers.h
@@ -10,6 +10,7 @@
 
 namespace net {
 class HttpRequestHeaders;
+class URLRequest;
 }
 
 class GURL;
@@ -35,6 +36,12 @@
 // Returns the HTTP header names which are added by AppendVariationHeaders().
 std::set<std::string> GetVariationHeaderNames();
 
+// Strips the variation header if |new_location| does not point to a location
+// that should receive it. This is being called by the ChromeNetworkDelegate.
+// Components calling AppendVariationsHeaders() don't need to take care of this.
+void StripVariationHeaderIfNeeded(const GURL& new_location,
+                                  net::URLRequest* request);
+
 namespace internal {
 
 // Checks whether variation headers should be appended to requests to the
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index e9cdb90c..296f2a0 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -60,6 +60,8 @@
     "display/overlay_strategy_underlay_cast.h",
     "display/program_binding.cc",
     "display/program_binding.h",
+    "display/scoped_gpu_memory_buffer_texture.cc",
+    "display/scoped_gpu_memory_buffer_texture.h",
     "display/scoped_render_pass_texture.cc",
     "display/scoped_render_pass_texture.h",
     "display/shader.cc",
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
index 7f47941..67d1e4c 100644
--- a/components/viz/service/display/gl_renderer.cc
+++ b/components/viz/service/display/gl_renderer.cc
@@ -32,7 +32,7 @@
 #include "cc/debug/debug_colors.h"
 #include "cc/paint/render_surface_filters.h"
 #include "cc/raster/scoped_gpu_raster.h"
-#include "cc/resources/resource_pool.h"
+#include "cc/resources/resource.h"
 #include "components/viz/common/display/renderer_settings.h"
 #include "components/viz/common/frame_sinks/copy_output_request.h"
 #include "components/viz/common/gpu/context_provider.h"
@@ -72,6 +72,7 @@
 #include "ui/gfx/color_transform.h"
 #include "ui/gfx/geometry/quad_f.h"
 #include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 #include "ui/gfx/skia_util.h"
 
 using gpu::gles2::GLES2Interface;
@@ -2829,8 +2830,21 @@
     output_frame.sub_buffer_rect = swap_buffer_rect_;
   }
 
+  // Record resources from viz clients that have been shipped as overlays to the
+  // gpu together.
   swapping_overlay_resources_.push_back(std::move(pending_overlay_resources_));
   pending_overlay_resources_.clear();
+  if (settings_->release_overlay_resources_after_gpu_query) {
+    // Record RenderPass textures that have been shipped as overlays to the gpu
+    // together.
+    displayed_overlay_textures_.push_back(
+        std::move(awaiting_swap_overlay_textures_));
+    awaiting_swap_overlay_textures_.clear();
+  } else {
+    // If |displayed_overlay_textures_| is appended to in this case then
+    // SwapBuffersComplete needs to be extended to handle it.
+    DCHECK(awaiting_swap_overlay_textures_.empty());
+  }
 
   output_surface_->SwapBuffers(std::move(output_frame));
 
@@ -2852,23 +2866,46 @@
       }
       swapping_overlay_resources_.pop_front();
     }
-
-    if (!swapped_and_acked_overlay_resources_.empty()) {
-      std::vector<unsigned> textures;
-      textures.reserve(swapped_and_acked_overlay_resources_.size());
-      for (auto& pair : swapped_and_acked_overlay_resources_) {
-        textures.push_back(pair.first);
-      }
-      gl_->ScheduleCALayerInUseQueryCHROMIUM(textures.size(), textures.data());
+    if (!displayed_overlay_textures_.empty()) {
+      for (auto& overlay : displayed_overlay_textures_.front())
+        awaiting_release_overlay_textures_.push_back(std::move(overlay));
+      displayed_overlay_textures_.erase(displayed_overlay_textures_.begin());
     }
-  } else if (swapping_overlay_resources_.size() > 1) {
-    cc::DisplayResourceProvider::ScopedBatchReturnResources returner(
-        resource_provider_);
 
+    size_t query_texture_count = swapped_and_acked_overlay_resources_.size() +
+                                 awaiting_release_overlay_textures_.size();
+    if (query_texture_count) {
+      std::vector<uint32_t> query_texture_ids;
+      query_texture_ids.reserve(query_texture_count);
+
+      for (auto& pair : swapped_and_acked_overlay_resources_)
+        query_texture_ids.push_back(pair.first);
+      for (auto& overlay : awaiting_release_overlay_textures_)
+        query_texture_ids.push_back(overlay->texture.id());
+
+      // We query for *all* outstanding texture ids, even if we previously
+      // queried, as we will not hear back about things becoming available
+      // until after we query again.
+      gl_->ScheduleCALayerInUseQueryCHROMIUM(query_texture_count,
+                                             query_texture_ids.data());
+    }
+  } else {
     // If a query is not needed to release the overlay buffers, we can assume
     // that once a swap buffer has completed we can remove the oldest buffers
-    // from the queue.
-    swapping_overlay_resources_.pop_front();
+    // from the queue, but only once we've swapped another frame afterward.
+    if (swapping_overlay_resources_.size() > 1) {
+      cc::DisplayResourceProvider::ScopedBatchReturnResources returner(
+          resource_provider_);
+      swapping_overlay_resources_.pop_front();
+    }
+    // If |displayed_overlay_textures_| has a non-empty member that means we're
+    // sending RenderPassDrawQuads as an overlay. This is only supported for
+    // CALayers now, where |release_overlay_resources_after_gpu_query| will be
+    // true. In order to support them here, the OverlayTextures would need to
+    // move to |awaiting_release_overlay_textures_| and stay there until the
+    // ResourceFence that was in use for the frame they were submitted is
+    // passed.
+    DCHECK(displayed_overlay_textures_.empty());
   }
 }
 
@@ -2878,8 +2915,29 @@
   cc::DisplayResourceProvider::ScopedBatchReturnResources returner(
       resource_provider_);
   for (const gpu::TextureInUseResponse& response : responses) {
-    if (!response.in_use) {
-      swapped_and_acked_overlay_resources_.erase(response.texture);
+    if (response.in_use)
+      continue;
+
+    // Returned texture ids may be for resources from clients of the
+    // display compositor, in |swapped_and_acked_overlay_resources_|. In that
+    // case we remove the lock from the map, allowing them to be returned to the
+    // client if the resource has been deleted from the DisplayResourceProvider.
+    if (swapped_and_acked_overlay_resources_.erase(response.texture))
+      continue;
+    // If not, then they would be a RenderPass copy texture, which is held in
+    // |awaiting_release_overlay_textures_|. We move it back to the available
+    // texture list to use it for the next frame.
+    auto it = std::find_if(
+        awaiting_release_overlay_textures_.begin(),
+        awaiting_release_overlay_textures_.end(),
+        [&response](const std::unique_ptr<OverlayTexture>& overlay) {
+          return overlay->texture.id() == response.texture;
+        });
+    if (it != awaiting_release_overlay_textures_.end()) {
+      // Mark the OverlayTexture as newly returned to the available set.
+      (*it)->frames_waiting_for_reuse = 0;
+      available_overlay_textures_.push_back(std::move(*it));
+      awaiting_release_overlay_textures_.erase(it);
     }
   }
   color_lut_cache_.Swap();
@@ -3141,16 +3199,24 @@
 }
 
 void GLRenderer::ScheduleCALayers() {
-  if (overlay_resource_pool_) {
-    overlay_resource_pool_->CheckBusyResources();
-  }
+  // The use of OverlayTextures for RenderPasses is only supported on the code
+  // paths for |release_overlay_resources_after_gpu_query| at the moment. See
+  // SwapBuffersComplete for notes on the missing support for other paths. This
+  // method uses ScheduleRenderPassDrawQuad to send RenderPass outputs as
+  // overlays, so it can only be used because this setting is true.
+  if (!settings_->release_overlay_resources_after_gpu_query)
+    return;
 
   scoped_refptr<CALayerOverlaySharedState> shared_state;
   size_t copied_render_pass_count = 0;
+
   for (const CALayerOverlay& ca_layer_overlay :
        current_frame()->ca_layer_overlay_list) {
     if (ca_layer_overlay.rpdq) {
-      ScheduleRenderPassDrawQuad(&ca_layer_overlay);
+      std::unique_ptr<OverlayTexture> overlay_texture =
+          ScheduleRenderPassDrawQuad(&ca_layer_overlay);
+      if (overlay_texture)
+        awaiting_swap_overlay_textures_.push_back(std::move(overlay_texture));
       shared_state = nullptr;
       ++copied_render_pass_count;
       continue;
@@ -3196,12 +3262,7 @@
         ca_layer_overlay.edge_aa_mask, bounds_rect, filter);
   }
 
-  // Take the number of copied render passes in this frame, and use 3 times that
-  // amount as the cache limit.
-  if (overlay_resource_pool_) {
-    overlay_resource_pool_->SetResourceUsageLimits(
-        std::numeric_limits<std::size_t>::max(), copied_render_pass_count * 5);
-  }
+  ReduceAvailableOverlayTextures(awaiting_swap_overlay_textures_);
 }
 
 void GLRenderer::ScheduleDCLayers() {
@@ -3303,7 +3364,7 @@
 //   5. Draw the RPDQ.
 void GLRenderer::CopyRenderPassDrawQuadToOverlayResource(
     const CALayerOverlay* ca_layer_overlay,
-    cc::Resource** resource,
+    std::unique_ptr<OverlayTexture>* overlay_texture,
     gfx::RectF* new_bounds) {
   // Don't carry over any GL state from previous RenderPass draw operations.
   ReinitializeGLState();
@@ -3343,26 +3404,26 @@
   // |params.dst_rect| now contain values that reflect a potentially increased
   // size quad.
   gfx::RectF updated_dst_rect = params.dst_rect;
+  gfx::Size dst_pixel_size = gfx::ToCeiledSize(updated_dst_rect.size());
 
-  // Round the size of the IOSurface to a multiple of 64 pixels. This reduces
-  // memory fragmentation. https://crbug.com/146070. This also allows IOSurfaces
-  // to be more easily reused during a resize operation.
-  uint32_t iosurface_width = static_cast<uint32_t>(updated_dst_rect.width());
-  uint32_t iosurface_height = static_cast<uint32_t>(updated_dst_rect.height());
+  int iosurface_width = dst_pixel_size.width();
+  int iosurface_height = dst_pixel_size.height();
   if (!settings_->dont_round_texture_sizes_for_pixel_tests) {
-    uint32_t iosurface_multiple = 64;
+    // Round the size of the IOSurface to a multiple of 64 pixels. This reduces
+    // memory fragmentation. https://crbug.com/146070. This also allows
+    // IOSurfaces to be more easily reused during a resize operation.
+    int iosurface_multiple = 64;
     iosurface_width =
         cc::MathUtil::CheckedRoundUp(iosurface_width, iosurface_multiple);
     iosurface_height =
         cc::MathUtil::CheckedRoundUp(iosurface_height, iosurface_multiple);
   }
 
-  *resource = overlay_resource_pool_->AcquireResource(
-      gfx::Size(iosurface_width, iosurface_height), ResourceFormat::RGBA_8888,
+  *overlay_texture = FindOrCreateOverlayTexture(
+      params.quad->render_pass_id, iosurface_width, iosurface_height,
       current_frame()->root_render_pass->color_space);
-  *new_bounds =
-      gfx::RectF(updated_dst_rect.x(), updated_dst_rect.y(),
-                 (*resource)->size().width(), (*resource)->size().height());
+  *new_bounds = gfx::RectF(updated_dst_rect.origin(),
+                           gfx::SizeF((*overlay_texture)->texture.size()));
 
   // Calculate new projection and window matrices for a minimally sized viewport
   // using InitializeViewport(). This requires creating a dummy DrawingFrame.
@@ -3402,14 +3463,12 @@
   }
 
   // Establish destination texture.
-  cc::ResourceProvider::ScopedWriteLockGL destination(resource_provider_,
-                                                      (*resource)->id());
   GLuint temp_fbo;
-
   gl_->GenFramebuffers(1, &temp_fbo);
   gl_->BindFramebuffer(GL_FRAMEBUFFER, temp_fbo);
   gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                            destination.target(), destination.GetTexture(), 0);
+                            (*overlay_texture)->texture.target(),
+                            (*overlay_texture)->texture.id(), 0);
   DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) ==
          GL_FRAMEBUFFER_COMPLETE);
 
@@ -3419,7 +3478,7 @@
 
   UpdateRPDQTexturesForSampling(&params);
   UpdateRPDQBlendMode(&params);
-  ChooseRPDQProgram(&params, destination.color_space_for_raster());
+  ChooseRPDQProgram(&params, (*overlay_texture)->texture.color_space());
   UpdateRPDQUniforms(&params);
 
   // Prior to drawing, set up the destination framebuffer and viewport.
@@ -3434,33 +3493,90 @@
   gl_->DeleteFramebuffers(1, &temp_fbo);
 }
 
-void GLRenderer::ScheduleRenderPassDrawQuad(
-    const CALayerOverlay* ca_layer_overlay) {
-  DCHECK(ca_layer_overlay->rpdq);
+std::unique_ptr<GLRenderer::OverlayTexture>
+GLRenderer::FindOrCreateOverlayTexture(const RenderPassId& render_pass_id,
+                                       int width,
+                                       int height,
+                                       const gfx::ColorSpace& color_space) {
+  // First try to use a texture for the same RenderPassId, to keep things more
+  // stable and less likely to clobber each others textures.
+  auto match_with_id = [&](const std::unique_ptr<OverlayTexture>& overlay) {
+    return overlay->render_pass_id == render_pass_id &&
+           overlay->texture.size().width() >= width &&
+           overlay->texture.size().height() >= height &&
+           overlay->texture.size().width() <= width * 2 &&
+           overlay->texture.size().height() <= height * 2;
+  };
+  auto it = std::find_if(available_overlay_textures_.begin(),
+                         available_overlay_textures_.end(), match_with_id);
+  if (it != available_overlay_textures_.end()) {
+    std::unique_ptr<OverlayTexture> result = std::move(*it);
+    available_overlay_textures_.erase(it);
 
-  if (!overlay_resource_pool_) {
-    DCHECK(current_task_runner_);
-    overlay_resource_pool_ = cc::ResourcePool::Create(
-        resource_provider_, true, current_task_runner_.get(),
-        ResourceTextureHint::kOverlay, base::TimeDelta::FromSeconds(3),
-        settings_->disallow_non_exact_resource_reuse);
+    result->render_pass_id = render_pass_id;
+    return result;
   }
 
-  cc::Resource* resource = nullptr;
+  // Then fallback to trying other textures that still match.
+  auto match = [&](const std::unique_ptr<OverlayTexture>& overlay) {
+    return overlay->texture.size().width() >= width &&
+           overlay->texture.size().height() >= height &&
+           overlay->texture.size().width() <= width * 2 &&
+           overlay->texture.size().height() <= height * 2;
+  };
+  it = std::find_if(available_overlay_textures_.begin(),
+                    available_overlay_textures_.end(), match);
+  if (it != available_overlay_textures_.end()) {
+    std::unique_ptr<OverlayTexture> result = std::move(*it);
+    available_overlay_textures_.erase(it);
+
+    result->render_pass_id = render_pass_id;
+    return result;
+  }
+
+  // Make a new texture if we could not find a match. Sadtimes.
+  auto result = std::make_unique<OverlayTexture>();
+  result->texture = ScopedGpuMemoryBufferTexture(
+      output_surface_->context_provider(),
+      settings_->resource_settings.texture_target_exception_list,
+      gfx::Size(width, height), color_space);
+  result->render_pass_id = render_pass_id;
+  return result;
+}
+
+void GLRenderer::ReduceAvailableOverlayTextures(
+    const std::vector<std::unique_ptr<OverlayTexture>>& most_recent) {
+  // Overlay resources may get returned back to the compositor at varying rates,
+  // so we may get a number of resources returned at once, then none for a
+  // while. As such, we want to hold onto enough resources to not have to create
+  // any when none are released for a while. Emperical study by erikchen@ on
+  // crbug.com/636884 found that saving 5 spare textures per RenderPass was
+  // sufficient for important benchmarks. This seems to imply that the OS may
+  // hold up to 5 frames of textures before releasing them.
+  static const int kKeepCountPerRenderPass = 5;
+
+  // In order to accomodate the above requirements, we hold any released texture
+  // in the |available_overlay_textures_| set for up to 5 frames before
+  // discarding it.
+  for (const auto& overlay : available_overlay_textures_)
+    overlay->frames_waiting_for_reuse++;
+  base::EraseIf(available_overlay_textures_,
+                [](const std::unique_ptr<OverlayTexture>& overlay) {
+                  return overlay->frames_waiting_for_reuse >=
+                         kKeepCountPerRenderPass;
+                });
+}
+
+std::unique_ptr<GLRenderer::OverlayTexture>
+GLRenderer::ScheduleRenderPassDrawQuad(const CALayerOverlay* ca_layer_overlay) {
+  DCHECK(ca_layer_overlay->rpdq);
+
+  std::unique_ptr<OverlayTexture> overlay_texture;
   gfx::RectF new_bounds;
-  CopyRenderPassDrawQuadToOverlayResource(ca_layer_overlay, &resource,
+  CopyRenderPassDrawQuadToOverlayResource(ca_layer_overlay, &overlay_texture,
                                           &new_bounds);
-  if (!resource || !resource->id())
-    return;
-
-  pending_overlay_resources_.push_back(
-      std::make_unique<cc::DisplayResourceProvider::ScopedReadLockGL>(
-          resource_provider_, resource->id()));
-  unsigned texture_id = pending_overlay_resources_.back()->texture_id();
-
-  // Once a resource is released, it is marked as "busy". It will be
-  // available for reuse after the ScopedReadLockGL is destroyed.
-  overlay_resource_pool_->ReleaseResource(resource);
+  if (!overlay_texture)
+    return {};
 
   GLfloat contents_rect[4] = {
       ca_layer_overlay->contents_rect.x(), ca_layer_overlay->contents_rect.y(),
@@ -3485,9 +3601,11 @@
   GLfloat alpha = 1;
   gl_->ScheduleCALayerSharedStateCHROMIUM(alpha, is_clipped, clip_rect,
                                           sorting_context_id, gl_transform);
-  gl_->ScheduleCALayerCHROMIUM(
-      texture_id, contents_rect, ca_layer_overlay->background_color,
-      ca_layer_overlay->edge_aa_mask, bounds_rect, filter);
+  gl_->ScheduleCALayerCHROMIUM(overlay_texture->texture.id(), contents_rect,
+                               ca_layer_overlay->background_color,
+                               ca_layer_overlay->edge_aa_mask, bounds_rect,
+                               filter);
+  return overlay_texture;
 }
 
 void GLRenderer::SetupOverdrawFeedback() {
diff --git a/components/viz/service/display/gl_renderer.h b/components/viz/service/display/gl_renderer.h
index 4f28e3c8..8ff5ba3 100644
--- a/components/viz/service/display/gl_renderer.h
+++ b/components/viz/service/display/gl_renderer.h
@@ -22,6 +22,7 @@
 #include "components/viz/service/display/gl_renderer_copier.h"
 #include "components/viz/service/display/gl_renderer_draw_cache.h"
 #include "components/viz/service/display/program_binding.h"
+#include "components/viz/service/display/scoped_gpu_memory_buffer_texture.h"
 #include "components/viz/service/display/texture_deleter.h"
 #include "components/viz/service/viz_service_export.h"
 #include "ui/gfx/geometry/quad_f.h"
@@ -34,8 +35,6 @@
 namespace cc {
 class GLRendererShaderTest;
 class OutputSurface;
-class Resource;
-class ResourcePool;
 class StreamVideoDrawQuad;
 }  // namespace cc
 
@@ -154,6 +153,20 @@
   friend class GLRendererShaderTest;
   friend class GLRendererTest;
 
+  using OverlayResourceLock =
+      std::unique_ptr<cc::DisplayResourceProvider::ScopedReadLockGL>;
+  using OverlayResourceLockList = std::vector<OverlayResourceLock>;
+
+  // If a RenderPass is used as an overlay, we render the RenderPass with any
+  // effects into a texture for overlay use. We must keep the texture alive past
+  // the execution of SwapBuffers, and such textures are more expensive to make
+  // so we want to reuse them.
+  struct OverlayTexture {
+    RenderPassId render_pass_id;
+    ScopedGpuMemoryBufferTexture texture;
+    int frames_waiting_for_reuse = 0;
+  };
+
   // If any of the following functions returns false, then it means that drawing
   // is not possible.
   bool InitializeRPDQParameters(DrawRenderPassDrawQuadParams* params);
@@ -263,18 +276,26 @@
   void ScheduleOverlays();
 
   // Copies the contents of the render pass draw quad, including filter effects,
-  // to an overlay resource, returned in |resource|. The resource is allocated
-  // from |overlay_resource_pool_|.
-  // The resulting cc::Resource may be larger than the original quad. The new
-  // size and position is placed in |new_bounds|.
+  // to a GL texture, returned in |overlay_texture|. The resulting texture may
+  // be larger than the RenderPassDrawQuad's output, in order to reuse existing
+  // textures. The new size and position is placed in |new_bounds|.
   void CopyRenderPassDrawQuadToOverlayResource(
       const CALayerOverlay* ca_layer_overlay,
-      cc::Resource** resource,
+      std::unique_ptr<OverlayTexture>* overlay_texture,
       gfx::RectF* new_bounds);
+  std::unique_ptr<OverlayTexture> FindOrCreateOverlayTexture(
+      const RenderPassId& render_pass_id,
+      int width,
+      int height,
+      const gfx::ColorSpace& color_space);
+  void ReduceAvailableOverlayTextures(
+      const std::vector<std::unique_ptr<OverlayTexture>>& most_recent);
 
   // Schedules the |ca_layer_overlay|, which is guaranteed to have a non-null
-  // |rpdq| parameter.
-  void ScheduleRenderPassDrawQuad(const CALayerOverlay* ca_layer_overlay);
+  // |rpdq| parameter. Returns ownership of a GL texture that contains the
+  // output of the RenderPassDrawQuad.
+  std::unique_ptr<OverlayTexture> ScheduleRenderPassDrawQuad(
+      const CALayerOverlay* ca_layer_overlay);
 
   // Setup/flush all pending overdraw feedback to framebuffer.
   void SetupOverdrawFeedback();
@@ -292,16 +313,25 @@
   // A map from RenderPass id to the texture used to draw the RenderPass from.
   base::flat_map<RenderPassId, ScopedRenderPassTexture> render_pass_textures_;
 
-  using OverlayResourceLock =
-      std::unique_ptr<cc::DisplayResourceProvider::ScopedReadLockGL>;
-  using OverlayResourceLockList = std::vector<OverlayResourceLock>;
+  // OverlayTextures that are free to be used in the next frame.
+  std::vector<std::unique_ptr<OverlayTexture>> available_overlay_textures_;
+  // OverlayTextures that have been set up for use but are waiting for
+  // SwapBuffers.
+  std::vector<std::unique_ptr<OverlayTexture>> awaiting_swap_overlay_textures_;
+  // OverlayTextures that have been swapped for display on the gpu. Each vector
+  // represents a single frame, and may be empty if none were used in that
+  // frame. Ordered from oldest to most recent frame.
+  std::vector<std::vector<std::unique_ptr<OverlayTexture>>>
+      displayed_overlay_textures_;
+  // OverlayTextures that we have replaced on the gpu but are awaiting
+  // confirmation that we can reuse them.
+  std::vector<std::unique_ptr<OverlayTexture>>
+      awaiting_release_overlay_textures_;
 
   // Resources that have been sent to the GPU process, but not yet swapped.
   OverlayResourceLockList pending_overlay_resources_;
-
   // Resources that should be shortly swapped by the GPU process.
   base::circular_deque<OverlayResourceLockList> swapping_overlay_resources_;
-
   // Resources that the GPU process has finished swapping. The key is the
   // texture id of the resource.
   std::map<unsigned, OverlayResourceLock> swapped_and_acked_overlay_resources_;
@@ -377,10 +407,6 @@
   // This may be null if the compositor is run on a thread without a
   // MessageLoop.
   scoped_refptr<base::SingleThreadTaskRunner> current_task_runner_;
-  // Some overlays require that content is copied from a render pass into an
-  // overlay resource. This means the GLRenderer needs its own cc::ResourcePool.
-  // This references the |current_task_runner_| and |resource_provider_|.
-  std::unique_ptr<cc::ResourcePool> overlay_resource_pool_;
   base::WeakPtrFactory<GLRenderer> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(GLRenderer);
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc
index df542e8..4674bb7d 100644
--- a/components/viz/service/display/gl_renderer_unittest.cc
+++ b/components/viz/service/display/gl_renderer_unittest.cc
@@ -47,11 +47,13 @@
 using testing::AnyNumber;
 using testing::Args;
 using testing::AtLeast;
+using testing::Contains;
 using testing::ElementsAre;
 using testing::Expectation;
 using testing::InSequence;
 using testing::Invoke;
 using testing::Mock;
+using testing::Not;
 using testing::Pointee;
 using testing::Return;
 using testing::StrictMock;
@@ -2800,48 +2802,80 @@
                     GLuint edge_aa_mask,
                     const GLfloat* bounds_rect,
                     GLuint filter));
+  MOCK_METHOD2(ScheduleCALayerInUseQueryCHROMIUM,
+               void(GLsizei count, const GLuint* textures));
+
+  void InitializeTestContext(cc::TestWebGraphicsContext3D* context) override {
+    // Support image storage for GpuMemoryBuffers, needed for
+    // CALayers/IOSurfaces backed by textures.
+    context->set_support_texture_storage_image(true);
+
+    // Allow the renderer to make an empty SwapBuffers - skipping even the
+    // root RenderPass.
+    context->set_have_commit_overlay_planes(true);
+  }
 };
 
-TEST_F(GLRendererTest, CALayerOverlaysWithAllQuadsPromoted) {
+class CALayerGLRendererTest : public GLRendererTest {
+ protected:
+  void SetUp() override {
+    // A mock GLES2Interface that can watch CALayer stuff happen.
+    auto gles2_interface = std::make_unique<MockCALayerGLES2Interface>();
+    gl_ = gles2_interface.get();
+
+    auto provider = cc::TestContextProvider::Create(std::move(gles2_interface));
+    provider->BindToCurrentThread();
+
+    cc::FakeOutputSurfaceClient output_surface_client;
+    output_surface_ = cc::FakeOutputSurface::Create3d(std::move(provider));
+    output_surface_->BindToClient(&output_surface_client);
+
+    // This validator allows the renderer to make CALayer overlays. If all
+    // quads can be turned into CALayer overlays, then all damage is removed and
+    // we can skip the root RenderPass, swapping empty.
+    output_surface_->SetOverlayCandidateValidator(&validator_);
+
+    display_resource_provider_ =
+        cc::FakeResourceProvider::CreateDisplayResourceProvider(
+            output_surface_->context_provider(), nullptr);
+
+    settings_ = std::make_unique<RendererSettings>();
+    // This setting is enabled to use CALayer overlays.
+    settings_->release_overlay_resources_after_gpu_query = true;
+    renderer_ = std::make_unique<FakeRendererGL>(
+        settings_.get(), output_surface_.get(),
+        display_resource_provider_.get(), base::ThreadTaskRunnerHandle::Get());
+    renderer_->Initialize();
+    renderer_->SetVisible(true);
+
+    TestOverlayProcessor* processor =
+        new TestOverlayProcessor(output_surface_.get());
+    processor->Initialize();
+    renderer_->SetOverlayProcessor(processor);
+  }
+
+  void TearDown() override {
+    renderer_.reset();
+    display_resource_provider_.reset();
+    output_surface_.reset();
+  }
+
+  MockCALayerGLES2Interface& gl() const { return *gl_; }
+  FakeRendererGL& renderer() const { return *renderer_; }
+  cc::FakeOutputSurface& output_surface() const { return *output_surface_; }
+
+ private:
+  MockCALayerGLES2Interface* gl_;
+  CALayerValidator validator_;
+  std::unique_ptr<cc::FakeOutputSurface> output_surface_;
+  std::unique_ptr<cc::DisplayResourceProvider> display_resource_provider_;
+  std::unique_ptr<RendererSettings> settings_;
+  std::unique_ptr<FakeRendererGL> renderer_;
+};
+
+TEST_F(CALayerGLRendererTest, CALayerOverlaysWithAllQuadsPromoted) {
   gfx::Size viewport_size(10, 10);
 
-  // A mock GLES2Interface that can watch CALayer stuff happen.
-  auto gles2_interface = std::make_unique<MockCALayerGLES2Interface>();
-  auto* gl = gles2_interface.get();
-
-  // The context capabilities include |commit_overlay_planes| which will
-  // allow the renderer to make an empty SwapBuffers - skipping even the
-  // root RenderPass.
-  auto provider = cc::TestContextProvider::Create(std::move(gles2_interface));
-  provider->UnboundTestContext3d()->set_have_commit_overlay_planes(true);
-  provider->BindToCurrentThread();
-
-  cc::FakeOutputSurfaceClient output_surface_client;
-  auto output_surface = cc::FakeOutputSurface::Create3d(std::move(provider));
-  output_surface->BindToClient(&output_surface_client);
-
-  auto parent_resource_provider =
-      cc::FakeResourceProvider::CreateDisplayResourceProvider(
-          output_surface->context_provider(), nullptr);
-
-  RendererSettings settings;
-  FakeRendererGL renderer(&settings, output_surface.get(),
-                          parent_resource_provider.get(),
-                          base::ThreadTaskRunnerHandle::Get());
-  renderer.Initialize();
-  renderer.SetVisible(true);
-
-  TestOverlayProcessor* processor =
-      new TestOverlayProcessor(output_surface.get());
-  processor->Initialize();
-  renderer.SetOverlayProcessor(processor);
-
-  // This validator allows the renderer to make CALayer overlays. If all
-  // quads can be turned into CALayer overlays, then all damage is removed and
-  // we can skip the root RenderPass, swapping empty.
-  auto validator = std::make_unique<CALayerValidator>();
-  output_surface->SetOverlayCandidateValidator(validator.get());
-
   // This frame has a root pass with a RenderPassDrawQuad pointing to a child
   // pass that is at 1,2 to make it identifiable.
   RenderPassId child_pass_id = 2;
@@ -2858,14 +2892,14 @@
                           SkBlendMode::kSrcOver);
   }
 
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
+  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
 
   // The child pass is drawn, promoted to an overlay, and scheduled as a
   // CALayer.
   {
     InSequence sequence;
-    EXPECT_CALL(*gl, ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
-    EXPECT_CALL(*gl, ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
         .WillOnce(
             Invoke([](GLuint contents_texture_id, const GLfloat* contents_rect,
                       GLuint background_color, GLuint edge_aa_mask,
@@ -2875,14 +2909,14 @@
               EXPECT_EQ(2, bounds_rect[1]);
             }));
   }
-  DrawFrame(&renderer, viewport_size);
-  Mock::VerifyAndClearExpectations(gl);
+  DrawFrame(&renderer(), viewport_size);
+  Mock::VerifyAndClearExpectations(&gl());
 
-  renderer.SwapBuffers(std::vector<ui::LatencyInfo>());
+  renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
 
   // The damage was eliminated when everything was promoted to CALayers.
-  ASSERT_TRUE(output_surface->last_sent_frame()->sub_buffer_rect);
-  EXPECT_TRUE(output_surface->last_sent_frame()->sub_buffer_rect->IsEmpty());
+  ASSERT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect);
+  EXPECT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect->IsEmpty());
 
   // Frame number 2. Same inputs, except...
   {
@@ -2900,7 +2934,7 @@
     child_pass->cache_render_pass = true;
   }
 
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
+  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
 
   // The child RenderPassDrawQuad gets promoted again, but importantly it
   // did not itself have to be drawn this time as it can use the cached texture.
@@ -2910,13 +2944,699 @@
   // RenderPassDrawQuad is emitted.
   {
     InSequence sequence;
-    EXPECT_CALL(*gl, ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
-    EXPECT_CALL(*gl, ScheduleCALayerCHROMIUM(_, _, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _));
   }
-  DrawFrame(&renderer, viewport_size);
-  Mock::VerifyAndClearExpectations(gl);
+  DrawFrame(&renderer(), viewport_size);
+  Mock::VerifyAndClearExpectations(&gl());
 
-  renderer.SwapBuffers(std::vector<ui::LatencyInfo>());
+  renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+}
+
+TEST_F(CALayerGLRendererTest, CALayerOverlaysReusesTextureWithDifferentSizes) {
+  gfx::Size viewport_size(300, 300);
+
+  // This frame has a root pass with a RenderPassDrawQuad pointing to a child
+  // pass that is at 1,2 to make it identifiable.
+  // The child's size is 250x251, but it will be rounded up to a multiple of 64
+  // in order to promote easier texture reuse. See https://crbug.com/146070.
+  RenderPassId child_pass_id = 2;
+  RenderPassId root_pass_id = 1;
+  {
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
+                          gfx::Rect(250, 251) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+  }
+
+  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
+
+  // The child pass is drawn, promoted to an overlay, and scheduled as a
+  // CALayer. The bounds of the texture are rounded up to 256x256. We save the
+  // texture ID to make sure we reuse it correctly.
+  uint32_t saved_texture_id = 0;
+  {
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+        .WillOnce(
+            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
+                       GLuint background_color, GLuint edge_aa_mask,
+                       const GLfloat* bounds_rect, GLuint filter) {
+              // This is the child RenderPassDrawQuad.
+              EXPECT_EQ(1, bounds_rect[0]);
+              EXPECT_EQ(2, bounds_rect[1]);
+              // The size is rounded to a multiple of 64.
+              EXPECT_EQ(256, bounds_rect[2]);
+              EXPECT_EQ(256, bounds_rect[3]);
+              saved_texture_id = contents_texture_id;
+            }));
+  }
+  DrawFrame(&renderer(), viewport_size);
+  Mock::VerifyAndClearExpectations(&gl());
+  renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+
+  // ScheduleCALayerCHROMIUM happened and used a non-0 texture.
+  EXPECT_NE(saved_texture_id, 0u);
+
+  // The damage was eliminated when everything was promoted to CALayers.
+  ASSERT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect);
+  EXPECT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect->IsEmpty());
+
+  // The texture will be checked to verify if it is free yet.
+  EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(1, _));
+  renderer().SwapBuffersComplete();
+  Mock::VerifyAndClearExpectations(&gl());
+
+  // Frame number 2. We change the size of the child RenderPass to be smaller
+  // than the next multiple of 64, but larger than half the previous size so
+  // that our texture reuse heuristics will reuse the texture if it is free.
+  // For now, it is not.
+  {
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
+                          gfx::Rect(190, 191) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+  }
+
+  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
+
+  // The child RenderPass will use a new 192x192 texture, since the last texture
+  // is still in use.
+  {
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+        .WillOnce(
+            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
+                       GLuint background_color, GLuint edge_aa_mask,
+                       const GLfloat* bounds_rect, GLuint filter) {
+              // New texture id.
+              EXPECT_NE(saved_texture_id, contents_texture_id);
+              EXPECT_EQ(1, bounds_rect[0]);
+              EXPECT_EQ(2, bounds_rect[1]);
+              // The texture is 192x192 since we snap up to multiples of 64.
+              EXPECT_EQ(192, bounds_rect[2]);
+              EXPECT_EQ(192, bounds_rect[3]);
+            }));
+  }
+  DrawFrame(&renderer(), viewport_size);
+  Mock::VerifyAndClearExpectations(&gl());
+  renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+
+  // There are now 2 textures to check if they are free.
+  EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(2, _));
+  renderer().SwapBuffersComplete();
+  Mock::VerifyAndClearExpectations(&gl());
+
+  // The first (256x256) texture is returned to the GLRenderer.
+  renderer().DidReceiveTextureInUseResponses({{saved_texture_id, false}});
+
+  // Frame number 3 looks just like frame number 2. The child RenderPass is
+  // smaller than the next multiple of 64 from the released texture, but larger
+  // than half of its size so that our texture reuse heuristics will kick in.
+  {
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
+                          gfx::Rect(190, 191) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+  }
+
+  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
+
+  // The child RenderPass would try to use a 192x192 texture, but since we have
+  // an existing 256x256 texture, we can reuse that.
+  {
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+        .WillOnce(
+            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
+                       GLuint background_color, GLuint edge_aa_mask,
+                       const GLfloat* bounds_rect, GLuint filter) {
+              // The first texture is reused.
+              EXPECT_EQ(saved_texture_id, contents_texture_id);
+              // This is the child RenderPassDrawQuad.
+              EXPECT_EQ(1, bounds_rect[0]);
+              EXPECT_EQ(2, bounds_rect[1]);
+              // The size here is the size of the texture being used, not
+              // the size we tried to use (192x192).
+              EXPECT_EQ(256, bounds_rect[2]);
+              EXPECT_EQ(256, bounds_rect[3]);
+            }));
+  }
+  DrawFrame(&renderer(), viewport_size);
+  Mock::VerifyAndClearExpectations(&gl());
+  renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+}
+
+TEST_F(CALayerGLRendererTest, CALayerOverlaysDontReuseTooBigTexture) {
+  gfx::Size viewport_size(300, 300);
+
+  // This frame has a root pass with a RenderPassDrawQuad pointing to a child
+  // pass that is at 1,2 to make it identifiable.
+  // The child's size is 250x251, but it will be rounded up to a multiple of 64
+  // in order to promote easier texture reuse. See https://crbug.com/146070.
+  RenderPassId child_pass_id = 2;
+  RenderPassId root_pass_id = 1;
+  {
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
+                          gfx::Rect(250, 251) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+  }
+
+  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
+
+  // The child pass is drawn, promoted to an overlay, and scheduled as a
+  // CALayer. The bounds of the texture are rounded up to 256x256. We save the
+  // texture ID to make sure we reuse it correctly.
+  uint32_t saved_texture_id = 0;
+  {
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+        .WillOnce(
+            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
+                       GLuint background_color, GLuint edge_aa_mask,
+                       const GLfloat* bounds_rect, GLuint filter) {
+              // This is the child RenderPassDrawQuad.
+              EXPECT_EQ(1, bounds_rect[0]);
+              EXPECT_EQ(2, bounds_rect[1]);
+              // The size is rounded to a multiple of 64.
+              EXPECT_EQ(256, bounds_rect[2]);
+              EXPECT_EQ(256, bounds_rect[3]);
+              saved_texture_id = contents_texture_id;
+            }));
+  }
+  DrawFrame(&renderer(), viewport_size);
+  Mock::VerifyAndClearExpectations(&gl());
+  renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+
+  // ScheduleCALayerCHROMIUM happened and used a non-0 texture.
+  EXPECT_NE(saved_texture_id, 0u);
+
+  // The damage was eliminated when everything was promoted to CALayers.
+  ASSERT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect);
+  EXPECT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect->IsEmpty());
+
+  // The texture will be checked to verify if it is free yet.
+  EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(1, _));
+  renderer().SwapBuffersComplete();
+  Mock::VerifyAndClearExpectations(&gl());
+
+  // Frame number 2. We change the size of the child RenderPass to be much
+  // smaller.
+  {
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
+                          gfx::Rect(20, 21) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+  }
+
+  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
+
+  // The child RenderPass will use a new 64x64 texture, since the last texture
+  // is still in use.
+  {
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+        .WillOnce(
+            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
+                       GLuint background_color, GLuint edge_aa_mask,
+                       const GLfloat* bounds_rect, GLuint filter) {
+              // New texture id.
+              EXPECT_NE(saved_texture_id, contents_texture_id);
+              EXPECT_EQ(1, bounds_rect[0]);
+              EXPECT_EQ(2, bounds_rect[1]);
+              // The texture is 64x64 since we snap up to multiples of 64.
+              EXPECT_EQ(64, bounds_rect[2]);
+              EXPECT_EQ(64, bounds_rect[3]);
+            }));
+  }
+  DrawFrame(&renderer(), viewport_size);
+  Mock::VerifyAndClearExpectations(&gl());
+  renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+
+  // There are now 2 textures to check if they are free.
+  EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(2, _));
+  renderer().SwapBuffersComplete();
+  Mock::VerifyAndClearExpectations(&gl());
+
+  // The first (256x256) texture is returned to the GLRenderer.
+  renderer().DidReceiveTextureInUseResponses({{saved_texture_id, false}});
+
+  // Frame number 3 looks just like frame number 2. The child RenderPass is
+  // too small to reuse the old texture.
+  {
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
+                          gfx::Rect(20, 21) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+  }
+
+  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
+
+  // The child RenderPass would try to use a 64x64 texture. We have a free and
+  // existing 256x256 texture, but it's too large for us to reuse it.
+  {
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+        .WillOnce(
+            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
+                       GLuint background_color, GLuint edge_aa_mask,
+                       const GLfloat* bounds_rect, GLuint filter) {
+              // The first texture is not reused.
+              EXPECT_NE(saved_texture_id, contents_texture_id);
+              // This is the child RenderPassDrawQuad.
+              EXPECT_EQ(1, bounds_rect[0]);
+              EXPECT_EQ(2, bounds_rect[1]);
+              // The new texture has a smaller size.
+              EXPECT_EQ(64, bounds_rect[2]);
+              EXPECT_EQ(64, bounds_rect[3]);
+            }));
+  }
+  DrawFrame(&renderer(), viewport_size);
+  Mock::VerifyAndClearExpectations(&gl());
+  renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+}
+
+TEST_F(CALayerGLRendererTest, CALayerOverlaysReuseAfterNoSwapBuffers) {
+  gfx::Size viewport_size(300, 300);
+
+  // This frame has a root pass with a RenderPassDrawQuad pointing to a child
+  // pass that is at 1,2 to make it identifiable.
+  RenderPassId child_pass_id = 2;
+  RenderPassId root_pass_id = 1;
+  {
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
+                          gfx::Rect(100, 100) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+  }
+
+  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
+
+  // The child pass is drawn, promoted to an overlay, and scheduled as a
+  // CALayer. We save the texture ID to make sure we reuse it correctly.
+  uint32_t saved_texture_id = 0;
+  {
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+        .WillOnce(
+            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
+                       GLuint background_color, GLuint edge_aa_mask,
+                       const GLfloat* bounds_rect, GLuint filter) {
+              // This is the child RenderPassDrawQuad.
+              EXPECT_EQ(1, bounds_rect[0]);
+              EXPECT_EQ(2, bounds_rect[1]);
+              saved_texture_id = contents_texture_id;
+            }));
+  }
+  DrawFrame(&renderer(), viewport_size);
+  Mock::VerifyAndClearExpectations(&gl());
+
+  // ScheduleCALayerCHROMIUM happened and used a non-0 texture.
+  EXPECT_NE(saved_texture_id, 0u);
+
+  // SwapBuffers() is *not* called though! Display can do this sometimes.
+
+  // Frame number 2. We can not reuse the texture since the last one isn't
+  // returned yet. We use a different size so we can control which texture gets
+  // reused later.
+  {
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
+                          gfx::Rect(200, 200) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+  }
+
+  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
+
+  uint32_t second_saved_texture_id = 0;
+  {
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+        .WillOnce(
+            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
+                       GLuint background_color, GLuint edge_aa_mask,
+                       const GLfloat* bounds_rect, GLuint filter) {
+              // New texture id.
+              EXPECT_NE(saved_texture_id, contents_texture_id);
+              EXPECT_EQ(1, bounds_rect[0]);
+              EXPECT_EQ(2, bounds_rect[1]);
+              second_saved_texture_id = contents_texture_id;
+            }));
+  }
+  DrawFrame(&renderer(), viewport_size);
+  Mock::VerifyAndClearExpectations(&gl());
+
+  // SwapBuffers() *does* happen this time.
+  renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+
+  // There are 2 textures to check if they are free.
+  EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(2, _));
+  renderer().SwapBuffersComplete();
+  Mock::VerifyAndClearExpectations(&gl());
+
+  // Both textures get returned and the 2nd one can be reused.
+  renderer().DidReceiveTextureInUseResponses(
+      {{saved_texture_id, false}, {second_saved_texture_id, false}});
+
+  // Frame number 3 looks just like frame number 2.
+  {
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
+                          gfx::Rect(200, 200) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+  }
+
+  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
+
+  // The 2nd texture that we sent has been returned so we can reuse it. We
+  // verify that happened.
+  {
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+        .WillOnce(
+            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
+                       GLuint background_color, GLuint edge_aa_mask,
+                       const GLfloat* bounds_rect, GLuint filter) {
+              // The second texture is reused.
+              EXPECT_EQ(second_saved_texture_id, contents_texture_id);
+              // This is the child RenderPassDrawQuad.
+              EXPECT_EQ(1, bounds_rect[0]);
+              EXPECT_EQ(2, bounds_rect[1]);
+            }));
+  }
+  DrawFrame(&renderer(), viewport_size);
+  Mock::VerifyAndClearExpectations(&gl());
+  renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+}
+
+TEST_F(CALayerGLRendererTest, CALayerOverlaysReuseManyIfReturnedSlowly) {
+  gfx::Size viewport_size(300, 300);
+
+  // Each frame has a root pass with a RenderPassDrawQuad pointing to a child
+  // pass. We generate a bunch of frames and swap them, each with a different
+  // child RenderPass id, without getting any of the resources back from the OS.
+  RenderPassId root_pass_id = 1;
+
+  // The number is at least 2 larger than the number of textures we expect to
+  // reuse, so that we can leave one in the OS, and have 1 texture returned but
+  // not reused.
+  const int kNumSendManyTextureIds = 7;
+  uint32_t sent_texture_ids[kNumSendManyTextureIds];
+  for (int i = 0; i < kNumSendManyTextureIds; ++i) {
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, i + 2,
+                          gfx::Rect(250, 251) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+
+    renderer().DecideRenderPassAllocationsForFrame(
+        render_passes_in_draw_order_);
+
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+        .WillOnce(
+            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
+                       GLuint background_color, GLuint edge_aa_mask,
+                       const GLfloat* bounds_rect, GLuint filter) {
+              // This is the child RenderPassDrawQuad.
+              EXPECT_EQ(1, bounds_rect[0]);
+              EXPECT_EQ(2, bounds_rect[1]);
+              sent_texture_ids[i] = contents_texture_id;
+            }));
+    DrawFrame(&renderer(), viewport_size);
+    Mock::VerifyAndClearExpectations(&gl());
+    renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+
+    // ScheduleCALayerCHROMIUM happened and used a non-0 texture.
+    EXPECT_NE(sent_texture_ids[i], 0u);
+
+    // The damage was eliminated when everything was promoted to CALayers.
+    ASSERT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect);
+    EXPECT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect->IsEmpty());
+
+    // All sent textures will be checked to verify if they are free yet.
+    EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(i + 1, _));
+    renderer().SwapBuffersComplete();
+    Mock::VerifyAndClearExpectations(&gl());
+  }
+
+  // Now all but 1 texture get returned by the OS, so they are all inserted
+  // into the cache for reuse.
+  std::vector<uint32_t> returned_texture_ids;
+  for (int i = 0; i < kNumSendManyTextureIds - 1; ++i) {
+    uint32_t id = sent_texture_ids[i];
+    renderer().DidReceiveTextureInUseResponses({{id, false}});
+    returned_texture_ids.push_back(id);
+  }
+
+  // We should keep *some* of these textures around to reuse them across
+  // multiple frames. https://crbug.com/146070 motivates this, and empirical
+  // testing found 5 to be a good number.
+  const int kNumSendReusedTextures = 5;
+  // See comment on |kNumSendManyTextureIds|.
+  ASSERT_LT(kNumSendReusedTextures, kNumSendManyTextureIds - 1);
+
+  for (int i = 0; i < kNumSendReusedTextures + 1; ++i) {
+    // We use different RenderPass ids to ensure that the cache allows reuse
+    // even if they don't match.
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, i + 100,
+                          gfx::Rect(250, 251) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+
+    renderer().DecideRenderPassAllocationsForFrame(
+        render_passes_in_draw_order_);
+
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+        .WillOnce(Invoke([&](GLuint contents_texture_id,
+                             const GLfloat* contents_rect,
+                             GLuint background_color, GLuint edge_aa_mask,
+                             const GLfloat* bounds_rect, GLuint filter) {
+          // This is the child RenderPassDrawQuad.
+          EXPECT_EQ(1, bounds_rect[0]);
+          EXPECT_EQ(2, bounds_rect[1]);
+
+          if (i < kNumSendReusedTextures) {
+            // The texture id should be from the set of returned ones.
+            EXPECT_THAT(returned_texture_ids, Contains(contents_texture_id));
+            base::Erase(returned_texture_ids, contents_texture_id);
+          } else {
+            // More textures were returned at once than we expect to reuse
+            // so eventually we should be making a new texture to show we're
+            // not just keeping infinity textures in the cache.
+            EXPECT_THAT(returned_texture_ids,
+                        Not(Contains(contents_texture_id)));
+            // This shows that there was some returned id that we didn't use.
+            EXPECT_FALSE(returned_texture_ids.empty());
+          }
+        }));
+    DrawFrame(&renderer(), viewport_size);
+    Mock::VerifyAndClearExpectations(&gl());
+    renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+
+    // All sent textures will be checked to verify if they are free yet. There's
+    // also 1 outstanding texture to check for that wasn't returned yet from the
+    // above loop.
+    EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(i + 2, _));
+    renderer().SwapBuffersComplete();
+    Mock::VerifyAndClearExpectations(&gl());
+  }
+}
+
+TEST_F(CALayerGLRendererTest, CALayerOverlaysCachedTexturesAreFreed) {
+  gfx::Size viewport_size(300, 300);
+
+  // Each frame has a root pass with a RenderPassDrawQuad pointing to a child
+  // pass. We generate a bunch of frames and swap them, each with a different
+  // child RenderPass id, without getting any of the resources back from the OS.
+  RenderPassId child_pass_id = 2;
+  RenderPassId root_pass_id = 1;
+
+  // We send a whole bunch of textures as overlays to the OS.
+  const int kNumSendManyTextureIds = 7;
+  uint32_t sent_texture_ids[kNumSendManyTextureIds];
+  for (int i = 0; i < kNumSendManyTextureIds; ++i) {
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, i + 2,
+                          gfx::Rect(250, 251) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+
+    renderer().DecideRenderPassAllocationsForFrame(
+        render_passes_in_draw_order_);
+
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+        .WillOnce(
+            Invoke([&](GLuint contents_texture_id, const GLfloat* contents_rect,
+                       GLuint background_color, GLuint edge_aa_mask,
+                       const GLfloat* bounds_rect, GLuint filter) {
+              // This is the child RenderPassDrawQuad.
+              EXPECT_EQ(1, bounds_rect[0]);
+              EXPECT_EQ(2, bounds_rect[1]);
+              sent_texture_ids[i] = contents_texture_id;
+            }));
+    DrawFrame(&renderer(), viewport_size);
+    Mock::VerifyAndClearExpectations(&gl());
+    renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+
+    // ScheduleCALayerCHROMIUM happened and used a non-0 texture.
+    EXPECT_NE(sent_texture_ids[i], 0u);
+
+    // The damage was eliminated when everything was promoted to CALayers.
+    ASSERT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect);
+    EXPECT_TRUE(output_surface().last_sent_frame()->sub_buffer_rect->IsEmpty());
+
+    // All sent textures will be checked to verify if they are free yet.
+    EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(i + 1, _));
+    renderer().SwapBuffersComplete();
+    Mock::VerifyAndClearExpectations(&gl());
+  }
+
+  // Now all but 1 texture get returned by the OS, so they are all inserted
+  // into the cache for reuse.
+  std::vector<uint32_t> returned_texture_ids;
+  for (int i = 0; i < kNumSendManyTextureIds - 1; ++i) {
+    uint32_t id = sent_texture_ids[i];
+    renderer().DidReceiveTextureInUseResponses({{id, false}});
+    returned_texture_ids.push_back(id);
+  }
+
+  // We generate a bunch of frames that don't use the cache, one less than the
+  // number of textures returned.
+  for (int i = 0; i < kNumSendManyTextureIds - 2; ++i) {
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddQuad(root_pass, gfx::Rect(100, 100), SK_ColorRED);
+
+    renderer().DecideRenderPassAllocationsForFrame(
+        render_passes_in_draw_order_);
+
+    InSequence sequence;
+    EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+    EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _));
+    DrawFrame(&renderer(), viewport_size);
+    Mock::VerifyAndClearExpectations(&gl());
+    renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
+
+    // There's just 1 outstanding RenderPass texture to query for.
+    EXPECT_CALL(gl(), ScheduleCALayerInUseQueryCHROMIUM(1, _));
+    renderer().SwapBuffersComplete();
+    Mock::VerifyAndClearExpectations(&gl());
+  }
+
+  // By now the cache should be empty, to show that we don't keep cached
+  // textures that won't be used forever. We generate a frame with a
+  // RenderPassDrawQuad and verify that it does not reuse a texture from the
+  // (empty) cache.
+  {
+    RenderPass* child_pass =
+        cc::AddRenderPass(&render_passes_in_draw_order_, child_pass_id,
+                          gfx::Rect(250, 251) + gfx::Vector2d(1, 2),
+                          gfx::Transform(), cc::FilterOperations());
+    RenderPass* root_pass = cc::AddRenderPass(
+        &render_passes_in_draw_order_, root_pass_id, gfx::Rect(viewport_size),
+        gfx::Transform(), cc::FilterOperations());
+    cc::AddRenderPassQuad(root_pass, child_pass, 0, gfx::Transform(),
+                          SkBlendMode::kSrcOver);
+  }
+
+  renderer().DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
+
+  InSequence sequence;
+  EXPECT_CALL(gl(), ScheduleCALayerSharedStateCHROMIUM(_, _, _, _, _));
+  EXPECT_CALL(gl(), ScheduleCALayerCHROMIUM(_, _, _, _, _, _))
+      .WillOnce(Invoke([&](GLuint contents_texture_id,
+                           const GLfloat* contents_rect,
+                           GLuint background_color, GLuint edge_aa_mask,
+                           const GLfloat* bounds_rect, GLuint filter) {
+        // This is the child RenderPassDrawQuad.
+        EXPECT_EQ(1, bounds_rect[0]);
+        EXPECT_EQ(2, bounds_rect[1]);
+
+        // More textures were returned at once than we expect to reuse
+        // so eventually we should be making a new texture to show we're
+        // not just keeping infinity textures in the cache.
+        EXPECT_THAT(returned_texture_ids, Not(Contains(contents_texture_id)));
+        // This shows that there was some returned id that we didn't use.
+        EXPECT_FALSE(returned_texture_ids.empty());
+      }));
+  DrawFrame(&renderer(), viewport_size);
+  Mock::VerifyAndClearExpectations(&gl());
+  renderer().SwapBuffers(std::vector<ui::LatencyInfo>());
 }
 
 class FramebufferWatchingGLRenderer : public FakeRendererGL {
diff --git a/components/viz/service/display/overlay_unittest.cc b/components/viz/service/display/overlay_unittest.cc
index f1fc201e..fb2249f 100644
--- a/components/viz/service/display/overlay_unittest.cc
+++ b/components/viz/service/display/overlay_unittest.cc
@@ -2680,32 +2680,45 @@
   SwapBuffersWithoutComplete();
   Mock::VerifyAndClearExpectations(&scheduler_);
 
+  SwapBuffersComplete();
+  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource3));
+
   EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(2);
   renderer_->SetCurrentFrame(frame2);
   renderer_->BeginDrawingFrame();
   renderer_->FinishDrawingFrame();
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
-  SwapBuffersComplete();
   SwapBuffersWithoutComplete();
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
   Mock::VerifyAndClearExpectations(&scheduler_);
 
+  SwapBuffersComplete();
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
+  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource3));
+
   EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(2);
   renderer_->SetCurrentFrame(frame3);
   renderer_->BeginDrawingFrame();
   renderer_->FinishDrawingFrame();
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource3));
-  SwapBuffersComplete();
   SwapBuffersWithoutComplete();
   EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource3));
   Mock::VerifyAndClearExpectations(&scheduler_);
 
+  SwapBuffersComplete();
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource3));
+
   // No overlays, release the resource.
   EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
   DirectRenderer::DrawingFrame frame_no_overlays;
@@ -2715,15 +2728,19 @@
   renderer_->BeginDrawingFrame();
   renderer_->FinishDrawingFrame();
   EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource3));
-  SwapBuffersComplete();
   SwapBuffersWithoutComplete();
   EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
   EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource3));
   Mock::VerifyAndClearExpectations(&scheduler_);
 
+  SwapBuffersComplete();
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource3));
+
   // Use the same buffer twice.
   renderer_->set_expect_overlays(true);
   EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(2);
@@ -2731,40 +2748,55 @@
   renderer_->BeginDrawingFrame();
   renderer_->FinishDrawingFrame();
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
-  SwapBuffersComplete();
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource3));
   SwapBuffersWithoutComplete();
+  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource3));
   Mock::VerifyAndClearExpectations(&scheduler_);
 
+  SwapBuffersComplete();
+  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource3));
+
   EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(2);
   renderer_->SetCurrentFrame(frame1);
   renderer_->BeginDrawingFrame();
   renderer_->FinishDrawingFrame();
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
-  SwapBuffersComplete();
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource3));
   SwapBuffersWithoutComplete();
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource3));
   Mock::VerifyAndClearExpectations(&scheduler_);
 
+  SwapBuffersComplete();
+  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource3));
+
   EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
   renderer_->set_expect_overlays(false);
   renderer_->SetCurrentFrame(frame_no_overlays);
   renderer_->BeginDrawingFrame();
   renderer_->FinishDrawingFrame();
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
-  SwapBuffersComplete();
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource3));
   SwapBuffersWithoutComplete();
   EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource3));
   Mock::VerifyAndClearExpectations(&scheduler_);
 
-  EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
-  renderer_->set_expect_overlays(false);
-  renderer_->SetCurrentFrame(frame_no_overlays);
-  renderer_->BeginDrawingFrame();
-  renderer_->FinishDrawingFrame();
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
   SwapBuffersComplete();
-  SwapBuffersWithoutComplete();
   EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource3));
   Mock::VerifyAndClearExpectations(&scheduler_);
 }
 
diff --git a/components/viz/service/display/scoped_gpu_memory_buffer_texture.cc b/components/viz/service/display/scoped_gpu_memory_buffer_texture.cc
new file mode 100644
index 0000000..26cc3c57
--- /dev/null
+++ b/components/viz/service/display/scoped_gpu_memory_buffer_texture.cc
@@ -0,0 +1,102 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display/scoped_gpu_memory_buffer_texture.h"
+
+#include "base/bits.h"
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "components/viz/common/gpu/context_provider.h"
+#include "components/viz/common/resources/resource_format.h"
+#include "components/viz/common/resources/resource_format_utils.h"
+#include "gpu/GLES2/gl2extchromium.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
+
+namespace viz {
+
+ScopedGpuMemoryBufferTexture::ScopedGpuMemoryBufferTexture(
+    ContextProvider* context_provider,
+    const BufferUsageAndFormatList& formats,
+    const gfx::Size& size,
+    const gfx::ColorSpace& color_space)
+    : context_provider_(context_provider),
+      size_(size),
+      color_space_(color_space) {
+  DCHECK(context_provider_);
+
+  const auto& caps = context_provider->ContextCapabilities();
+  // This capability is needed to use TexStorage2DImageCHROMIUM, and should be
+  // known to be enabled before using an object of this type.
+  DCHECK(caps.texture_storage_image);
+
+  gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
+  gl->GenTextures(1, &gl_id_);
+
+  gfx::BufferUsage usage = gfx::BufferUsage::SCANOUT;
+  ResourceFormat format = RGBA_8888;
+  gfx::BufferFormat buffer_format = BufferFormat(format);
+
+  target_ = GL_TEXTURE_2D;
+  if (base::ContainsValue(formats, std::make_pair(usage, buffer_format)))
+    target_ = gpu::GetPlatformSpecificTextureTarget();
+
+  gl->BindTexture(target_, gl_id_);
+  gl->TexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  gl->TexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  gl->TexParameteri(target_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  gl->TexParameteri(target_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+  gl->TexStorage2DImageCHROMIUM(target_, TextureStorageFormat(format),
+                                GL_SCANOUT_CHROMIUM, size_.width(),
+                                size_.height());
+  if (color_space_.IsValid()) {
+    gl->SetColorSpaceMetadataCHROMIUM(
+        gl_id_, reinterpret_cast<GLColorSpace>(&color_space_));
+  }
+  gl->BindTexture(target_, 0);
+}
+
+ScopedGpuMemoryBufferTexture::ScopedGpuMemoryBufferTexture() = default;
+
+ScopedGpuMemoryBufferTexture::~ScopedGpuMemoryBufferTexture() {
+  Free();
+}
+
+ScopedGpuMemoryBufferTexture::ScopedGpuMemoryBufferTexture(
+    ScopedGpuMemoryBufferTexture&& other)
+    : context_provider_(other.context_provider_),
+      gl_id_(other.gl_id_),
+      target_(other.target_),
+      size_(other.size_),
+      color_space_(other.color_space_) {
+  other.gl_id_ = 0;
+}
+
+ScopedGpuMemoryBufferTexture& ScopedGpuMemoryBufferTexture::operator=(
+    ScopedGpuMemoryBufferTexture&& other) {
+  DCHECK(!context_provider_ || !other.context_provider_ ||
+         context_provider_ == other.context_provider_);
+  if (this != &other) {
+    Free();
+    context_provider_ = other.context_provider_;
+    gl_id_ = other.gl_id_;
+    target_ = other.target_;
+    size_ = other.size_;
+    color_space_ = other.color_space_;
+
+    other.gl_id_ = 0;
+  }
+  return *this;
+}
+
+void ScopedGpuMemoryBufferTexture::Free() {
+  if (!gl_id_)
+    return;
+  gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
+  gl->DeleteTextures(1, &gl_id_);
+  gl_id_ = 0;
+}
+
+}  // namespace viz
diff --git a/components/viz/service/display/scoped_gpu_memory_buffer_texture.h b/components/viz/service/display/scoped_gpu_memory_buffer_texture.h
new file mode 100644
index 0000000..ce7549c
--- /dev/null
+++ b/components/viz/service/display/scoped_gpu_memory_buffer_texture.h
@@ -0,0 +1,51 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_SCOPED_GPU_MEMORY_BUFFER_TEXTURE_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_SCOPED_GPU_MEMORY_BUFFER_TEXTURE_H_
+
+#include "base/macros.h"
+#include "components/viz/common/resources/buffer_to_texture_target_map.h"
+#include "components/viz/service/viz_service_export.h"
+#include "ui/gfx/color_space.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace viz {
+class ContextProvider;
+
+// ScopedGpuMemoryBufferTexture is a GL texture backed by a GL image and a
+// GpuMemoryBuffer, so that it can be used as an overlay.
+class VIZ_SERVICE_EXPORT ScopedGpuMemoryBufferTexture {
+ public:
+  explicit ScopedGpuMemoryBufferTexture(ContextProvider* context_provider,
+                                        const BufferUsageAndFormatList& formats,
+                                        const gfx::Size& size,
+                                        const gfx::ColorSpace& color_space);
+
+  ScopedGpuMemoryBufferTexture();
+  ~ScopedGpuMemoryBufferTexture();
+
+  ScopedGpuMemoryBufferTexture(ScopedGpuMemoryBufferTexture&& other);
+  ScopedGpuMemoryBufferTexture& operator=(ScopedGpuMemoryBufferTexture&& other);
+
+  uint32_t id() const { return gl_id_; }
+  uint32_t target() const { return target_; }
+  const gfx::Size& size() const { return size_; }
+  const gfx::ColorSpace& color_space() const { return color_space_; }
+
+ private:
+  void Free();
+
+  // The ContextProvider used to free the texture when this object is destroyed,
+  // so it must outlive this object.
+  ContextProvider* context_provider_;
+  uint32_t gl_id_;
+  uint32_t target_;
+  gfx::Size size_;
+  gfx::ColorSpace color_space_;
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_SCOPED_GPU_MEMORY_BUFFER_TEXTURE_H_
diff --git a/components/viz/service/gl/gpu_service_impl.h b/components/viz/service/gl/gpu_service_impl.h
index 3e26b06..ffe6c8c 100644
--- a/components/viz/service/gl/gpu_service_impl.h
+++ b/components/viz/service/gl/gpu_service_impl.h
@@ -84,7 +84,7 @@
     return gpu_memory_buffer_factory_.get();
   }
 
-  gpu::gles2::MailboxManager* mailbox_manager() {
+  gpu::MailboxManager* mailbox_manager() {
     return gpu_channel_manager_->mailbox_manager();
   }
 
diff --git a/components/wifi/wifi_service_win.cc b/components/wifi/wifi_service_win.cc
index 711719e..85b4e58 100644
--- a/components/wifi/wifi_service_win.cc
+++ b/components/wifi/wifi_service_win.cc
@@ -4,6 +4,8 @@
 
 #include "components/wifi/wifi_service.h"
 
+#include <windows.h>  // Must be in front of other Windows header files.
+
 #include <iphlpapi.h>
 #include <objbase.h>
 #include <stddef.h>
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 41ff9900..8ed5261 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -411,6 +411,8 @@
     "background_fetch/background_fetch_request_info.cc",
     "background_fetch/background_fetch_request_info.h",
     "background_fetch/background_fetch_request_manager.h",
+    "background_fetch/background_fetch_scheduler.cc",
+    "background_fetch/background_fetch_scheduler.h",
     "background_fetch/background_fetch_service_impl.cc",
     "background_fetch/background_fetch_service_impl.h",
     "background_fetch/storage/cleanup_task.cc",
@@ -1559,8 +1561,6 @@
     "shared_worker/shared_worker_instance.h",
     "shared_worker/shared_worker_service_impl.cc",
     "shared_worker/shared_worker_service_impl.h",
-    "shared_worker/worker_storage_partition.cc",
-    "shared_worker/worker_storage_partition.h",
     "site_instance_impl.cc",
     "site_instance_impl.h",
     "site_isolation_policy.cc",
diff --git a/content/browser/accessibility/browser_accessibility_state_impl_win.cc b/content/browser/accessibility/browser_accessibility_state_impl_win.cc
index 1661ce5c..df3b54b 100644
--- a/content/browser/accessibility/browser_accessibility_state_impl_win.cc
+++ b/content/browser/accessibility/browser_accessibility_state_impl_win.cc
@@ -4,9 +4,10 @@
 
 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
 
+#include <windows.h>  // Must be in front of other Windows header files.
+
 #include <psapi.h>
 #include <stddef.h>
-#include <windows.h>
 
 #include <memory>
 
diff --git a/content/browser/android/selection_popup_controller.cc b/content/browser/android/selection_popup_controller.cc
index 20055b57..c86c4555 100644
--- a/content/browser/android/selection_popup_controller.cc
+++ b/content/browser/android/selection_popup_controller.cc
@@ -160,10 +160,10 @@
 
   Java_SelectionPopupController_showSelectionMenu(
       env, obj, params.selection_rect.x(), params.selection_rect.y(),
-      params.selection_rect.right(),
-      params.selection_rect.bottom() + handle_height, params.is_editable,
-      is_password_type, jselected_text, params.selection_start_offset,
-      can_select_all, can_edit_richly, should_suggest, params.source_type);
+      params.selection_rect.right(), params.selection_rect.bottom(),
+      handle_height, params.is_editable, is_password_type, jselected_text,
+      params.selection_start_offset, can_select_all, can_edit_richly,
+      should_suggest, params.source_type);
   return true;
 }
 
diff --git a/content/browser/appcache/appcache_host_unittest.cc b/content/browser/appcache/appcache_host_unittest.cc
index b4cf5f5..3411a4f 100644
--- a/content/browser/appcache/appcache_host_unittest.cc
+++ b/content/browser/appcache/appcache_host_unittest.cc
@@ -95,18 +95,18 @@
     void RegisterClient(storage::QuotaClient* client) override {}
     void NotifyStorageAccessed(storage::QuotaClient::ID client_id,
                                const GURL& origin,
-                               blink::StorageType type) override {}
+                               blink::mojom::StorageType type) override {}
     void NotifyStorageModified(storage::QuotaClient::ID client_id,
                                const GURL& origin,
-                               blink::StorageType type,
+                               blink::mojom::StorageType type,
                                int64_t delta) override {}
     void SetUsageCacheEnabled(storage::QuotaClient::ID client_id,
                               const GURL& origin,
-                              blink::StorageType type,
+                              blink::mojom::StorageType type,
                               bool enabled) override {}
     void GetUsageAndQuota(base::SequencedTaskRunner* original_task_runner,
                           const GURL& origin,
-                          blink::StorageType type,
+                          blink::mojom::StorageType type,
                           const UsageAndQuotaCallback& callback) override {}
 
     void NotifyOriginInUse(const GURL& origin) override { inuse_[origin] += 1; }
diff --git a/content/browser/appcache/appcache_quota_client.cc b/content/browser/appcache/appcache_quota_client.cc
index 4bbf0a870..e7d538c 100644
--- a/content/browser/appcache/appcache_quota_client.cc
+++ b/content/browser/appcache/appcache_quota_client.cc
@@ -11,19 +11,19 @@
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "content/browser/appcache/appcache_service_impl.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 using storage::QuotaClient;
 
 namespace {
-blink::QuotaStatusCode NetErrorCodeToQuotaStatus(int code) {
+blink::mojom::QuotaStatusCode NetErrorCodeToQuotaStatus(int code) {
   if (code == net::OK)
-    return blink::QuotaStatusCode::kOk;
+    return blink::mojom::QuotaStatusCode::kOk;
   else if (code == net::ERR_ABORTED)
-    return blink::QuotaStatusCode::kErrorAbort;
+    return blink::mojom::QuotaStatusCode::kErrorAbort;
   else
-    return blink::QuotaStatusCode::kUnknown;
+    return blink::mojom::QuotaStatusCode::kUnknown;
 }
 
 void RunFront(content::AppCacheQuotaClient::RequestQueue* queue) {
@@ -119,7 +119,7 @@
   DCHECK(!quota_manager_is_destroyed_);
 
   if (!service_) {
-    callback.Run(blink::QuotaStatusCode::kErrorAbort);
+    callback.Run(blink::mojom::QuotaStatusCode::kErrorAbort);
     return;
   }
 
@@ -241,7 +241,8 @@
     RunFront(&pending_serial_requests_);
 
   if (!current_delete_request_callback_.is_null()) {
-    current_delete_request_callback_.Run(blink::QuotaStatusCode::kErrorAbort);
+    current_delete_request_callback_.Run(
+        blink::mojom::QuotaStatusCode::kErrorAbort);
     current_delete_request_callback_.Reset();
     GetServiceDeleteCallback()->Cancel();
   }
diff --git a/content/browser/appcache/appcache_quota_client.h b/content/browser/appcache/appcache_quota_client.h
index 776b0ea..50dddd2 100644
--- a/content/browser/appcache/appcache_quota_client.h
+++ b/content/browser/appcache/appcache_quota_client.h
@@ -17,7 +17,7 @@
 #include "net/base/completion_callback.h"
 #include "storage/browser/quota/quota_client.h"
 #include "storage/browser/quota/quota_task.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace content {
 class AppCacheQuotaClientTest;
@@ -39,17 +39,17 @@
   ID id() const override;
   void OnQuotaManagerDestroyed() override;
   void GetOriginUsage(const GURL& origin,
-                      blink::StorageType type,
+                      blink::mojom::StorageType type,
                       const GetUsageCallback& callback) override;
-  void GetOriginsForType(blink::StorageType type,
+  void GetOriginsForType(blink::mojom::StorageType type,
                          const GetOriginsCallback& callback) override;
-  void GetOriginsForHost(blink::StorageType type,
+  void GetOriginsForHost(blink::mojom::StorageType type,
                          const std::string& host,
                          const GetOriginsCallback& callback) override;
   void DeleteOriginData(const GURL& origin,
-                        blink::StorageType type,
+                        blink::mojom::StorageType type,
                         const DeletionCallback& callback) override;
-  bool DoesSupport(blink::StorageType type) const override;
+  bool DoesSupport(blink::mojom::StorageType type) const override;
 
  private:
   friend class content::AppCacheQuotaClientTest;
@@ -60,7 +60,7 @@
       explicit AppCacheQuotaClient(AppCacheServiceImpl* service);
 
   void DidDeleteAppCachesForOrigin(int rv);
-  void GetOriginsHelper(blink::StorageType type,
+  void GetOriginsHelper(blink::mojom::StorageType type,
                         const std::string& opt_host,
                         const GetOriginsCallback& callback);
   void ProcessPendingRequests();
diff --git a/content/browser/appcache/appcache_quota_client_unittest.cc b/content/browser/appcache/appcache_quota_client_unittest.cc
index cc5ee29..4aa4477 100644
--- a/content/browser/appcache/appcache_quota_client_unittest.cc
+++ b/content/browser/appcache/appcache_quota_client_unittest.cc
@@ -17,7 +17,7 @@
 
 namespace content {
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 
 // Declared to shorten the line lengths.
 static const StorageType kTemp = StorageType::kTemporary;
@@ -35,7 +35,7 @@
         kOriginB("http://host:8000"),
         kOriginOther("http://other"),
         usage_(0),
-        delete_status_(blink::QuotaStatusCode::kUnknown),
+        delete_status_(blink::mojom::QuotaStatusCode::kUnknown),
         num_get_origin_usage_completions_(0),
         num_get_origins_completions_(0),
         num_delete_origins_completions_(0),
@@ -67,10 +67,10 @@
     return origins_;
   }
 
-  blink::QuotaStatusCode DeleteOriginData(storage::QuotaClient* client,
-                                          StorageType type,
-                                          const GURL& origin) {
-    delete_status_ = blink::QuotaStatusCode::kUnknown;
+  blink::mojom::QuotaStatusCode DeleteOriginData(storage::QuotaClient* client,
+                                                 StorageType type,
+                                                 const GURL& origin) {
+    delete_status_ = blink::mojom::QuotaStatusCode::kUnknown;
     AsyncDeleteOriginData(client, type, origin);
     base::RunLoop().RunUntilIdle();
     return delete_status_;
@@ -141,7 +141,7 @@
     origins_ = origins;
   }
 
-  void OnDeleteOriginDataComplete(blink::QuotaStatusCode status) {
+  void OnDeleteOriginDataComplete(blink::mojom::QuotaStatusCode status) {
     ++num_delete_origins_completions_;
     delete_status_ = status;
   }
@@ -149,7 +149,7 @@
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   int64_t usage_;
   std::set<GURL> origins_;
-  blink::QuotaStatusCode delete_status_;
+  blink::mojom::QuotaStatusCode delete_status_;
   int num_get_origin_usage_completions_;
   int num_get_origins_completions_;
   int num_delete_origins_completions_;
@@ -175,9 +175,9 @@
   EXPECT_TRUE(GetOriginsForType(client, kPerm).empty());
   EXPECT_TRUE(GetOriginsForHost(client, kTemp, kOriginA.host()).empty());
   EXPECT_TRUE(GetOriginsForHost(client, kPerm, kOriginA.host()).empty());
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             DeleteOriginData(client, kTemp, kOriginA));
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             DeleteOriginData(client, kPerm, kOriginA));
 
   Call_NotifyAppCacheDestroyed(client);
@@ -195,9 +195,9 @@
   EXPECT_TRUE(GetOriginsForType(client, kPerm).empty());
   EXPECT_TRUE(GetOriginsForHost(client, kTemp, kOriginA.host()).empty());
   EXPECT_TRUE(GetOriginsForHost(client, kPerm, kOriginA.host()).empty());
-  EXPECT_EQ(blink::QuotaStatusCode::kErrorAbort,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kErrorAbort,
             DeleteOriginData(client, kTemp, kOriginA));
-  EXPECT_EQ(blink::QuotaStatusCode::kErrorAbort,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kErrorAbort,
             DeleteOriginData(client, kPerm, kOriginA));
 
   Call_OnQuotaManagerDestroyed(client);
@@ -272,17 +272,17 @@
 
   // Perm deletions are short circuited in the Client and
   // should not reach the AppCacheServiceImpl.
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             DeleteOriginData(client, kPerm, kOriginA));
   EXPECT_EQ(0, mock_service_.delete_called_count());
 
-  EXPECT_EQ(blink::QuotaStatusCode::kOk,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk,
             DeleteOriginData(client, kTemp, kOriginA));
   EXPECT_EQ(1, mock_service_.delete_called_count());
 
   mock_service_.set_mock_delete_appcaches_for_origin_result(
       net::ERR_ABORTED);
-  EXPECT_EQ(blink::QuotaStatusCode::kErrorAbort,
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kErrorAbort,
             DeleteOriginData(client, kTemp, kOriginA));
   EXPECT_EQ(2, mock_service_.delete_called_count());
 
@@ -364,7 +364,7 @@
   EXPECT_EQ(3, num_delete_origins_completions_);
   EXPECT_EQ(0, usage_);
   EXPECT_TRUE(origins_.empty());
-  EXPECT_EQ(blink::QuotaStatusCode::kErrorAbort, delete_status_);
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kErrorAbort, delete_status_);
 
   Call_OnQuotaManagerDestroyed(client);
 }
@@ -417,13 +417,13 @@
 
   // Should have been aborted.
   EXPECT_EQ(1, num_delete_origins_completions_);
-  EXPECT_EQ(blink::QuotaStatusCode::kErrorAbort, delete_status_);
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kErrorAbort, delete_status_);
 
   // A real completion callback from the service should
   // be dropped if it comes in after NotifyAppCacheDestroyed.
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, num_delete_origins_completions_);
-  EXPECT_EQ(blink::QuotaStatusCode::kErrorAbort, delete_status_);
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kErrorAbort, delete_status_);
 
   Call_OnQuotaManagerDestroyed(client);
 }
diff --git a/content/browser/appcache/appcache_storage.cc b/content/browser/appcache/appcache_storage.cc
index dae08109..58b1e85 100644
--- a/content/browser/appcache/appcache_storage.cc
+++ b/content/browser/appcache/appcache_storage.cc
@@ -11,7 +11,7 @@
 #include "content/browser/appcache/appcache_service_impl.h"
 #include "storage/browser/quota/quota_client.h"
 #include "storage/browser/quota/quota_manager_proxy.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace content {
 
@@ -111,8 +111,8 @@
     usage_map_.erase(origin);
   if (new_usage != old_usage && service()->quota_manager_proxy()) {
     service()->quota_manager_proxy()->NotifyStorageModified(
-        storage::QuotaClient::kAppcache, origin, blink::StorageType::kTemporary,
-        new_usage - old_usage);
+        storage::QuotaClient::kAppcache, origin,
+        blink::mojom::StorageType::kTemporary, new_usage - old_usage);
   }
 }
 
@@ -122,7 +122,7 @@
          iter != usage_map_.end(); ++iter) {
       service()->quota_manager_proxy()->NotifyStorageModified(
           storage::QuotaClient::kAppcache, iter->first,
-          blink::StorageType::kTemporary, -(iter->second));
+          blink::mojom::StorageType::kTemporary, -(iter->second));
     }
   }
   usage_map_.clear();
@@ -133,7 +133,7 @@
       usage_map_.find(origin) != usage_map_.end())
     service()->quota_manager_proxy()->NotifyStorageAccessed(
         storage::QuotaClient::kAppcache, origin,
-        blink::StorageType::kTemporary);
+        blink::mojom::StorageType::kTemporary);
 }
 
 }  // namespace content
diff --git a/content/browser/appcache/appcache_storage_impl.cc b/content/browser/appcache/appcache_storage_impl.cc
index ae53912..95de861c 100644
--- a/content/browser/appcache/appcache_storage_impl.cc
+++ b/content/browser/appcache/appcache_storage_impl.cc
@@ -37,8 +37,7 @@
 #include "storage/browser/quota/quota_client.h"
 #include "storage/browser/quota/quota_manager.h"
 #include "storage/browser/quota/quota_manager_proxy.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace content {
 
@@ -603,7 +602,7 @@
                          AppCache* newest_cache);
 
   void GetQuotaThenSchedule();
-  void OnQuotaCallback(blink::QuotaStatusCode status,
+  void OnQuotaCallback(blink::mojom::QuotaStatusCode status,
                        int64_t usage,
                        int64_t quota);
 
@@ -669,16 +668,16 @@
   // We have to ask the quota manager for the value.
   storage_->pending_quota_queries_.insert(this);
   quota_manager->GetUsageAndQuota(
-      group_record_.origin, blink::StorageType::kTemporary,
+      group_record_.origin, blink::mojom::StorageType::kTemporary,
       base::Bind(&StoreGroupAndCacheTask::OnQuotaCallback, this));
 }
 
 void AppCacheStorageImpl::StoreGroupAndCacheTask::OnQuotaCallback(
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     int64_t usage,
     int64_t quota) {
   if (storage_) {
-    if (status == blink::QuotaStatusCode::kOk)
+    if (status == blink::mojom::QuotaStatusCode::kOk)
       space_available_ = std::max(static_cast<int64_t>(0), quota - usage);
     else
       space_available_ = 0;
diff --git a/content/browser/appcache/appcache_storage_impl_unittest.cc b/content/browser/appcache/appcache_storage_impl_unittest.cc
index 5d5662aa..6731729 100644
--- a/content/browser/appcache/appcache_storage_impl_unittest.cc
+++ b/content/browser/appcache/appcache_storage_impl_unittest.cc
@@ -47,7 +47,7 @@
 
 namespace content {
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 
 namespace {
 
@@ -300,7 +300,7 @@
     }
 
     void CallCallback(const UsageAndQuotaCallback& callback) {
-      callback.Run(blink::QuotaStatusCode::kOk, 0, kMockQuota);
+      callback.Run(blink::mojom::QuotaStatusCode::kOk, 0, kMockQuota);
     }
 
     bool async_;
diff --git a/content/browser/appcache/appcache_storage_unittest.cc b/content/browser/appcache/appcache_storage_unittest.cc
index 4cd055d..9772c4cb 100644
--- a/content/browser/appcache/appcache_storage_unittest.cc
+++ b/content/browser/appcache/appcache_storage_unittest.cc
@@ -15,7 +15,7 @@
 namespace content {
 namespace appcache_storage_unittest {
 
-const blink::StorageType kTemp = blink::StorageType::kTemporary;
+const blink::mojom::StorageType kTemp = blink::mojom::StorageType::kTemporary;
 
 class AppCacheStorageTest : public testing::Test {
  public:
diff --git a/content/browser/background_fetch/background_fetch_context.cc b/content/browser/background_fetch/background_fetch_context.cc
index cc1cb4b..1d1f5df9 100644
--- a/content/browser/background_fetch/background_fetch_context.cc
+++ b/content/browser/background_fetch/background_fetch_context.cc
@@ -10,6 +10,7 @@
 #include "content/browser/background_fetch/background_fetch_job_controller.h"
 #include "content/browser/background_fetch/background_fetch_registration_id.h"
 #include "content/browser/background_fetch/background_fetch_registration_notifier.h"
+#include "content/browser/background_fetch/background_fetch_scheduler.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/public/browser/background_fetch_delegate.h"
 #include "content/public/browser/browser_context.h"
@@ -47,6 +48,7 @@
       registration_notifier_(
           std::make_unique<BackgroundFetchRegistrationNotifier>()),
       delegate_proxy_(browser_context_->GetBackgroundFetchDelegate()),
+      scheduler_(std::make_unique<BackgroundFetchScheduler>(&data_manager_)),
       weak_factory_(this) {
   // Although this lives only on the IO thread, it is constructed on UI thread.
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -182,7 +184,8 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   auto controller = std::make_unique<BackgroundFetchJobController>(
-      &delegate_proxy_, registration_id, options, registration, &data_manager_,
+      &delegate_proxy_, registration_id, options, registration,
+      scheduler_.get(),
       // Safe because JobControllers are destroyed before RegistrationNotifier.
       base::BindRepeating(&BackgroundFetchRegistrationNotifier::Notify,
                           base::Unretained(registration_notifier_.get())),
@@ -197,9 +200,7 @@
       data_manager_.GetTotalNumberOfRequests(registration_id),
       std::vector<std::string>() /* outstanding download GUIDs */);
 
-  // Start fetching the first few requests immediately. At some point in the
-  // future we may want a more elaborate scheduling mechanism here.
-  controller->Start();
+  scheduler_->AddJobController(controller.get());
 
   job_controllers_.insert(
       std::make_pair(registration_id.unique_id(), std::move(controller)));
diff --git a/content/browser/background_fetch/background_fetch_context.h b/content/browser/background_fetch/background_fetch_context.h
index 8692ef07..0693caa 100644
--- a/content/browser/background_fetch/background_fetch_context.h
+++ b/content/browser/background_fetch/background_fetch_context.h
@@ -30,6 +30,7 @@
 struct BackgroundFetchOptions;
 class BackgroundFetchRegistrationId;
 class BackgroundFetchRegistrationNotifier;
+class BackgroundFetchScheduler;
 class BrowserContext;
 class ServiceWorkerContextWrapper;
 struct ServiceWorkerFetchRequest;
@@ -173,6 +174,7 @@
   BackgroundFetchEventDispatcher event_dispatcher_;
   std::unique_ptr<BackgroundFetchRegistrationNotifier> registration_notifier_;
   BackgroundFetchDelegateProxy delegate_proxy_;
+  std::unique_ptr<BackgroundFetchScheduler> scheduler_;
 
   // Map from background fetch registration |unique_id|s to active job
   // controllers. Must be destroyed before |data_manager_| and
diff --git a/content/browser/background_fetch/background_fetch_data_manager.cc b/content/browser/background_fetch/background_fetch_data_manager.cc
index 21b9620..a251239 100644
--- a/content/browser/background_fetch/background_fetch_data_manager.cc
+++ b/content/browser/background_fetch/background_fetch_data_manager.cc
@@ -82,24 +82,9 @@
     return request;
   }
 
-  // Marks the |request| as having started with the given |download_guid|.
-  // Persistent storage needs to store the association so we can resume fetches
-  // after a browser restart, here we just verify that the |request| is active.
-  void MarkRequestAsStarted(BackgroundFetchRequestInfo* request,
-                            const std::string& download_guid) {
-    const auto iter = std::find_if(
-        active_requests_.begin(), active_requests_.end(),
-        [&request](scoped_refptr<BackgroundFetchRequestInfo> active_request) {
-          return active_request->request_index() == request->request_index();
-        });
-
-    // The |request| must have been consumed from this RegistrationData.
-    DCHECK(iter != active_requests_.end());
-  }
-
   // Marks the |request| as having completed. Verifies that the |request| is
   // currently active and moves it to the |completed_requests_| vector.
-  bool MarkRequestAsComplete(BackgroundFetchRequestInfo* request) {
+  void MarkRequestAsComplete(BackgroundFetchRequestInfo* request) {
     const auto iter = std::find_if(
         active_requests_.begin(), active_requests_.end(),
         [&request](scoped_refptr<BackgroundFetchRequestInfo> active_request) {
@@ -113,10 +98,6 @@
     active_requests_.erase(iter);
 
     complete_requests_downloaded_bytes_ += request->GetFileSize();
-
-    bool has_pending_or_active_requests =
-        !pending_requests_.empty() || !active_requests_.empty();
-    return has_pending_or_active_requests;
   }
 
   // Returns the vector with all completed requests part of this registration.
@@ -325,33 +306,19 @@
   std::move(callback).Run(std::move(next_request));
 }
 
-void BackgroundFetchDataManager::MarkRequestAsStarted(
-    const BackgroundFetchRegistrationId& registration_id,
-    BackgroundFetchRequestInfo* request,
-    const std::string& download_guid) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  auto iter = registrations_.find(registration_id.unique_id());
-  DCHECK(iter != registrations_.end());
-
-  RegistrationData* registration_data = iter->second.get();
-  registration_data->MarkRequestAsStarted(request, download_guid);
-}
-
 void BackgroundFetchDataManager::MarkRequestAsComplete(
     const BackgroundFetchRegistrationId& registration_id,
     BackgroundFetchRequestInfo* request,
-    MarkedCompleteCallback callback) {
+    BackgroundFetchScheduler::MarkedCompleteCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   auto iter = registrations_.find(registration_id.unique_id());
   DCHECK(iter != registrations_.end());
 
   RegistrationData* registration_data = iter->second.get();
-  bool has_pending_or_active_requests =
-      registration_data->MarkRequestAsComplete(request);
+  registration_data->MarkRequestAsComplete(request);
 
-  std::move(callback).Run(has_pending_or_active_requests);
+  std::move(callback).Run();
 }
 
 void BackgroundFetchDataManager::GetSettledFetchesForRegistration(
diff --git a/content/browser/background_fetch/background_fetch_data_manager.h b/content/browser/background_fetch/background_fetch_data_manager.h
index c901b40..9b3705b 100644
--- a/content/browser/background_fetch/background_fetch_data_manager.h
+++ b/content/browser/background_fetch/background_fetch_data_manager.h
@@ -17,7 +17,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "content/browser/background_fetch/background_fetch_registration_id.h"
-#include "content/browser/background_fetch/background_fetch_request_manager.h"
+#include "content/browser/background_fetch/background_fetch_scheduler.h"
 #include "content/browser/background_fetch/storage/database_task.h"
 #include "content/common/content_export.h"
 #include "third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom.h"
@@ -47,7 +47,7 @@
 //
 // Storage schema is documented in storage/README.md
 class CONTENT_EXPORT BackgroundFetchDataManager
-    : public BackgroundFetchRequestManager {
+    : public BackgroundFetchScheduler::RequestProvider {
  public:
   using SettledFetchesCallback = base::OnceCallback<void(
       blink::mojom::BackgroundFetchError,
@@ -57,10 +57,13 @@
   using GetRegistrationCallback =
       base::OnceCallback<void(blink::mojom::BackgroundFetchError,
                               std::unique_ptr<BackgroundFetchRegistration>)>;
+  using NextRequestCallback =
+      base::OnceCallback<void(scoped_refptr<BackgroundFetchRequestInfo>)>;
 
   BackgroundFetchDataManager(
       BrowserContext* browser_context,
       scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
+
   ~BackgroundFetchDataManager() override;
 
   // Creates and stores a new registration with the given properties. Will
@@ -122,17 +125,13 @@
   int GetTotalNumberOfRequests(
       const BackgroundFetchRegistrationId& registration_id) const;
 
-  // BackgroundFetchRequestManager implementation:
+  // BackgroundFetchScheduler::RequestProvider implementation:
   void PopNextRequest(const BackgroundFetchRegistrationId& registration_id,
                       NextRequestCallback callback) override;
-  void MarkRequestAsStarted(
-      const BackgroundFetchRegistrationId& registration_id,
-      BackgroundFetchRequestInfo* request,
-      const std::string& download_guid) override;
   void MarkRequestAsComplete(
       const BackgroundFetchRegistrationId& registration_id,
       BackgroundFetchRequestInfo* request,
-      MarkedCompleteCallback callback) override;
+      BackgroundFetchScheduler::MarkedCompleteCallback callback) override;
 
  private:
   FRIEND_TEST_ALL_PREFIXES(BackgroundFetchDataManagerTest, Cleanup);
diff --git a/content/browser/background_fetch/background_fetch_job_controller.cc b/content/browser/background_fetch/background_fetch_job_controller.cc
index 84aea94f..f498d24 100644
--- a/content/browser/background_fetch/background_fetch_job_controller.cc
+++ b/content/browser/background_fetch/background_fetch_job_controller.cc
@@ -19,14 +19,14 @@
     const BackgroundFetchRegistration& registration,
     BackgroundFetchRequestManager* request_manager,
     ProgressCallback progress_callback,
-    FinishedCallback finished_callback)
-    : registration_id_(registration_id),
+    BackgroundFetchScheduler::FinishedCallback finished_callback)
+    : BackgroundFetchScheduler::Controller(registration_id,
+                                           std::move(finished_callback)),
       options_(options),
       complete_requests_downloaded_bytes_cache_(registration.downloaded),
       request_manager_(request_manager),
       delegate_proxy_(delegate_proxy),
       progress_callback_(std::move(progress_callback)),
-      finished_callback_(std::move(finished_callback)),
       weak_ptr_factory_(this) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 }
@@ -37,8 +37,15 @@
     const std::vector<std::string>& outstanding_guids) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
+  // Don't allow double initialization.
+  DCHECK_GT(total_downloads, 0);
+  DCHECK_EQ(total_downloads_, 0);
+
+  completed_downloads_ = completed_downloads;
+  total_downloads_ = total_downloads;
+
   delegate_proxy_->CreateDownloadJob(
-      registration_id_.unique_id(), options_.title, registration_id_.origin(),
+      registration_id().unique_id(), options_.title, registration_id().origin(),
       GetWeakPtr(), completed_downloads, total_downloads, outstanding_guids);
 }
 
@@ -46,39 +53,29 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 }
 
-void BackgroundFetchJobController::Start() {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  // TODO(crbug.com/741609): Enforce kMaximumBackgroundFetchParallelRequests
-  // globally and/or per origin rather than per fetch.
-  for (size_t i = 0; i < kMaximumBackgroundFetchParallelRequests; i++) {
-    request_manager_->PopNextRequest(
-        registration_id_,
-        base::BindOnce(&BackgroundFetchJobController::StartRequest,
-                       weak_ptr_factory_.GetWeakPtr()));
-  }
+bool BackgroundFetchJobController::HasMoreRequests() {
+  return completed_downloads_ < total_downloads_;
 }
 
 void BackgroundFetchJobController::StartRequest(
     scoped_refptr<BackgroundFetchRequestInfo> request) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (!request) {
-    // This can happen when |Start| tries to start multiple initial requests,
-    // but the fetch does not contain that many pending requests; or when
-    // |DidMarkRequestCompleted| tries to start the next request but there are
-    // none left, perhaps because the registration was aborted.
-    return;
-  }
+  DCHECK_LT(completed_downloads_, total_downloads_);
+  DCHECK(request);
 
-  delegate_proxy_->StartRequest(registration_id_.unique_id(),
-                                registration_id_.origin(), request);
+  active_request_download_bytes_[request->download_guid()] = 0;
+
+  delegate_proxy_->StartRequest(registration_id().unique_id(),
+                                registration_id().origin(), request);
 }
 
 void BackgroundFetchJobController::DidStartRequest(
     const scoped_refptr<BackgroundFetchRequestInfo>& request) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  request_manager_->MarkRequestAsStarted(registration_id_, request.get(),
-                                         request->download_guid());
+  // TODO(delphick): Either add CORS check here or remove this function and do
+  // the CORS check in BackgroundFetchDelegateImpl (since
+  // download::Client::OnDownloadStarted returns a value that can abort the
+  // download).
 }
 
 void BackgroundFetchJobController::DidUpdateRequest(
@@ -92,7 +89,7 @@
 
   active_request_download_bytes_[download_guid] = bytes_downloaded;
 
-  progress_callback_.Run(registration_id_.unique_id(), options_.download_total,
+  progress_callback_.Run(registration_id().unique_id(), options_.download_total,
                          complete_requests_downloaded_bytes_cache_ +
                              GetInProgressDownloadedBytes());
 }
@@ -103,38 +100,9 @@
 
   active_request_download_bytes_.erase(request->download_guid());
   complete_requests_downloaded_bytes_cache_ += request->GetFileSize();
+  ++completed_downloads_;
 
-  // The RequestManager must acknowledge that it stored the data and that there
-  // are no more pending requests to avoid marking this job as completed too
-  // early.
-  request_manager_->MarkRequestAsComplete(
-      registration_id_, request.get(),
-      base::BindOnce(&BackgroundFetchJobController::DidMarkRequestCompleted,
-                     weak_ptr_factory_.GetWeakPtr()));
-}
-
-void BackgroundFetchJobController::DidMarkRequestCompleted(
-    bool has_pending_or_active_requests) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  // If not all requests have completed, start a pending request if there are
-  // any left, and bail.
-  if (has_pending_or_active_requests) {
-    request_manager_->PopNextRequest(
-        registration_id_,
-        base::BindOnce(&BackgroundFetchJobController::StartRequest,
-                       weak_ptr_factory_.GetWeakPtr()));
-    return;
-  }
-
-  // Otherwise the job this controller is responsible for has completed.
-  if (finished_callback_) {
-    // Copy registration_id_ onto stack as finished_callback_ may delete |this|.
-    BackgroundFetchRegistrationId registration_id(registration_id_);
-
-    // This call will be ignored if the job has already been aborted.
-    std::move(finished_callback_).Run(registration_id, false /* aborted */);
-  }
+  request_manager_->MarkRequestAsComplete(registration_id(), request.get());
 }
 
 void BackgroundFetchJobController::AbortFromUser() {
@@ -146,7 +114,7 @@
 void BackgroundFetchJobController::UpdateUI(const std::string& title) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  delegate_proxy_->UpdateUI(registration_id_.unique_id(), title);
+  delegate_proxy_->UpdateUI(registration_id().unique_id(), title);
 }
 
 uint64_t BackgroundFetchJobController::GetInProgressDownloadedBytes() {
@@ -164,16 +132,13 @@
 
 void BackgroundFetchJobController::Abort(bool cancel_download) {
   if (cancel_download)
-    delegate_proxy_->Abort(registration_id_.unique_id());
+    delegate_proxy_->Abort(registration_id().unique_id());
 
-  if (!finished_callback_)
-    return;
-
-  // Copy registration_id_ onto stack as finished_callback_ may delete |this|.
-  BackgroundFetchRegistrationId registration_id(registration_id_);
-
-  // This call will be ignored if job has already completed/failed/aborted.
-  std::move(finished_callback_).Run(registration_id, true /* aborted */);
+  std::vector<std::string> aborted_guids;
+  for (const auto& pair : active_request_download_bytes_)
+    aborted_guids.push_back(pair.first);
+  request_manager_->OnJobAborted(registration_id(), std::move(aborted_guids));
+  Finish(true /* aborted */);
 }
 
 }  // namespace content
diff --git a/content/browser/background_fetch/background_fetch_job_controller.h b/content/browser/background_fetch/background_fetch_job_controller.h
index cfd75f5..ff94210 100644
--- a/content/browser/background_fetch/background_fetch_job_controller.h
+++ b/content/browser/background_fetch/background_fetch_job_controller.h
@@ -16,6 +16,7 @@
 #include "content/browser/background_fetch/background_fetch_delegate_proxy.h"
 #include "content/browser/background_fetch/background_fetch_registration_id.h"
 #include "content/browser/background_fetch/background_fetch_request_info.h"
+#include "content/browser/background_fetch/background_fetch_scheduler.h"
 #include "content/common/background_fetch/background_fetch_types.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/browser_thread.h"
@@ -34,7 +35,8 @@
 // registration has been aborted, or once it has completed/failed and the
 // waitUntil promise has been resolved so UpdateUI can no longer be called).
 class CONTENT_EXPORT BackgroundFetchJobController final
-    : public BackgroundFetchDelegateProxy::Controller {
+    : public BackgroundFetchDelegateProxy::Controller,
+      public BackgroundFetchScheduler::Controller {
  public:
   using FinishedCallback =
       base::OnceCallback<void(const BackgroundFetchRegistrationId&,
@@ -50,13 +52,9 @@
       const BackgroundFetchRegistration& registration,
       BackgroundFetchRequestManager* request_manager,
       ProgressCallback progress_callback,
-      FinishedCallback finished_callback);
+      BackgroundFetchScheduler::FinishedCallback finished_callback);
   ~BackgroundFetchJobController() override;
 
-  // Starts fetching the first few requests. The controller will continue to
-  // fetch new content until all requests have been handled.
-  void Start();
-
   // Initializes the job controller with the status of the active and completed
   // downloads. Only called when this has been loaded from the database.
   void InitializeRequestStatus(
@@ -74,11 +72,6 @@
   // Aborts the job including cancelling any ongoing downloads.
   void Abort();
 
-  // Returns the registration id for which this job is fetching data.
-  const BackgroundFetchRegistrationId& registration_id() const {
-    return registration_id_;
-  }
-
   // Returns the options with which this job is fetching data.
   const BackgroundFetchOptions& options() const { return options_; }
 
@@ -96,21 +89,16 @@
       const scoped_refptr<BackgroundFetchRequestInfo>& request) override;
   void AbortFromUser() override;
 
+  // BackgroundFetchScheduler::Controller implementation:
+  bool HasMoreRequests() override;
+  void StartRequest(scoped_refptr<BackgroundFetchRequestInfo> request) override;
+
  private:
   // Aborts a job updating the registration with the new state. If
   // |cancel_download| is true, the ongoing download is also cancelled
   // (otherwise it assumes that has already happened).
   void Abort(bool cancel_download);
 
-  // Requests the download manager to start fetching |request|.
-  void StartRequest(scoped_refptr<BackgroundFetchRequestInfo> request);
-
-  // Called when a completed download has been marked as such in DataManager.
-  void DidMarkRequestCompleted(bool has_pending_or_active_requests);
-
-  // The registration id on behalf of which this controller is fetching data.
-  BackgroundFetchRegistrationId registration_id_;
-
   // Options for the represented background fetch registration.
   BackgroundFetchOptions options_;
 
@@ -132,8 +120,11 @@
   // Callback run each time download progress updates.
   ProgressCallback progress_callback_;
 
-  // Callback for when all fetches have completed/failed/aborted.
-  FinishedCallback finished_callback_;
+  // Number of requests that comprise the whole job.
+  int total_downloads_ = 0;
+
+  // Number of the requests that have been completed so far.
+  int completed_downloads_ = 0;
 
   base::WeakPtrFactory<BackgroundFetchJobController> weak_ptr_factory_;
 
diff --git a/content/browser/background_fetch/background_fetch_job_controller_unittest.cc b/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
index 99b9eba..98d7ed2a0 100644
--- a/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <map>
 #include <memory>
+#include <set>
 #include <string>
 #include <unordered_map>
 #include <utility>
@@ -31,14 +32,66 @@
 namespace content {
 namespace {
 
+const int64_t kExampleServiceWorkerRegistrationId = 1;
 const char kExampleDeveloperId[] = "my-example-id";
 const char kExampleResponseData[] = "My response data";
 
+enum class JobCompletionStatus { kRunning, kCompleted, kAborted };
+
+class FakeBackgroundFetchRequestManager : public BackgroundFetchRequestManager {
+ public:
+  void AddDownloadJob(const BackgroundFetchRegistrationId& registration_id,
+                      const std::set<std::string>& download_guids) {
+    DCHECK(!registration_status_map_.count(registration_id.unique_id()));
+    registration_status_map_.emplace(registration_id.unique_id(),
+                                     RegistrationState(download_guids));
+  }
+
+  // BackgroundFetchRequestManager implementation:
+  void MarkRequestAsComplete(
+      const BackgroundFetchRegistrationId& registration_id,
+      scoped_refptr<BackgroundFetchRequestInfo> request) override {
+    DCHECK(registration_status_map_.count(registration_id.unique_id()));
+    auto& state = registration_status_map_[registration_id.unique_id()];
+
+    DCHECK_EQ(state.status, JobCompletionStatus::kRunning);
+    DCHECK(state.uncompleted_downloads.count(request->download_guid()));
+    state.uncompleted_downloads.erase(request->download_guid());
+
+    if (state.uncompleted_downloads.size() == 0) {
+      state.status = JobCompletionStatus::kCompleted;
+    }
+  }
+
+  void OnJobAborted(const BackgroundFetchRegistrationId& registration_id,
+                    std::vector<std::string> aborted_guids) override {
+    DCHECK(registration_status_map_.count(registration_id.unique_id()));
+    auto& state = registration_status_map_[registration_id.unique_id()];
+    DCHECK_EQ(state.status, JobCompletionStatus::kRunning);
+    state.status = JobCompletionStatus::kAborted;
+  }
+
+  JobCompletionStatus GetCompletionStatus(
+      const BackgroundFetchRegistrationId& registration_id) {
+    DCHECK(registration_status_map_.count(registration_id.unique_id()));
+    return registration_status_map_[registration_id.unique_id()].status;
+  }
+
+  struct RegistrationState {
+    RegistrationState() = default;
+    explicit RegistrationState(const std::set<std::string>& downloads)
+        : uncompleted_downloads(downloads) {}
+    JobCompletionStatus status = JobCompletionStatus::kRunning;
+    std::set<std::string> uncompleted_downloads;
+  };
+
+  std::map<std::string, RegistrationState> registration_status_map_;
+};
+
 class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
  public:
-  BackgroundFetchJobControllerTest()
-      : data_manager_(browser_context(),
-                      embedded_worker_test_helper()->context_wrapper()) {}
+  BackgroundFetchJobControllerTest() = default;
+
   ~BackgroundFetchJobControllerTest() override = default;
 
   // Creates a new Background Fetch registration, whose id will be stored in the
@@ -46,40 +99,34 @@
   // |request_data|. If |auto_complete_requests| is true, the request will
   // immediately receive a successful response. Should be wrapped in
   // ASSERT_NO_FATAL_FAILURE().
-  void CreateRegistrationForRequests(
+  std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
+  CreateRegistrationForRequests(
       BackgroundFetchRegistrationId* registration_id,
       std::map<GURL, std::string /* method */> request_data,
       bool auto_complete_requests) {
     DCHECK(registration_id);
 
-    int64_t service_worker_registration_id = RegisterServiceWorker();
-    ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
-              service_worker_registration_id);
-
     // New |unique_id|, since this is a new Background Fetch registration.
     *registration_id = BackgroundFetchRegistrationId(
-        service_worker_registration_id, origin(), kExampleDeveloperId,
+        kExampleServiceWorkerRegistrationId, origin(), kExampleDeveloperId,
         base::GenerateGUID());
 
-    std::vector<ServiceWorkerFetchRequest> requests;
-    requests.reserve(request_data.size());
-
+    std::vector<scoped_refptr<BackgroundFetchRequestInfo>> request_infos;
+    std::set<std::string> uncompleted_downloads_guids;
+    int request_counter = 0;
     for (const auto& pair : request_data) {
-      requests.emplace_back(pair.first, pair.second /* method */,
-                            ServiceWorkerHeaderMap(), Referrer(),
-                            false /* is_reload */);
+      ServiceWorkerFetchRequest fetch_request(
+          GURL(pair.first), pair.second, ServiceWorkerHeaderMap(), Referrer(),
+          false /* is_reload */);
+      auto request = base::MakeRefCounted<BackgroundFetchRequestInfo>(
+          request_counter++, fetch_request);
+      request->InitializeDownloadGuid();
+      request_infos.push_back(request);
+      uncompleted_downloads_guids.insert(request->download_guid());
     }
 
-    blink::mojom::BackgroundFetchError error;
-
-    base::RunLoop run_loop;
-    data_manager_.CreateRegistration(
-        *registration_id, requests, BackgroundFetchOptions(),
-        base::BindOnce(&BackgroundFetchJobControllerTest::DidCreateRegistration,
-                       base::Unretained(this), &error, run_loop.QuitClosure()));
-    run_loop.Run();
-
-    ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+    request_manager_.AddDownloadJob(*registration_id,
+                                    uncompleted_downloads_guids);
 
     if (auto_complete_requests) {
       // Provide fake responses for the given |request_data| pairs.
@@ -91,12 +138,14 @@
                 .Build());
       }
     }
+
+    return request_infos;
   }
 
   // Creates a new BackgroundFetchJobController instance.
   std::unique_ptr<BackgroundFetchJobController> CreateJobController(
       const BackgroundFetchRegistrationId& registration_id,
-      int total_downloads = 1) {
+      int total_downloads) {
     delegate_ = browser_context()->GetBackgroundFetchDelegate();
     DCHECK(delegate_);
     delegate_proxy_ = std::make_unique<BackgroundFetchDelegateProxy>(delegate_);
@@ -107,12 +156,11 @@
 
     auto controller = std::make_unique<BackgroundFetchJobController>(
         delegate_proxy_.get(), registration_id, BackgroundFetchOptions(),
-        registration, &data_manager_,
+        registration, &request_manager_,
         base::BindRepeating(
             &BackgroundFetchJobControllerTest::DidUpdateProgress,
             base::Unretained(this)),
-        base::BindOnce(&BackgroundFetchJobControllerTest::DidFinishJob,
-                       base::Unretained(this)));
+        base::BindOnce(&BackgroundFetchJobControllerTest::OnJobFinished));
 
     controller->InitializeRequestStatus(0, total_downloads,
                                         std::vector<std::string>());
@@ -120,36 +168,18 @@
   }
 
  protected:
-  BackgroundFetchDataManager data_manager_;
+  FakeBackgroundFetchRequestManager request_manager_;
 
   uint64_t last_downloaded_ = 0;
-  bool did_finish_job_ = false;
-  bool was_aborted_ = false;
 
   // Closure that will be invoked every time the JobController receives a
   // progress update from a download.
   base::RepeatingClosure job_progress_closure_;
 
-  // Closure that will be invoked when the JobController has completed all
-  // available jobs. Enables use of a run loop for deterministic waits.
-  base::OnceClosure job_completed_closure_;
-
   std::unique_ptr<BackgroundFetchDelegateProxy> delegate_proxy_;
   BackgroundFetchDelegate* delegate_;
 
  private:
-  void DidCreateRegistration(
-      blink::mojom::BackgroundFetchError* out_error,
-      const base::Closure& quit_closure,
-      blink::mojom::BackgroundFetchError error,
-      std::unique_ptr<BackgroundFetchRegistration> registration) {
-    DCHECK(out_error);
-
-    *out_error = error;
-
-    quit_closure.Run();
-  }
-
   void DidUpdateProgress(const std::string& unique_id,
                          uint64_t download_total,
                          uint64_t downloaded) {
@@ -159,14 +189,8 @@
       job_progress_closure_.Run();
   }
 
-  void DidFinishJob(const BackgroundFetchRegistrationId& registration_id,
-                    bool aborted) {
-    did_finish_job_ = true;
-    was_aborted_ = aborted;
-
-    if (job_completed_closure_)
-      std::move(job_completed_closure_).Run();
-  }
+  static void OnJobFinished(const BackgroundFetchRegistrationId&,
+                            bool aborted) {}
 
   DISALLOW_COPY_AND_ASSIGN(BackgroundFetchJobControllerTest);
 };
@@ -174,100 +198,101 @@
 TEST_F(BackgroundFetchJobControllerTest, SingleRequestJob) {
   BackgroundFetchRegistrationId registration_id;
 
-  ASSERT_NO_FATAL_FAILURE(CreateRegistrationForRequests(
+  auto requests = CreateRegistrationForRequests(
       &registration_id, {{GURL("https://example.com/funny_cat.png"), "GET"}},
-      true /* auto_complete_requests */));
+      true /* auto_complete_requests */);
+
+  EXPECT_EQ(JobCompletionStatus::kRunning,
+            request_manager_.GetCompletionStatus(registration_id));
 
   std::unique_ptr<BackgroundFetchJobController> controller =
-      CreateJobController(registration_id);
+      CreateJobController(registration_id, requests.size());
 
-  controller->Start();
+  controller->StartRequest(requests[0]);
 
-  // Continue spinning until the Job Controller has completed the request.
-  // The Delegate has been told to automatically mark it as finished.
-  {
-    base::RunLoop run_loop;
-    job_completed_closure_ = run_loop.QuitClosure();
+  base::RunLoop().RunUntilIdle();
 
-    run_loop.Run();
-  }
-
-  EXPECT_TRUE(did_finish_job_);
-  EXPECT_FALSE(was_aborted_);
+  EXPECT_EQ(JobCompletionStatus::kCompleted,
+            request_manager_.GetCompletionStatus(registration_id));
 }
 
 TEST_F(BackgroundFetchJobControllerTest, MultipleRequestJob) {
   BackgroundFetchRegistrationId registration_id;
 
-  // This test should always issue more requests than the number of allowed
-  // parallel requests. That way we ensure testing the iteration behaviour.
-  ASSERT_GT(5u, kMaximumBackgroundFetchParallelRequests);
-
-  ASSERT_NO_FATAL_FAILURE(CreateRegistrationForRequests(
+  auto requests = CreateRegistrationForRequests(
       &registration_id,
       {{GURL("https://example.com/funny_cat.png"), "GET"},
        {GURL("https://example.com/scary_cat.png"), "GET"},
-       {GURL("https://example.com/crazy_cat.png"), "GET"},
-       {GURL("https://example.com/silly_cat.png"), "GET"},
-       {GURL("https://example.com/happy_cat.png"), "GET"}},
-      true /* auto_complete_requests */));
+       {GURL("https://example.com/crazy_cat.png"), "GET"}},
+      true /* auto_complete_requests */);
+
+  EXPECT_EQ(JobCompletionStatus::kRunning,
+            request_manager_.GetCompletionStatus(registration_id));
 
   std::unique_ptr<BackgroundFetchJobController> controller =
-      CreateJobController(registration_id);
+      CreateJobController(registration_id, requests.size());
 
-  // Continue spinning until the Job Controller has completed all the requests.
-  // The Delegate has been told to automatically mark them as finished.
-  {
-    base::RunLoop run_loop;
-    job_completed_closure_ = run_loop.QuitClosure();
+  controller->StartRequest(requests[0]);
 
-    controller->Start();
+  base::RunLoop().RunUntilIdle();
 
-    run_loop.Run();
-  }
+  EXPECT_EQ(JobCompletionStatus::kRunning,
+            request_manager_.GetCompletionStatus(registration_id));
 
-  EXPECT_TRUE(did_finish_job_);
-  EXPECT_FALSE(was_aborted_);
+  controller->StartRequest(requests[1]);
+
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(JobCompletionStatus::kRunning,
+            request_manager_.GetCompletionStatus(registration_id));
+
+  controller->StartRequest(requests[2]);
+
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(JobCompletionStatus::kCompleted,
+            request_manager_.GetCompletionStatus(registration_id));
 }
 
 TEST_F(BackgroundFetchJobControllerTest, Abort) {
   BackgroundFetchRegistrationId registration_id;
 
-  ASSERT_NO_FATAL_FAILURE(CreateRegistrationForRequests(
-      &registration_id, {{GURL("https://example.com/sad_cat.png"), "GET"}},
-      false /* auto_complete_requests */));
+  auto requests = CreateRegistrationForRequests(
+      &registration_id, {{GURL("https://example.com/funny_cat.png"), "GET"}},
+      true /* auto_complete_requests */);
+
+  EXPECT_EQ(JobCompletionStatus::kRunning,
+            request_manager_.GetCompletionStatus(registration_id));
 
   std::unique_ptr<BackgroundFetchJobController> controller =
-      CreateJobController(registration_id);
+      CreateJobController(registration_id, requests.size());
 
-  // Start the request, and abort it immediately after.
-  controller->Start();
+  controller->StartRequest(requests[0]);
+  controller->AbortFromUser();
+  // Tell the delegate to abort the job as well so it doesn't send completed
+  // messages to the JobController.
+  delegate_->Abort(registration_id.unique_id());
 
-  // TODO(delphick): Add test for AbortFromUser as well.
-  controller->Abort();
-
-  // Run until idle to ensure that spurious download successful tasks are not
-  // executed.
   base::RunLoop().RunUntilIdle();
 
-  // TODO(peter): Verify that the issued download items have had their state
-  // updated to be cancelled as well.
-
-  EXPECT_TRUE(did_finish_job_);
-  EXPECT_TRUE(was_aborted_);
+  EXPECT_EQ(JobCompletionStatus::kAborted,
+            request_manager_.GetCompletionStatus(registration_id));
 }
 
 TEST_F(BackgroundFetchJobControllerTest, Progress) {
   BackgroundFetchRegistrationId registration_id;
 
-  ASSERT_NO_FATAL_FAILURE(CreateRegistrationForRequests(
-      &registration_id, {{GURL("https://example.com/slow_cat.png"), "GET"}},
-      true /* auto_complete_requests */));
+  auto requests = CreateRegistrationForRequests(
+      &registration_id, {{GURL("https://example.com/funny_cat.png"), "GET"}},
+      true /* auto_complete_requests */);
+
+  EXPECT_EQ(JobCompletionStatus::kRunning,
+            request_manager_.GetCompletionStatus(registration_id));
 
   std::unique_ptr<BackgroundFetchJobController> controller =
-      CreateJobController(registration_id);
+      CreateJobController(registration_id, requests.size());
 
-  controller->Start();
+  controller->StartRequest(requests[0]);
 
   {
     base::RunLoop run_loop;
@@ -277,14 +302,13 @@
 
   EXPECT_GT(last_downloaded_, 0u);
   EXPECT_LT(last_downloaded_, strlen(kExampleResponseData));
+  EXPECT_EQ(JobCompletionStatus::kRunning,
+            request_manager_.GetCompletionStatus(registration_id));
 
-  {
-    base::RunLoop run_loop;
-    job_completed_closure_ = run_loop.QuitClosure();
-    run_loop.Run();
-  }
+  base::RunLoop().RunUntilIdle();
 
-  EXPECT_TRUE(did_finish_job_);
+  EXPECT_EQ(JobCompletionStatus::kCompleted,
+            request_manager_.GetCompletionStatus(registration_id));
   EXPECT_EQ(last_downloaded_, strlen(kExampleResponseData));
 }
 
diff --git a/content/browser/background_fetch/background_fetch_request_manager.h b/content/browser/background_fetch/background_fetch_request_manager.h
index f987104..6a264c8 100644
--- a/content/browser/background_fetch/background_fetch_request_manager.h
+++ b/content/browser/background_fetch/background_fetch_request_manager.h
@@ -6,6 +6,7 @@
 #define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_REQUEST_MANAGER_H_
 
 #include <string>
+#include <vector>
 
 #include "base/callback_forward.h"
 #include "base/memory/scoped_refptr.h"
@@ -20,32 +21,19 @@
 // |BackgroundFetchRegistrationId| that may be backed by a database.
 class BackgroundFetchRequestManager {
  public:
-  using NextRequestCallback =
-      base::OnceCallback<void(scoped_refptr<BackgroundFetchRequestInfo>)>;
-  using MarkedCompleteCallback =
-      base::OnceCallback<void(bool /* has_pending_or_active_requests */)>;
-
   virtual ~BackgroundFetchRequestManager() {}
 
-  // Removes the next request, if any, from the pending requests queue, and
-  // invokes the |callback| with that request, else a null request.
-  virtual void PopNextRequest(
-      const BackgroundFetchRegistrationId& registration_id,
-      NextRequestCallback callback) = 0;
-
-  // Marks that the |request|, part of the Background Fetch identified by
-  // |registration_id|, has been started as |download_guid|.
-  virtual void MarkRequestAsStarted(
-      const BackgroundFetchRegistrationId& registration_id,
-      BackgroundFetchRequestInfo* request,
-      const std::string& download_guid) = 0;
-
   // Marks that the |request|, part of the Background Fetch identified by
   // |registration_id|, has completed.
   virtual void MarkRequestAsComplete(
       const BackgroundFetchRegistrationId& registration_id,
-      BackgroundFetchRequestInfo* request,
-      MarkedCompleteCallback callback) = 0;
+      scoped_refptr<BackgroundFetchRequestInfo> request) = 0;
+
+  // Called when the job identified by |registration_id| has been aborted along
+  // with the GUIDs of any associated downloads that were still active.
+  virtual void OnJobAborted(
+      const BackgroundFetchRegistrationId& registration_id,
+      std::vector<std::string> aborted_guids) = 0;
 };
 
 }  // namespace content
diff --git a/content/browser/background_fetch/background_fetch_scheduler.cc b/content/browser/background_fetch/background_fetch_scheduler.cc
new file mode 100644
index 0000000..1b96430
--- /dev/null
+++ b/content/browser/background_fetch/background_fetch_scheduler.cc
@@ -0,0 +1,99 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/background_fetch_scheduler.h"
+
+#include "base/guid.h"
+#include "content/browser/background_fetch/background_fetch_job_controller.h"
+
+namespace content {
+
+BackgroundFetchScheduler::Controller::Controller(
+    const BackgroundFetchRegistrationId& registration_id,
+    FinishedCallback finished_callback)
+    : registration_id_(registration_id),
+      finished_callback_(std::move(finished_callback)) {
+  DCHECK(finished_callback_);
+}
+
+BackgroundFetchScheduler::Controller::~Controller() = default;
+
+void BackgroundFetchScheduler::Controller::Finish(bool abort) {
+  DCHECK(abort || !HasMoreRequests());
+  std::move(finished_callback_).Run(registration_id_, abort);
+}
+
+BackgroundFetchScheduler::BackgroundFetchScheduler(
+    BackgroundFetchScheduler::RequestProvider* request_provider)
+    : request_provider_(request_provider) {}
+
+BackgroundFetchScheduler::~BackgroundFetchScheduler() = default;
+
+void BackgroundFetchScheduler::AddJobController(
+    BackgroundFetchScheduler::Controller* controller) {
+  controller_queue_.push_back(controller);
+
+  while (!controller_queue_.empty() &&
+         download_controller_map_.size() < max_concurrent_downloads_) {
+    ScheduleDownload();
+  }
+}
+
+void BackgroundFetchScheduler::ScheduleDownload() {
+  DCHECK(download_controller_map_.size() < max_concurrent_downloads_);
+
+  if (controller_queue_.empty())
+    return;
+
+  auto* controller = controller_queue_.front();
+  controller_queue_.pop_front();
+
+  request_provider_->PopNextRequest(
+      controller->registration_id(),
+      base::BindOnce(&BackgroundFetchScheduler::DidPopNextRequest,
+                     base::Unretained(this), controller));
+}
+
+void BackgroundFetchScheduler::DidPopNextRequest(
+    BackgroundFetchScheduler::Controller* controller,
+    scoped_refptr<BackgroundFetchRequestInfo> request_info) {
+  download_controller_map_[request_info->download_guid()] = controller;
+  controller->StartRequest(request_info);
+}
+
+void BackgroundFetchScheduler::MarkRequestAsComplete(
+    const BackgroundFetchRegistrationId& registration_id,
+    scoped_refptr<BackgroundFetchRequestInfo> request) {
+  DCHECK(download_controller_map_.count(request->download_guid()));
+  auto* controller = download_controller_map_[request->download_guid()];
+  download_controller_map_.erase(request->download_guid());
+
+  request_provider_->MarkRequestAsComplete(
+      controller->registration_id(), request.get(),
+      base::BindOnce(&BackgroundFetchScheduler::DidMarkRequestAsComplete,
+                     base::Unretained(this), controller));
+}
+
+void BackgroundFetchScheduler::DidMarkRequestAsComplete(
+    BackgroundFetchScheduler::Controller* controller) {
+  if (controller->HasMoreRequests())
+    controller_queue_.push_back(controller);
+  else
+    controller->Finish(false);
+
+  ScheduleDownload();
+}
+
+void BackgroundFetchScheduler::OnJobAborted(
+    const BackgroundFetchRegistrationId& registration_id,
+    std::vector<std::string> aborted_guids) {
+  // For every active download that was aborted, remove it and schedule a new
+  // download.
+  for (const auto& guid : aborted_guids) {
+    download_controller_map_.erase(guid);
+    ScheduleDownload();
+  }
+}
+
+}  // namespace content
diff --git a/content/browser/background_fetch/background_fetch_scheduler.h b/content/browser/background_fetch/background_fetch_scheduler.h
new file mode 100644
index 0000000..fb72f314
--- /dev/null
+++ b/content/browser/background_fetch/background_fetch_scheduler.h
@@ -0,0 +1,124 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_SCHEDULER_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_SCHEDULER_H_
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/containers/circular_deque.h"
+#include "base/macros.h"
+#include "content/browser/background_fetch/background_fetch_registration_id.h"
+#include "content/browser/background_fetch/background_fetch_request_manager.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class BackgroundFetchRegistrationId;
+class BackgroundFetchRequestInfo;
+
+// Maintains a list of Controllers and chooses which ones should launch new
+// downloads.
+class CONTENT_EXPORT BackgroundFetchScheduler
+    : public BackgroundFetchRequestManager {
+ public:
+  using FinishedCallback =
+      base::OnceCallback<void(const BackgroundFetchRegistrationId&,
+                              bool /* aborted */)>;
+  using MarkedCompleteCallback = base::OnceCallback<void()>;
+
+  // Interface for download job controllers.
+  class CONTENT_EXPORT Controller {
+   public:
+    virtual ~Controller();
+
+    // Returns whether the Controller has any pending download requests.
+    virtual bool HasMoreRequests() = 0;
+
+    // Requests the download manager to start fetching |request|.
+    virtual void StartRequest(
+        scoped_refptr<BackgroundFetchRequestInfo> request) = 0;
+
+    void Finish(bool abort);
+
+    const BackgroundFetchRegistrationId& registration_id() const {
+      return registration_id_;
+    }
+
+   protected:
+    Controller(const BackgroundFetchRegistrationId& registration_id,
+               FinishedCallback finished_callback);
+
+   private:
+    BackgroundFetchRegistrationId registration_id_;
+    FinishedCallback finished_callback_;
+  };
+
+  using NextRequestCallback =
+      base::OnceCallback<void(scoped_refptr<BackgroundFetchRequestInfo>)>;
+
+  class CONTENT_EXPORT RequestProvider {
+   public:
+    virtual ~RequestProvider() {}
+
+    // Retrieves the next pending request for |registration_id| and invoke
+    // |callback| with it.
+    virtual void PopNextRequest(
+        const BackgroundFetchRegistrationId& registration_id,
+        NextRequestCallback callback) = 0;
+
+    // Marks |request| as complete and calls |callback| when done.
+    virtual void MarkRequestAsComplete(
+        const BackgroundFetchRegistrationId& registration_id,
+        BackgroundFetchRequestInfo* request,
+        MarkedCompleteCallback callback) = 0;
+  };
+
+  explicit BackgroundFetchScheduler(RequestProvider* request_provider);
+
+  ~BackgroundFetchScheduler() override;
+
+  // Adds a new job controller to the scheduler. May immediately start to
+  // schedule jobs for |controller|.
+  void AddJobController(Controller* controller);
+
+  void set_max_concurrent_downloads(size_t new_max) {
+    max_concurrent_downloads_ = new_max;
+  }
+
+  // BackgroundFetchRequestManager implementation:
+  void MarkRequestAsComplete(
+      const BackgroundFetchRegistrationId& registration_id,
+      scoped_refptr<BackgroundFetchRequestInfo> request) override;
+  void OnJobAborted(const BackgroundFetchRegistrationId& registration_id,
+                    std::vector<std::string> aborted_guids) override;
+
+ private:
+  void ScheduleDownload();
+
+  void DidPopNextRequest(BackgroundFetchScheduler::Controller* controller,
+                         scoped_refptr<BackgroundFetchRequestInfo>);
+
+  void DidMarkRequestAsComplete(
+      BackgroundFetchScheduler::Controller* controller);
+
+  RequestProvider* request_provider_;
+
+  // The scheduler owns all the job controllers, holding them either in the
+  // controller queue or the guid to controller map.
+  base::circular_deque<Controller*> controller_queue_;
+  std::map<std::string, Controller*> download_controller_map_;
+
+  size_t max_concurrent_downloads_ = 1;
+
+  DISALLOW_COPY_AND_ASSIGN(BackgroundFetchScheduler);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_SCHEDULER_H_
diff --git a/content/browser/background_fetch/background_fetch_scheduler_unittest.cc b/content/browser/background_fetch/background_fetch_scheduler_unittest.cc
new file mode 100644
index 0000000..6645140
--- /dev/null
+++ b/content/browser/background_fetch/background_fetch_scheduler_unittest.cc
@@ -0,0 +1,199 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/background_fetch_scheduler.h"
+
+#include <vector>
+
+#include "base/guid.h"
+#include "base/strings/string_number_conversions.h"
+#include "content/browser/background_fetch/background_fetch_request_info.h"
+#include "content/browser/background_fetch/background_fetch_test_base.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::ElementsAre;
+
+namespace content {
+
+namespace {
+
+const int kExampleServiceWorkerRegistrationId = 1;
+const char kExampleDeveloperId1[] = "my-example-id";
+const char kExampleDeveloperId2[] = "my-other-id";
+
+class FakeController : public BackgroundFetchScheduler::Controller {
+ public:
+  FakeController(const BackgroundFetchRegistrationId& registration_id,
+                 BackgroundFetchScheduler* scheduler,
+                 const std::string& name,
+                 std::vector<std::string>* controller_sequence_list,
+                 int total_jobs)
+      : BackgroundFetchScheduler::Controller(
+            registration_id,
+            base::BindOnce(&FakeController::OnJobFinished)),
+        scheduler_(scheduler),
+        controller_sequence_list_(controller_sequence_list),
+        name_(name),
+        total_jobs_(total_jobs) {}
+
+  ~FakeController() override {}
+
+  // BackgroundFetchScheduler::Controller implementation:
+  bool HasMoreRequests() override { return jobs_started_ < total_jobs_; }
+  void StartRequest(
+      scoped_refptr<BackgroundFetchRequestInfo> request) override {
+    DCHECK_LT(jobs_started_, total_jobs_);
+    ++jobs_started_;
+    controller_sequence_list_->push_back(name_ +
+                                         base::IntToString(jobs_started_));
+    BrowserThread::PostTask(
+        BrowserThread::IO, FROM_HERE,
+        base::BindOnce(&FakeController::OnDownloadCompleted,
+                       base::Unretained(this), std::move(request)));
+  }
+
+ private:
+  void OnDownloadCompleted(scoped_refptr<BackgroundFetchRequestInfo> request) {
+    scheduler_->MarkRequestAsComplete(registration_id(), std::move(request));
+  }
+
+  static void OnJobFinished(const BackgroundFetchRegistrationId&,
+                            bool aborted) {}
+
+  int jobs_started_ = 0;
+  BackgroundFetchScheduler* scheduler_;
+  std::vector<std::string>* controller_sequence_list_;
+  std::string name_;
+  int total_jobs_;
+};
+
+class BackgroundFetchSchedulerTest
+    : public BackgroundFetchTestBase,
+      public BackgroundFetchScheduler::RequestProvider {
+ public:
+  BackgroundFetchSchedulerTest() : scheduler_(this) {}
+
+  // Posts itself as a task |number_of_barriers| times and on the last iteration
+  // invokes the quit_closure.
+  void PostQuitAfterRepeatingBarriers(base::Closure quit_closure,
+                                      int number_of_barriers) {
+    if (--number_of_barriers == 0) {
+      quit_closure.Run();
+      return;
+    }
+
+    BrowserThread::PostTask(
+        BrowserThread::IO, FROM_HERE,
+        base::BindOnce(
+            &BackgroundFetchSchedulerTest::PostQuitAfterRepeatingBarriers,
+            base::Unretained(this), quit_closure, number_of_barriers));
+  }
+
+  void PopNextRequest(
+      const BackgroundFetchRegistrationId& registration_id,
+      BackgroundFetchScheduler::NextRequestCallback callback) override {
+    ServiceWorkerFetchRequest fetch_request(GURL(), "GET",
+                                            ServiceWorkerHeaderMap(),
+                                            Referrer(), false /* is_reload */);
+    auto request = base::MakeRefCounted<BackgroundFetchRequestInfo>(
+        0 /* request_count */, fetch_request);
+    request->InitializeDownloadGuid();
+
+    std::move(callback).Run(std::move(request));
+  }
+
+  void MarkRequestAsComplete(
+      const BackgroundFetchRegistrationId& registration_id,
+      BackgroundFetchRequestInfo* request,
+      BackgroundFetchScheduler::MarkedCompleteCallback callback) override {
+    std::move(callback).Run();
+  }
+
+ protected:
+  BackgroundFetchScheduler scheduler_;
+  std::vector<std::string> controller_sequence_list_;
+};
+
+}  // namespace
+
+TEST_F(BackgroundFetchSchedulerTest, SingleController) {
+  BackgroundFetchRegistrationId registration_id1(
+      kExampleServiceWorkerRegistrationId, origin(), kExampleDeveloperId1,
+      base::GenerateGUID());
+  FakeController controller(registration_id1, &scheduler_, "A",
+                            &controller_sequence_list_, 4);
+
+  scheduler_.AddJobController(&controller);
+
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_THAT(controller_sequence_list_, ElementsAre("A1", "A2", "A3", "A4"));
+}
+
+TEST_F(BackgroundFetchSchedulerTest, TwoControllers) {
+  BackgroundFetchRegistrationId registration_id1(
+      kExampleServiceWorkerRegistrationId, origin(), kExampleDeveloperId1,
+      base::GenerateGUID());
+  BackgroundFetchRegistrationId registration_id2(
+      kExampleServiceWorkerRegistrationId, origin(), kExampleDeveloperId2,
+      base::GenerateGUID());
+  FakeController controller1(registration_id1, &scheduler_, "A",
+                             &controller_sequence_list_, 4);
+  FakeController controller2(registration_id2, &scheduler_, "B",
+                             &controller_sequence_list_, 4);
+
+  scheduler_.AddJobController(&controller1);
+  scheduler_.AddJobController(&controller2);
+
+  {
+    base::RunLoop run_loop;
+    PostQuitAfterRepeatingBarriers(run_loop.QuitClosure(), 3);
+    run_loop.Run();
+
+    // Only one task is run at a time so after 3 barrier iterations, 3 tasks
+    // should have been have run.
+    EXPECT_THAT(controller_sequence_list_, ElementsAre("A1", "B1", "A2"));
+  }
+
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_THAT(controller_sequence_list_,
+              ElementsAre("A1", "B1", "A2", "B2", "A3", "B3", "A4", "B4"));
+}
+
+TEST_F(BackgroundFetchSchedulerTest, TwoControllers_TwoConcurrent) {
+  BackgroundFetchRegistrationId registration_id1(
+      kExampleServiceWorkerRegistrationId, origin(), kExampleDeveloperId1,
+      base::GenerateGUID());
+  BackgroundFetchRegistrationId registration_id2(
+      kExampleServiceWorkerRegistrationId, origin(), kExampleDeveloperId2,
+      base::GenerateGUID());
+  FakeController controller1(registration_id1, &scheduler_, "A",
+                             &controller_sequence_list_, 4);
+  FakeController controller2(registration_id2, &scheduler_, "B",
+                             &controller_sequence_list_, 4);
+
+  scheduler_.set_max_concurrent_downloads(2);
+  scheduler_.AddJobController(&controller1);
+  scheduler_.AddJobController(&controller2);
+
+  {
+    base::RunLoop run_loop;
+    PostQuitAfterRepeatingBarriers(run_loop.QuitClosure(), 3);
+    run_loop.Run();
+
+    // Two tasks are run at a time so after 3 barrier iterations, 6 tasks should
+    // have run.
+    EXPECT_THAT(controller_sequence_list_,
+                ElementsAre("A1", "B1", "A2", "B2", "A3", "B3"));
+  }
+
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_THAT(controller_sequence_list_,
+              ElementsAre("A1", "B1", "A2", "B2", "A3", "B3", "A4", "B4"));
+}
+
+}  // namespace content
diff --git a/content/browser/browser_plugin/OWNERS b/content/browser/browser_plugin/OWNERS
index bd373b0..74d34105 100644
--- a/content/browser/browser_plugin/OWNERS
+++ b/content/browser/browser_plugin/OWNERS
@@ -1,7 +1,3 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-lfg@chromium.org
-wjmaclean@chromium.org
-ekaramad@chromium.org
+file://components/guest_view/OWNERS
 
 # COMPONENT: Platform>Apps>BrowserTag
diff --git a/content/browser/cache_storage/cache_storage.cc b/content/browser/cache_storage/cache_storage.cc
index 7acd661..f16e2261 100644
--- a/content/browser/cache_storage/cache_storage.cc
+++ b/content/browser/cache_storage/cache_storage.cc
@@ -40,11 +40,11 @@
 #include "net/url_request/url_request_context_getter.h"
 #include "storage/browser/blob/blob_storage_context.h"
 #include "storage/browser/quota/quota_manager_proxy.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 using base::LazyInstance;
 using blink::mojom::CacheStorageError;
-using blink::StorageType;
+using blink::mojom::StorageType;
 using crypto::SymmetricKey;
 
 namespace content {
diff --git a/content/browser/cache_storage/cache_storage_cache.cc b/content/browser/cache_storage/cache_storage_cache.cc
index 82aa69a..abba89c 100644
--- a/content/browser/cache_storage/cache_storage_cache.cc
+++ b/content/browser/cache_storage/cache_storage_cache.cc
@@ -47,7 +47,7 @@
 #include "storage/browser/quota/quota_manager_proxy.h"
 #include "storage/common/blob_storage/blob_handle.h"
 #include "storage/common/storage_histograms.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 using blink::mojom::CacheStorageError;
 
@@ -512,7 +512,7 @@
   // can call Size, another scheduled operation.
   quota_manager_proxy_->GetUsageAndQuota(
       base::ThreadTaskRunnerHandle::Get().get(), origin_,
-      blink::StorageType::kTemporary,
+      blink::mojom::StorageType::kTemporary,
       base::AdaptCallbackForRepeating(
           base::BindOnce(&CacheStorageCache::WriteSideDataDidGetQuota,
                          weak_ptr_factory_.GetWeakPtr(), std::move(callback),
@@ -560,7 +560,7 @@
     // than it's supposed to be.
     quota_manager_proxy_->GetUsageAndQuota(
         base::ThreadTaskRunnerHandle::Get().get(), origin_,
-        blink::StorageType::kTemporary,
+        blink::mojom::StorageType::kTemporary,
         base::AdaptCallbackForRepeating(base::BindOnce(
             &CacheStorageCache::BatchDidGetUsageAndQuota,
             weak_ptr_factory_.GetWeakPtr(), operations, std::move(callback),
@@ -571,7 +571,7 @@
   BatchDidGetUsageAndQuota(
       operations, std::move(callback), std::move(bad_message_callback),
       0 /* space_required */, 0 /* side_data_size */,
-      blink::QuotaStatusCode::kOk, 0 /* usage */, 0 /* quota */);
+      blink::mojom::QuotaStatusCode::kOk, 0 /* usage */, 0 /* quota */);
 }
 
 void CacheStorageCache::BatchDidGetUsageAndQuota(
@@ -580,7 +580,7 @@
     BadMessageCallback bad_message_callback,
     uint64_t space_required,
     uint64_t side_data_size,
-    blink::QuotaStatusCode status_code,
+    blink::mojom::QuotaStatusCode status_code,
     int64_t usage,
     int64_t quota) {
   base::CheckedNumeric<uint64_t> safe_space_required = space_required;
@@ -597,7 +597,7 @@
         base::BindOnce(std::move(callback), CacheStorageError::kErrorStorage));
     return;
   }
-  if (status_code != blink::QuotaStatusCode::kOk ||
+  if (status_code != blink::mojom::QuotaStatusCode::kOk ||
       safe_space_required.ValueOrDie() > quota) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE, base::BindOnce(std::move(callback),
@@ -1090,10 +1090,11 @@
     base::Time expected_response_time,
     scoped_refptr<net::IOBuffer> buffer,
     int buf_len,
-    blink::QuotaStatusCode status_code,
+    blink::mojom::QuotaStatusCode status_code,
     int64_t usage,
     int64_t quota) {
-  if (status_code != blink::QuotaStatusCode::kOk || (buf_len > quota - usage)) {
+  if (status_code != blink::mojom::QuotaStatusCode::kOk ||
+      (buf_len > quota - usage)) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE, base::BindOnce(std::move(callback),
                                   CacheStorageError::kErrorQuotaExceeded));
@@ -1566,7 +1567,7 @@
 
   quota_manager_proxy_->NotifyStorageModified(
       storage::QuotaClient::kServiceWorkerCache, origin_,
-      blink::StorageType::kTemporary, size_delta);
+      blink::mojom::StorageType::kTemporary, size_delta);
 
   if (cache_storage_)
     cache_storage_->NotifyCacheContentChanged(cache_name_);
diff --git a/content/browser/cache_storage/cache_storage_cache.h b/content/browser/cache_storage/cache_storage_cache.h
index 6cd3d3d..f52768b6 100644
--- a/content/browser/cache_storage/cache_storage_cache.h
+++ b/content/browser/cache_storage/cache_storage_cache.h
@@ -21,7 +21,7 @@
 #include "content/common/service_worker/service_worker_types.h"
 #include "net/base/io_buffer.h"
 #include "net/disk_cache/disk_cache.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "third_party/WebKit/public/platform/modules/cache_storage/cache_storage.mojom.h"
 
 namespace crypto {
@@ -155,7 +155,7 @@
       BadMessageCallback bad_message_callback,
       uint64_t space_required,
       uint64_t side_data_size,
-      blink::QuotaStatusCode status_code,
+      blink::mojom::QuotaStatusCode status_code,
       int64_t usage,
       int64_t quota);
   // Callback passed to operations. If |error| is a real error, invokes
@@ -307,7 +307,7 @@
                                 base::Time expected_response_time,
                                 scoped_refptr<net::IOBuffer> buffer,
                                 int buf_len,
-                                blink::QuotaStatusCode status_code,
+                                blink::mojom::QuotaStatusCode status_code,
                                 int64_t usage,
                                 int64_t quota);
 
@@ -316,14 +316,15 @@
                          base::Time expected_response_time,
                          scoped_refptr<net::IOBuffer> buffer,
                          int buf_len);
-  void WriteSideDataDidGetUsageAndQuota(ErrorCallback callback,
-                                        const GURL& url,
-                                        base::Time expected_response_time,
-                                        scoped_refptr<net::IOBuffer> buffer,
-                                        int buf_len,
-                                        blink::QuotaStatusCode status_code,
-                                        int64_t usage,
-                                        int64_t quota);
+  void WriteSideDataDidGetUsageAndQuota(
+      ErrorCallback callback,
+      const GURL& url,
+      base::Time expected_response_time,
+      scoped_refptr<net::IOBuffer> buffer,
+      int buf_len,
+      blink::mojom::QuotaStatusCode status_code,
+      int64_t usage,
+      int64_t quota);
   void WriteSideDataDidOpenEntry(ErrorCallback callback,
                                  base::Time expected_response_time,
                                  scoped_refptr<net::IOBuffer> buffer,
@@ -353,7 +354,7 @@
   void PutDidDeleteEntry(std::unique_ptr<PutContext> put_context,
                          blink::mojom::CacheStorageError error);
   void PutDidGetUsageAndQuota(std::unique_ptr<PutContext> put_context,
-                              blink::QuotaStatusCode status_code,
+                              blink::mojom::QuotaStatusCode status_code,
                               int64_t usage,
                               int64_t quota);
   void PutDidCreateEntry(std::unique_ptr<disk_cache::Entry*> entry_ptr,
diff --git a/content/browser/cache_storage/cache_storage_cache_unittest.cc b/content/browser/cache_storage/cache_storage_cache_unittest.cc
index 03b63842..8d80ab6 100644
--- a/content/browser/cache_storage/cache_storage_cache_unittest.cc
+++ b/content/browser/cache_storage/cache_storage_cache_unittest.cc
@@ -377,7 +377,8 @@
     mock_quota_manager_ = new MockQuotaManager(
         is_incognito, temp_dir_path, base::ThreadTaskRunnerHandle::Get().get(),
         quota_policy_.get());
-    mock_quota_manager_->SetQuota(GURL(kOrigin), blink::StorageType::kTemporary,
+    mock_quota_manager_->SetQuota(GURL(kOrigin),
+                                  blink::mojom::StorageType::kTemporary,
                                   1024 * 1024 * 100);
 
     quota_manager_proxy_ = new MockQuotaManagerProxy(
@@ -1507,7 +1508,8 @@
 }
 
 TEST_P(CacheStorageCacheTestP, PutWithSideData_QuotaExceeded) {
-  mock_quota_manager_->SetQuota(GURL(kOrigin), blink::StorageType::kTemporary,
+  mock_quota_manager_->SetQuota(GURL(kOrigin),
+                                blink::mojom::StorageType::kTemporary,
                                 expected_blob_data_.size() - 1);
   ServiceWorkerResponse response(body_response_);
   const std::string expected_side_data = "SideData";
@@ -1522,7 +1524,8 @@
 }
 
 TEST_P(CacheStorageCacheTestP, PutWithSideData_QuotaExceededSkipSideData) {
-  mock_quota_manager_->SetQuota(GURL(kOrigin), blink::StorageType::kTemporary,
+  mock_quota_manager_->SetQuota(GURL(kOrigin),
+                                blink::mojom::StorageType::kTemporary,
                                 expected_blob_data_.size());
   ServiceWorkerResponse response(body_response_);
   const std::string expected_side_data = "SideData";
@@ -1600,8 +1603,8 @@
 }
 
 TEST_P(CacheStorageCacheTestP, WriteSideData_QuotaExceeded) {
-  mock_quota_manager_->SetQuota(GURL(kOrigin), blink::StorageType::kTemporary,
-                                1024 * 1023);
+  mock_quota_manager_->SetQuota(
+      GURL(kOrigin), blink::mojom::StorageType::kTemporary, 1024 * 1023);
   base::Time response_time(base::Time::Now());
   ServiceWorkerResponse response;
   response.response_time = response_time;
@@ -1721,8 +1724,8 @@
 }
 
 TEST_P(CacheStorageCacheTestP, PutObeysQuotaLimits) {
-  mock_quota_manager_->SetQuota(GURL(kOrigin), blink::StorageType::kTemporary,
-                                0);
+  mock_quota_manager_->SetQuota(GURL(kOrigin),
+                                blink::mojom::StorageType::kTemporary, 0);
   EXPECT_FALSE(Put(body_request_, body_response_));
   EXPECT_EQ(CacheStorageError::kErrorQuotaExceeded, callback_error_);
 }
diff --git a/content/browser/cache_storage/cache_storage_manager.cc b/content/browser/cache_storage/cache_storage_manager.cc
index d15a5727..cc7de66 100644
--- a/content/browser/cache_storage/cache_storage_manager.cc
+++ b/content/browser/cache_storage/cache_storage_manager.cc
@@ -31,8 +31,7 @@
 #include "net/base/url_util.h"
 #include "storage/browser/quota/quota_manager_proxy.h"
 #include "storage/common/database/database_identifier.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -51,8 +50,9 @@
 
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE,
-      base::BindOnce(callback, rv ? blink::QuotaStatusCode::kOk
-                                  : blink::QuotaStatusCode::kErrorAbort));
+      base::BindOnce(callback,
+                     rv ? blink::mojom::QuotaStatusCode::kOk
+                        : blink::mojom::QuotaStatusCode::kErrorAbort));
 }
 
 // Calculate the sum of all cache sizes in this store, but only if all sizes are
@@ -125,7 +125,7 @@
       FROM_HERE, base::BindOnce(callback, out_origins));
 }
 
-void EmptyQuotaStatusCallback(blink::QuotaStatusCode code) {}
+void EmptyQuotaStatusCallback(blink::mojom::QuotaStatusCode code) {}
 
 void AllOriginSizesReported(
     std::unique_ptr<std::vector<CacheStorageUsageInfo>> usages,
@@ -423,12 +423,13 @@
 
   quota_manager_proxy_->NotifyStorageModified(
       storage::QuotaClient::kServiceWorkerCache, origin,
-      blink::StorageType::kTemporary, -1 * origin_size);
+      blink::mojom::StorageType::kTemporary, -1 * origin_size);
   NotifyCacheListChanged(origin);
 
   if (IsMemoryBacked()) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(callback, blink::QuotaStatusCode::kOk));
+        FROM_HERE,
+        base::BindOnce(callback, blink::mojom::QuotaStatusCode::kOk));
     return;
   }
 
diff --git a/content/browser/cache_storage/cache_storage_manager_unittest.cc b/content/browser/cache_storage/cache_storage_manager_unittest.cc
index 23a7aad..27f8b567 100644
--- a/content/browser/cache_storage/cache_storage_manager_unittest.cc
+++ b/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -60,7 +60,7 @@
 namespace content {
 namespace cache_storage_manager_unittest {
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 
 bool IsIndexFileCurrent(const base::FilePath& cache_dir) {
   base::File::Info info;
@@ -553,10 +553,10 @@
 
   void DidGetQuotaOriginUsage(int64_t* out_usage,
                               base::RunLoop* run_loop,
-                              blink::QuotaStatusCode status_code,
+                              blink::mojom::QuotaStatusCode status_code,
                               int64_t usage,
                               int64_t quota) {
-    if (status_code == blink::QuotaStatusCode::kOk)
+    if (status_code == blink::mojom::QuotaStatusCode::kOk)
       *out_usage = usage;
     run_loop->Quit();
   }
@@ -1671,7 +1671,7 @@
   }
 
   void DeleteOriginCallback(base::RunLoop* run_loop,
-                            blink::QuotaStatusCode status) {
+                            blink::mojom::QuotaStatusCode status) {
     callback_status_ = status;
     run_loop->Quit();
   }
@@ -1713,7 +1713,7 @@
         base::Bind(&CacheStorageQuotaClientTest::DeleteOriginCallback,
                    base::Unretained(this), base::Unretained(&loop)));
     loop.Run();
-    return callback_status_ == blink::QuotaStatusCode::kOk;
+    return callback_status_ == blink::mojom::QuotaStatusCode::kOk;
   }
 
   bool QuotaDoesSupport(StorageType type) {
@@ -1722,7 +1722,7 @@
 
   std::unique_ptr<CacheStorageQuotaClient> quota_client_;
 
-  blink::QuotaStatusCode callback_status_;
+  blink::mojom::QuotaStatusCode callback_status_;
   int64_t callback_quota_usage_ = 0;
   std::set<GURL> callback_origins_;
 
diff --git a/content/browser/cache_storage/cache_storage_quota_client.cc b/content/browser/cache_storage/cache_storage_quota_client.cc
index c5361453..4a2d9d4 100644
--- a/content/browser/cache_storage/cache_storage_quota_client.cc
+++ b/content/browser/cache_storage/cache_storage_quota_client.cc
@@ -6,7 +6,7 @@
 
 #include "content/browser/cache_storage/cache_storage_manager.h"
 #include "content/public/browser/browser_thread.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace content {
 
@@ -28,7 +28,7 @@
 }
 
 void CacheStorageQuotaClient::GetOriginUsage(const GURL& origin_url,
-                                             blink::StorageType type,
+                                             blink::mojom::StorageType type,
                                              const GetUsageCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
@@ -41,7 +41,7 @@
 }
 
 void CacheStorageQuotaClient::GetOriginsForType(
-    blink::StorageType type,
+    blink::mojom::StorageType type,
     const GetOriginsCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
@@ -54,7 +54,7 @@
 }
 
 void CacheStorageQuotaClient::GetOriginsForHost(
-    blink::StorageType type,
+    blink::mojom::StorageType type,
     const std::string& host,
     const GetOriginsCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -69,27 +69,28 @@
 
 void CacheStorageQuotaClient::DeleteOriginData(
     const GURL& origin,
-    blink::StorageType type,
+    blink::mojom::StorageType type,
     const DeletionCallback& callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   if (!cache_manager_) {
-    callback.Run(blink::QuotaStatusCode::kErrorAbort);
+    callback.Run(blink::mojom::QuotaStatusCode::kErrorAbort);
     return;
   }
 
   if (!DoesSupport(type)) {
-    callback.Run(blink::QuotaStatusCode::kOk);
+    callback.Run(blink::mojom::QuotaStatusCode::kOk);
     return;
   }
 
   cache_manager_->DeleteOriginData(origin, callback);
 }
 
-bool CacheStorageQuotaClient::DoesSupport(blink::StorageType type) const {
+bool CacheStorageQuotaClient::DoesSupport(
+    blink::mojom::StorageType type) const {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
-  return type == blink::StorageType::kTemporary;
+  return type == blink::mojom::StorageType::kTemporary;
 }
 
 }  // namespace content
diff --git a/content/browser/cache_storage/cache_storage_quota_client.h b/content/browser/cache_storage/cache_storage_quota_client.h
index 702b091..c3f2c20 100644
--- a/content/browser/cache_storage/cache_storage_quota_client.h
+++ b/content/browser/cache_storage/cache_storage_quota_client.h
@@ -9,7 +9,7 @@
 #include "base/memory/weak_ptr.h"
 #include "content/common/content_export.h"
 #include "storage/browser/quota/quota_client.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace content {
 class CacheStorageManager;
@@ -27,17 +27,17 @@
   ID id() const override;
   void OnQuotaManagerDestroyed() override;
   void GetOriginUsage(const GURL& origin_url,
-                      blink::StorageType type,
+                      blink::mojom::StorageType type,
                       const GetUsageCallback& callback) override;
-  void GetOriginsForType(blink::StorageType type,
+  void GetOriginsForType(blink::mojom::StorageType type,
                          const GetOriginsCallback& callback) override;
-  void GetOriginsForHost(blink::StorageType type,
+  void GetOriginsForHost(blink::mojom::StorageType type,
                          const std::string& host,
                          const GetOriginsCallback& callback) override;
   void DeleteOriginData(const GURL& origin,
-                        blink::StorageType type,
+                        blink::mojom::StorageType type,
                         const DeletionCallback& callback) override;
-  bool DoesSupport(blink::StorageType type) const override;
+  bool DoesSupport(blink::mojom::StorageType type) const override;
 
  private:
   base::WeakPtr<CacheStorageManager> cache_manager_;
diff --git a/content/browser/devtools/devtools_manager_unittest.cc b/content/browser/devtools/devtools_manager_unittest.cc
index 6275e13..6c0a9cf 100644
--- a/content/browser/devtools/devtools_manager_unittest.cc
+++ b/content/browser/devtools/devtools_manager_unittest.cc
@@ -15,8 +15,6 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "content/browser/devtools/shared_worker_devtools_manager.h"
-#include "content/browser/shared_worker/shared_worker_instance.h"
-#include "content/browser/shared_worker/worker_storage_partition.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/content_browser_client.h"
diff --git a/content/browser/devtools/protocol/storage_handler.cc b/content/browser/devtools/protocol/storage_handler.cc
index 2712d364..32b8b5e 100644
--- a/content/browser/devtools/protocol/storage_handler.cc
+++ b/content/browser/devtools/protocol/storage_handler.cc
@@ -16,8 +16,7 @@
 #include "content/public/browser/storage_partition.h"
 #include "storage/browser/quota/quota_client.h"
 #include "storage/browser/quota/quota_manager.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -46,12 +45,12 @@
 
 void ReportUsageAndQuotaDataOnUIThread(
     std::unique_ptr<StorageHandler::GetUsageAndQuotaCallback> callback,
-    blink::QuotaStatusCode code,
+    blink::mojom::QuotaStatusCode code,
     int64_t usage,
     int64_t quota,
     base::flat_map<storage::QuotaClient::ID, int64_t> usage_breakdown) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (code != blink::QuotaStatusCode::kOk) {
+  if (code != blink::mojom::QuotaStatusCode::kOk) {
     return callback->sendFailure(
         Response::Error("Quota information is not available"));
   }
@@ -71,7 +70,7 @@
 
 void GotUsageAndQuotaDataCallback(
     std::unique_ptr<StorageHandler::GetUsageAndQuotaCallback> callback,
-    blink::QuotaStatusCode code,
+    blink::mojom::QuotaStatusCode code,
     int64_t usage,
     int64_t quota,
     base::flat_map<storage::QuotaClient::ID, int64_t> usage_breakdown) {
@@ -89,7 +88,7 @@
     std::unique_ptr<StorageHandler::GetUsageAndQuotaCallback> callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   manager->GetUsageAndQuotaWithBreakdown(
-      url, blink::StorageType::kTemporary,
+      url, blink::mojom::StorageType::kTemporary,
       base::Bind(&GotUsageAndQuotaDataCallback,
                  base::Passed(std::move(callback))));
 }
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc
index 974482b..687c819 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -809,7 +809,15 @@
 
 void GpuDataManagerImplPrivate::AddLogMessage(
     int level, const std::string& header, const std::string& message) {
+  // Some clients emit many log messages. This has been observed to consume GBs
+  // of memory in the wild
+  // https://bugs.chromium.org/p/chromium/issues/detail?id=798012. Use a limit
+  // of 1000 messages to prevent excess memory usage.
+  const int kLogMessageLimit = 1000;
+
   log_messages_.push_back(LogMessage(level, header, message));
+  if (log_messages_.size() > kLogMessageLimit)
+    log_messages_.erase(log_messages_.begin());
 }
 
 void GpuDataManagerImplPrivate::ProcessCrashed(
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.h b/content/browser/gpu/gpu_data_manager_impl_private.h
index 75197ff9..6be3c4b 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.h
+++ b/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -188,6 +188,7 @@
 
   const scoped_refptr<GpuDataManagerObserverList> observer_list_;
 
+  // Contains the 1000 most recent log messages.
   std::vector<LogMessage> log_messages_;
 
   // Current card force-disabled due to GPU crashes, or disabled through
diff --git a/content/browser/indexed_db/database_impl.cc b/content/browser/indexed_db/database_impl.cc
index f64dd49..faaa42c 100644
--- a/content/browser/indexed_db/database_impl.cc
+++ b/content/browser/indexed_db/database_impl.cc
@@ -18,8 +18,7 @@
 #include "content/browser/indexed_db/indexed_db_value.h"
 #include "storage/browser/blob/blob_storage_context.h"
 #include "storage/browser/quota/quota_manager_proxy.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseException.h"
 
 using std::swap;
@@ -132,7 +131,7 @@
                       const IndexedDBDatabaseError& error);
   void Commit(int64_t transaction_id);
   void OnGotUsageAndQuotaForCommit(int64_t transaction_id,
-                                   blink::QuotaStatusCode status,
+                                   blink::mojom::QuotaStatusCode status,
                                    int64_t usage,
                                    int64_t quota);
   void AckReceivedBlobs(const std::vector<std::string>& uuids);
@@ -918,14 +917,14 @@
 
   indexed_db_context_->quota_manager_proxy()->GetUsageAndQuota(
       indexed_db_context_->TaskRunner(), origin_.GetURL(),
-      blink::StorageType::kTemporary,
+      blink::mojom::StorageType::kTemporary,
       base::Bind(&IDBSequenceHelper::OnGotUsageAndQuotaForCommit,
                  weak_factory_.GetWeakPtr(), transaction_id));
 }
 
 void DatabaseImpl::IDBSequenceHelper::OnGotUsageAndQuotaForCommit(
     int64_t transaction_id,
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     int64_t usage,
     int64_t quota) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -938,7 +937,7 @@
   if (!transaction)
     return;
 
-  if (status == blink::QuotaStatusCode::kOk &&
+  if (status == blink::mojom::QuotaStatusCode::kOk &&
       usage + transaction->size() <= quota) {
     connection_->database()->Commit(transaction);
   } else {
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc
index 4f4d394..1a9d22b89 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -36,7 +36,7 @@
 #include "content/public/common/content_switches.h"
 #include "storage/browser/database/database_util.h"
 #include "storage/common/database/database_identifier.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "ui/base/text/bytes_formatting.h"
 #include "url/origin.h"
 
@@ -445,7 +445,7 @@
   DCHECK(TaskRunner()->RunsTasksInCurrentSequence());
   quota_manager_proxy()->NotifyStorageAccessed(
       storage::QuotaClient::kIndexedDatabase, origin.GetURL(),
-      blink::StorageType::kTemporary);
+      blink::mojom::StorageType::kTemporary);
   if (AddToOriginSet(origin)) {
     // A newly created db, notify the quota system.
     QueryDiskAndUpdateQuotaUsage(origin);
@@ -459,7 +459,7 @@
   DCHECK(TaskRunner()->RunsTasksInCurrentSequence());
   quota_manager_proxy()->NotifyStorageAccessed(
       storage::QuotaClient::kIndexedDatabase, origin.GetURL(),
-      blink::StorageType::kTemporary);
+      blink::mojom::StorageType::kTemporary);
   if (factory_.get() && factory_->GetConnectionCount(origin) == 0)
     QueryDiskAndUpdateQuotaUsage(origin);
 }
@@ -584,7 +584,7 @@
     origin_size_map_[origin] = current_disk_usage;
     quota_manager_proxy()->NotifyStorageModified(
         storage::QuotaClient::kIndexedDatabase, origin.GetURL(),
-        blink::StorageType::kTemporary, difference);
+        blink::mojom::StorageType::kTemporary, difference);
     NotifyIndexedDBListChanged(origin);
   }
 }
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc b/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc
index d12a260..e405d2f7 100644
--- a/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc
@@ -172,8 +172,8 @@
                 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)),
             context_impl_,
             ChromeBlobStorageContext::GetFor(&browser_context_))) {
-    quota_manager_->SetQuota(GURL(kOrigin), blink::StorageType::kTemporary,
-                             kTemporaryQuota);
+    quota_manager_->SetQuota(
+        GURL(kOrigin), blink::mojom::StorageType::kTemporary, kTemporaryQuota);
   }
 
   void TearDown() override {
diff --git a/content/browser/indexed_db/indexed_db_quota_client.cc b/content/browser/indexed_db/indexed_db_quota_client.cc
index 53a13b0..4b973aa 100644
--- a/content/browser/indexed_db/indexed_db_quota_client.cc
+++ b/content/browser/indexed_db/indexed_db_quota_client.cc
@@ -13,21 +13,21 @@
 #include "content/public/browser/browser_thread.h"
 #include "net/base/url_util.h"
 #include "storage/browser/database/database_util.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/origin.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 using storage::QuotaClient;
 using storage::DatabaseUtil;
 
 namespace content {
 namespace {
 
-blink::QuotaStatusCode DeleteOriginDataOnIndexedDBThread(
+blink::mojom::QuotaStatusCode DeleteOriginDataOnIndexedDBThread(
     IndexedDBContextImpl* context,
     const GURL& origin) {
   context->DeleteForOrigin(origin);
-  return blink::QuotaStatusCode::kOk;
+  return blink::mojom::QuotaStatusCode::kOk;
 }
 
 int64_t GetOriginUsageOnIndexedDBThread(IndexedDBContextImpl* context,
@@ -140,7 +140,7 @@
                                             StorageType type,
                                             const DeletionCallback& callback) {
   if (type != StorageType::kTemporary) {
-    callback.Run(blink::QuotaStatusCode::kOk);
+    callback.Run(blink::mojom::QuotaStatusCode::kOk);
     return;
   }
 
diff --git a/content/browser/indexed_db/indexed_db_quota_client.h b/content/browser/indexed_db/indexed_db_quota_client.h
index b47a698..cc6a42bb 100644
--- a/content/browser/indexed_db/indexed_db_quota_client.h
+++ b/content/browser/indexed_db/indexed_db_quota_client.h
@@ -14,7 +14,7 @@
 #include "content/common/content_export.h"
 #include "storage/browser/quota/quota_client.h"
 #include "storage/browser/quota/quota_task.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 namespace content {
@@ -33,20 +33,20 @@
   ID id() const override;
   void OnQuotaManagerDestroyed() override;
   CONTENT_EXPORT void GetOriginUsage(const GURL& origin_url,
-                                     blink::StorageType type,
+                                     blink::mojom::StorageType type,
                                      const GetUsageCallback& callback) override;
   CONTENT_EXPORT void GetOriginsForType(
-      blink::StorageType type,
+      blink::mojom::StorageType type,
       const GetOriginsCallback& callback) override;
   CONTENT_EXPORT void GetOriginsForHost(
-      blink::StorageType type,
+      blink::mojom::StorageType type,
       const std::string& host,
       const GetOriginsCallback& callback) override;
   CONTENT_EXPORT void DeleteOriginData(
       const GURL& origin,
-      blink::StorageType type,
+      blink::mojom::StorageType type,
       const DeletionCallback& callback) override;
-  bool DoesSupport(blink::StorageType type) const override;
+  bool DoesSupport(blink::mojom::StorageType type) const override;
 
  private:
   scoped_refptr<IndexedDBContextImpl> indexed_db_context_;
diff --git a/content/browser/indexed_db/indexed_db_quota_client_unittest.cc b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
index e989803..74aa652 100644
--- a/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_quota_client_unittest.cc
@@ -25,7 +25,7 @@
 #include "storage/browser/test/mock_quota_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 
 // Declared to shorten the line lengths.
 static const StorageType kTemp = StorageType::kTemporary;
@@ -114,10 +114,10 @@
     return origins_;
   }
 
-  blink::QuotaStatusCode DeleteOrigin(storage::QuotaClient* client,
-                                      const GURL& origin_url,
-                                      StorageType type) {
-    delete_status_ = blink::QuotaStatusCode::kUnknown;
+  blink::mojom::QuotaStatusCode DeleteOrigin(storage::QuotaClient* client,
+                                             const GURL& origin_url,
+                                             StorageType type) {
+    delete_status_ = blink::mojom::QuotaStatusCode::kUnknown;
     client->DeleteOriginData(
         origin_url, type,
         base::Bind(&IndexedDBQuotaClientTest::OnDeleteOriginComplete,
@@ -152,7 +152,7 @@
     origins_ = origins;
   }
 
-  void OnDeleteOriginComplete(blink::QuotaStatusCode code) {
+  void OnDeleteOriginComplete(blink::mojom::QuotaStatusCode code) {
     delete_status_ = code;
   }
 
@@ -162,7 +162,7 @@
   std::set<GURL> origins_;
   scoped_refptr<IndexedDBContextImpl> idb_context_;
   std::unique_ptr<TestBrowserContext> browser_context_;
-  blink::QuotaStatusCode delete_status_;
+  blink::mojom::QuotaStatusCode delete_status_;
   base::WeakPtrFactory<IndexedDBQuotaClientTest> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(IndexedDBQuotaClientTest);
@@ -231,18 +231,19 @@
   EXPECT_EQ(1000, GetOriginUsage(&client, kOriginA, kTemp));
   EXPECT_EQ(50, GetOriginUsage(&client, kOriginB, kTemp));
 
-  blink::QuotaStatusCode delete_status = DeleteOrigin(&client, kOriginA, kTemp);
-  EXPECT_EQ(blink::QuotaStatusCode::kOk, delete_status);
+  blink::mojom::QuotaStatusCode delete_status =
+      DeleteOrigin(&client, kOriginA, kTemp);
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, delete_status);
   EXPECT_EQ(0, GetOriginUsage(&client, kOriginA, kTemp));
   EXPECT_EQ(50, GetOriginUsage(&client, kOriginB, kTemp));
 
   // IndexedDB only supports temporary storage; requests to delete other types
   // are no-ops, but should not fail.
   delete_status = DeleteOrigin(&client, kOriginA, kPerm);
-  EXPECT_EQ(blink::QuotaStatusCode::kOk, delete_status);
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, delete_status);
 
   delete_status = DeleteOrigin(&client, kOriginA, kSync);
-  EXPECT_EQ(blink::QuotaStatusCode::kOk, delete_status);
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, delete_status);
 }
 
 }  // namespace content
diff --git a/content/browser/net/OWNERS b/content/browser/net/OWNERS
index fb59c70..688bc408c 100644
--- a/content/browser/net/OWNERS
+++ b/content/browser/net/OWNERS
@@ -1 +1,3 @@
 file://net/OWNERS
+
+per-file network_quality*=file://net/nqe/OWNERS
diff --git a/content/browser/net/network_quality_observer_impl.cc b/content/browser/net/network_quality_observer_impl.cc
index 879df30..dfb3e4a 100644
--- a/content/browser/net/network_quality_observer_impl.cc
+++ b/content/browser/net/network_quality_observer_impl.cc
@@ -5,6 +5,7 @@
 #include "content/browser/net/network_quality_observer_impl.h"
 
 #include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/browser_thread.h"
@@ -18,7 +19,7 @@
 namespace {
 
 // Returns true if the |current_value| is meaningfully different from the
-// |past_value|.
+// |past_value|. May be called with either RTT or throughput values to compare.
 bool MetricChangedMeaningfully(int32_t past_value, int32_t current_value) {
   if ((past_value == net::nqe::internal::INVALID_RTT_THROUGHPUT) !=
       (current_value == net::nqe::internal::INVALID_RTT_THROUGHPUT)) {
@@ -30,6 +31,9 @@
     return false;
   }
 
+  DCHECK_LE(0, past_value);
+  DCHECK_LE(0, current_value);
+
   // Metric has changed meaningfully only if (i) the difference between the two
   // values exceed the threshold; and, (ii) the ratio of the values also exceeds
   // the threshold.
@@ -63,6 +67,10 @@
       : last_notified_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {}
 
   ~UiThreadObserver() override {
+    if (!registrar_.IsRegistered(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
+                                 NotificationService::AllSources())) {
+      return;
+    }
     registrar_.Remove(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
                       NotificationService::AllSources());
   }
@@ -197,7 +205,12 @@
       last_notified_network_quality_.downstream_throughput_kbps(),
       downstream_throughput_kbps);
 
-  if (!http_rtt_changed && !transport_rtt_changed && !kbps_changed) {
+  bool network_quality_meaningfully_changed =
+      http_rtt_changed || transport_rtt_changed || kbps_changed;
+  UMA_HISTOGRAM_BOOLEAN("NQE.ContentObserver.NetworkQualityMeaningfullyChanged",
+                        network_quality_meaningfully_changed);
+
+  if (!network_quality_meaningfully_changed) {
     // Return since none of the metrics changed meaningfully. This reduces
     // the number of notifications to the different renderers every time
     // the network quality is recomputed.
diff --git a/content/browser/net/network_quality_observer_impl_unittest.cc b/content/browser/net/network_quality_observer_impl_unittest.cc
new file mode 100644
index 0000000..76602426
--- /dev/null
+++ b/content/browser/net/network_quality_observer_impl_unittest.cc
@@ -0,0 +1,63 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/net/network_quality_observer_impl.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/test/histogram_tester.h"
+#include "base/time/time.h"
+#include "net/nqe/effective_connection_type.h"
+#include "net/nqe/network_quality_estimator_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+TEST(NetworkQualityObserverImplTest, TestObserverNotified) {
+  base::MessageLoopForIO message_loop;
+
+  net::TestNetworkQualityEstimator estimator;
+  estimator.set_start_time_null_http_rtt(base::TimeDelta::FromMilliseconds(1));
+
+  NetworkQualityObserverImpl observer(&estimator);
+  // Give a chance for |observer| to register with the |estimator|.
+  base::RunLoop().RunUntilIdle();
+  // Run one main frame request to force recomputation of effective connection
+  // type.
+  estimator.RunOneRequest();
+  base::RunLoop().RunUntilIdle();
+
+  base::HistogramTester histogram_tester;
+  estimator.set_start_time_null_http_rtt(
+      base::TimeDelta::FromMilliseconds(500));
+  // Run one main frame request to force recomputation of effective connection
+  // type.
+  estimator.RunOneRequest();
+  base::RunLoop().RunUntilIdle();
+  // RTT changed from 1 msec to 500 msec.
+  histogram_tester.ExpectBucketCount(
+      "NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 1, 1);
+
+  estimator.set_start_time_null_http_rtt(
+      base::TimeDelta::FromMilliseconds(625));
+  estimator.RunOneRequest();
+  base::RunLoop().RunUntilIdle();
+  // RTT changed from 500 msec to 625 msec.
+  histogram_tester.ExpectBucketCount(
+      "NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 1, 2);
+
+  estimator.set_start_time_null_http_rtt(
+      base::TimeDelta::FromMilliseconds(626));
+  estimator.RunOneRequest();
+  base::RunLoop().RunUntilIdle();
+  // RTT changed from 625 msec to 626 msec which is not a meaningful change.
+  histogram_tester.ExpectBucketCount(
+      "NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 1, 2);
+  EXPECT_LE(1, histogram_tester.GetBucketCount(
+                   "NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 0));
+}
+
+}  // namespace
+}  // namespace content
\ No newline at end of file
diff --git a/content/browser/network_service_restart_browsertest.cc b/content/browser/network_service_restart_browsertest.cc
index 44e74b42..57b951fc 100644
--- a/content/browser/network_service_restart_browsertest.cc
+++ b/content/browser/network_service_restart_browsertest.cc
@@ -5,15 +5,19 @@
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "content/browser/storage_partition_impl.h"
+#include "content/browser/url_loader_factory_getter.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/network_service.mojom.h"
+#include "content/public/common/simple_url_loader.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/simple_url_loader_test_helper.h"
 #include "content/shell/browser/shell.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 
 namespace content {
 
@@ -28,6 +32,41 @@
   return network_context;
 }
 
+int LoadBasicRequestOnIOThread(
+    URLLoaderFactoryGetter* url_loader_factory_getter,
+    const GURL& url) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  auto request = std::make_unique<ResourceRequest>();
+  request->url = url;
+
+  SimpleURLLoaderTestHelper simple_loader_helper;
+  // Wait for callback on UI thread to avoid nesting IO message loops.
+  simple_loader_helper.SetRunLoopQuitThread(BrowserThread::UI);
+
+  std::unique_ptr<content::SimpleURLLoader> simple_loader =
+      content::SimpleURLLoader::Create(std::move(request),
+                                       TRAFFIC_ANNOTATION_FOR_TESTS);
+
+  // |URLLoaderFactoryGetter::GetNetworkFactory()| can only be accessed on IO
+  // thread.
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::BindOnce(
+          [](content::SimpleURLLoader* loader,
+             URLLoaderFactoryGetter* factory_getter,
+             SimpleURLLoader::BodyAsStringCallback body_as_string_callback) {
+            loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+                factory_getter->GetNetworkFactory(),
+                std::move(body_as_string_callback));
+          },
+          base::Unretained(simple_loader.get()),
+          base::Unretained(url_loader_factory_getter),
+          simple_loader_helper.GetCallback()));
+
+  simple_loader_helper.WaitForCallback();
+  return simple_loader->NetError();
+}
+
 }  // namespace
 
 // This test source has been excluded from Android as Android doesn't have
@@ -45,6 +84,10 @@
     return embedded_test_server()->GetURL("/echoheader");
   }
 
+  BrowserContext* browser_context() {
+    return shell()->web_contents()->GetBrowserContext();
+  }
+
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
 
@@ -83,8 +126,7 @@
 IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
                        StoragePartitionImplGetNetworkContext) {
   StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
-      BrowserContext::GetDefaultStoragePartition(
-          shell()->web_contents()->GetBrowserContext()));
+      BrowserContext::GetDefaultStoragePartition(browser_context()));
 
   mojom::NetworkContext* old_network_context = partition->GetNetworkContext();
   EXPECT_EQ(net::OK, LoadBasicRequest(old_network_context, GetTestURL()));
@@ -102,4 +144,47 @@
             LoadBasicRequest(partition->GetNetworkContext(), GetTestURL()));
 }
 
+// Make sure |URLLoaderFactoryGetter| returns valid interface after crash.
+IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
+                       URLLoaderFactoryGetterGetNetworkFactory) {
+  StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+      BrowserContext::GetDefaultStoragePartition(browser_context()));
+  scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter =
+      partition->url_loader_factory_getter();
+  EXPECT_EQ(net::OK, LoadBasicRequestOnIOThread(url_loader_factory_getter.get(),
+                                                GetTestURL()));
+  // Crash the NetworkService process. Existing interfaces should receive error
+  // notifications at some point.
+  SimulateNetworkServiceCrash();
+  // Flush the interface to make sure the error notification was received.
+  partition->FlushNetworkInterfaceForTesting();
+  url_loader_factory_getter->FlushNetworkInterfaceOnIOThreadForTesting();
+
+  // |url_loader_factory_getter| should be able to get a valid new pointer after
+  // crash.
+  EXPECT_EQ(net::OK, LoadBasicRequestOnIOThread(url_loader_factory_getter.get(),
+                                                GetTestURL()));
+}
+
+// Make sure basic navigation works after crash.
+IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
+                       NavigationURLLoaderBasic) {
+  StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+      BrowserContext::GetDefaultStoragePartition(browser_context()));
+
+  EXPECT_TRUE(
+      NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
+
+  // Crash the NetworkService process. Existing interfaces should receive error
+  // notifications at some point.
+  SimulateNetworkServiceCrash();
+  // Flush the interface to make sure the error notification was received.
+  partition->FlushNetworkInterfaceForTesting();
+  partition->url_loader_factory_getter()
+      ->FlushNetworkInterfaceOnIOThreadForTesting();
+
+  EXPECT_TRUE(
+      NavigateToURL(shell(), embedded_test_server()->GetURL("/title2.html")));
+}
+
 }  // namespace content
diff --git a/content/browser/quota_dispatcher_host.cc b/content/browser/quota_dispatcher_host.cc
index 9cad2dd..b208647 100644
--- a/content/browser/quota_dispatcher_host.cc
+++ b/content/browser/quota_dispatcher_host.cc
@@ -16,7 +16,7 @@
 #include "storage/browser/quota/quota_manager.h"
 #include "url/origin.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 using storage::QuotaClient;
 using storage::QuotaManager;
 
@@ -66,7 +66,8 @@
   if (storage_type != StorageType::kTemporary &&
       storage_type != StorageType::kPersistent) {
     // Unsupported storage types.
-    std::move(callback).Run(blink::QuotaStatusCode::kErrorNotSupported, 0, 0);
+    std::move(callback).Run(blink::mojom::QuotaStatusCode::kErrorNotSupported,
+                            0, 0);
     return;
   }
 
@@ -90,7 +91,7 @@
 
 void QuotaDispatcherHost::DidQueryStorageUsageAndQuota(
     RequestStorageQuotaCallback callback,
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     int64_t usage,
     int64_t quota) {
   std::move(callback).Run(status, usage, quota);
@@ -102,10 +103,10 @@
     StorageType storage_type,
     uint64_t requested_quota,
     RequestStorageQuotaCallback callback,
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     int64_t current_usage,
     int64_t current_quota) {
-  if (status != blink::QuotaStatusCode::kOk) {
+  if (status != blink::mojom::QuotaStatusCode::kOk) {
     std::move(callback).Run(status, 0, 0);
     return;
   }
@@ -118,7 +119,7 @@
       base::saturated_cast<int64_t>(requested_quota);
   if (quota_manager_->IsStorageUnlimited(origin.GetURL(), storage_type) ||
       requested_quota_signed <= current_quota) {
-    std::move(callback).Run(blink::QuotaStatusCode::kOk, current_usage,
+    std::move(callback).Run(blink::mojom::QuotaStatusCode::kOk, current_usage,
                             requested_quota);
     return;
   }
@@ -149,7 +150,7 @@
     QuotaPermissionContext::QuotaPermissionResponse response) {
   // If user didn't allow the new quota, just return the current quota.
   if (response != QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW) {
-    std::move(callback).Run(blink::QuotaStatusCode::kOk, current_usage,
+    std::move(callback).Run(blink::mojom::QuotaStatusCode::kOk, current_usage,
                             current_quota);
     return;
   }
@@ -167,7 +168,7 @@
 
 void QuotaDispatcherHost::DidSetHostQuota(int64_t current_usage,
                                           RequestStorageQuotaCallback callback,
-                                          blink::QuotaStatusCode status,
+                                          blink::mojom::QuotaStatusCode status,
                                           int64_t new_quota) {
   std::move(callback).Run(status, current_usage, new_quota);
 }
@@ -175,7 +176,7 @@
 void QuotaDispatcherHost::DidGetTemporaryUsageAndQuota(
     int64_t requested_quota,
     RequestStorageQuotaCallback callback,
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     int64_t usage,
     int64_t quota) {
   std::move(callback).Run(status, usage, std::min(requested_quota, quota));
diff --git a/content/browser/quota_dispatcher_host.h b/content/browser/quota_dispatcher_host.h
index 879884e8..e850077 100644
--- a/content/browser/quota_dispatcher_host.h
+++ b/content/browser/quota_dispatcher_host.h
@@ -36,25 +36,25 @@
   // blink::mojom::QuotaDispatcherHost:
   void QueryStorageUsageAndQuota(
       const url::Origin& origin,
-      blink::StorageType storage_type,
+      blink::mojom::StorageType storage_type,
       QueryStorageUsageAndQuotaCallback callback) override;
   void RequestStorageQuota(int64_t render_frame_id,
                            const url::Origin& origin,
-                           blink::StorageType storage_type,
+                           blink::mojom::StorageType storage_type,
                            uint64_t requested_size,
                            RequestStorageQuotaCallback callback) override;
 
  private:
   void DidQueryStorageUsageAndQuota(RequestStorageQuotaCallback callback,
-                                    blink::QuotaStatusCode status,
+                                    blink::mojom::QuotaStatusCode status,
                                     int64_t usage,
                                     int64_t quota);
   void DidGetPersistentUsageAndQuota(int64_t render_frame_id,
                                      const url::Origin& origin,
-                                     blink::StorageType storage_type,
+                                     blink::mojom::StorageType storage_type,
                                      uint64_t requested_quota,
                                      RequestStorageQuotaCallback callback,
-                                     blink::QuotaStatusCode status,
+                                     blink::mojom::QuotaStatusCode status,
                                      int64_t usage,
                                      int64_t quota);
   void DidGetPermissionResponse(
@@ -66,11 +66,11 @@
       QuotaPermissionContext::QuotaPermissionResponse response);
   void DidSetHostQuota(int64_t current_usage,
                        RequestStorageQuotaCallback callback,
-                       blink::QuotaStatusCode status,
+                       blink::mojom::QuotaStatusCode status,
                        int64_t new_quota);
   void DidGetTemporaryUsageAndQuota(int64_t requested_quota,
                                     RequestStorageQuotaCallback callback,
-                                    blink::QuotaStatusCode status,
+                                    blink::mojom::QuotaStatusCode status,
                                     int64_t usage,
                                     int64_t quota);
 
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index e98cf4a..d41e3e9 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2039,6 +2039,16 @@
   }
 }
 
+void RenderWidgetHostViewAura::WasResized() {
+  window_->AllocateLocalSurfaceId();
+  if (delegated_frame_host_)
+    delegated_frame_host_->WasResized();
+  if (host_->auto_resize_enabled()) {
+    host_->DidAllocateLocalSurfaceIdForAutoResize(
+        host_->last_auto_resize_request_number());
+  }
+}
+
 ui::InputMethod* RenderWidgetHostViewAura::GetInputMethod() const {
   if (!window_)
     return nullptr;
@@ -2468,13 +2478,12 @@
 }
 
 void RenderWidgetHostViewAura::OnSynchronizedDisplayPropertiesChanged() {
-  window_->AllocateLocalSurfaceId();
-  if (delegated_frame_host_)
-    delegated_frame_host_->WasResized();
-  if (host_->auto_resize_enabled()) {
-    host_->DidAllocateLocalSurfaceIdForAutoResize(
-        host_->last_auto_resize_request_number());
-  }
+  WasResized();
+}
+
+void RenderWidgetHostViewAura::ResizeDueToAutoResize(const gfx::Size& new_size,
+                                                     uint64_t sequence_number) {
+  WasResized();
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index dad96717..96c481b 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -205,6 +205,8 @@
                      base::OnceCallback<void(const base::UnguessableToken&)>
                          callback) override;
   void OnSynchronizedDisplayPropertiesChanged() override;
+  void ResizeDueToAutoResize(const gfx::Size& new_size,
+                             uint64_t sequence_number) override;
 
   // Overridden from ui::TextInputClient:
   void SetCompositionText(const ui::CompositionText& composition) override;
@@ -423,6 +425,8 @@
 
   void UpdateCursorIfOverSelf();
 
+  void WasResized();
+
   // Tracks whether SnapToPhysicalPixelBoundary() has been called.
   bool has_snapped_to_boundary() { return has_snapped_to_boundary_; }
   void ResetHasSnappedToBoundary() { has_snapped_to_boundary_ = false; }
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index 6123277..65eea82 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -2227,6 +2227,9 @@
       view_->GetNativeView(), parent_view_->GetNativeView()->GetRootWindow(),
       gfx::Rect());
   sink_->ClearMessages();
+  viz::LocalSurfaceId local_surface_id1(view_->GetLocalSurfaceId());
+  EXPECT_TRUE(local_surface_id1.is_valid());
+
   widget_host_->SetAutoResize(true, gfx::Size(50, 50), gfx::Size(100, 100));
   ViewHostMsg_ResizeOrRepaint_ACK_Params params;
   params.view_size = gfx::Size(75, 75);
@@ -2240,6 +2243,7 @@
                                                 run_loop.QuitClosure());
   run_loop.Run();
 
+  viz::LocalSurfaceId local_surface_id2;
   ASSERT_EQ(1u, sink_->message_count());
   {
     const IPC::Message* msg = sink_->GetMessageAt(0);
@@ -2251,6 +2255,8 @@
     EXPECT_EQ("50x50", std::get<1>(params).ToString());
     EXPECT_EQ("100x100", std::get<2>(params).ToString());
     EXPECT_EQ(1, std::get<3>(params).device_scale_factor);
+    local_surface_id2 = std::get<4>(params);
+    EXPECT_NE(local_surface_id1, local_surface_id2);
   }
 
   sink_->ClearMessages();
@@ -2268,6 +2274,8 @@
     EXPECT_EQ("50x50", std::get<1>(params).ToString());
     EXPECT_EQ("100x100", std::get<2>(params).ToString());
     EXPECT_EQ(2, std::get<3>(params).device_scale_factor);
+    EXPECT_NE(local_surface_id1, std::get<4>(params));
+    EXPECT_NE(local_surface_id2, std::get<4>(params));
   }
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
index 8764c129..fe6e3d06 100644
--- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -47,6 +47,10 @@
 #include "ui/gfx/geometry/size_conversions.h"
 #include "ui/gl/gl_switches.h"
 
+#if defined(USE_AURA)
+#include "ui/aura/env.h"
+#endif
+
 #if defined(OS_WIN)
 #include "base/win/windows_version.h"
 #endif
@@ -1031,6 +1035,11 @@
 
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestHiDPI,
                        ScrollOffset) {
+// TODO(sadrul): enable for mus: http://crbug.com/798904.
+#if defined(USE_AURA)
+  if (aura::Env::GetInstance()->mode() == aura::Env::Mode::MUS)
+    return;
+#endif
   const int kContentHeight = 2000;
   const int kScrollAmount = 100;
 
diff --git a/content/browser/renderer_host/web_database_host_impl.cc b/content/browser/renderer_host/web_database_host_impl.cc
index e63e34c..f0dcf54 100644
--- a/content/browser/renderer_host/web_database_host_impl.cc
+++ b/content/browser/renderer_host/web_database_host_impl.cc
@@ -18,8 +18,7 @@
 #include "storage/browser/quota/quota_manager.h"
 #include "storage/browser/quota/quota_manager_proxy.h"
 #include "storage/common/database/database_identifier.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "third_party/sqlite/sqlite3.h"
 
 using storage::DatabaseUtil;
@@ -186,12 +185,14 @@
 
   db_tracker_->quota_manager_proxy()->GetUsageAndQuota(
       db_tracker_->task_runner(), origin.GetURL(),
-      blink::StorageType::kTemporary,
+      blink::mojom::StorageType::kTemporary,
       base::Bind(
-          [](GetSpaceAvailableCallback callback, blink::QuotaStatusCode status,
-             int64_t usage, int64_t quota) {
+          [](GetSpaceAvailableCallback callback,
+             blink::mojom::QuotaStatusCode status, int64_t usage,
+             int64_t quota) {
             int64_t available = 0;
-            if ((status == blink::QuotaStatusCode::kOk) && (usage < quota)) {
+            if ((status == blink::mojom::QuotaStatusCode::kOk) &&
+                (usage < quota)) {
               available = quota - usage;
             }
             std::move(callback).Run(available);
diff --git a/content/browser/service_worker/service_worker_quota_client.cc b/content/browser/service_worker/service_worker_quota_client.cc
index 32a445fc..6b41ee5 100644
--- a/content/browser/service_worker/service_worker_quota_client.cc
+++ b/content/browser/service_worker/service_worker_quota_client.cc
@@ -7,7 +7,7 @@
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/public/browser/browser_thread.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 using storage::QuotaClient;
 
 namespace content {
@@ -28,8 +28,8 @@
 
 void ReportToQuotaStatus(const QuotaClient::DeletionCallback& callback,
                          bool status) {
-  callback.Run(status ? blink::QuotaStatusCode::kOk
-                      : blink::QuotaStatusCode::kUnknown);
+  callback.Run(status ? blink::mojom::QuotaStatusCode::kOk
+                      : blink::mojom::QuotaStatusCode::kUnknown);
 }
 
 void FindUsageForOrigin(const QuotaClient::GetUsageCallback& callback,
@@ -99,7 +99,7 @@
     StorageType type,
     const DeletionCallback& callback) {
   if (type != StorageType::kTemporary) {
-    callback.Run(blink::QuotaStatusCode::kOk);
+    callback.Run(blink::mojom::QuotaStatusCode::kOk);
     return;
   }
   context_->DeleteForOrigin(origin, base::Bind(&ReportToQuotaStatus, callback));
diff --git a/content/browser/service_worker/service_worker_quota_client.h b/content/browser/service_worker/service_worker_quota_client.h
index f37b8a9..41b20ab3ae 100644
--- a/content/browser/service_worker/service_worker_quota_client.h
+++ b/content/browser/service_worker/service_worker_quota_client.h
@@ -9,7 +9,7 @@
 #include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
 #include "storage/browser/quota/quota_client.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace content {
 class ServiceWorkerContextWrapper;
@@ -22,17 +22,17 @@
   ID id() const override;
   void OnQuotaManagerDestroyed() override;
   void GetOriginUsage(const GURL& origin,
-                      blink::StorageType type,
+                      blink::mojom::StorageType type,
                       const GetUsageCallback& callback) override;
-  void GetOriginsForType(blink::StorageType type,
+  void GetOriginsForType(blink::mojom::StorageType type,
                          const GetOriginsCallback& callback) override;
-  void GetOriginsForHost(blink::StorageType type,
+  void GetOriginsForHost(blink::mojom::StorageType type,
                          const std::string& host,
                          const GetOriginsCallback& callback) override;
   void DeleteOriginData(const GURL& origin,
-                        blink::StorageType type,
+                        blink::mojom::StorageType type,
                         const DeletionCallback& callback) override;
-  bool DoesSupport(blink::StorageType type) const override;
+  bool DoesSupport(blink::mojom::StorageType type) const override;
 
  private:
   friend class ServiceWorkerContextWrapper;
diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc
index 72dc729..ea619054 100644
--- a/content/browser/service_worker/service_worker_storage.cc
+++ b/content/browser/service_worker/service_worker_storage.cc
@@ -29,7 +29,7 @@
 #include "net/base/net_errors.h"
 #include "storage/browser/quota/quota_manager_proxy.h"
 #include "storage/browser/quota/special_storage_policy.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "third_party/WebKit/common/service_worker/service_worker_object.mojom.h"
 #include "third_party/WebKit/common/service_worker/service_worker_registration.mojom.h"
 #include "third_party/WebKit/public/platform/web_feature.mojom.h"
@@ -1380,7 +1380,7 @@
     // Can be nullptr in tests.
     quota_manager_proxy_->NotifyStorageModified(
         storage::QuotaClient::kServiceWorker, origin,
-        blink::StorageType::kTemporary,
+        blink::mojom::StorageType::kTemporary,
         new_version.resources_total_size_bytes -
             deleted_version.resources_total_size_bytes);
   }
@@ -1417,7 +1417,7 @@
     // Can be nullptr in tests.
     quota_manager_proxy_->NotifyStorageModified(
         storage::QuotaClient::kServiceWorker, params->origin,
-        blink::StorageType::kTemporary,
+        blink::mojom::StorageType::kTemporary,
         -deleted_version.resources_total_size_bytes);
   }
   if (origin_state == OriginState::kDelete)
diff --git a/content/browser/shared_worker/shared_worker_connector_impl.cc b/content/browser/shared_worker/shared_worker_connector_impl.cc
index 4fb7fcd..1e95910e 100644
--- a/content/browser/shared_worker/shared_worker_connector_impl.cc
+++ b/content/browser/shared_worker/shared_worker_connector_impl.cc
@@ -20,62 +20,27 @@
     int process_id,
     int frame_id,
     mojom::SharedWorkerConnectorRequest request) {
-  RenderProcessHost* host = RenderProcessHost::FromID(process_id);
-  ResourceContext* resource_context =
-      host->GetBrowserContext()->GetResourceContext();
-  StoragePartitionImpl* storage_partition_impl =
-      static_cast<StoragePartitionImpl*>(host->GetStoragePartition());
-
-  // TODO(darin): Surely there can be a better way to extract a comparable
-  // identifier from a StoragePartition instance.
-  WorkerStoragePartition worker_storage_partition(
-      storage_partition_impl->GetURLRequestContext(),
-      storage_partition_impl->GetMediaURLRequestContext(),
-      storage_partition_impl->GetAppCacheService(),
-      storage_partition_impl->GetQuotaManager(),
-      storage_partition_impl->GetFileSystemContext(),
-      storage_partition_impl->GetDatabaseTracker(),
-      storage_partition_impl->GetIndexedDBContext(),
-      storage_partition_impl->GetServiceWorkerContext());
-
-  CreateInternal(process_id, frame_id, resource_context,
-                 worker_storage_partition, std::move(request));
-}
-
-// static
-void SharedWorkerConnectorImpl::CreateInternal(
-    int process_id,
-    int frame_id,
-    ResourceContext* resource_context,
-    const WorkerStoragePartition& worker_storage_partition,
-    mojom::SharedWorkerConnectorRequest request) {
   mojo::MakeStrongBinding(
-      base::WrapUnique(new SharedWorkerConnectorImpl(
-          process_id, frame_id, resource_context, worker_storage_partition)),
+      base::WrapUnique(new SharedWorkerConnectorImpl(process_id, frame_id)),
       std::move(request));
 }
 
-SharedWorkerConnectorImpl::SharedWorkerConnectorImpl(
-    int process_id,
-    int frame_id,
-    ResourceContext* resource_context,
-    const WorkerStoragePartition& worker_storage_partition)
-    : process_id_(process_id),
-      frame_id_(frame_id),
-      resource_context_(resource_context),
-      worker_storage_partition_(worker_storage_partition) {}
+SharedWorkerConnectorImpl::SharedWorkerConnectorImpl(int process_id,
+                                                     int frame_id)
+    : process_id_(process_id), frame_id_(frame_id) {}
 
 void SharedWorkerConnectorImpl::Connect(
     mojom::SharedWorkerInfoPtr info,
     mojom::SharedWorkerClientPtr client,
     blink::mojom::SharedWorkerCreationContextType creation_context_type,
     mojo::ScopedMessagePipeHandle message_port) {
-  static_cast<SharedWorkerServiceImpl*>(SharedWorkerService::GetInstance())
-      ->ConnectToWorker(process_id_, frame_id_, std::move(info),
-                        std::move(client), creation_context_type,
-                        blink::MessagePortChannel(std::move(message_port)),
-                        resource_context_,
-                        WorkerStoragePartitionId(worker_storage_partition_));
+  SharedWorkerServiceImpl* service =
+      static_cast<StoragePartitionImpl*>(
+          RenderProcessHost::FromID(process_id_)->GetStoragePartition())
+          ->GetSharedWorkerService();
+  service->ConnectToWorker(process_id_, frame_id_, std::move(info),
+                           std::move(client), creation_context_type,
+                           blink::MessagePortChannel(std::move(message_port)));
 }
 
 }  // namespace content
diff --git a/content/browser/shared_worker/shared_worker_connector_impl.h b/content/browser/shared_worker/shared_worker_connector_impl.h
index 63c5a85a..2c609c6 100644
--- a/content/browser/shared_worker/shared_worker_connector_impl.h
+++ b/content/browser/shared_worker/shared_worker_connector_impl.h
@@ -5,12 +5,10 @@
 #ifndef CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_CONNECTOR_IMPL_H_
 #define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_CONNECTOR_IMPL_H_
 
-#include "content/browser/shared_worker/worker_storage_partition.h"
 #include "content/common/content_export.h"
 #include "content/common/shared_worker/shared_worker_connector.mojom.h"
 
 namespace content {
-class ResourceContext;
 
 // Instances of this class live on the UI thread and have their lifetime bound
 // to a Mojo connection.
@@ -22,19 +20,7 @@
                      mojom::SharedWorkerConnectorRequest request);
 
  private:
-  friend class SharedWorkerServiceImplTest;
-
-  static void CreateInternal(int process_id,
-                             int frame_id,
-                             ResourceContext* resource_context,
-                             const WorkerStoragePartition& partition,
-                             mojom::SharedWorkerConnectorRequest request);
-
-  SharedWorkerConnectorImpl(
-      int process_id,
-      int frame_id,
-      ResourceContext* resource_context,
-      const WorkerStoragePartition& worker_storage_partition);
+  SharedWorkerConnectorImpl(int process_id, int frame_id);
 
   // mojom::SharedWorkerConnector methods:
   void Connect(
@@ -45,8 +31,6 @@
 
   const int process_id_;
   const int frame_id_;
-  ResourceContext* resource_context_;
-  WorkerStoragePartition worker_storage_partition_;
 };
 
 }  // namespace content
diff --git a/content/browser/shared_worker/shared_worker_host.cc b/content/browser/shared_worker/shared_worker_host.cc
index 4c7c9051..93e0d8c 100644
--- a/content/browser/shared_worker/shared_worker_host.cc
+++ b/content/browser/shared_worker/shared_worker_host.cc
@@ -13,6 +13,7 @@
 #include "content/browser/shared_worker/shared_worker_content_settings_proxy_impl.h"
 #include "content/browser/shared_worker/shared_worker_instance.h"
 #include "content/browser/shared_worker/shared_worker_service_impl.h"
+#include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/render_process_host.h"
@@ -53,10 +54,12 @@
 }  // namespace
 
 SharedWorkerHost::SharedWorkerHost(
+    SharedWorkerServiceImpl* service,
     std::unique_ptr<SharedWorkerInstance> instance,
     int process_id,
     int route_id)
     : binding_(this),
+      service_(service),
       instance_(std::move(instance)),
       process_id_(process_id),
       route_id_(route_id),
@@ -111,7 +114,9 @@
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
       base::BindOnce(&AllowFileSystemOnIOThread, url,
-                     instance_->resource_context(),
+                     RenderProcessHost::FromID(process_id_)
+                         ->GetBrowserContext()
+                         ->GetResourceContext(),
                      GetRenderFrameIDsForWorker(), std::move(callback)));
 }
 
@@ -121,7 +126,9 @@
   BrowserThread::PostTaskAndReplyWithResult(
       BrowserThread::IO, FROM_HERE,
       base::BindOnce(&AllowIndexedDBOnIOThread, url, name,
-                     instance_->resource_context(),
+                     RenderProcessHost::FromID(process_id_)
+                         ->GetBrowserContext()
+                         ->GetResourceContext(),
                      GetRenderFrameIDsForWorker()),
       std::move(callback));
 }
@@ -250,8 +257,7 @@
 void SharedWorkerHost::OnWorkerConnectionLost() {
   // This will destroy |this| resulting in client's observing their mojo
   // connection being dropped.
-  static_cast<SharedWorkerServiceImpl*>(SharedWorkerService::GetInstance())
-      ->DestroyHost(this);
+  service_->DestroyHost(this);
 }
 
 void SharedWorkerHost::GetInterface(
diff --git a/content/browser/shared_worker/shared_worker_host.h b/content/browser/shared_worker/shared_worker_host.h
index da3b79e..a392e583 100644
--- a/content/browser/shared_worker/shared_worker_host.h
+++ b/content/browser/shared_worker/shared_worker_host.h
@@ -33,6 +33,7 @@
 
 class SharedWorkerContentSettingsProxyImpl;
 class SharedWorkerInstance;
+class SharedWorkerServiceImpl;
 
 // The SharedWorkerHost is the interface that represents the browser side of
 // the browser <-> worker communication channel. This is owned by
@@ -41,7 +42,8 @@
 class SharedWorkerHost : public mojom::SharedWorkerHost,
                          public service_manager::mojom::InterfaceProvider {
  public:
-  SharedWorkerHost(std::unique_ptr<SharedWorkerInstance> instance,
+  SharedWorkerHost(SharedWorkerServiceImpl* service,
+                   std::unique_ptr<SharedWorkerInstance> instance,
                    int process_id,
                    int route_id);
   ~SharedWorkerHost() override;
@@ -109,6 +111,7 @@
                     mojo::ScopedMessagePipeHandle interface_pipe) override;
 
   mojo::Binding<mojom::SharedWorkerHost> binding_;
+  SharedWorkerServiceImpl* service_;
   std::unique_ptr<SharedWorkerInstance> instance_;
   ClientList clients_;
 
diff --git a/content/browser/shared_worker/shared_worker_instance.cc b/content/browser/shared_worker/shared_worker_instance.cc
index bb2eceb6..83ed192 100644
--- a/content/browser/shared_worker/shared_worker_instance.cc
+++ b/content/browser/shared_worker/shared_worker_instance.cc
@@ -15,8 +15,6 @@
     const std::string& content_security_policy,
     blink::WebContentSecurityPolicyType security_policy_type,
     blink::WebAddressSpace creation_address_space,
-    ResourceContext* resource_context,
-    const WorkerStoragePartitionId& partition_id,
     blink::mojom::SharedWorkerCreationContextType creation_context_type)
     : url_(url),
       name_(name),
@@ -24,10 +22,7 @@
       content_security_policy_(content_security_policy),
       content_security_policy_type_(security_policy_type),
       creation_address_space_(creation_address_space),
-      resource_context_(resource_context),
-      partition_id_(partition_id),
       creation_context_type_(creation_context_type) {
-  DCHECK(resource_context_);
 }
 
 SharedWorkerInstance::SharedWorkerInstance(const SharedWorkerInstance& other) =
@@ -35,26 +30,15 @@
 
 SharedWorkerInstance::~SharedWorkerInstance() = default;
 
-bool SharedWorkerInstance::Matches(const GURL& url,
-                                   const std::string& name,
-                                   const url::Origin& constructor_origin,
-                                   const WorkerStoragePartitionId& partition_id,
-                                   ResourceContext* resource_context) const {
+bool SharedWorkerInstance::Matches(
+    const GURL& url,
+    const std::string& name,
+    const url::Origin& constructor_origin) const {
   // |url| and |constructor_origin| should be in the same origin, or |url|
   // should be a data: URL.
   DCHECK(url::Origin::Create(url).IsSameOriginWith(constructor_origin) ||
          url.SchemeIs(url::kDataScheme));
 
-  // ResourceContext equivalence is being used as a proxy to ensure we only
-  // matched shared workers within the same BrowserContext.
-  if (resource_context_ != resource_context)
-    return false;
-
-  // We must be in the same storage partition otherwise sharing will violate
-  // isolation.
-  if (!partition_id_.Equals(partition_id))
-    return false;
-
   // Step 11.2: "If there exists a SharedWorkerGlobalScope object whose closing
   // flag is false, constructor origin is same origin with outside settings's
   // origin, constructor url equals urlRecord, and name equals the value of
@@ -67,8 +51,7 @@
 }
 
 bool SharedWorkerInstance::Matches(const SharedWorkerInstance& other) const {
-  return Matches(other.url(), other.name(), other.constructor_origin(),
-                 other.partition_id(), other.resource_context());
+  return Matches(other.url(), other.name(), other.constructor_origin());
 }
 
 }  // namespace content
diff --git a/content/browser/shared_worker/shared_worker_instance.h b/content/browser/shared_worker/shared_worker_instance.h
index fac028f4..c71f253 100644
--- a/content/browser/shared_worker/shared_worker_instance.h
+++ b/content/browser/shared_worker/shared_worker_instance.h
@@ -7,7 +7,6 @@
 
 #include <string>
 
-#include "content/browser/shared_worker/worker_storage_partition.h"
 #include "content/common/content_export.h"
 #include "third_party/WebKit/public/platform/WebAddressSpace.h"
 #include "third_party/WebKit/public/platform/WebContentSecurityPolicy.h"
@@ -16,7 +15,6 @@
 #include "url/origin.h"
 
 namespace content {
-class ResourceContext;
 
 // SharedWorkerInstance is copyable value-type data type. It could be passed to
 // the UI thread and be used for comparison in SharedWorkerDevToolsManager.
@@ -29,8 +27,6 @@
       const std::string& content_security_policy,
       blink::WebContentSecurityPolicyType content_security_policy_type,
       blink::WebAddressSpace creation_address_space,
-      ResourceContext* resource_context,
-      const WorkerStoragePartitionId& partition_id,
       blink::mojom::SharedWorkerCreationContextType creation_context_type);
   SharedWorkerInstance(const SharedWorkerInstance& other);
   ~SharedWorkerInstance();
@@ -41,9 +37,7 @@
   // https://html.spec.whatwg.org/multipage/workers.html#shared-workers-and-the-sharedworker-interface
   bool Matches(const GURL& url,
                const std::string& name,
-               const url::Origin& constructor_origin,
-               const WorkerStoragePartitionId& partition,
-               ResourceContext* resource_context) const;
+               const url::Origin& constructor_origin) const;
   bool Matches(const SharedWorkerInstance& other) const;
 
   // Accessors.
@@ -59,10 +53,6 @@
   blink::WebAddressSpace creation_address_space() const {
     return creation_address_space_;
   }
-  ResourceContext* resource_context() const {
-    return resource_context_;
-  }
-  const WorkerStoragePartitionId& partition_id() const { return partition_id_; }
   blink::mojom::SharedWorkerCreationContextType creation_context_type() const {
     return creation_context_type_;
   }
@@ -79,8 +69,6 @@
   const std::string content_security_policy_;
   const blink::WebContentSecurityPolicyType content_security_policy_type_;
   const blink::WebAddressSpace creation_address_space_;
-  ResourceContext* const resource_context_;
-  const WorkerStoragePartitionId partition_id_;
   const blink::mojom::SharedWorkerCreationContextType creation_context_type_;
 };
 
diff --git a/content/browser/shared_worker/shared_worker_instance_unittest.cc b/content/browser/shared_worker/shared_worker_instance_unittest.cc
index b8d00d2..73b7bfe 100644
--- a/content/browser/shared_worker/shared_worker_instance_unittest.cc
+++ b/content/browser/shared_worker/shared_worker_instance_unittest.cc
@@ -9,29 +9,13 @@
 #include "base/macros.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
-#include "content/browser/shared_worker/worker_storage_partition.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/test/test_browser_context.h"
-#include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
 
 class SharedWorkerInstanceTest : public testing::Test {
  protected:
-  SharedWorkerInstanceTest()
-      : browser_context_(new TestBrowserContext()),
-        partition_(new WorkerStoragePartition(
-            BrowserContext::GetDefaultStoragePartition(browser_context_.get())
-                ->GetURLRequestContext(),
-            nullptr /* media_url_request_context */,
-            nullptr /* appcache_service */,
-            nullptr /* quota_manager */,
-            nullptr /* filesystem_context */,
-            nullptr /* database_tracker */,
-            nullptr /* indexed_db_context */,
-            nullptr /* service_worker_context */)),
-        partition_id_(*partition_.get()) {}
+  SharedWorkerInstanceTest() {}
 
   SharedWorkerInstance CreateInstance(const GURL& script_url,
                                       const std::string& name,
@@ -39,8 +23,7 @@
     return SharedWorkerInstance(
         script_url, name, constructor_origin, std::string(),
         blink::kWebContentSecurityPolicyTypeReport,
-        blink::kWebAddressSpacePublic, browser_context_->GetResourceContext(),
-        partition_id_,
+        blink::kWebAddressSpacePublic,
         blink::mojom::SharedWorkerCreationContextType::kNonsecure);
   }
 
@@ -52,16 +35,9 @@
       constructor_origin = url::Origin::Create(GURL("http://example.com/"));
     else
       constructor_origin = url::Origin::Create(GURL(url));
-    return instance.Matches(GURL(url), name.as_string(), constructor_origin,
-                            partition_id_,
-                            browser_context_->GetResourceContext());
+    return instance.Matches(GURL(url), name.as_string(), constructor_origin);
   }
 
-  TestBrowserThreadBundle thread_bundle_;
-  std::unique_ptr<TestBrowserContext> browser_context_;
-  std::unique_ptr<WorkerStoragePartition> partition_;
-  const WorkerStoragePartitionId partition_id_;
-
  private:
   DISALLOW_COPY_AND_ASSIGN(SharedWorkerInstanceTest);
 };
@@ -223,7 +199,6 @@
         url::Origin::Create(GURL("http://example.com/")), std::string(),
         blink::kWebContentSecurityPolicyTypeReport,
         static_cast<blink::WebAddressSpace>(i),
-        browser_context_->GetResourceContext(), partition_id_,
         blink::mojom::SharedWorkerCreationContextType::kNonsecure);
     EXPECT_EQ(static_cast<blink::WebAddressSpace>(i),
               instance.creation_address_space());
diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/shared_worker/shared_worker_service_impl.cc
index 847e3b1..53de15a 100644
--- a/content/browser/shared_worker/shared_worker_service_impl.cc
+++ b/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -16,7 +16,6 @@
 #include "content/browser/devtools/shared_worker_devtools_manager.h"
 #include "content/browser/shared_worker/shared_worker_host.h"
 #include "content/browser/shared_worker/shared_worker_instance.h"
-#include "content/browser/storage_partition_impl.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/common/shared_worker/shared_worker_client.mojom.h"
 #include "content/public/browser/browser_thread.h"
@@ -38,47 +37,17 @@
 
 }  // namespace
 
-// static
-SharedWorkerService* SharedWorkerService::GetInstance() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  // OK to just leak the instance.
-  // TODO(darin): Consider hanging instances off of StoragePartitionImpl.
-  static SharedWorkerServiceImpl* instance = nullptr;
-  if (!instance)
-    instance = new SharedWorkerServiceImpl();
-  return instance;
-}
-
 SharedWorkerServiceImpl::SharedWorkerServiceImpl() {}
 
 SharedWorkerServiceImpl::~SharedWorkerServiceImpl() {}
 
-void SharedWorkerServiceImpl::ResetForTesting() {
-  worker_hosts_.clear();
-}
-
 bool SharedWorkerServiceImpl::TerminateWorker(
     const GURL& url,
     const std::string& name,
-    const url::Origin& constructor_origin,
-    StoragePartition* storage_partition,
-    ResourceContext* resource_context) {
-  StoragePartitionImpl* storage_partition_impl =
-      static_cast<StoragePartitionImpl*>(storage_partition);
-  WorkerStoragePartitionId partition_id(WorkerStoragePartition(
-      storage_partition_impl->GetURLRequestContext(),
-      storage_partition_impl->GetMediaURLRequestContext(),
-      storage_partition_impl->GetAppCacheService(),
-      storage_partition_impl->GetQuotaManager(),
-      storage_partition_impl->GetFileSystemContext(),
-      storage_partition_impl->GetDatabaseTracker(),
-      storage_partition_impl->GetIndexedDBContext(),
-      storage_partition_impl->GetServiceWorkerContext()));
-
+    const url::Origin& constructor_origin) {
   for (auto& host : worker_hosts_) {
     if (host->IsAvailable() &&
-        host->instance()->Matches(url, name, constructor_origin, partition_id,
-                                  resource_context)) {
+        host->instance()->Matches(url, name, constructor_origin)) {
       host->TerminateWorker();
       return true;
     }
@@ -108,9 +77,7 @@
     mojom::SharedWorkerInfoPtr info,
     mojom::SharedWorkerClientPtr client,
     blink::mojom::SharedWorkerCreationContextType creation_context_type,
-    const blink::MessagePortChannel& message_port,
-    ResourceContext* resource_context,
-    const WorkerStoragePartitionId& partition_id) {
+    const blink::MessagePortChannel& message_port) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   RenderFrameHostImpl* render_frame_host =
@@ -137,8 +104,7 @@
   auto instance = std::make_unique<SharedWorkerInstance>(
       info->url, info->name, render_frame_host->GetLastCommittedOrigin(),
       info->content_security_policy, info->content_security_policy_type,
-      info->creation_address_space, resource_context, partition_id,
-      creation_context_type);
+      info->creation_address_space, creation_context_type);
 
   SharedWorkerHost* host = FindAvailableSharedWorkerHost(*instance);
   if (host) {
@@ -202,7 +168,7 @@
   int worker_route_id = process_host->GetNextRoutingID();
 
   auto host = std::make_unique<SharedWorkerHost>(
-      std::move(instance), worker_process_id, worker_route_id);
+      this, std::move(instance), worker_process_id, worker_route_id);
 
   bool pause_on_start;
   base::UnguessableToken devtools_worker_token;
diff --git a/content/browser/shared_worker/shared_worker_service_impl.h b/content/browser/shared_worker/shared_worker_service_impl.h
index 60e7abc..963d90c0 100644
--- a/content/browser/shared_worker/shared_worker_service_impl.h
+++ b/content/browser/shared_worker/shared_worker_service_impl.h
@@ -27,18 +27,16 @@
 
 class SharedWorkerInstance;
 class SharedWorkerHost;
-class StoragePartition;
-class ResourceContext;
-class WorkerStoragePartitionId;
 
 class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
  public:
+  SharedWorkerServiceImpl();
+  ~SharedWorkerServiceImpl() override;
+
   // SharedWorkerService implementation.
   bool TerminateWorker(const GURL& url,
                        const std::string& name,
-                       const url::Origin& constructor_origin,
-                       StoragePartition* storage_partition,
-                       ResourceContext* resource_context) override;
+                       const url::Origin& constructor_origin) override;
 
   void TerminateAllWorkersForTesting(base::OnceClosure callback);
 
@@ -49,21 +47,12 @@
       mojom::SharedWorkerInfoPtr info,
       mojom::SharedWorkerClientPtr client,
       blink::mojom::SharedWorkerCreationContextType creation_context_type,
-      const blink::MessagePortChannel& port,
-      ResourceContext* resource_context,
-      const WorkerStoragePartitionId& partition_id);
+      const blink::MessagePortChannel& port);
 
   void DestroyHost(SharedWorkerHost* host);
 
  private:
-  friend struct base::DefaultSingletonTraits<SharedWorkerServiceImpl>;
   friend class SharedWorkerServiceImplTest;
-  friend class SharedWorkerService;
-
-  SharedWorkerServiceImpl();
-  ~SharedWorkerServiceImpl() override;
-
-  void ResetForTesting();
 
   void CreateWorker(std::unique_ptr<SharedWorkerInstance> instance,
                     mojom::SharedWorkerClientPtr client,
diff --git a/content/browser/shared_worker/shared_worker_service_impl_unittest.cc b/content/browser/shared_worker/shared_worker_service_impl_unittest.cc
index b78a6c9..84adbfe 100644
--- a/content/browser/shared_worker/shared_worker_service_impl_unittest.cc
+++ b/content/browser/shared_worker/shared_worker_service_impl_unittest.cc
@@ -20,7 +20,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/lock.h"
 #include "content/browser/shared_worker/shared_worker_connector_impl.h"
-#include "content/browser/shared_worker/worker_storage_partition.h"
 #include "content/browser/site_instance_impl.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/test/mock_render_process_host.h"
@@ -43,10 +42,8 @@
       RenderProcessHost* process_host,
       int frame_id) {
     mojom::SharedWorkerConnectorPtr connector;
-    SharedWorkerConnectorImpl::CreateInternal(
-        process_host->GetID(), frame_id,
-        process_host->GetBrowserContext()->GetResourceContext(), *partition_,
-        mojo::MakeRequest(&connector));
+    SharedWorkerConnectorImpl::Create(process_host->GetID(), frame_id,
+                                      mojo::MakeRequest(&connector));
     return connector;
   }
 
@@ -77,18 +74,7 @@
   }
 
  protected:
-  SharedWorkerServiceImplTest()
-      : browser_context_(new TestBrowserContext()),
-        partition_(new WorkerStoragePartition(
-            BrowserContext::GetDefaultStoragePartition(browser_context_.get())
-                ->GetURLRequestContext(),
-            nullptr /* media_url_request_context */,
-            nullptr /* appcache_service */,
-            nullptr /* quota_manager */,
-            nullptr /* filesystem_context */,
-            nullptr /* database_tracker */,
-            nullptr /* indexed_db_context */,
-            nullptr /* service_worker_context */)) {}
+  SharedWorkerServiceImplTest() : browser_context_(new TestBrowserContext()) {}
 
   void SetUp() override {
     RenderViewHostImplTestHarness::SetUp();
@@ -99,14 +85,11 @@
   }
 
   void TearDown() override {
-    static_cast<SharedWorkerServiceImpl*>(SharedWorkerService::GetInstance())
-        ->ResetForTesting();
     browser_context_.reset();
     RenderViewHostImplTestHarness::TearDown();
   }
 
   std::unique_ptr<TestBrowserContext> browser_context_;
-  std::unique_ptr<WorkerStoragePartition> partition_;
   static std::queue<mojom::SharedWorkerFactoryRequest>
       s_factory_request_received_;
   std::unique_ptr<MockRenderProcessHostFactory> render_process_host_factory_;
diff --git a/content/browser/shared_worker/worker_storage_partition.cc b/content/browser/shared_worker/worker_storage_partition.cc
deleted file mode 100644
index c9bb5be..0000000
--- a/content/browser/shared_worker/worker_storage_partition.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/shared_worker/worker_storage_partition.h"
-
-#include <string>
-
-#include "content/browser/appcache/chrome_appcache_service.h"
-#include "content/browser/indexed_db/indexed_db_context_impl.h"
-#include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "storage/browser/database/database_tracker.h"
-#include "storage/browser/fileapi/file_system_context.h"
-#include "storage/browser/quota/quota_manager.h"
-
-namespace content {
-
-WorkerStoragePartition::WorkerStoragePartition(
-    net::URLRequestContextGetter* url_request_context,
-    net::URLRequestContextGetter* media_url_request_context,
-    ChromeAppCacheService* appcache_service,
-    storage::QuotaManager* quota_manager,
-    storage::FileSystemContext* filesystem_context,
-    storage::DatabaseTracker* database_tracker,
-    IndexedDBContextImpl* indexed_db_context,
-    ServiceWorkerContextWrapper* service_worker_context)
-    : url_request_context_(url_request_context),
-      media_url_request_context_(media_url_request_context),
-      appcache_service_(appcache_service),
-      quota_manager_(quota_manager),
-      filesystem_context_(filesystem_context),
-      database_tracker_(database_tracker),
-      indexed_db_context_(indexed_db_context),
-      service_worker_context_(service_worker_context) {
-}
-
-WorkerStoragePartition::WorkerStoragePartition(
-    const WorkerStoragePartition& other) {
-  Copy(other);
-}
-
-const WorkerStoragePartition& WorkerStoragePartition::operator=(
-    const WorkerStoragePartition& rhs) {
-  Copy(rhs);
-  return *this;
-}
-
-bool WorkerStoragePartition::Equals(
-    const WorkerStoragePartition& other) const {
-  return url_request_context_.get() == other.url_request_context_.get() &&
-         media_url_request_context_.get() ==
-             other.media_url_request_context_.get() &&
-         appcache_service_.get() == other.appcache_service_.get() &&
-         quota_manager_.get() == other.quota_manager_.get() &&
-         filesystem_context_.get() == other.filesystem_context_.get() &&
-         database_tracker_.get() == other.database_tracker_.get() &&
-         indexed_db_context_.get() == other.indexed_db_context_.get() &&
-         service_worker_context_.get() == other.service_worker_context_.get();
-}
-
-WorkerStoragePartition::~WorkerStoragePartition() {
-}
-
-void WorkerStoragePartition::Copy(const WorkerStoragePartition& other) {
-  url_request_context_ = other.url_request_context_;
-  media_url_request_context_ = other.media_url_request_context_;
-  appcache_service_ = other.appcache_service_;
-  quota_manager_ = other.quota_manager_;
-  filesystem_context_ = other.filesystem_context_;
-  database_tracker_ = other.database_tracker_;
-  indexed_db_context_ = other.indexed_db_context_;
-  service_worker_context_ = other.service_worker_context_;
-}
-
-WorkerStoragePartitionId::WorkerStoragePartitionId(
-    const WorkerStoragePartition& partition)
-    : url_request_context_(partition.url_request_context()),
-      media_url_request_context_(partition.media_url_request_context()),
-      appcache_service_(partition.appcache_service()),
-      quota_manager_(partition.quota_manager()),
-      filesystem_context_(partition.filesystem_context()),
-      database_tracker_(partition.database_tracker()),
-      indexed_db_context_(partition.indexed_db_context()),
-      service_worker_context_(partition.service_worker_context()) {
-}
-
-WorkerStoragePartitionId::~WorkerStoragePartitionId() {
-}
-
-bool WorkerStoragePartitionId::Equals(
-    const WorkerStoragePartitionId& other) const {
-  return url_request_context_ == other.url_request_context_ &&
-         media_url_request_context_ == other.media_url_request_context_ &&
-         appcache_service_ == other.appcache_service_ &&
-         quota_manager_ == other.quota_manager_ &&
-         filesystem_context_ == other.filesystem_context_ &&
-         database_tracker_ == other.database_tracker_ &&
-         indexed_db_context_ == other.indexed_db_context_ &&
-         service_worker_context_ == other.service_worker_context_;
-}
-
-}  // namespace content
diff --git a/content/browser/shared_worker/worker_storage_partition.h b/content/browser/shared_worker/worker_storage_partition.h
deleted file mode 100644
index 9e375b4c..0000000
--- a/content/browser/shared_worker/worker_storage_partition.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_SHARED_WORKER_WORKER_STORAGE_PARTITION_H_
-#define CONTENT_BROWSER_SHARED_WORKER_WORKER_STORAGE_PARTITION_H_
-
-#include "base/memory/ref_counted.h"
-#include "content/common/content_export.h"
-
-namespace storage {
-class QuotaManager;
-}
-
-namespace storage {
-class FileSystemContext;
-}  // namespace storage
-
-namespace net {
-class URLRequestContextGetter;
-}
-
-namespace storage {
-class DatabaseTracker;
-}  // namespace storage
-
-namespace content {
-class ChromeAppCacheService;
-class IndexedDBContextImpl;
-class ServiceWorkerContextWrapper;
-
-// Contains the data from StoragePartition for use by Worker APIs.
-//
-// StoragePartition meant for the UI so we can't use it directly in many
-// Worker APIs that run on the IO thread. While we could make it RefCounted,
-// the Worker system is the only place that really needs access on the IO
-// thread. Instead of changing the lifetime semantics of StoragePartition,
-// we just create a parallel struct here to simplify the APIs of various
-// methods in WorkerServiceImpl.
-//
-// This class is effectively a struct, but we make it a class because we want to
-// define copy constructors, assignment operators, and an Equals() function for
-// it which makes it look awkward as a struct.
-//
-// TODO(darin): This class is no longer used off the UI thread, so we can
-// probably simplify it or eliminate it altogether.
-//
-class CONTENT_EXPORT WorkerStoragePartition {
- public:
-  WorkerStoragePartition(
-      net::URLRequestContextGetter* url_request_context,
-      net::URLRequestContextGetter* media_url_request_context,
-      ChromeAppCacheService* appcache_service,
-      storage::QuotaManager* quota_manager,
-      storage::FileSystemContext* filesystem_context,
-      storage::DatabaseTracker* database_tracker,
-      IndexedDBContextImpl* indexed_db_context,
-      ServiceWorkerContextWrapper* service_worker_context);
-  ~WorkerStoragePartition();
-
-  // Declaring so these don't get inlined which has the unfortunate effect of
-  // requiring all including classes to have the full definition of every member
-  // type.
-  WorkerStoragePartition(const WorkerStoragePartition& other);
-  const WorkerStoragePartition& operator=(const WorkerStoragePartition& rhs);
-
-  bool Equals(const WorkerStoragePartition& other) const;
-
-  net::URLRequestContextGetter* url_request_context() const {
-    return url_request_context_.get();
-  }
-
-  net::URLRequestContextGetter* media_url_request_context() const {
-    return media_url_request_context_.get();
-  }
-
-  ChromeAppCacheService* appcache_service() const {
-    return appcache_service_.get();
-  }
-
-  storage::QuotaManager* quota_manager() const { return quota_manager_.get(); }
-
-  storage::FileSystemContext* filesystem_context() const {
-    return filesystem_context_.get();
-  }
-
-  storage::DatabaseTracker* database_tracker() const {
-    return database_tracker_.get();
-  }
-
-  IndexedDBContextImpl* indexed_db_context() const {
-    return indexed_db_context_.get();
-  }
-
-  ServiceWorkerContextWrapper* service_worker_context() const {
-    return service_worker_context_.get();
-  }
-
- private:
-  void Copy(const WorkerStoragePartition& other);
-
-  scoped_refptr<net::URLRequestContextGetter> url_request_context_;
-  scoped_refptr<net::URLRequestContextGetter> media_url_request_context_;
-  scoped_refptr<ChromeAppCacheService> appcache_service_;
-  scoped_refptr<storage::QuotaManager> quota_manager_;
-  scoped_refptr<storage::FileSystemContext> filesystem_context_;
-  scoped_refptr<storage::DatabaseTracker> database_tracker_;
-  scoped_refptr<IndexedDBContextImpl> indexed_db_context_;
-  scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
-};
-
-// WorkerStoragePartitionId can be used to identify each
-// WorkerStoragePartitions. We can hold WorkerStoragePartitionId without
-// extending the lifetime of all objects in the WorkerStoragePartition.
-// That means that holding a WorkerStoragePartitionId doesn't mean the
-// corresponding partition and its members are kept alive.
-class CONTENT_EXPORT WorkerStoragePartitionId {
- public:
-  explicit WorkerStoragePartitionId(const WorkerStoragePartition& partition);
-  ~WorkerStoragePartitionId();
-  bool Equals(const WorkerStoragePartitionId& other) const;
-
- private:
-  net::URLRequestContextGetter* url_request_context_;
-  net::URLRequestContextGetter* media_url_request_context_;
-  ChromeAppCacheService* appcache_service_;
-  storage::QuotaManager* quota_manager_;
-  storage::FileSystemContext* filesystem_context_;
-  storage::DatabaseTracker* database_tracker_;
-  IndexedDBContextImpl* indexed_db_context_;
-  ServiceWorkerContextWrapper* service_worker_context_;
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_SHARED_WORKER_WORKER_STORAGE_PARTITION_H_
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 99fb719..9af9da6 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -51,8 +51,7 @@
 #include "storage/browser/blob/blob_storage_context.h"
 #include "storage/browser/database/database_tracker.h"
 #include "storage/browser/quota/quota_manager.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 #if !defined(OS_ANDROID)
 #include "content/browser/host_zoom_map_impl.h"
@@ -125,13 +124,13 @@
 }
 
 void OnQuotaManagedOriginDeleted(const GURL& origin,
-                                 blink::StorageType type,
+                                 blink::mojom::StorageType type,
                                  size_t* deletion_task_count,
                                  const base::Closure& callback,
-                                 blink::QuotaStatusCode status) {
+                                 blink::mojom::QuotaStatusCode status) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK_GT(*deletion_task_count, 0u);
-  if (status != blink::QuotaStatusCode::kOk) {
+  if (status != blink::mojom::QuotaStatusCode::kOk) {
     DLOG(ERROR) << "Couldn't remove data of type " << static_cast<int>(type)
                 << " for origin " << origin
                 << ". Status: " << static_cast<int>(status);
@@ -340,7 +339,7 @@
       const StoragePartition::OriginMatcherFunction& origin_matcher,
       const base::Closure& callback,
       const std::set<GURL>& origins,
-      blink::StorageType quota_storage_type);
+      blink::mojom::StorageType quota_storage_type);
 
   // All of these data are accessed on IO thread.
   uint32_t remove_mask;
@@ -458,6 +457,9 @@
 StoragePartitionImpl::~StoragePartitionImpl() {
   browser_context_ = nullptr;
 
+  if (url_loader_factory_getter_)
+    url_loader_factory_getter_->OnStoragePartitionDestroyed();
+
   if (GetDatabaseTracker()) {
     GetDatabaseTracker()->task_runner()->PostTask(
         FROM_HERE, base::BindOnce(&storage::DatabaseTracker::Shutdown,
@@ -548,6 +550,9 @@
   partition->service_worker_context_ = new ServiceWorkerContextWrapper(context);
   partition->service_worker_context_->set_storage_partition(partition.get());
 
+  partition->shared_worker_service_ =
+      std::make_unique<SharedWorkerServiceImpl>();
+
   partition->appcache_service_ =
       new ChromeAppCacheService(quota_manager_proxy.get());
 
@@ -698,6 +703,10 @@
   return service_worker_context_.get();
 }
 
+SharedWorkerServiceImpl* StoragePartitionImpl::GetSharedWorkerService() {
+  return shared_worker_service_.get();
+}
+
 #if !defined(OS_ANDROID)
 HostZoomMap* StoragePartitionImpl::GetHostZoomMap() {
   DCHECK(host_zoom_level_context_.get());
@@ -828,7 +837,7 @@
     // within the user-specified timeframe, and deal with the resulting set in
     // ClearQuotaManagedOriginsOnIOThread().
     quota_manager->GetOriginsModifiedSince(
-        blink::StorageType::kPersistent, begin,
+        blink::mojom::StorageType::kPersistent, begin,
         base::Bind(&QuotaManagedDataDeletionHelper::ClearOriginsOnIOThread,
                    base::Unretained(this), base::RetainedRef(quota_manager),
                    special_storage_policy, origin_matcher, decrement_callback));
@@ -838,7 +847,7 @@
   if (quota_storage_remove_mask & QUOTA_MANAGED_STORAGE_MASK_TEMPORARY) {
     IncrementTaskCountOnIO();
     quota_manager->GetOriginsModifiedSince(
-        blink::StorageType::kTemporary, begin,
+        blink::mojom::StorageType::kTemporary, begin,
         base::Bind(&QuotaManagedDataDeletionHelper::ClearOriginsOnIOThread,
                    base::Unretained(this), base::RetainedRef(quota_manager),
                    special_storage_policy, origin_matcher, decrement_callback));
@@ -848,7 +857,7 @@
   if (quota_storage_remove_mask & QUOTA_MANAGED_STORAGE_MASK_SYNCABLE) {
     IncrementTaskCountOnIO();
     quota_manager->GetOriginsModifiedSince(
-        blink::StorageType::kSyncable, begin,
+        blink::mojom::StorageType::kSyncable, begin,
         base::Bind(&QuotaManagedDataDeletionHelper::ClearOriginsOnIOThread,
                    base::Unretained(this), base::RetainedRef(quota_manager),
                    special_storage_policy, origin_matcher, decrement_callback));
@@ -865,7 +874,7 @@
         const StoragePartition::OriginMatcherFunction& origin_matcher,
         const base::Closure& callback,
         const std::set<GURL>& origins,
-        blink::StorageType quota_storage_type) {
+        blink::mojom::StorageType quota_storage_type) {
   // The QuotaManager manages all storage other than cookies, LocalStorage,
   // and SessionStorage. This loop wipes out most HTML5 storage for the given
   // origins.
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index 449eeab..3ca766c 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -29,6 +29,7 @@
 #include "content/browser/payments/payment_app_context_impl.h"
 #include "content/browser/push_messaging/push_messaging_context.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/shared_worker/shared_worker_service_impl.h"
 #include "content/browser/url_loader_factory_getter.h"
 #include "content/common/content_export.h"
 #include "content/common/storage_partition_service.mojom.h"
@@ -89,6 +90,7 @@
   IndexedDBContextImpl* GetIndexedDBContext() override;
   CacheStorageContextImpl* GetCacheStorageContext() override;
   ServiceWorkerContextWrapper* GetServiceWorkerContext() override;
+  SharedWorkerServiceImpl* GetSharedWorkerService() override;
 #if !defined(OS_ANDROID)
   HostZoomMap* GetHostZoomMap() override;
   HostZoomLevelContext* GetHostZoomLevelContext() override;
@@ -273,6 +275,7 @@
   scoped_refptr<IndexedDBContextImpl> indexed_db_context_;
   scoped_refptr<CacheStorageContextImpl> cache_storage_context_;
   scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
+  std::unique_ptr<SharedWorkerServiceImpl> shared_worker_service_;
   scoped_refptr<PushMessagingContext> push_messaging_context_;
   scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
 #if !defined(OS_ANDROID)
diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc
index 445ade0..04828d2 100644
--- a/content/browser/storage_partition_impl_unittest.cc
+++ b/content/browser/storage_partition_impl_unittest.cc
@@ -69,8 +69,10 @@
 const GURL kOrigin3(kTestOrigin3);
 const GURL kOriginDevTools(kTestOriginDevTools);
 
-const blink::StorageType kTemporary = blink::StorageType::kTemporary;
-const blink::StorageType kPersistent = blink::StorageType::kPersistent;
+const blink::mojom::StorageType kTemporary =
+    blink::mojom::StorageType::kTemporary;
+const blink::mojom::StorageType kPersistent =
+    blink::mojom::StorageType::kPersistent;
 
 const storage::QuotaClient::ID kClientFile = storage::QuotaClient::kFileSystem;
 
diff --git a/content/browser/url_loader_factory_getter.cc b/content/browser/url_loader_factory_getter.cc
index 9e1ebef8..26f3c7b 100644
--- a/content/browser/url_loader_factory_getter.cc
+++ b/content/browser/url_loader_factory_getter.cc
@@ -19,12 +19,14 @@
 URLLoaderFactoryGetter::URLLoaderFactoryGetter() {}
 
 void URLLoaderFactoryGetter::Initialize(StoragePartitionImpl* partition) {
+  DCHECK(partition);
+  partition_ = partition;
+
   mojom::URLLoaderFactoryPtr network_factory;
-  partition->GetNetworkContext()->CreateURLLoaderFactory(
-      MakeRequest(&network_factory), 0);
+  HandleNetworkFactoryRequestOnUIThread(MakeRequest(&network_factory));
 
   mojom::URLLoaderFactoryPtr blob_factory;
-  partition->GetBlobURLLoaderFactory()->HandleRequest(
+  partition_->GetBlobURLLoaderFactory()->HandleRequest(
       mojo::MakeRequest(&blob_factory));
 
   BrowserThread::PostTask(
@@ -34,11 +36,27 @@
                      blob_factory.PassInterface()));
 }
 
+void URLLoaderFactoryGetter::OnStoragePartitionDestroyed() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  partition_ = nullptr;
+}
+
 mojom::URLLoaderFactory* URLLoaderFactoryGetter::GetNetworkFactory() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   if (g_get_network_factory_callback.Get() && !test_factory_)
     g_get_network_factory_callback.Get().Run(this);
-  return test_factory_ ? test_factory_ : network_factory_.get();
+
+  if (test_factory_)
+    return test_factory_;
+
+  if (!network_factory_.is_bound() || network_factory_.encountered_error()) {
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        base::BindOnce(
+            &URLLoaderFactoryGetter::HandleNetworkFactoryRequestOnUIThread,
+            this, mojo::MakeRequest(&network_factory_)));
+  }
+  return network_factory_.get();
 }
 
 mojom::URLLoaderFactory* URLLoaderFactoryGetter::GetBlobFactory() {
@@ -62,6 +80,23 @@
   g_get_network_factory_callback.Get() = get_network_factory_callback;
 }
 
+void URLLoaderFactoryGetter::FlushNetworkInterfaceOnIOThreadForTesting() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  base::RunLoop run_loop;
+  BrowserThread::PostTaskAndReply(
+      BrowserThread::IO, FROM_HERE,
+      base::BindOnce(&URLLoaderFactoryGetter::FlushNetworkInterfaceForTesting,
+                     this),
+      run_loop.QuitClosure());
+  run_loop.Run();
+}
+
+void URLLoaderFactoryGetter::FlushNetworkInterfaceForTesting() {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (network_factory_)
+    network_factory_.FlushForTesting();
+}
+
 URLLoaderFactoryGetter::~URLLoaderFactoryGetter() {}
 
 void URLLoaderFactoryGetter::InitializeOnIOThread(
@@ -71,4 +106,15 @@
   blob_factory_.Bind(std::move(blob_factory));
 }
 
+void URLLoaderFactoryGetter::HandleNetworkFactoryRequestOnUIThread(
+    mojom::URLLoaderFactoryRequest network_factory_request) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  // |StoragePartitionImpl| may have went away while |URLLoaderFactoryGetter| is
+  // still held by consumers.
+  if (!partition_)
+    return;
+  partition_->GetNetworkContext()->CreateURLLoaderFactory(
+      std::move(network_factory_request), 0);
+}
+
 }  // namespace content
diff --git a/content/browser/url_loader_factory_getter.h b/content/browser/url_loader_factory_getter.h
index 2311472..b079878 100644
--- a/content/browser/url_loader_factory_getter.h
+++ b/content/browser/url_loader_factory_getter.h
@@ -26,12 +26,17 @@
   CONTENT_EXPORT URLLoaderFactoryGetter();
 
   // Initializes this object on the UI thread. The |partition| is used to
-  // initialize the URLLoaderFactories for the network service and AppCache.
+  // initialize the URLLoaderFactories for the network service and AppCache, and
+  // will be cached to recover from connection error.
   void Initialize(StoragePartitionImpl* partition);
 
+  // Clear the cached pointer to |StoragePartitionImpl| on the UI thread. Should
+  // be called when the partition is going away.
+  void OnStoragePartitionDestroyed();
+
   // Called on the IO thread to get the URLLoaderFactory to the network service.
   // The pointer shouldn't be cached.
-  mojom::URLLoaderFactory* GetNetworkFactory();
+  CONTENT_EXPORT mojom::URLLoaderFactory* GetNetworkFactory();
 
   // Called on the IO thread to get the URLLoaderFactory to the blob service.
   // The pointer shouldn't be cached.
@@ -56,6 +61,9 @@
   CONTENT_EXPORT static void SetGetNetworkFactoryCallbackForTesting(
       const GetNetworkFactoryCallback& get_network_factory_callback);
 
+  // Call |network_factory_.FlushForTesting()| on IO thread. For test use only.
+  CONTENT_EXPORT void FlushNetworkInterfaceOnIOThreadForTesting();
+
  private:
   friend class base::DeleteHelper<URLLoaderFactoryGetter>;
   friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
@@ -64,11 +72,23 @@
   void InitializeOnIOThread(mojom::URLLoaderFactoryPtrInfo network_factory,
                             mojom::URLLoaderFactoryPtrInfo blob_factory);
 
+  // Send |network_factory_request| to cached |StoragePartitionImpl|.
+  void HandleNetworkFactoryRequestOnUIThread(
+      mojom::URLLoaderFactoryRequest network_factory_request);
+
+  // Call |network_factory_.FlushForTesting()|. For test use only.
+  void FlushNetworkInterfaceForTesting();
+
   // Only accessed on IO thread.
   mojom::URLLoaderFactoryPtr network_factory_;
   mojom::URLLoaderFactoryPtr blob_factory_;
   mojom::URLLoaderFactory* test_factory_ = nullptr;
 
+  // Used to re-create |network_factory_| when connection error happens. Can
+  // only be accessed on UI thread. Must be cleared by |StoragePartitionImpl|
+  // when it's going away.
+  StoragePartitionImpl* partition_ = nullptr;
+
   DISALLOW_COPY_AND_ASSIGN(URLLoaderFactoryGetter);
 };
 
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index ae68a49e..289a3a0 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -120,6 +120,9 @@
   WebRuntimeFeatures::EnableWebAssemblyStreaming(
       base::FeatureList::IsEnabled(features::kWebAssemblyStreaming));
 
+  WebRuntimeFeatures::EnableSharedArrayBuffer(
+      base::FeatureList::IsEnabled(features::kSharedArrayBuffer));
+
   if (command_line.HasSwitch(switches::kDisableSharedWorkers))
     WebRuntimeFeatures::EnableSharedWorker(false);
 
diff --git a/content/common/browser_plugin/OWNERS b/content/common/browser_plugin/OWNERS
index 465e847..d3826db 100644
--- a/content/common/browser_plugin/OWNERS
+++ b/content/common/browser_plugin/OWNERS
@@ -1,6 +1,4 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-wjmaclean@chromium.org
+file://components/guest_view/OWNERS
 
 per-file *_messages*.h=set noparent
 per-file *_messages*.h=file://ipc/SECURITY_OWNERS
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java
index 2bd1b69..855e50a 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java
@@ -1224,15 +1224,15 @@
             }
             mWebContentsAccessibility = WebContentsAccessibility.create(
                     mContext, mContainerView, mWebContents, mShouldSetAccessibilityFocusOnPageLoad);
+            // For Lollipop devices, we need to register a broadcast receiver for locale change.
+            if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP
+                    && mContainerView.isAttachedToWindow()) {
+                mWebContentsAccessibility.onAttachedToWindow();
+            }
         }
         if (!mWebContentsAccessibility.isEnabled()) {
             mWebContentsAccessibility.enable();
         }
-        // For Lollipop devices, we need to register a broadcast receiver for locale change.
-        if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP
-                && mContainerView.isAttachedToWindow()) {
-            mWebContentsAccessibility.onAttachedToWindow();
-        }
         return mWebContentsAccessibility.getAccessibilityNodeProvider();
     }
 
diff --git a/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java b/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java
index 163357f..47876bb 100644
--- a/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java
+++ b/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java
@@ -272,11 +272,14 @@
 
     @VisibleForTesting
     @CalledByNative
-    public void showSelectionMenu(int left, int top, int right, int bottom, boolean isEditable,
-            boolean isPasswordType, String selectionText, int selectionStartOffset,
-            boolean canSelectAll, boolean canRichlyEdit, boolean shouldSuggest,
-            @MenuSourceType int sourceType) {
-        mSelectionRect.set(left, top, right, bottom);
+    public void showSelectionMenu(int left, int top, int right, int bottom, int handleHeight,
+            boolean isEditable, boolean isPasswordType, String selectionText,
+            int selectionStartOffset, boolean canSelectAll, boolean canRichlyEdit,
+            boolean shouldSuggest, @MenuSourceType int sourceType) {
+        int offsetBottom = bottom;
+        // Legacy action mode expects the selection rectangle not to include touch handle.
+        if (supportsFloatingActionMode()) offsetBottom += handleHeight;
+        mSelectionRect.set(left, top, right, offsetBottom);
         mEditable = isEditable;
         mLastSelectedText = selectionText;
         mLastSelectionOffset = selectionStartOffset;
diff --git a/content/public/android/junit/src/org/chromium/content/browser/SelectionPopupControllerTest.java b/content/public/android/junit/src/org/chromium/content/browser/SelectionPopupControllerTest.java
index c375a6f..60ecd25 100644
--- a/content/public/android/junit/src/org/chromium/content/browser/SelectionPopupControllerTest.java
+++ b/content/public/android/junit/src/org/chromium/content/browser/SelectionPopupControllerTest.java
@@ -147,7 +147,7 @@
         mController.setSelectionClient(client);
 
         // Long press triggered showSelectionMenu() call.
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
@@ -162,7 +162,7 @@
                 .thenReturn(mActionMode);
 
         // Call showSelectionMenu again, which is adjustSelectionByCharacterOffset triggered.
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
@@ -193,7 +193,7 @@
         mController.setSelectionClient(client);
 
         // Long press triggered showSelectionMenu() call.
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
@@ -206,7 +206,7 @@
 
         // Another long press triggered showSelectionMenu() call.
         client.setResult(newResult);
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, MOUNTAIN, /* selectionOffset = */ 21,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
@@ -219,7 +219,7 @@
                 .thenReturn(mActionMode);
 
         // First adjustSelectionByCharacterOffset() triggered.
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
@@ -231,7 +231,7 @@
         assertEquals("Maps", returnResult.label);
 
         // Second adjustSelectionByCharacterOffset() triggered.
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, MOUNTAIN_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
@@ -254,14 +254,14 @@
         mController.setSelectionClient(client);
 
         // Long press triggered showSelectionMenu() call.
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
                 MenuSourceType.MENU_SOURCE_LONG_PRESS);
 
         // Another long press triggered showSelectionMenu() call.
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, MOUNTAIN, /* selectionOffset = */ 21,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
@@ -284,7 +284,7 @@
                 .thenReturn(mActionMode);
 
         // First adjustSelectionByCharacterOffset() triggered.
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
@@ -296,7 +296,7 @@
         assertEquals("Maps", returnResult.label);
 
         // Second adjustSelectionByCharacterOffset() triggered.
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, MOUNTAIN_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
@@ -321,7 +321,7 @@
         mController.setSelectionClient(client);
 
         // Long press triggered showSelectionMenu() call.
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
@@ -335,7 +335,7 @@
         mController.getResultCallback().onClassified(result);
 
         // Call showSelectionMenu again, which is adjustSelectionByCharacterOffset triggered.
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
@@ -345,7 +345,7 @@
                 eq(AMPHITHEATRE_FULL), eq(0), isA(SelectionClient.Result.class));
 
         // Dragging selection handle, select "1600 Amphitheatre".
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, AMPHITHEATRE_FULL.substring(0, 17),
                 /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
@@ -375,7 +375,7 @@
         mController.setSelectionClient(client);
 
         // Long press triggered showSelectionMenu() call.
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
                 /* canSelectAll = */ true,
                 /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
@@ -391,7 +391,7 @@
                 eq(AMPHITHEATRE), eq(5), any(SelectionClient.Result.class));
 
         // Dragging selection handle, select "1600 Amphitheatre".
-        mController.showSelectionMenu(0, 0, 0, 0, /* isEditable = */ true,
+        mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
                 /* isPasswordType = */ false, AMPHITHEATRE_FULL.substring(0, 17),
                 /* selectionOffset = */ 0,
                 /* canSelectAll = */ true,
diff --git a/content/public/browser/shared_worker_service.h b/content/public/browser/shared_worker_service.h
index 5ed1c72..0d09919 100644
--- a/content/public/browser/shared_worker_service.h
+++ b/content/public/browser/shared_worker_service.h
@@ -11,25 +11,17 @@
 
 namespace content {
 
-class ResourceContext;
-class StoragePartition;
-
-// A singleton for managing shared workers. These may be run in a separate
+// An interface for managing shared workers. These may be run in a separate
 // process, since multiple renderer processes can be talking to a single shared
-// worker. All the methods below can only be called on the UI thread. This
-// service does not manage service workers.
+// worker. All the methods below can only be called on the UI thread.
 class CONTENT_EXPORT SharedWorkerService {
  public:
-  static SharedWorkerService* GetInstance();
-
   // Terminates the given shared worker identified by its name, the URL of
   // its main script resource, and the constructor origin. Returns true on
   // success.
   virtual bool TerminateWorker(const GURL& url,
                                const std::string& name,
-                               const url::Origin& constructor_origin,
-                               StoragePartition* storage_partition,
-                               ResourceContext* resource_context) = 0;
+                               const url::Origin& constructor_origin) = 0;
 
  protected:
   virtual ~SharedWorkerService() = default;
diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h
index 61bea47..d481b30 100644
--- a/content/public/browser/storage_partition.h
+++ b/content/public/browser/storage_partition.h
@@ -53,6 +53,7 @@
 class IndexedDBContext;
 class PlatformNotificationContext;
 class ServiceWorkerContext;
+class SharedWorkerService;
 
 #if !defined(OS_ANDROID)
 class HostZoomLevelContext;
@@ -91,6 +92,7 @@
   virtual DOMStorageContext* GetDOMStorageContext() = 0;
   virtual IndexedDBContext* GetIndexedDBContext() = 0;
   virtual ServiceWorkerContext* GetServiceWorkerContext() = 0;
+  virtual SharedWorkerService* GetSharedWorkerService() = 0;
   virtual CacheStorageContext* GetCacheStorageContext() = 0;
 #if !defined(OS_ANDROID)
   virtual HostZoomMap* GetHostZoomMap() = 0;
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 1cc5948..847a1af6 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -310,6 +310,10 @@
 const base::Feature kServiceWorkerScriptFullCodeCache{
     "ServiceWorkerScriptFullCodeCache", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// http://tc39.github.io/ecmascript_sharedmem/shmem.html
+const base::Feature kSharedArrayBuffer{"SharedArrayBuffer",
+                                       base::FEATURE_ENABLED_BY_DEFAULT};
+
 // An experiment to require process isolation for the sign-in origin,
 // https://accounts.google.com.  Launch bug: https://crbug.com/739418.
 const base::Feature kSignInProcessIsolation{"sign-in-process-isolation",
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 91d19b0..1efcd0c 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -82,6 +82,7 @@
 CONTENT_EXPORT extern const base::Feature kServiceWorkerPaymentApps;
 CONTENT_EXPORT extern const base::Feature kServiceWorkerScriptStreaming;
 CONTENT_EXPORT extern const base::Feature kServiceWorkerScriptFullCodeCache;
+CONTENT_EXPORT extern const base::Feature kSharedArrayBuffer;
 CONTENT_EXPORT extern const base::Feature kSignInProcessIsolation;
 CONTENT_EXPORT extern const base::Feature kSitePerProcess;
 CONTENT_EXPORT extern const base::Feature kSlimmingPaintInvalidation;
diff --git a/content/public/common/storage_quota_params.h b/content/public/common/storage_quota_params.h
index 6e45a13..fd1ae65 100644
--- a/content/public/common/storage_quota_params.h
+++ b/content/public/common/storage_quota_params.h
@@ -9,7 +9,7 @@
 
 #include "content/common/content_export.h"
 #include "ipc/ipc_message.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 namespace content {
@@ -19,13 +19,13 @@
 struct CONTENT_EXPORT StorageQuotaParams {
   StorageQuotaParams()
       : render_frame_id(MSG_ROUTING_NONE),
-        storage_type(blink::StorageType::kTemporary),
+        storage_type(blink::mojom::StorageType::kTemporary),
         requested_size(0) {}
 
   int render_frame_id;
   // TODO(sashab): Change this to url::Origin, crbug.com/598424.
   GURL origin_url;
-  blink::StorageType storage_type;
+  blink::mojom::StorageType storage_type;
   uint64_t requested_size;
 };
 
diff --git a/content/public/test/layouttest_support.h b/content/public/test/layouttest_support.h
index 5fe4fdbb..fe538d8a 100644
--- a/content/public/test/layouttest_support.h
+++ b/content/public/test/layouttest_support.h
@@ -45,6 +45,7 @@
 class RenderFrame;
 class RendererGamepadProvider;
 class RenderView;
+class StoragePartition;
 struct Manifest;
 
 // Turn the browser process into layout test mode.
@@ -53,7 +54,8 @@
 // Terminates all workers and notifies when complete. This is used for
 // testing when it is important to make sure that all shared worker activity
 // has stopped.
-void TerminateAllSharedWorkersForTesting(base::OnceClosure callback);
+void TerminateAllSharedWorkersForTesting(StoragePartition* storage_partition,
+                                         base::OnceClosure callback);
 
 ///////////////////////////////////////////////////////////////////////////////
 // The following methods are meant to be used from a renderer.
diff --git a/content/public/test/simple_url_loader_test_helper.cc b/content/public/test/simple_url_loader_test_helper.cc
index 85f74f5f..5745901a 100644
--- a/content/public/test/simple_url_loader_test_helper.cc
+++ b/content/public/test/simple_url_loader_test_helper.cc
@@ -29,11 +29,24 @@
   run_loop_.Run();
 }
 
+void SimpleURLLoaderTestHelper::SetRunLoopQuitThread(
+    BrowserThread::ID thread_id) {
+  run_loop_quit_thread_ = thread_id;
+}
+
 void SimpleURLLoaderTestHelper::OnCompleteCallback(
     std::unique_ptr<std::string> response_body) {
   DCHECK(!response_body_);
 
   response_body_ = std::move(response_body);
+
+  if (run_loop_quit_thread_ &&
+      !BrowserThread::CurrentlyOn(*run_loop_quit_thread_)) {
+    BrowserThread::PostTask(*run_loop_quit_thread_, FROM_HERE,
+                            run_loop_.QuitClosure());
+    return;
+  }
+
   run_loop_.Quit();
 }
 
diff --git a/content/public/test/simple_url_loader_test_helper.h b/content/public/test/simple_url_loader_test_helper.h
index b3cec95d..97f71a1 100644
--- a/content/public/test/simple_url_loader_test_helper.h
+++ b/content/public/test/simple_url_loader_test_helper.h
@@ -11,7 +11,9 @@
 #include "base/callback_forward.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "base/optional.h"
 #include "base/run_loop.h"
+#include "content/public/browser/browser_thread.h"
 #include "content/public/common/simple_url_loader.h"
 
 namespace content {
@@ -30,6 +32,9 @@
   // Waits until the callback returned by GetCallback() is invoked.
   void WaitForCallback();
 
+  // Specify the thread to quit the runloop.
+  void SetRunLoopQuitThread(BrowserThread::ID);
+
   // Response body passed to the callback returned by GetCallback, if there was
   // one.
   const std::string* response_body() const { return response_body_.get(); }
@@ -46,6 +51,10 @@
 
   base::RunLoop run_loop_;
 
+  // When set, will post |run_loop_.Quit()| to |run_loop_quit_thread_| if it's
+  // not current thread.
+  base::Optional<BrowserThread::ID> run_loop_quit_thread_;
+
   std::unique_ptr<std::string> response_body_;
 
   base::WeakPtrFactory<SimpleURLLoaderTestHelper> weak_ptr_factory_;
diff --git a/content/public/test/test_storage_partition.cc b/content/public/test/test_storage_partition.cc
index 9ec3908..8f9c98b 100644
--- a/content/public/test/test_storage_partition.cc
+++ b/content/public/test/test_storage_partition.cc
@@ -64,6 +64,10 @@
   return service_worker_context_;
 }
 
+SharedWorkerService* TestStoragePartition::GetSharedWorkerService() {
+  return shared_worker_service_;
+}
+
 CacheStorageContext* TestStoragePartition::GetCacheStorageContext() {
   return cache_storage_context_;
 }
diff --git a/content/public/test/test_storage_partition.h b/content/public/test/test_storage_partition.h
index 32c66aaa..e9a3e5c9 100644
--- a/content/public/test/test_storage_partition.h
+++ b/content/public/test/test_storage_partition.h
@@ -105,6 +105,11 @@
   }
   ServiceWorkerContext* GetServiceWorkerContext() override;
 
+  void set_shared_worker_service(SharedWorkerService* service) {
+    shared_worker_service_ = service;
+  }
+  SharedWorkerService* GetSharedWorkerService() override;
+
   void set_cache_storage_context(CacheStorageContext* context) {
     cache_storage_context_ = context;
   }
@@ -175,6 +180,7 @@
   DOMStorageContext* dom_storage_context_ = nullptr;
   IndexedDBContext* indexed_db_context_ = nullptr;
   ServiceWorkerContext* service_worker_context_ = nullptr;
+  SharedWorkerService* shared_worker_service_ = nullptr;
   CacheStorageContext* cache_storage_context_ = nullptr;
   PlatformNotificationContext* platform_notification_context_ = nullptr;
 #if !defined(OS_ANDROID)
diff --git a/content/public/test/url_loader_interceptor.cc b/content/public/test/url_loader_interceptor.cc
index c7260b4..b0c833a8 100644
--- a/content/public/test/url_loader_interceptor.cc
+++ b/content/public/test/url_loader_interceptor.cc
@@ -50,10 +50,24 @@
     params.client = std::move(client);
     params.traffic_annotation = traffic_annotation;
     // We don't intercept the blob URL for plznavigate requests.
-    if (url_request.resource_body_stream_url.is_empty() &&
+    if (params.url_request.resource_body_stream_url.is_empty() &&
         parent_->callback_.Run(&params))
       return;
 
+    // mock.failed.request is a special request whereby the query indicates what
+    // error code to respond with.
+    if (params.url_request.url.DomainIs("mock.failed.request")) {
+      std::string query = params.url_request.url.query();
+      std::string error_code = query.substr(query.find("=") + 1);
+
+      int error = 0;
+      base::StringToInt(error_code, &error);
+      network::URLLoaderCompletionStatus status;
+      status.error_code = error;
+      params.client->OnComplete(status);
+      return;
+    }
+
     original_factory_getter_.Run()->CreateLoaderAndStart(
         std::move(params.request), params.routing_id, params.request_id,
         params.options, std::move(params.url_request), std::move(params.client),
@@ -144,7 +158,7 @@
   DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) ||
          BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  if (intercept_subresources &&
+  if (intercept_subresources_ &&
       base::FeatureList::IsEnabled(features::kNetworkService)) {
     RenderFrameHostImpl::SetNetworkFactoryForTesting(base::BindRepeating(
         &URLLoaderInterceptor::CreateURLLoaderFactoryForSubresources,
diff --git a/content/public/test/url_loader_interceptor.h b/content/public/test/url_loader_interceptor.h
index d282812..5936500 100644
--- a/content/public/test/url_loader_interceptor.h
+++ b/content/public/test/url_loader_interceptor.h
@@ -22,6 +22,9 @@
 //     -at ResourceMessageFilter for non network-service code path
 //     -by sending renderer an intermediate URLLoaderFactory for network-service
 //      codepath, as that normally routes directly to the network process
+//     -http(s)://mock.failed.request/foo URLs internally, copying the behavior
+//      of net::URLRequestFailedJob
+//
 // Notes:
 //  -intercepting frame requests doesn't work yet for non network-service case
 //   (will work once http://crbug.com/747130 is fixed)
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index a18f955e..c91654d1 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -935,6 +935,7 @@
       "//third_party/webrtc/modules/audio_processing",
       "//third_party/webrtc/modules/audio_processing:audio_processing_statistics",
       "//third_party/webrtc/modules/audio_processing/aec_dump",
+      "//third_party/webrtc/modules/video_coding",
       "//third_party/webrtc/modules/video_coding:webrtc_h264",
       "//third_party/webrtc/p2p:libstunprober",
       "//third_party/webrtc/p2p:rtc_p2p",
diff --git a/content/renderer/browser_plugin/OWNERS b/content/renderer/browser_plugin/OWNERS
index bd373b0..74d34105 100644
--- a/content/renderer/browser_plugin/OWNERS
+++ b/content/renderer/browser_plugin/OWNERS
@@ -1,7 +1,3 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-lfg@chromium.org
-wjmaclean@chromium.org
-ekaramad@chromium.org
+file://components/guest_view/OWNERS
 
 # COMPONENT: Platform>Apps>BrowserTag
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc
index 87c676f..07dd309 100644
--- a/content/renderer/gpu/gpu_benchmarking_extension.cc
+++ b/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -559,11 +559,6 @@
       .SetMethod("visualViewportY", &GpuBenchmarking::VisualViewportY)
       .SetMethod("visualViewportHeight", &GpuBenchmarking::VisualViewportHeight)
       .SetMethod("visualViewportWidth", &GpuBenchmarking::VisualViewportWidth)
-      // TODO(bokan): Temporary bit on gpuBenchmarking to let telemetry know
-      // when changes to gesture methods have landed in Chrome and it can start
-      // passing visual viewport coordinates. Will be removed once all changes
-      // are rolled. crbug.com/610021.
-      .SetValue("gesturesExpectedInViewportCoordinates", 1)
       .SetMethod("clearImageCache", &GpuBenchmarking::ClearImageCache)
       .SetMethod("runMicroBenchmark", &GpuBenchmarking::RunMicroBenchmark)
       .SetMethod("sendMessageToMicroBenchmark",
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index f87408c..d211c01c 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -327,7 +327,7 @@
     // shared memory allocations which need to make synchronous calls to the
     // IO thread.
     params.image_worker_task_runner = base::CreateSequencedTaskRunnerWithTraits(
-        {base::WithBaseSyncPrimitives(), base::TaskPriority::BACKGROUND,
+        {base::WithBaseSyncPrimitives(), base::TaskPriority::USER_VISIBLE,
          base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN});
   }
   if (!is_threaded) {
diff --git a/content/renderer/input/input_handler_wrapper.cc b/content/renderer/input/input_handler_wrapper.cc
index a00a763..4e5ed8bf 100644
--- a/content/renderer/input/input_handler_wrapper.cc
+++ b/content/renderer/input/input_handler_wrapper.cc
@@ -24,10 +24,12 @@
     bool enable_smooth_scrolling)
     : input_handler_manager_(input_handler_manager),
       routing_id_(routing_id),
-      input_handler_proxy_(input_handler.get(),
-                           this,
-                           base::FeatureList::IsEnabled(
-                               features::kTouchpadAndWheelScrollLatching)),
+      input_handler_proxy_(
+          input_handler.get(),
+          this,
+          base::FeatureList::IsEnabled(
+              features::kTouchpadAndWheelScrollLatching),
+          base::FeatureList::IsEnabled(features::kAsyncWheelEvents)),
       main_task_runner_(main_task_runner),
       render_widget_(render_widget) {
   DCHECK(input_handler);
diff --git a/content/renderer/input/widget_input_handler_manager.cc b/content/renderer/input/widget_input_handler_manager.cc
index ed5570f..423b403 100644
--- a/content/renderer/input/widget_input_handler_manager.cc
+++ b/content/renderer/input/widget_input_handler_manager.cc
@@ -275,7 +275,8 @@
     bool smooth_scroll_enabled) {
   input_handler_proxy_ = std::make_unique<ui::InputHandlerProxy>(
       input_handler.get(), this,
-      base::FeatureList::IsEnabled(features::kTouchpadAndWheelScrollLatching));
+      base::FeatureList::IsEnabled(features::kTouchpadAndWheelScrollLatching),
+      base::FeatureList::IsEnabled(features::kAsyncWheelEvents));
   input_handler_proxy_->set_smooth_scroll_enabled(smooth_scroll_enabled);
 }
 
diff --git a/content/renderer/pepper/event_conversion.cc b/content/renderer/pepper/event_conversion.cc
index 0e344f6..121f700e 100644
--- a/content/renderer/pepper/event_conversion.cc
+++ b/content/renderer/pepper/event_conversion.cc
@@ -28,6 +28,10 @@
 #include "third_party/WebKit/public/platform/WebTouchEvent.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
 
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
 using ppapi::InputEventData;
 using ppapi::TouchPointWithTilt;
 using blink::WebInputEvent;
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index eb49555..f387de9 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -143,6 +143,11 @@
 #include "ui/events/keycodes/keyboard_codes_posix.h"
 #endif
 
+// Windows defines 'PostMessage', so we have to undef it.
+#ifdef PostMessage
+#undef PostMessage
+#endif
+
 using base::StringPrintf;
 using ppapi::InputEventData;
 using ppapi::PpapiGlobals;
diff --git a/content/renderer/quota_dispatcher.cc b/content/renderer/quota_dispatcher.cc
index d3e17fc..46de0938 100644
--- a/content/renderer/quota_dispatcher.cc
+++ b/content/renderer/quota_dispatcher.cc
@@ -14,12 +14,12 @@
 #include "content/public/common/service_names.mojom.h"
 #include "content/public/renderer/render_thread.h"
 #include "services/service_manager/public/cpp/connector.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h"
 #include "url/origin.h"
 
-using blink::QuotaStatusCode;
-using blink::StorageType;
+using blink::mojom::QuotaStatusCode;
+using blink::mojom::StorageType;
 using blink::WebStorageQuotaCallbacks;
 
 namespace content {
@@ -61,7 +61,7 @@
   base::IDMap<std::unique_ptr<WebStorageQuotaCallbacks>>::iterator iter(
       &pending_quota_callbacks_);
   while (!iter.IsAtEnd()) {
-    iter.GetCurrentValue()->DidFail(blink::QuotaStatusCode::kErrorAbort);
+    iter.GetCurrentValue()->DidFail(blink::mojom::QuotaStatusCode::kErrorAbort);
     iter.Advance();
   }
 
@@ -115,7 +115,7 @@
                                            QuotaStatusCode status,
                                            int64_t current_usage,
                                            int64_t granted_quota) {
-  if (status != blink::QuotaStatusCode::kOk) {
+  if (status != blink::mojom::QuotaStatusCode::kOk) {
     DidFail(request_id, status);
     return;
   }
@@ -131,7 +131,7 @@
                                                    QuotaStatusCode status,
                                                    int64_t current_usage,
                                                    int64_t current_quota) {
-  if (status != blink::QuotaStatusCode::kOk) {
+  if (status != blink::mojom::QuotaStatusCode::kOk) {
     DidFail(request_id, status);
     return;
   }
diff --git a/content/renderer/quota_dispatcher.h b/content/renderer/quota_dispatcher.h
index 107cff2b..c95b2fd 100644
--- a/content/renderer/quota_dispatcher.h
+++ b/content/renderer/quota_dispatcher.h
@@ -45,26 +45,26 @@
 
   void QueryStorageUsageAndQuota(
       const url::Origin& origin,
-      blink::StorageType type,
+      blink::mojom::StorageType type,
       std::unique_ptr<blink::WebStorageQuotaCallbacks> callback);
   void RequestStorageQuota(
       int render_frame_id,
       const url::Origin& origin,
-      blink::StorageType type,
+      blink::mojom::StorageType type,
       int64_t requested_size,
       std::unique_ptr<blink::WebStorageQuotaCallbacks> callback);
 
  private:
   // Message handlers.
   void DidQueryStorageUsageAndQuota(int64_t request_id,
-                                    blink::QuotaStatusCode status,
+                                    blink::mojom::QuotaStatusCode status,
                                     int64_t current_usage,
                                     int64_t current_quota);
   void DidGrantStorageQuota(int64_t request_id,
-                            blink::QuotaStatusCode status,
+                            blink::mojom::QuotaStatusCode status,
                             int64_t current_usage,
                             int64_t granted_quota);
-  void DidFail(int request_id, blink::QuotaStatusCode error);
+  void DidFail(int request_id, blink::mojom::QuotaStatusCode error);
 
   blink::mojom::QuotaDispatcherHostPtr quota_host_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 017b43df..5a56bc2a 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -168,7 +168,7 @@
 #include "third_party/WebKit/common/associated_interfaces/associated_interface_provider.h"
 #include "third_party/WebKit/common/frame_policy.h"
 #include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "third_party/WebKit/common/sandbox_flags.h"
 #include "third_party/WebKit/public/platform/FilePathConversion.h"
 #include "third_party/WebKit/public/platform/InterfaceProvider.h"
@@ -5110,13 +5110,13 @@
 }
 
 void RenderFrameImpl::RequestStorageQuota(
-    blink::StorageType type,
+    blink::mojom::StorageType type,
     unsigned long long requested_size,
     blink::WebStorageQuotaCallbacks callbacks) {
   WebSecurityOrigin origin = frame_->GetDocument().GetSecurityOrigin();
   if (origin.IsUnique()) {
     // Unique origins cannot store persistent state.
-    callbacks.DidFail(blink::QuotaStatusCode::kErrorAbort);
+    callbacks.DidFail(blink::mojom::QuotaStatusCode::kErrorAbort);
     return;
   }
   RenderThreadImpl::current()->quota_dispatcher()->RequestStorageQuota(
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index a050f0a..912ab4d8 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -692,7 +692,7 @@
   void ReportFindInPageSelection(int request_id,
                                  int active_match_ordinal,
                                  const blink::WebRect& sel) override;
-  void RequestStorageQuota(blink::StorageType type,
+  void RequestStorageQuota(blink::mojom::StorageType type,
                            unsigned long long requested_size,
                            blink::WebStorageQuotaCallbacks callbacks) override;
   blink::WebPushClient* PushClient() override;
diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc
index 963cda5..33cc50c 100644
--- a/content/renderer/render_process_impl.cc
+++ b/content/renderer/render_process_impl.cc
@@ -160,6 +160,10 @@
 
   SetV8FlagIfFeature(features::kV8VmFuture, "--future");
   SetV8FlagIfNotFeature(features::kV8VmFuture, "--no-future");
+  SetV8FlagIfFeature(features::kSharedArrayBuffer,
+                     "--harmony-sharedarraybuffer");
+  SetV8FlagIfNotFeature(features::kSharedArrayBuffer,
+                        "--no-harmony-sharedarraybuffer");
 
   SetV8FlagIfFeature(features::kWebAssemblyTrapHandler, "--wasm-trap-handler");
   SetV8FlagIfNotFeature(features::kWebAssemblyTrapHandler,
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 0e7d9b48..7b25a741 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -98,7 +98,7 @@
 #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
 #include "storage/common/database/database_identifier.h"
 #include "third_party/WebKit/common/origin_trials/trial_token_validator.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "third_party/WebKit/public/platform/BlameContext.h"
 #include "third_party/WebKit/public/platform/FilePathConversion.h"
 #include "third_party/WebKit/public/platform/URLConversion.h"
@@ -1368,7 +1368,7 @@
 
 void RendererBlinkPlatformImpl::QueryStorageUsageAndQuota(
     const blink::WebSecurityOrigin& storage_partition,
-    blink::StorageType type,
+    blink::mojom::StorageType type,
     blink::WebStorageQuotaCallbacks callbacks) {
   QuotaDispatcher::ThreadSpecificInstance(default_task_runner_)
       ->QueryStorageUsageAndQuota(
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index 47d14ec..9719faf 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -209,7 +209,7 @@
   void StopListening(blink::WebPlatformEventType) override;
   void QueryStorageUsageAndQuota(
       const blink::WebSecurityOrigin& storage_partition,
-      blink::StorageType,
+      blink::mojom::StorageType,
       blink::WebStorageQuotaCallbacks) override;
   blink::WebThread* CurrentThread() override;
   blink::BlameContext* GetTopLevelBlameContext() override;
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc
index 8bbd09a5..26a09583 100644
--- a/content/shell/browser/layout_test/blink_test_controller.cc
+++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -790,7 +790,11 @@
 }
 
 void BlinkTestController::OnAllServiceWorkersCleared() {
+  // TODO(nhiroki): Add a comment about the reason why we terminate all shared
+  // workers here.
   TerminateAllSharedWorkersForTesting(
+      BrowserContext::GetStoragePartition(
+          ShellContentBrowserClient::Get()->browser_context(), nullptr),
       base::BindOnce(&BlinkTestController::OnAllSharedWorkersDestroyed,
                      weak_factory_.GetWeakPtr()));
 }
diff --git a/content/shell/browser/layout_test/layout_test_message_filter.cc b/content/shell/browser/layout_test/layout_test_message_filter.cc
index 9961608..1fb0c72 100644
--- a/content/shell/browser/layout_test/layout_test_message_filter.cc
+++ b/content/shell/browser/layout_test/layout_test_message_filter.cc
@@ -187,6 +187,10 @@
     type = PermissionType::BACKGROUND_SYNC;
   } else if (name == "accessibility-events") {
     type = PermissionType::ACCESSIBILITY_EVENTS;
+  } else if (name == "clipboard-read") {
+    type = PermissionType::CLIPBOARD_READ;
+  } else if (name == "clipboard-write") {
+    type = PermissionType::CLIPBOARD_WRITE;
   } else {
     NOTREACHED();
     type = PermissionType::NOTIFICATIONS;
diff --git a/content/shell/browser/shell_quota_permission_context.cc b/content/shell/browser/shell_quota_permission_context.cc
index 3674d3e..fffd2fc7 100644
--- a/content/shell/browser/shell_quota_permission_context.cc
+++ b/content/shell/browser/shell_quota_permission_context.cc
@@ -4,7 +4,7 @@
 
 #include "content/shell/browser/shell_quota_permission_context.h"
 
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace content {
 
@@ -14,7 +14,7 @@
     const StorageQuotaParams& params,
     int render_process_id,
     const PermissionCallback& callback) {
-  if (params.storage_type != blink::StorageType::kPersistent) {
+  if (params.storage_type != blink::mojom::StorageType::kPersistent) {
     // For now we only support requesting quota with this interface
     // for Persistent storage type.
     callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 1733b98..e61a7e5b 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1186,6 +1186,7 @@
     "../browser/background_fetch/background_fetch_event_dispatcher_unittest.cc",
     "../browser/background_fetch/background_fetch_job_controller_unittest.cc",
     "../browser/background_fetch/background_fetch_registration_notifier_unittest.cc",
+    "../browser/background_fetch/background_fetch_scheduler_unittest.cc",
     "../browser/background_fetch/background_fetch_service_unittest.cc",
     "../browser/background_sync/background_sync_manager_unittest.cc",
     "../browser/background_sync/background_sync_network_observer_unittest.cc",
@@ -1335,6 +1336,7 @@
     "../browser/memory/swap_metrics_driver_impl_unittest.cc",
     "../browser/memory/test_memory_monitor.cc",
     "../browser/memory/test_memory_monitor.h",
+    "../browser/net/network_quality_observer_impl_unittest.cc",
     "../browser/net/quota_policy_cookie_store_unittest.cc",
     "../browser/notification_service_impl_unittest.cc",
     "../browser/notifications/notification_database_data_unittest.cc",
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py
index 2d11531..e39961a 100755
--- a/content/test/gpu/generate_buildbot_json.py
+++ b/content/test/gpu/generate_buildbot_json.py
@@ -2731,7 +2731,7 @@
       'isolated_scripts': sorted(isolated_scripts, key=lambda x: x['name'])
     }
   tests['AAAAA1 AUTOGENERATED FILE DO NOT EDIT'] = {}
-  tests['AAAAA2 See generate_buildbot_json.py to make changes'] = {}
+  tests['AAAAA2 See gpu/generate_buildbot_json.py to make changes'] = {}
   with open(os.path.join(SRC_DIR, 'testing', 'buildbot', filename), 'wb') as fp:
     json.dump(tests, fp, indent=2, separators=(',', ': '), sort_keys=True)
     fp.write('\n')
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index 48c800a97..87820f3 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -225,11 +225,6 @@
     self.Flaky('deqp/functional/gles3/textureformat/unsized_3d.html',
         ['win', 'intel', 'd3d11'], bug=614418)
 
-    # These tests seem to crash flakily. It's best to leave them as skip
-    # until we can run them without GPU hangs and crashes.
-    self.Skip('deqp/functional/gles3/textureshadow/2d_array_*.html',
-        ['win', 'intel', 'd3d11'], bug=666392)
-
     # It's unfortunate that these suppressions need to be so broad, but it
     # looks like the D3D11 device can be lost spontaneously on this
     # configuration while running basically any test.
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc
index ae2a8ae7..4f00036 100644
--- a/content/test/layouttest_support.cc
+++ b/content/test/layouttest_support.cc
@@ -27,6 +27,7 @@
 #include "content/common/gpu_stream_constants.h"
 #include "content/common/renderer.mojom.h"
 #include "content/common/unique_name_helper.h"
+#include "content/public/browser/storage_partition.h"
 #include "content/public/common/page_state.h"
 #include "content/public/common/screen_info.h"
 #include "content/public/renderer/renderer_gamepad_provider.h"
@@ -439,8 +440,10 @@
   RenderWidgetHostImpl::DisableResizeAckCheckForTesting();
 }
 
-void TerminateAllSharedWorkersForTesting(base::OnceClosure callback) {
-  static_cast<SharedWorkerServiceImpl*>(SharedWorkerService::GetInstance())
+void TerminateAllSharedWorkersForTesting(StoragePartition* storage_partition,
+                                         base::OnceClosure callback) {
+  static_cast<SharedWorkerServiceImpl*>(
+      storage_partition->GetSharedWorkerService())
       ->TerminateAllWorkersForTesting(std::move(callback));
 }
 
diff --git a/courgette/memory_allocator.cc b/courgette/memory_allocator.cc
index e83a293..7eda998 100644
--- a/courgette/memory_allocator.cc
+++ b/courgette/memory_allocator.cc
@@ -14,6 +14,8 @@
 
 #if defined(OS_WIN)
 
+#include <windows.h>
+
 namespace {
 
 // The file is created in the %TEMP% folder.
diff --git a/device/serial/serial_device_enumerator_win.cc b/device/serial/serial_device_enumerator_win.cc
index 5c12541..130d657 100644
--- a/device/serial/serial_device_enumerator_win.cc
+++ b/device/serial/serial_device_enumerator_win.cc
@@ -4,10 +4,11 @@
 
 #include "device/serial/serial_device_enumerator_win.h"
 
+#include <windows.h>  // Must be in front of other Windows header files.
+
 #include <devguid.h>
 #include <setupapi.h>
 #include <stdint.h>
-#include <windows.h>
 
 #include <memory>
 #include <unordered_set>
diff --git a/device/usb/usb_device_handle_win.cc b/device/usb/usb_device_handle_win.cc
index a5babcd..1084d49a 100644
--- a/device/usb/usb_device_handle_win.cc
+++ b/device/usb/usb_device_handle_win.cc
@@ -4,6 +4,8 @@
 
 #include "device/usb/usb_device_handle_win.h"
 
+#include <windows.h>  // Must be in front of other Windows header files.
+
 #include <usbioctl.h>
 #include <usbspec.h>
 #include <winioctl.h>
diff --git a/device/usb/usb_device_win.cc b/device/usb/usb_device_win.cc
index 0d86f9c..f8e4aef 100644
--- a/device/usb/usb_device_win.cc
+++ b/device/usb/usb_device_win.cc
@@ -14,6 +14,8 @@
 #include "device/usb/usb_device_handle_win.h"
 #include "device/usb/webusb_descriptors.h"
 
+#include <windows.h>
+
 namespace device {
 
 namespace {
diff --git a/extensions/browser/api/feedback_private/feedback_private_api.cc b/extensions/browser/api/feedback_private/feedback_private_api.cc
index b04ebe3..e174700 100644
--- a/extensions/browser/api/feedback_private/feedback_private_api.cc
+++ b/extensions/browser/api/feedback_private/feedback_private_api.cc
@@ -97,6 +97,7 @@
 
 void FeedbackPrivateAPI::RequestFeedbackForFlow(
     const std::string& description_template,
+    const std::string& description_placeholder_text,
     const std::string& category_tag,
     const std::string& extra_diagnostics,
     const GURL& page_url,
@@ -104,6 +105,8 @@
   if (browser_context_ && EventRouter::Get(browser_context_)) {
     FeedbackInfo info;
     info.description = description_template;
+    info.description_placeholder =
+        std::make_unique<std::string>(description_placeholder_text);
     info.category_tag = std::make_unique<std::string>(category_tag);
     info.page_url = std::make_unique<std::string>(page_url.spec());
     info.system_information = std::make_unique<SystemInformationList>();
diff --git a/extensions/browser/api/feedback_private/feedback_private_api.h b/extensions/browser/api/feedback_private/feedback_private_api.h
index 9fdee6d..10be1a5 100644
--- a/extensions/browser/api/feedback_private/feedback_private_api.h
+++ b/extensions/browser/api/feedback_private/feedback_private_api.h
@@ -32,6 +32,7 @@
 #endif  // defined(OS_CHROMEOS)
 
   void RequestFeedbackForFlow(const std::string& description_template,
+                              const std::string& description_placeholder_text,
                               const std::string& category_tag,
                               const std::string& extra_diagnostics,
                               const GURL& page_url,
diff --git a/extensions/browser/api/guest_view/OWNERS b/extensions/browser/api/guest_view/OWNERS
index 24f9be71..74d34105 100644
--- a/extensions/browser/api/guest_view/OWNERS
+++ b/extensions/browser/api/guest_view/OWNERS
@@ -1,8 +1,3 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-hanxi@chromium.org
-wjmaclean@chromium.org
-lfg@chromium.org
-ekaramad@chromium.org
+file://components/guest_view/OWNERS
 
 # COMPONENT: Platform>Apps>BrowserTag
diff --git a/extensions/browser/guest_view/OWNERS b/extensions/browser/guest_view/OWNERS
index 8781c1c1..74d34105 100644
--- a/extensions/browser/guest_view/OWNERS
+++ b/extensions/browser/guest_view/OWNERS
@@ -1,9 +1,3 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-lfg@chromium.org
-hanxi@chromium.org
-paulmeyer@chromium.org
-wjmaclean@chromium.org
-ekaramad@chromium.org
+file://components/guest_view/OWNERS
 
 # COMPONENT: Platform>Apps>BrowserTag
diff --git a/extensions/browser/updater/BUILD.gn b/extensions/browser/updater/BUILD.gn
index 6bf5e31f..ccd6359c 100644
--- a/extensions/browser/updater/BUILD.gn
+++ b/extensions/browser/updater/BUILD.gn
@@ -17,6 +17,8 @@
     "extension_downloader_test_delegate.h",
     "extension_installer.cc",
     "extension_installer.h",
+    "extension_update_data.cc",
+    "extension_update_data.h",
     "manifest_fetch_data.cc",
     "manifest_fetch_data.h",
     "null_extension_cache.cc",
diff --git a/extensions/browser/updater/extension_update_data.cc b/extensions/browser/updater/extension_update_data.cc
new file mode 100644
index 0000000..9adac420
--- /dev/null
+++ b/extensions/browser/updater/extension_update_data.cc
@@ -0,0 +1,24 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/updater/extension_update_data.h"
+
+namespace extensions {
+
+ExtensionUpdateData::ExtensionUpdateData() : is_corrupt_reinstall(false) {}
+
+ExtensionUpdateData::ExtensionUpdateData(const ExtensionUpdateData& other) =
+    default;
+
+ExtensionUpdateData::~ExtensionUpdateData() {}
+
+ExtensionUpdateCheckParams::ExtensionUpdateCheckParams()
+    : priority(BACKGROUND) {}
+
+ExtensionUpdateCheckParams::ExtensionUpdateCheckParams(
+    const ExtensionUpdateCheckParams& other) = default;
+
+ExtensionUpdateCheckParams::~ExtensionUpdateCheckParams() {}
+
+}  // namespace extensions
diff --git a/extensions/browser/updater/extension_update_data.h b/extensions/browser/updater/extension_update_data.h
new file mode 100644
index 0000000..3223b93f
--- /dev/null
+++ b/extensions/browser/updater/extension_update_data.h
@@ -0,0 +1,46 @@
+// Copyright (c) 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTENSIONS_BROWSER_UPDATER_EXTENSION_UPDATE_DATA_H_
+#define EXTENSIONS_BROWSER_UPDATER_EXTENSION_UPDATE_DATA_H_
+
+#include <map>
+#include <string>
+
+namespace extensions {
+
+struct ExtensionUpdateData;
+struct ExtensionUpdateCheckParams;
+
+using ExtensionUpdateDataMap = std::map<std::string, ExtensionUpdateData>;
+
+// This struct contains update information for a specific extension.
+struct ExtensionUpdateData {
+  ExtensionUpdateData();
+  ExtensionUpdateData(const ExtensionUpdateData& other);
+  ~ExtensionUpdateData();
+
+  std::string install_source;
+  bool is_corrupt_reinstall;
+};
+
+// The basic structure for an extension update check request, which
+// can contain a collection of extensions.
+struct ExtensionUpdateCheckParams {
+  enum UpdateCheckPriority {
+    BACKGROUND,
+    FOREGROUND,
+  };
+
+  ExtensionUpdateCheckParams();
+  ExtensionUpdateCheckParams(const ExtensionUpdateCheckParams& other);
+  ~ExtensionUpdateCheckParams();
+
+  ExtensionUpdateDataMap update_info;
+  UpdateCheckPriority priority;
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_BROWSER_UPDATER_EXTENSION_UPDATE_DATA_H_
diff --git a/extensions/browser/updater/update_data_provider.cc b/extensions/browser/updater/update_data_provider.cc
index d930ab57..ebde2f61 100644
--- a/extensions/browser/updater/update_data_provider.cc
+++ b/extensions/browser/updater/update_data_provider.cc
@@ -22,27 +22,31 @@
 
 namespace extensions {
 
-UpdateDataProvider::UpdateDataProvider(content::BrowserContext* context,
+UpdateDataProvider::UpdateDataProvider(content::BrowserContext* browser_context,
                                        InstallCallback install_callback)
-    : context_(context), install_callback_(std::move(install_callback)) {}
+    : browser_context_(browser_context),
+      install_callback_(std::move(install_callback)) {}
 
 UpdateDataProvider::~UpdateDataProvider() {}
 
 void UpdateDataProvider::Shutdown() {
-  context_ = nullptr;
+  browser_context_ = nullptr;
 }
 
 void UpdateDataProvider::GetData(
+    const ExtensionUpdateDataMap& update_info,
     const std::vector<std::string>& ids,
     std::vector<update_client::CrxComponent>* data) {
-  if (!context_)
+  if (!browser_context_)
     return;
-  const ExtensionRegistry* registry = ExtensionRegistry::Get(context_);
-  const ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(context_);
+  const ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
+  const ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(browser_context_);
   for (const auto& id : ids) {
     const Extension* extension = registry->GetInstalledExtension(id);
     if (!extension)
       continue;
+    DCHECK_GT(update_info.count(id), 0ULL);
+    const ExtensionUpdateData& extension_data = update_info.at(id);
     data->push_back(update_client::CrxComponent());
     update_client::CrxComponent* info = &data->back();
     std::string pubkey_bytes;
@@ -50,13 +54,16 @@
     info->pk_hash.resize(crypto::kSHA256Length, 0);
     crypto::SHA256HashString(pubkey_bytes, info->pk_hash.data(),
                              info->pk_hash.size());
-    info->version = extension->version();
+    info->version = extension_data.is_corrupt_reinstall
+                        ? base::Version("0.0.0.0")
+                        : extension->version();
     info->allows_background_download = false;
     info->requires_network_encryption = true;
     info->installer = base::MakeRefCounted<ExtensionInstaller>(
         id, extension->path(),
         base::BindOnce(&UpdateDataProvider::RunInstallCallback, this));
-    if (!ExtensionsBrowserClient::Get()->IsExtensionEnabled(id, context_)) {
+    if (!ExtensionsBrowserClient::Get()->IsExtensionEnabled(id,
+                                                            browser_context_)) {
       int disabled_reasons = extension_prefs->GetDisableReasons(id);
       if (disabled_reasons == extensions::disable_reason::DISABLE_NONE ||
           disabled_reasons >= extensions::disable_reason::DISABLE_REASON_LAST) {
@@ -69,6 +76,7 @@
           info->disabled_reasons.push_back(enum_value);
       }
     }
+    info->install_source = extension_data.install_source;
   }
 }
 
@@ -77,7 +85,7 @@
     const std::string& public_key,
     const base::FilePath& unpacked_dir,
     UpdateClientCallback update_client_callback) {
-  if (!context_) {
+  if (!browser_context_) {
     base::PostTaskWithTraits(
         FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()},
         base::BindOnce(base::IgnoreResult(&base::DeleteFile), unpacked_dir,
@@ -88,7 +96,7 @@
   DCHECK(!install_callback_.is_null());
   content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI)
       ->PostTask(FROM_HERE,
-                 base::BindOnce(std::move(install_callback_), context_,
+                 base::BindOnce(std::move(install_callback_), browser_context_,
                                 extension_id, public_key, unpacked_dir,
                                 std::move(update_client_callback)));
 }
diff --git a/extensions/browser/updater/update_data_provider.h b/extensions/browser/updater/update_data_provider.h
index 85954edb..c45f322e 100644
--- a/extensions/browser/updater/update_data_provider.h
+++ b/extensions/browser/updater/update_data_provider.h
@@ -5,6 +5,7 @@
 #ifndef EXTENSIONS_BROWSER_UPDATER_UPDATE_DATA_PROVIDER_H_
 #define EXTENSIONS_BROWSER_UPDATER_UPDATE_DATA_PROVIDER_H_
 
+#include <map>
 #include <string>
 #include <vector>
 
@@ -12,6 +13,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "extensions/browser/updater/extension_installer.h"
+#include "extensions/browser/updater/extension_update_data.h"
 
 namespace base {
 class FilePath;
@@ -43,7 +45,7 @@
   // extension ids, as well as an install callback for proceeding with
   // installation steps once the UpdateClient has downloaded and unpacked
   // an update for an extension.
-  UpdateDataProvider(content::BrowserContext* context,
+  UpdateDataProvider(content::BrowserContext* browser_context,
                      InstallCallback install_callback);
 
   // Notify this object that the associated browser context is being shut down
@@ -52,7 +54,8 @@
   void Shutdown();
 
   // Matches update_client::UpdateClient::CrxDataCallback
-  void GetData(const std::vector<std::string>& ids,
+  void GetData(const ExtensionUpdateDataMap& update_info,
+               const std::vector<std::string>& ids,
                std::vector<update_client::CrxComponent>* data);
 
  private:
@@ -65,7 +68,7 @@
                           const base::FilePath& unpacked_dir,
                           UpdateClientCallback update_client_callback);
 
-  content::BrowserContext* context_;
+  content::BrowserContext* browser_context_;
   InstallCallback install_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(UpdateDataProvider);
diff --git a/extensions/browser/updater/update_data_provider_unittest.cc b/extensions/browser/updater/update_data_provider_unittest.cc
index 821d9bf..3e5e9be 100644
--- a/extensions/browser/updater/update_data_provider_unittest.cc
+++ b/extensions/browser/updater/update_data_provider_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "extensions/browser/updater/update_data_provider.h"
 
+#include <map>
 #include <memory>
 #include <set>
 #include <string>
@@ -141,7 +142,7 @@
 
   std::vector<std::string> ids({kExtensionId1});
   std::vector<update_client::CrxComponent> data;
-  data_provider->GetData(ids, &data);
+  data_provider->GetData(ExtensionUpdateDataMap(), ids, &data);
   EXPECT_EQ(0UL, data.size());
 }
 
@@ -159,9 +160,12 @@
   AddExtension(kExtensionId1, version, true,
                disable_reason::DisableReason::DISABLE_NONE);
 
+  ExtensionUpdateDataMap update_data;
+  update_data[kExtensionId1] = {};
+
   std::vector<std::string> ids({kExtensionId1});
   std::vector<update_client::CrxComponent> data;
-  data_provider->GetData(ids, &data);
+  data_provider->GetData(update_data, ids, &data);
 
   ASSERT_EQ(1UL, data.size());
   EXPECT_EQ(version, data[0].version.GetString());
@@ -169,6 +173,36 @@
   EXPECT_EQ(0UL, data[0].disabled_reasons.size());
 }
 
+TEST_F(UpdateDataProviderTest, GetData_EnabledExtensionWithData) {
+  scoped_refptr<UpdateDataProvider> data_provider =
+      base::MakeRefCounted<UpdateDataProvider>(
+          browser_context(),
+          base::BindOnce([](content::BrowserContext* context,
+                            const std::string& extension_id,
+                            const std::string& public_key,
+                            const base::FilePath& temp_dir,
+                            UpdateClientCallback update_client_callback) {}));
+
+  const std::string version = "0.1.2.3";
+  AddExtension(kExtensionId1, version, true,
+               disable_reason::DisableReason::DISABLE_NONE);
+
+  ExtensionUpdateDataMap update_data;
+  auto& info = update_data[kExtensionId1];
+  info.is_corrupt_reinstall = true;
+  info.install_source = "webstore";
+
+  std::vector<std::string> ids({kExtensionId1});
+  std::vector<update_client::CrxComponent> data;
+  data_provider->GetData(update_data, ids, &data);
+
+  ASSERT_EQ(1UL, data.size());
+  EXPECT_EQ("0.0.0.0", data[0].version.GetString());
+  EXPECT_EQ("webstore", data[0].install_source);
+  EXPECT_NE(nullptr, data[0].installer.get());
+  EXPECT_EQ(0UL, data[0].disabled_reasons.size());
+}
+
 TEST_F(UpdateDataProviderTest, GetData_DisabledExtension_WithNoReason) {
   scoped_refptr<UpdateDataProvider> data_provider =
       base::MakeRefCounted<UpdateDataProvider>(
@@ -183,9 +217,12 @@
   AddExtension(kExtensionId1, version, false,
                disable_reason::DisableReason::DISABLE_NONE);
 
+  ExtensionUpdateDataMap update_data;
+  update_data[kExtensionId1] = {};
+
   std::vector<std::string> ids({kExtensionId1});
   std::vector<update_client::CrxComponent> data;
-  data_provider->GetData(ids, &data);
+  data_provider->GetData(update_data, ids, &data);
 
   ASSERT_EQ(1UL, data.size());
   EXPECT_EQ(version, data[0].version.GetString());
@@ -209,9 +246,12 @@
   AddExtension(kExtensionId1, version, false,
                disable_reason::DisableReason::DISABLE_REASON_LAST);
 
+  ExtensionUpdateDataMap update_data;
+  update_data[kExtensionId1] = {};
+
   std::vector<std::string> ids({kExtensionId1});
   std::vector<update_client::CrxComponent> data;
-  data_provider->GetData(ids, &data);
+  data_provider->GetData(update_data, ids, &data);
 
   ASSERT_EQ(1UL, data.size());
   EXPECT_EQ(version, data[0].version.GetString());
@@ -236,9 +276,12 @@
                disable_reason::DisableReason::DISABLE_USER_ACTION |
                    disable_reason::DisableReason::DISABLE_CORRUPTED);
 
+  ExtensionUpdateDataMap update_data;
+  update_data[kExtensionId1] = {};
+
   std::vector<std::string> ids({kExtensionId1});
   std::vector<update_client::CrxComponent> data;
-  data_provider->GetData(ids, &data);
+  data_provider->GetData(update_data, ids, &data);
 
   ASSERT_EQ(1UL, data.size());
   EXPECT_EQ(version, data[0].version.GetString());
@@ -267,9 +310,12 @@
                    disable_reason::DisableReason::DISABLE_CORRUPTED |
                    disable_reason::DisableReason::DISABLE_REASON_LAST);
 
+  ExtensionUpdateDataMap update_data;
+  update_data[kExtensionId1] = {};
+
   std::vector<std::string> ids({kExtensionId1});
   std::vector<update_client::CrxComponent> data;
-  data_provider->GetData(ids, &data);
+  data_provider->GetData(update_data, ids, &data);
 
   ASSERT_EQ(1UL, data.size());
   EXPECT_EQ(version, data[0].version.GetString());
@@ -283,7 +329,8 @@
             data[0].disabled_reasons[2]);
 }
 
-TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions1) {
+TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions) {
+  // GetData with more than 1 extension.
   scoped_refptr<UpdateDataProvider> data_provider =
       base::MakeRefCounted<UpdateDataProvider>(
           browser_context(),
@@ -300,9 +347,13 @@
   AddExtension(kExtensionId2, version2, true,
                disable_reason::DisableReason::DISABLE_NONE);
 
+  ExtensionUpdateDataMap update_data;
+  update_data[kExtensionId1] = {};
+  update_data[kExtensionId2] = {};
+
   std::vector<std::string> ids({kExtensionId1, kExtensionId2});
   std::vector<update_client::CrxComponent> data;
-  data_provider->GetData(ids, &data);
+  data_provider->GetData(update_data, ids, &data);
 
   ASSERT_EQ(2UL, data.size());
   EXPECT_EQ(version1, data[0].version.GetString());
@@ -313,7 +364,7 @@
   EXPECT_EQ(0UL, data[1].disabled_reasons.size());
 }
 
-TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions2) {
+TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions_DisabledExtension) {
   // One extension is disabled.
   scoped_refptr<UpdateDataProvider> data_provider =
       base::MakeRefCounted<UpdateDataProvider>(
@@ -331,9 +382,13 @@
   AddExtension(kExtensionId2, version2, true,
                disable_reason::DisableReason::DISABLE_NONE);
 
+  ExtensionUpdateDataMap update_data;
+  update_data[kExtensionId1] = {};
+  update_data[kExtensionId2] = {};
+
   std::vector<std::string> ids({kExtensionId1, kExtensionId2});
   std::vector<update_client::CrxComponent> data;
-  data_provider->GetData(ids, &data);
+  data_provider->GetData(update_data, ids, &data);
 
   ASSERT_EQ(2UL, data.size());
   EXPECT_EQ(version1, data[0].version.GetString());
@@ -347,7 +402,8 @@
   EXPECT_EQ(0UL, data[1].disabled_reasons.size());
 }
 
-TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions3) {
+TEST_F(UpdateDataProviderTest,
+       GetData_MultipleExtensions_NotInstalledExtension) {
   // One extension is not installed.
   scoped_refptr<UpdateDataProvider> data_provider =
       base::MakeRefCounted<UpdateDataProvider>(
@@ -362,9 +418,13 @@
   AddExtension(kExtensionId1, version, true,
                disable_reason::DisableReason::DISABLE_NONE);
 
+  ExtensionUpdateDataMap update_data;
+  update_data[kExtensionId1] = {};
+  update_data[kExtensionId2] = {};
+
   std::vector<std::string> ids({kExtensionId1, kExtensionId2});
   std::vector<update_client::CrxComponent> data;
-  data_provider->GetData(ids, &data);
+  data_provider->GetData(update_data, ids, &data);
 
   ASSERT_EQ(1UL, data.size());
   EXPECT_EQ(version, data[0].version.GetString());
@@ -372,6 +432,49 @@
   EXPECT_EQ(0UL, data[0].disabled_reasons.size());
 }
 
+TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions_CorruptExtension) {
+  // With non-default data, one extension is corrupted:
+  // is_corrupt_reinstall=true.
+  scoped_refptr<UpdateDataProvider> data_provider =
+      base::MakeRefCounted<UpdateDataProvider>(
+          browser_context(),
+          base::BindOnce([](content::BrowserContext* context,
+                            const std::string& extension_id,
+                            const std::string& public_key,
+                            const base::FilePath& temp_dir,
+                            UpdateClientCallback update_client_callback) {}));
+
+  const std::string version1 = "0.1.2.3";
+  const std::string version2 = "9.8.7.6";
+  const std::string initial_version = "0.0.0.0";
+  AddExtension(kExtensionId1, version1, true,
+               disable_reason::DisableReason::DISABLE_NONE);
+  AddExtension(kExtensionId2, version2, true,
+               disable_reason::DisableReason::DISABLE_NONE);
+
+  ExtensionUpdateDataMap update_data;
+  auto& info1 = update_data[kExtensionId1];
+  auto& info2 = update_data[kExtensionId2];
+
+  info1.install_source = "webstore";
+  info2.is_corrupt_reinstall = true;
+  info2.install_source = "sideload";
+
+  std::vector<std::string> ids({kExtensionId1, kExtensionId2});
+  std::vector<update_client::CrxComponent> data;
+  data_provider->GetData(update_data, ids, &data);
+
+  ASSERT_EQ(2UL, data.size());
+  EXPECT_EQ(version1, data[0].version.GetString());
+  EXPECT_EQ("webstore", data[0].install_source);
+  EXPECT_NE(nullptr, data[0].installer.get());
+  EXPECT_EQ(0UL, data[0].disabled_reasons.size());
+  EXPECT_EQ(initial_version, data[1].version.GetString());
+  EXPECT_EQ("sideload", data[1].install_source);
+  EXPECT_NE(nullptr, data[1].installer.get());
+  EXPECT_EQ(0UL, data[1].disabled_reasons.size());
+}
+
 }  // namespace
 
 }  // namespace extensions
diff --git a/extensions/browser/updater/update_service.cc b/extensions/browser/updater/update_service.cc
index 8649042..28bcc61b0 100644
--- a/extensions/browser/updater/update_service.cc
+++ b/extensions/browser/updater/update_service.cc
@@ -4,24 +4,28 @@
 
 #include "extensions/browser/updater/update_service.h"
 
+#include <map>
+
 #include "base/bind.h"
 #include "base/files/file_util.h"
 #include "components/update_client/update_client.h"
 #include "components/update_client/update_client_errors.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
+#include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/extensions_browser_client.h"
+#include "extensions/browser/updater/extension_update_data.h"
 #include "extensions/browser/updater/update_data_provider.h"
 #include "extensions/browser/updater/update_service_factory.h"
+#include "extensions/common/extension_urls.h"
+#include "extensions/common/manifest_url_handlers.h"
 
 namespace {
 
 using UpdateClientCallback =
     extensions::UpdateDataProvider::UpdateClientCallback;
 
-void UpdateCheckCompleteCallback(update_client::Error error) {}
-
 void SendUninstallPingCompleteCallback(update_client::Error error) {}
 
 void InstallUpdateCallback(content::BrowserContext* context,
@@ -58,35 +62,83 @@
     update_data_provider_ = nullptr;
   }
   update_client_ = nullptr;
-  context_ = nullptr;
+  browser_context_ = nullptr;
 }
 
 void UpdateService::SendUninstallPing(const std::string& id,
                                       const base::Version& version,
                                       int reason) {
+  DCHECK(update_client_);
   update_client_->SendUninstallPing(
       id, version, reason, base::BindOnce(&SendUninstallPingCompleteCallback));
 }
 
-void UpdateService::StartUpdateCheck(
-    const std::vector<std::string>& extension_ids) {
-  if (!update_client_)
-    return;
-  update_client_->Update(
-      extension_ids,
-      base::BindOnce(&UpdateDataProvider::GetData, update_data_provider_),
-      base::BindOnce(&UpdateCheckCompleteCallback));
+bool UpdateService::CanUpdate(const std::string& extension_id) const {
+  // We can only update extensions that have been installed on the system.
+  // Furthermore, we can only update extensions that were installed from the
+  // webstore.
+  const ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
+  const Extension* extension = registry->GetInstalledExtension(extension_id);
+  return extension && ManifestURL::UpdatesFromGallery(extension);
 }
 
 UpdateService::UpdateService(
-    content::BrowserContext* context,
+    content::BrowserContext* browser_context,
     scoped_refptr<update_client::UpdateClient> update_client)
-    : context_(context), update_client_(update_client) {
-  CHECK(update_client_);
+    : browser_context_(browser_context),
+      update_client_(update_client),
+      weak_ptr_factory_(this) {
+  DCHECK(update_client_);
   update_data_provider_ = base::MakeRefCounted<UpdateDataProvider>(
-      context_, base::BindOnce(&InstallUpdateCallback));
+      browser_context_, base::BindOnce(&InstallUpdateCallback));
 }
 
 UpdateService::~UpdateService() {}
 
+void UpdateService::StartUpdateCheck(
+    const ExtensionUpdateCheckParams& update_params) {
+  ExtensionUpdateDataMap update_data;
+  std::vector<std::string> extension_ids;
+  for (const auto& info : update_params.update_info) {
+    const std::string& extension_id = info.first;
+    if (updating_extensions_.find(extension_id) != updating_extensions_.end())
+      continue;
+
+    updating_extensions_.insert(extension_id);
+    extension_ids.push_back(extension_id);
+    update_data[extension_id] = info.second;
+  }
+  if (extension_ids.empty())
+    return;
+  if (update_params.priority == ExtensionUpdateCheckParams::BACKGROUND) {
+    update_client_->Update(
+        extension_ids,
+        base::BindOnce(&UpdateDataProvider::GetData, update_data_provider_,
+                       std::move(update_data)),
+        base::BindOnce(&UpdateService::UpdateCheckComplete,
+                       weak_ptr_factory_.GetWeakPtr(), extension_ids));
+  } else {
+    // TODO (mxnguyen): Run the on demand update in batch.
+    for (const std::string& extension_id : extension_ids) {
+      ExtensionUpdateDataMap update_data_for_extension;
+      update_data_for_extension[extension_id] =
+          std::move(update_data[extension_id]);
+      update_client_->Install(
+          extension_id,
+          base::BindOnce(&UpdateDataProvider::GetData, update_data_provider_,
+                         std::move(update_data_for_extension)),
+          base::BindOnce(&UpdateService::UpdateCheckComplete,
+                         weak_ptr_factory_.GetWeakPtr(),
+                         std::vector<std::string>({extension_id})));
+    }
+  }
+}
+
+void UpdateService::UpdateCheckComplete(
+    const std::vector<std::string>& extension_ids,
+    update_client::Error error) {
+  for (const std::string& extension_id : extension_ids)
+    updating_extensions_.erase(extension_id);
+}
+
 }  // namespace extensions
diff --git a/extensions/browser/updater/update_service.h b/extensions/browser/updater/update_service.h
index 77af0464..69acd1c 100644
--- a/extensions/browser/updater/update_service.h
+++ b/extensions/browser/updater/update_service.h
@@ -6,11 +6,13 @@
 #define EXTENSIONS_BROWSER_UPDATER_UPDATE_SERVICE_H_
 
 #include <memory>
+#include <set>
 #include <string>
 #include <vector>
 
 #include "base/callback.h"
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "components/keyed_service/core/keyed_service.h"
 
 namespace base {
@@ -22,14 +24,15 @@
 }
 
 namespace update_client {
+enum class Error;
 class UpdateClient;
 }
 
 namespace extensions {
 
 class UpdateDataProvider;
-class UpdateService;
 class UpdateServiceFactory;
+struct ExtensionUpdateCheckParams;
 
 // This service manages the autoupdate of extensions.  It should eventually
 // replace ExtensionUpdater in Chrome.
@@ -44,24 +47,40 @@
                          const base::Version& version,
                          int reason);
 
-  // Starts an update check for each of |extension_ids|. If there are any
-  // updates available, they will be downloaded, checked for integrity,
-  // unpacked, and then passed off to the ExtensionSystem::InstallUpdate method
-  // for install completion.
-  void StartUpdateCheck(const std::vector<std::string>& extension_ids);
+  // Starts an update check for each of extensions stored in |update_params|.
+  // If there are any updates available, they will be downloaded, checked for
+  // integrity, unpacked, and then passed off to the
+  // ExtensionSystem::InstallUpdate method for install completion.
+  void StartUpdateCheck(const ExtensionUpdateCheckParams& update_params);
+
+  // This function verifies if the current implementation can update
+  // |extension_id|.
+  bool CanUpdate(const std::string& extension_id) const;
 
  private:
   friend class UpdateServiceFactory;
+  friend std::unique_ptr<UpdateService>::deleter_type;
 
   UpdateService(content::BrowserContext* context,
                 scoped_refptr<update_client::UpdateClient> update_client);
   ~UpdateService() override;
 
-  content::BrowserContext* context_;
+  // This function is executed by the update client after an update check
+  // request has completed.
+  void UpdateCheckComplete(const std::vector<std::string>& extension_ids,
+                           update_client::Error error);
+
+  content::BrowserContext* browser_context_;
 
   scoped_refptr<update_client::UpdateClient> update_client_;
   scoped_refptr<UpdateDataProvider> update_data_provider_;
 
+  // The set of extensions that are being checked for update.
+  std::set<std::string> updating_extensions_;
+
+  // used to create WeakPtrs to |this|.
+  base::WeakPtrFactory<UpdateService> weak_ptr_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(UpdateService);
 };
 
diff --git a/extensions/browser/updater/update_service_unittest.cc b/extensions/browser/updater/update_service_unittest.cc
index 29ffd9a1..a03daff 100644
--- a/extensions/browser/updater/update_service_unittest.cc
+++ b/extensions/browser/updater/update_service_unittest.cc
@@ -22,8 +22,10 @@
 #include "extensions/browser/mock_extension_system.h"
 #include "extensions/browser/test_extensions_browser_client.h"
 #include "extensions/browser/uninstall_ping_sender.h"
+#include "extensions/browser/updater/extension_update_data.h"
 #include "extensions/browser/updater/update_service.h"
 #include "extensions/common/extension_builder.h"
+#include "extensions/common/manifest_url_handlers.h"
 #include "extensions/common/value_builder.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -89,6 +91,7 @@
                               CrxDataCallback crx_data_callback,
                               update_client::Callback callback) {
   std::move(crx_data_callback).Run(ids, &data_);
+  std::move(callback).Run(update_client::Error::NONE);
 }
 
 }  // namespace
@@ -227,12 +230,13 @@
   scoped_refptr<Extension> extension1(builder.Build());
 
   ExtensionRegistry::Get(browser_context())->AddEnabled(extension1);
-  std::vector<std::string> ids;
-  ids.push_back(extension1->id());
+
+  ExtensionUpdateCheckParams update_check_params;
+  update_check_params.update_info[extension1->id()] = ExtensionUpdateData();
 
   // Start an update check and verify that the UpdateClient was sent the right
   // data.
-  update_service()->StartUpdateCheck(ids);
+  update_service()->StartUpdateCheck(update_check_params);
   std::vector<update_client::CrxComponent>* data = update_client()->data();
   ASSERT_NE(nullptr, data);
   ASSERT_EQ(1u, data->size());
diff --git a/extensions/common/api/OWNERS b/extensions/common/api/OWNERS
index b1e39d62..7ccf6b57 100644
--- a/extensions/common/api/OWNERS
+++ b/extensions/common/api/OWNERS
@@ -4,11 +4,6 @@
 per-file *.json=file://extensions/common/api/API_OWNERS
 per-file *.idl=file://extensions/common/api/API_OWNERS
 
-per-file *view*.json=fsamuel@chromium.org
-per-file *view*.json=lazyboy@chromium.org
-per-file *view*.json=hanxi@chromium.org
-per-file *view*.json=wjmaclean@chromium.org
-per-file *view*.json=lfg@chromium.org
-per-file *view*.json=paulmeyer@chromium.org
+per-file *view*.json=file://components/guest_view/OWNERS
 
 # COMPONENT: Platform>Extensions>API
diff --git a/extensions/common/api/bluetooth/bluetooth_manifest_permission.cc b/extensions/common/api/bluetooth/bluetooth_manifest_permission.cc
index 4b67edf..37fe8e3 100644
--- a/extensions/common/api/bluetooth/bluetooth_manifest_permission.cc
+++ b/extensions/common/api/bluetooth/bluetooth_manifest_permission.cc
@@ -26,8 +26,6 @@
 const char kErrorInvalidUuid[] = "Invalid UUID '*'";
 }
 
-namespace errors = bluetooth_errors;
-
 namespace {
 
 bool ParseUuid(BluetoothManifestPermission* permission,
@@ -36,7 +34,7 @@
   device::BluetoothUUID bt_uuid(uuid);
   if (!bt_uuid.IsValid()) {
     *error = ErrorUtils::FormatErrorMessageUTF16(
-        errors::kErrorInvalidUuid, uuid);
+        bluetooth_errors::kErrorInvalidUuid, uuid);
     return false;
   }
   permission->AddPermission(uuid);
diff --git a/extensions/common/api/feedback_private.idl b/extensions/common/api/feedback_private.idl
index 9cf7aa6d..df87eb4 100644
--- a/extensions/common/api/feedback_private.idl
+++ b/extensions/common/api/feedback_private.idl
@@ -44,6 +44,10 @@
     // The feedback text describing the user issue.
     DOMString description;
 
+    // The placeholder text that will be shown in the description field when
+    // it's empty.
+    DOMString? descriptionPlaceholder;
+
     // The e-mail of the user that initiated this feedback.
     DOMString? email;
 
diff --git a/extensions/common/api/sockets/sockets_manifest_permission.cc b/extensions/common/api/sockets/sockets_manifest_permission.cc
index 3380173..1affb83 100644
--- a/extensions/common/api/sockets/sockets_manifest_permission.cc
+++ b/extensions/common/api/sockets/sockets_manifest_permission.cc
@@ -24,7 +24,6 @@
 const char kErrorInvalidHostPattern[] = "Invalid host:port pattern '*'";
 }
 
-namespace errors = sockets_errors;
 using api::extensions_manifest_types::Sockets;
 using api::extensions_manifest_types::SocketHostPatterns;
 using content::SocketPermissionRequest;
@@ -40,7 +39,7 @@
   if (!SocketPermissionEntry::ParseHostPattern(
           operation_type, host_pattern, &entry)) {
     *error = ErrorUtils::FormatErrorMessageUTF16(
-        errors::kErrorInvalidHostPattern, host_pattern);
+        sockets_errors::kErrorInvalidHostPattern, host_pattern);
     return false;
   }
   permission->AddPermission(entry);
diff --git a/extensions/common/guest_view/OWNERS b/extensions/common/guest_view/OWNERS
index 465e847..d3826db 100644
--- a/extensions/common/guest_view/OWNERS
+++ b/extensions/common/guest_view/OWNERS
@@ -1,6 +1,4 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-wjmaclean@chromium.org
+file://components/guest_view/OWNERS
 
 per-file *_messages*.h=set noparent
 per-file *_messages*.h=file://ipc/SECURITY_OWNERS
diff --git a/extensions/common/manifest_handlers/externally_connectable.cc b/extensions/common/manifest_handlers/externally_connectable.cc
index 871ea0c..02cb885 100644
--- a/extensions/common/manifest_handlers/externally_connectable.cc
+++ b/extensions/common/manifest_handlers/externally_connectable.cc
@@ -41,7 +41,6 @@
 }  // namespace externally_connectable_errors
 
 namespace keys = extensions::manifest_keys;
-namespace errors = externally_connectable_errors;
 using api::extensions_manifest_types::ExternallyConnectable;
 
 namespace {
@@ -120,7 +119,7 @@
       URLPattern pattern(URLPattern::SCHEME_ALL);
       if (pattern.Parse(*it) != URLPattern::PARSE_SUCCESS) {
         *error = ErrorUtils::FormatErrorMessageUTF16(
-            errors::kErrorInvalidMatchPattern, *it);
+            externally_connectable_errors::kErrorInvalidMatchPattern, *it);
         return std::unique_ptr<ExternallyConnectableInfo>();
       }
 
@@ -132,11 +131,11 @@
       // Wildcard hosts are not allowed.
       if (pattern.host().empty()) {
         // Warning not error for forwards compatibility.
-        install_warnings->push_back(
-            InstallWarning(ErrorUtils::FormatErrorMessage(
-                               errors::kErrorWildcardHostsNotAllowed, *it),
-                           keys::kExternallyConnectable,
-                           *it));
+        install_warnings->push_back(InstallWarning(
+            ErrorUtils::FormatErrorMessage(
+                externally_connectable_errors::kErrorWildcardHostsNotAllowed,
+                *it),
+            keys::kExternallyConnectable, *it));
         continue;
       }
 
@@ -147,7 +146,7 @@
         // CanonicalizeHost returns empty string on error. The URL parsing
         // combined with host().empty() should have caught this above.
         *error = ErrorUtils::FormatErrorMessageUTF16(
-            errors::kErrorInvalidMatchPattern, *it);
+            externally_connectable_errors::kErrorInvalidMatchPattern, *it);
         return std::unique_ptr<ExternallyConnectableInfo>();
       }
 
@@ -165,13 +164,11 @@
       // are not allowed. However just "appspot.com" is ok.
       if (!has_registry && pattern.match_subdomains()) {
         // Warning not error for forwards compatibility.
-        install_warnings->push_back(
-            InstallWarning(ErrorUtils::FormatErrorMessage(
-                               errors::kErrorTopLevelDomainsNotAllowed,
-                               pattern.host().c_str(),
-                               *it),
-                           keys::kExternallyConnectable,
-                           *it));
+        install_warnings->push_back(InstallWarning(
+            ErrorUtils::FormatErrorMessage(
+                externally_connectable_errors::kErrorTopLevelDomainsNotAllowed,
+                pattern.host().c_str(), *it),
+            keys::kExternallyConnectable, *it));
         continue;
       }
 
@@ -192,16 +189,17 @@
       } else if (crx_file::id_util::IdIsValid(*it)) {
         ids.push_back(*it);
       } else {
-        *error =
-            ErrorUtils::FormatErrorMessageUTF16(errors::kErrorInvalidId, *it);
+        *error = ErrorUtils::FormatErrorMessageUTF16(
+            externally_connectable_errors::kErrorInvalidId, *it);
         return std::unique_ptr<ExternallyConnectableInfo>();
       }
     }
   }
 
   if (!externally_connectable->matches && !externally_connectable->ids) {
-    install_warnings->push_back(InstallWarning(errors::kErrorNothingSpecified,
-                                               keys::kExternallyConnectable));
+    install_warnings->push_back(
+        InstallWarning(externally_connectable_errors::kErrorNothingSpecified,
+                       keys::kExternallyConnectable));
   }
 
   bool accepts_tls_channel_id =
diff --git a/extensions/renderer/guest_view/OWNERS b/extensions/renderer/guest_view/OWNERS
index f727e615..74d34105 100644
--- a/extensions/renderer/guest_view/OWNERS
+++ b/extensions/renderer/guest_view/OWNERS
@@ -1,8 +1,3 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-lfg@chromium.org
-hanxi@chromium.org
-wjmaclean@chromium.org
-ekaramad@chromium.org
+file://components/guest_view/OWNERS
 
 # COMPONENT: Platform>Apps>BrowserTag
diff --git a/extensions/renderer/resources/guest_view/OWNERS b/extensions/renderer/resources/guest_view/OWNERS
index 9877300..74d34105 100644
--- a/extensions/renderer/resources/guest_view/OWNERS
+++ b/extensions/renderer/resources/guest_view/OWNERS
@@ -1,6 +1,3 @@
-paulmeyer@chromium.org
-fsamuel@chromium.org
-lazyboy@chromium.org
-wjmaclean@chromium.org
+file://components/guest_view/OWNERS
 
 # COMPONENT: Platform>Apps>BrowserTag
diff --git a/extensions/test/data/web_view/OWNERS b/extensions/test/data/web_view/OWNERS
index cf8fef33..74d34105 100644
--- a/extensions/test/data/web_view/OWNERS
+++ b/extensions/test/data/web_view/OWNERS
@@ -1,5 +1,3 @@
-fsamuel@chromium.org
-lazyboy@chromium.org
-wjmaclean@chromium.org
+file://components/guest_view/OWNERS
 
 # COMPONENT: Platform>Apps>BrowserTag
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn
index 770f24a..77657b2 100644
--- a/gpu/command_buffer/service/BUILD.gn
+++ b/gpu/command_buffer/service/BUILD.gn
@@ -53,12 +53,15 @@
     "image_factory.h",
     "image_manager.cc",
     "image_manager.h",
+    "mailbox_manager.h",
     "memory_tracking.h",
     "scheduler.cc",
     "scheduler.h",
     "sequence_id.h",
     "sync_point_manager.cc",
     "sync_point_manager.h",
+    "texture_base.cc",
+    "texture_base.h",
     "transfer_buffer_manager.cc",
     "transfer_buffer_manager.h",
   ]
@@ -160,8 +163,8 @@
     "indexed_buffer_binding_host.h",
     "logger.cc",
     "logger.h",
-    "mailbox_manager.cc",
-    "mailbox_manager.h",
+    "mailbox_manager_factory.cc",
+    "mailbox_manager_factory.h",
     "mailbox_manager_impl.cc",
     "mailbox_manager_impl.h",
     "mailbox_manager_sync.cc",
diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h
index 74127fc..1af2520 100644
--- a/gpu/command_buffer/service/context_group.h
+++ b/gpu/command_buffer/service/context_group.h
@@ -28,6 +28,7 @@
 
 class ImageFactory;
 struct GpuPreferences;
+class MailboxManager;
 class TransferBufferManager;
 class ServiceDiscardableManager;
 class ServiceTransferCache;
@@ -38,7 +39,6 @@
 class BufferManager;
 class GLES2Decoder;
 class ImageManager;
-class MailboxManager;
 class RenderbufferManager;
 class PathManager;
 class ProgramManager;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index df6a0be..ace8739 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -18112,6 +18112,8 @@
 
   if (texture->IsAttachedToFramebuffer())
     framebuffer_state_.clear_state_dirty = true;
+
+  texture->SetImmutable(true);
 }
 
 void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index 1138bc9..9a07d2a1 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -40,6 +40,7 @@
 struct ContextCreationAttribs;
 struct Mailbox;
 struct SyncToken;
+class TextureBase;
 
 namespace gles2 {
 
@@ -55,7 +56,6 @@
 class QueryManager;
 class ShaderTranslatorInterface;
 class Texture;
-class TextureBase;
 class TransformFeedbackManager;
 class VertexArrayManager;
 struct ContextState;
diff --git a/gpu/command_buffer/service/mailbox_manager.h b/gpu/command_buffer/service/mailbox_manager.h
index cf3db3e..fa6895d 100644
--- a/gpu/command_buffer/service/mailbox_manager.h
+++ b/gpu/command_buffer/service/mailbox_manager.h
@@ -13,11 +13,7 @@
 
 namespace gpu {
 
-struct GpuPreferences;
 struct SyncToken;
-
-namespace gles2 {
-
 class TextureBase;
 
 // Manages resources scoped beyond the context or context group level.
@@ -40,12 +36,8 @@
 
   // Destroy any mailbox that reference the given texture.
   virtual void TextureDeleted(TextureBase* texture) = 0;
-
-  static std::unique_ptr<MailboxManager> Create(
-      const GpuPreferences& gpu_preferences);
 };
 
-}  // namespage gles2
 }  // namespace gpu
 
 #endif  // GPU_COMMAND_BUFFER_SERVICE_MAILBOX_MANAGER_H_
diff --git a/gpu/command_buffer/service/mailbox_manager.cc b/gpu/command_buffer/service/mailbox_manager_factory.cc
similarity index 74%
rename from gpu/command_buffer/service/mailbox_manager.cc
rename to gpu/command_buffer/service/mailbox_manager_factory.cc
index bf96d4f..395bd209 100644
--- a/gpu/command_buffer/service/mailbox_manager.cc
+++ b/gpu/command_buffer/service/mailbox_manager_factory.cc
@@ -1,8 +1,8 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
+// Copyright 2017 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager_factory.h"
 
 #include "base/command_line.h"
 #include "base/memory/ptr_util.h"
@@ -13,13 +13,12 @@
 namespace gpu {
 namespace gles2 {
 
-// static
-std::unique_ptr<MailboxManager> MailboxManager::Create(
+std::unique_ptr<MailboxManager> CreateMailboxManager(
     const GpuPreferences& gpu_preferences) {
   if (gpu_preferences.enable_threaded_texture_mailboxes)
     return std::make_unique<MailboxManagerSync>();
   return std::make_unique<MailboxManagerImpl>();
 }
 
-}  // namespage gles2
+}  // namespace gles2
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/mailbox_manager_factory.h b/gpu/command_buffer/service/mailbox_manager_factory.h
new file mode 100644
index 0000000..2faffcd
--- /dev/null
+++ b/gpu/command_buffer/service/mailbox_manager_factory.h
@@ -0,0 +1,21 @@
+// 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 GPU_COMMAND_BUFFER_SERVICE_MAILBOX_MANAGER_FACTORY_H_
+#define GPU_COMMAND_BUFFER_SERVICE_MAILBOX_MANAGER_FACTORY_H_
+
+#include "gpu/command_buffer/service/mailbox_manager.h"
+
+namespace gpu {
+
+struct GpuPreferences;
+
+namespace gles2 {
+
+std::unique_ptr<MailboxManager> CreateMailboxManager(
+    const GpuPreferences& gpu_preferences);
+
+}  // namespace gles2
+}  // namespace gpu
+#endif  // GPU_COMMAND_BUFFER_SERVICE_MAILBOX_MANAGER_FACTORY_H_
diff --git a/gpu/command_buffer/service/mailbox_manager_impl.cc b/gpu/command_buffer/service/mailbox_manager_impl.cc
index f62fce99..2cd186ad 100644
--- a/gpu/command_buffer/service/mailbox_manager_impl.cc
+++ b/gpu/command_buffer/service/mailbox_manager_impl.cc
@@ -8,7 +8,7 @@
 
 #include <algorithm>
 
-#include "gpu/command_buffer/service/texture_manager.h"
+#include "gpu/command_buffer/service/texture_base.h"
 
 namespace gpu {
 namespace gles2 {
diff --git a/gpu/command_buffer/service/mailbox_manager_impl.h b/gpu/command_buffer/service/mailbox_manager_impl.h
index 7cde11d9..cb31003 100644
--- a/gpu/command_buffer/service/mailbox_manager_impl.h
+++ b/gpu/command_buffer/service/mailbox_manager_impl.h
@@ -18,8 +18,6 @@
 namespace gpu {
 namespace gles2 {
 
-class TextureBase;
-
 // Manages resources scoped beyond the context or context group level.
 class GPU_EXPORT MailboxManagerImpl : public MailboxManager {
  public:
diff --git a/gpu/command_buffer/service/mailbox_manager_sync.cc b/gpu/command_buffer/service/mailbox_manager_sync.cc
index c67c6ba..a5b06f45 100644
--- a/gpu/command_buffer/service/mailbox_manager_sync.cc
+++ b/gpu/command_buffer/service/mailbox_manager_sync.cc
@@ -269,7 +269,7 @@
         texture, TextureGroupRef(kNewTextureVersion, group_for_texture)));
   }
 
-  DCHECK(texture->mailbox_manager_ == this);
+  DCHECK(texture->mailbox_manager() == this);
 }
 
 void MailboxManagerSync::TextureDeleted(TextureBase* texture_base) {
diff --git a/gpu/command_buffer/service/raster_decoder.h b/gpu/command_buffer/service/raster_decoder.h
index 4cdf58f7..b6f44657 100644
--- a/gpu/command_buffer/service/raster_decoder.h
+++ b/gpu/command_buffer/service/raster_decoder.h
@@ -31,6 +31,9 @@
 #include "gpu/gpu_export.h"
 
 namespace gpu {
+
+class TextureBase;
+
 namespace raster {
 
 // This class implements the AsyncAPIInterface interface, decoding
@@ -102,7 +105,7 @@
   void PerformPollingWork() override;
   bool GetServiceTextureId(uint32_t client_texture_id,
                            uint32_t* service_texture_id) override;
-  gles2::TextureBase* GetTextureBase(uint32_t client_id) override;
+  TextureBase* GetTextureBase(uint32_t client_id) override;
   bool ClearLevel(gles2::Texture* texture,
                   unsigned target,
                   int level,
diff --git a/gpu/command_buffer/service/texture_base.cc b/gpu/command_buffer/service/texture_base.cc
new file mode 100644
index 0000000..ad441ec
--- /dev/null
+++ b/gpu/command_buffer/service/texture_base.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 "gpu/command_buffer/service/texture_base.h"
+
+#include "base/logging.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+
+namespace gpu {
+
+TextureBase::TextureBase(unsigned int service_id)
+    : service_id_(service_id), target_(0), mailbox_manager_(nullptr) {}
+
+TextureBase::~TextureBase() {
+  DCHECK_EQ(nullptr, mailbox_manager_);
+}
+
+void TextureBase::SetTarget(unsigned int target) {
+  DCHECK_EQ(0u, target_);  // you can only set this once.
+  target_ = target;
+}
+
+void TextureBase::DeleteFromMailboxManager() {
+  if (mailbox_manager_) {
+    mailbox_manager_->TextureDeleted(this);
+    mailbox_manager_ = nullptr;
+  }
+}
+
+void TextureBase::SetMailboxManager(MailboxManager* mailbox_manager) {
+  DCHECK(!mailbox_manager_ || mailbox_manager_ == mailbox_manager);
+  mailbox_manager_ = mailbox_manager;
+}
+
+}  // namespace gpu
diff --git a/gpu/command_buffer/service/texture_base.h b/gpu/command_buffer/service/texture_base.h
new file mode 100644
index 0000000..d81aca5
--- /dev/null
+++ b/gpu/command_buffer/service/texture_base.h
@@ -0,0 +1,48 @@
+// 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 GPU_COMMAND_BUFFER_SERVICE_TEXTURE_BASE_H_
+#define GPU_COMMAND_BUFFER_SERVICE_TEXTURE_BASE_H_
+
+#include "gpu/gpu_export.h"
+
+namespace gpu {
+
+class MailboxManager;
+
+class GPU_EXPORT TextureBase {
+ public:
+  explicit TextureBase(unsigned int service_id);
+  virtual ~TextureBase();
+
+  // The service side OpenGL id of the texture.
+  unsigned int service_id() const { return service_id_; }
+
+  // Returns the target this texure was first bound to or 0 if it has not
+  // been bound. Once a texture is bound to a specific target it can never be
+  // bound to a different target.
+  unsigned int target() const { return target_; }
+
+  void SetMailboxManager(MailboxManager* mailbox_manager);
+  MailboxManager* mailbox_manager() const { return mailbox_manager_; }
+
+ protected:
+  // The id of the texture.
+  unsigned int service_id_;
+
+  // The target. 0 if unset, otherwise GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP.
+  //             Or GL_TEXTURE_2D_ARRAY or GL_TEXTURE_3D (for GLES3).
+  unsigned int target_;
+
+  void SetTarget(unsigned int target);
+
+  void DeleteFromMailboxManager();
+
+ private:
+  MailboxManager* mailbox_manager_;
+};
+
+}  // namespace gpu
+
+#endif  // GPU_COMMAND_BUFFER_SERVICE_TEXTURE_BASE_H_
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 8a2c00c..0be44b5 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -477,30 +477,6 @@
   DCHECK_EQ(0u, memory_type_tracker_->GetMemRepresented());
 }
 
-TextureBase::TextureBase(GLuint service_id)
-    : service_id_(service_id), target_(GL_NONE), mailbox_manager_(nullptr) {}
-
-TextureBase::~TextureBase() {
-  DCHECK_EQ(nullptr, mailbox_manager_);
-}
-
-void TextureBase::SetTarget(GLenum target) {
-  DCHECK_EQ(0u, target_);  // you can only set this once.
-  target_ = target;
-}
-
-void TextureBase::DeleteFromMailboxManager() {
-  if (mailbox_manager_) {
-    mailbox_manager_->TextureDeleted(this);
-    mailbox_manager_ = nullptr;
-  }
-}
-
-void TextureBase::SetMailboxManager(MailboxManager* mailbox_manager) {
-  DCHECK(!mailbox_manager_ || mailbox_manager_ == mailbox_manager);
-  mailbox_manager_ = mailbox_manager;
-}
-
 TexturePassthrough::TexturePassthrough(GLuint service_id, GLenum target)
     : TextureBase(service_id),
       have_context_(true),
diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
index 574b32e..6b10aec 100644
--- a/gpu/command_buffer/service/texture_manager.h
+++ b/gpu/command_buffer/service/texture_manager.h
@@ -22,6 +22,7 @@
 #include "gpu/command_buffer/service/gl_utils.h"
 #include "gpu/command_buffer/service/memory_tracking.h"
 #include "gpu/command_buffer/service/sampler_manager.h"
+#include "gpu/command_buffer/service/texture_base.h"
 #include "gpu/gpu_export.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gl/gl_image.h"
@@ -37,46 +38,11 @@
 class ErrorState;
 class FeatureInfo;
 class FramebufferManager;
-class MailboxManager;
 class ProgressReporter;
 class Texture;
 class TextureManager;
 class TextureRef;
 
-class GPU_EXPORT TextureBase {
- public:
-  explicit TextureBase(GLuint service_id);
-  virtual ~TextureBase();
-
-  // The service side OpenGL id of the texture.
-  GLuint service_id() const { return service_id_; }
-
-  // Returns the target this texure was first bound to or 0 if it has not
-  // been bound. Once a texture is bound to a specific target it can never be
-  // bound to a different target.
-  GLenum target() const { return target_; }
-
- protected:
-  // The id of the texture.
-  GLuint service_id_;
-
-  // The target. 0 if unset, otherwise GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP.
-  //             Or GL_TEXTURE_2D_ARRAY or GL_TEXTURE_3D (for GLES3).
-  GLenum target_;
-
-  void SetTarget(GLenum target);
-
-  void DeleteFromMailboxManager();
-
- private:
-  friend class MailboxManagerSync;
-  friend class MailboxManagerImpl;
-
-  void SetMailboxManager(MailboxManager* mailbox_manager);
-
-  MailboxManager* mailbox_manager_;
-};
-
 // A ref-counted version of the TextureBase class that deletes the texture after
 // all references have been released.
 class TexturePassthrough final : public TextureBase,
@@ -343,7 +309,6 @@
                               bool immutable);
 
  private:
-  friend class MailboxManagerImpl;
   friend class MailboxManagerSync;
   friend class MailboxManagerTest;
   friend class TextureDefinition;
diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h
index d699ae0..900b3d7 100644
--- a/gpu/command_buffer/tests/gl_manager.h
+++ b/gpu/command_buffer/tests/gl_manager.h
@@ -35,12 +35,12 @@
 
 class CommandBufferDirect;
 class ImageFactory;
+class MailboxManager;
 class SyncPointManager;
 class TransferBuffer;
 
 namespace gles2 {
 
-class MailboxManager;
 class GLES2CmdHelper;
 class GLES2Implementation;
 
@@ -113,7 +113,7 @@
     return decoder_.get();
   }
 
-  gles2::MailboxManager* mailbox_manager() const { return mailbox_manager_; }
+  MailboxManager* mailbox_manager() const { return mailbox_manager_; }
 
   gl::GLShareGroup* share_group() const { return share_group_.get(); }
 
@@ -171,7 +171,7 @@
   ServiceDiscardableManager discardable_manager_;
   std::unique_ptr<gles2::ShaderTranslatorCache> translator_cache_;
   gles2::FramebufferCompletenessCache completeness_cache_;
-  gles2::MailboxManager* mailbox_manager_ = nullptr;
+  MailboxManager* mailbox_manager_ = nullptr;
   scoped_refptr<gl::GLShareGroup> share_group_;
   std::unique_ptr<CommandBufferDirect> command_buffer_;
   std::unique_ptr<gles2::GLES2Decoder> decoder_;
diff --git a/gpu/config/BUILD.gn b/gpu/config/BUILD.gn
index 0996f14..f151284 100644
--- a/gpu/config/BUILD.gn
+++ b/gpu/config/BUILD.gn
@@ -18,17 +18,6 @@
   }
 }
 
-source_set("crash_keys") {
-  sources = [
-    "gpu_crash_keys.cc",
-    "gpu_crash_keys.h",
-  ]
-
-  deps = [
-    "//components/crash/core/common:crash_key",
-  ]
-}
-
 process_json_outputs = [
   "$target_gen_dir/gpu_driver_bug_list_arrays_and_structs_autogen.h",
   "$target_gen_dir/gpu_driver_bug_list_autogen.cc",
@@ -85,6 +74,8 @@
     "gpu_blacklist.h",
     "gpu_control_list.cc",
     "gpu_control_list.h",
+    "gpu_crash_keys.cc",
+    "gpu_crash_keys.h",
     "gpu_driver_bug_list.cc",
     "gpu_driver_bug_list.h",
     "gpu_driver_bug_workaround_type.h",
@@ -124,8 +115,11 @@
 
   configs += [ "//gpu:gpu_implementation" ]
 
+  public_deps = [
+    "//components/crash/core/common:crash_key",
+  ]
+
   deps = [
-    ":crash_keys",
     ":process_json",
     "//base",
     "//third_party/re2",
diff --git a/gpu/config/gpu_crash_keys.h b/gpu/config/gpu_crash_keys.h
index 36f9acc..3d099b7 100644
--- a/gpu/config/gpu_crash_keys.h
+++ b/gpu/config/gpu_crash_keys.h
@@ -7,25 +7,26 @@
 
 #include "build/build_config.h"
 #include "components/crash/core/common/crash_key.h"
+#include "gpu/gpu_export.h"
 
 namespace gpu {
 namespace crash_keys {
 
 // Keys that can be used for crash reporting.
 #if !defined(OS_ANDROID)
-extern crash_reporter::CrashKeyString<16> gpu_vendor_id;
-extern crash_reporter::CrashKeyString<16> gpu_device_id;
+extern GPU_EXPORT crash_reporter::CrashKeyString<16> gpu_vendor_id;
+extern GPU_EXPORT crash_reporter::CrashKeyString<16> gpu_device_id;
 #endif
-extern crash_reporter::CrashKeyString<64> gpu_driver_version;
-extern crash_reporter::CrashKeyString<16> gpu_pixel_shader_version;
-extern crash_reporter::CrashKeyString<16> gpu_vertex_shader_version;
+extern GPU_EXPORT crash_reporter::CrashKeyString<64> gpu_driver_version;
+extern GPU_EXPORT crash_reporter::CrashKeyString<16> gpu_pixel_shader_version;
+extern GPU_EXPORT crash_reporter::CrashKeyString<16> gpu_vertex_shader_version;
 #if defined(OS_MACOSX)
-extern crash_reporter::CrashKeyString<64> gpu_gl_version;
+extern GPU_EXPORT crash_reporter::CrashKeyString<64> gpu_gl_version;
 #elif defined(OS_POSIX)
-extern crash_reporter::CrashKeyString<256> gpu_vendor;
-extern crash_reporter::CrashKeyString<128> gpu_renderer;
+extern GPU_EXPORT crash_reporter::CrashKeyString<256> gpu_vendor;
+extern GPU_EXPORT crash_reporter::CrashKeyString<128> gpu_renderer;
 #endif
-extern crash_reporter::CrashKeyString<4> gpu_gl_context_is_virtual;
+extern GPU_EXPORT crash_reporter::CrashKeyString<4> gpu_gl_context_is_virtual;
 
 }  // namespace crash_keys
 }  // namespace gpu
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc
index d2e49457..269b013 100644
--- a/gpu/config/gpu_finch_features.cc
+++ b/gpu/config/gpu_finch_features.cc
@@ -9,8 +9,10 @@
 
 // Enable GPU Rasterization by default. This can still be overridden by
 // --force-gpu-rasterization or --disable-gpu-rasterization.
-#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_CHROMEOS)
-// DefaultEnableGpuRasterization has launched on Mac, Windows and ChromeOS.
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_CHROMEOS) || \
+    defined(OS_ANDROID)
+// DefaultEnableGpuRasterization has launched on Mac, Windows, ChromeOS, and
+// Android.
 const base::Feature kDefaultEnableGpuRasterization{
     "DefaultEnableGpuRasterization", base::FEATURE_ENABLED_BY_DEFAULT};
 #else
diff --git a/gpu/config/gpu_util.cc b/gpu/config/gpu_util.cc
index ee43a2a..98176c8 100644
--- a/gpu/config/gpu_util.cc
+++ b/gpu/config/gpu_util.cc
@@ -52,13 +52,6 @@
   if (blacklisted_features.count(GPU_FEATURE_TYPE_GPU_RASTERIZATION))
     return kGpuFeatureStatusBlacklisted;
 
-#if defined(OS_ANDROID)
-  // GPU Raster is always enabled on >512MB Android devices. On 512MB devices,
-  // it is controlled by a Finch experiment.
-  if (base::SysInfo::AmountOfPhysicalMemoryMB() > 512)
-    return kGpuFeatureStatusEnabled;
-#endif  // defined(OS_ANDROID)
-
   // Gpu Rasterization on platforms that are not fully enabled is controlled by
   // a finch experiment.
   if (!base::FeatureList::IsEnabled(features::kDefaultEnableGpuRasterization))
diff --git a/gpu/ipc/BUILD.gn b/gpu/ipc/BUILD.gn
index c4a579a..e5c68ea 100644
--- a/gpu/ipc/BUILD.gn
+++ b/gpu/ipc/BUILD.gn
@@ -40,7 +40,6 @@
     "//gpu/command_buffer/service:gles2_sources",
     "//gpu/command_buffer/service:service_sources",
     "//gpu/config:config_sources",
-    "//gpu/config:crash_keys",
     "//gpu/ipc/client:ipc_client_sources",
     "//gpu/ipc/service:ipc_service_sources",
     "//ui/gfx",
diff --git a/gpu/ipc/gpu_in_process_thread_service.cc b/gpu/ipc/gpu_in_process_thread_service.cc
index f79d1b8..7115c153 100644
--- a/gpu/ipc/gpu_in_process_thread_service.cc
+++ b/gpu/ipc/gpu_in_process_thread_service.cc
@@ -12,7 +12,7 @@
 GpuInProcessThreadService::GpuInProcessThreadService(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     gpu::SyncPointManager* sync_point_manager,
-    gpu::gles2::MailboxManager* mailbox_manager,
+    gpu::MailboxManager* mailbox_manager,
     scoped_refptr<gl::GLShareGroup> share_group,
     const GpuFeatureInfo& gpu_feature_info)
     : gpu::InProcessCommandBuffer::Service(GpuPreferences(),
diff --git a/gpu/ipc/gpu_in_process_thread_service.h b/gpu/ipc/gpu_in_process_thread_service.h
index 464e713..4cdd9a96 100644
--- a/gpu/ipc/gpu_in_process_thread_service.h
+++ b/gpu/ipc/gpu_in_process_thread_service.h
@@ -23,7 +23,7 @@
   GpuInProcessThreadService(
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
       gpu::SyncPointManager* sync_point_manager,
-      gpu::gles2::MailboxManager* mailbox_manager,
+      gpu::MailboxManager* mailbox_manager,
       scoped_refptr<gl::GLShareGroup> share_group,
       const GpuFeatureInfo& gpu_feature_info);
 
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc
index 3cc7d15..2296182 100644
--- a/gpu/ipc/in_process_command_buffer.cc
+++ b/gpu/ipc/in_process_command_buffer.cc
@@ -37,7 +37,7 @@
 #include "gpu/command_buffer/service/gpu_preferences.h"
 #include "gpu/command_buffer/service/gpu_tracer.h"
 #include "gpu/command_buffer/service/image_factory.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager_factory.h"
 #include "gpu/command_buffer/service/memory_program_cache.h"
 #include "gpu/command_buffer/service/memory_tracking.h"
 #include "gpu/command_buffer/service/query_manager.h"
@@ -139,7 +139,7 @@
 
 InProcessCommandBuffer::Service::Service(
     const GpuPreferences& gpu_preferences,
-    gles2::MailboxManager* mailbox_manager,
+    MailboxManager* mailbox_manager,
     scoped_refptr<gl::GLShareGroup> share_group,
     const GpuFeatureInfo& gpu_feature_info)
     : gpu_preferences_(gpu_preferences),
@@ -149,7 +149,7 @@
       shader_translator_cache_(gpu_preferences_) {
   if (!mailbox_manager_) {
     // TODO(piman): have embedders own the mailbox manager.
-    owned_mailbox_manager_ = gles2::MailboxManager::Create(gpu_preferences_);
+    owned_mailbox_manager_ = gles2::CreateMailboxManager(gpu_preferences_);
     mailbox_manager_ = owned_mailbox_manager_.get();
   }
 }
@@ -866,7 +866,7 @@
 void InProcessCommandBuffer::OnFenceSyncRelease(uint64_t release) {
   SyncToken sync_token(GetNamespaceID(), GetCommandBufferID(), release);
 
-  gles2::MailboxManager* mailbox_manager =
+  MailboxManager* mailbox_manager =
       decoder_->GetContextGroup()->mailbox_manager();
   mailbox_manager->PushTextureUpdates(sync_token);
 
@@ -878,7 +878,7 @@
   SyncPointManager* sync_point_manager = service_->sync_point_manager();
   DCHECK(sync_point_manager);
 
-  gles2::MailboxManager* mailbox_manager =
+  MailboxManager* mailbox_manager =
       decoder_->GetContextGroup()->mailbox_manager();
   DCHECK(mailbox_manager);
 
@@ -911,7 +911,7 @@
 void InProcessCommandBuffer::OnWaitSyncTokenCompleted(
     const SyncToken& sync_token) {
   DCHECK(waiting_for_sync_point_);
-  gles2::MailboxManager* mailbox_manager =
+  MailboxManager* mailbox_manager =
       decoder_->GetContextGroup()->mailbox_manager();
   mailbox_manager->PullTextureUpdates(sync_token);
   waiting_for_sync_point_ = false;
diff --git a/gpu/ipc/in_process_command_buffer.h b/gpu/ipc/in_process_command_buffer.h
index 6294d9a..7f181e8d 100644
--- a/gpu/ipc/in_process_command_buffer.h
+++ b/gpu/ipc/in_process_command_buffer.h
@@ -59,6 +59,7 @@
 namespace gpu {
 
 struct ContextCreationAttribs;
+class MailboxManager;
 class ServiceDiscardableManager;
 class SyncPointClientState;
 class SyncPointOrderData;
@@ -67,7 +68,6 @@
 
 namespace gles2 {
 class FramebufferCompletenessCache;
-class MailboxManager;
 class Outputter;
 class ProgramCache;
 class ShaderTranslatorCache;
@@ -218,7 +218,7 @@
   class Service {
    public:
     Service(const GpuPreferences& gpu_preferences,
-            gles2::MailboxManager* mailbox_manager,
+            MailboxManager* mailbox_manager,
             scoped_refptr<gl::GLShareGroup> share_group,
             const GpuFeatureInfo& gpu_feature_info);
 
@@ -241,7 +241,7 @@
     const GpuPreferences& gpu_preferences();
     const GpuFeatureInfo& gpu_feature_info() { return gpu_feature_info_; }
     scoped_refptr<gl::GLShareGroup> share_group();
-    gles2::MailboxManager* mailbox_manager() { return mailbox_manager_; }
+    MailboxManager* mailbox_manager() { return mailbox_manager_; }
     gles2::Outputter* outputter();
     gles2::ProgramCache* program_cache();
     gles2::ImageManager* image_manager() { return &image_manager_; }
@@ -259,8 +259,8 @@
    protected:
     const GpuPreferences gpu_preferences_;
     const GpuFeatureInfo gpu_feature_info_;
-    std::unique_ptr<gles2::MailboxManager> owned_mailbox_manager_;
-    gles2::MailboxManager* mailbox_manager_ = nullptr;
+    std::unique_ptr<MailboxManager> owned_mailbox_manager_;
+    MailboxManager* mailbox_manager_ = nullptr;
     std::unique_ptr<gles2::Outputter> outputter_;
     scoped_refptr<gl::GLShareGroup> share_group_;
     std::unique_ptr<gles2::ProgramCache> program_cache_;
diff --git a/gpu/ipc/service/BUILD.gn b/gpu/ipc/service/BUILD.gn
index 0bef733..24aac683 100644
--- a/gpu/ipc/service/BUILD.gn
+++ b/gpu/ipc/service/BUILD.gn
@@ -78,7 +78,6 @@
     "//gpu/command_buffer/service:gles2_sources",
     "//gpu/command_buffer/service:service_sources",
     "//gpu/config:config_sources",
-    "//gpu/config:crash_keys",
     "//gpu/ipc/common:ipc_common_sources",
   ]
   libs = []
diff --git a/gpu/ipc/service/command_buffer_stub.cc b/gpu/ipc/service/command_buffer_stub.cc
index b61c968b..79b0b0e 100644
--- a/gpu/ipc/service/command_buffer_stub.cc
+++ b/gpu/ipc/service/command_buffer_stub.cc
@@ -764,7 +764,7 @@
 void CommandBufferStub::OnFenceSyncRelease(uint64_t release) {
   SyncToken sync_token(CommandBufferNamespace::GPU_IO, command_buffer_id_,
                        release);
-  gles2::MailboxManager* mailbox_manager = context_group_->mailbox_manager();
+  MailboxManager* mailbox_manager = context_group_->mailbox_manager();
   if (mailbox_manager->UsesSync() && MakeCurrent())
     mailbox_manager->PushTextureUpdates(sync_token);
 
@@ -804,7 +804,7 @@
     return true;
   }
 
-  gles2::MailboxManager* mailbox_manager = context_group_->mailbox_manager();
+  MailboxManager* mailbox_manager = context_group_->mailbox_manager();
   if (mailbox_manager->UsesSync() && MakeCurrent())
     mailbox_manager->PullTextureUpdates(sync_token);
   return false;
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc
index d7306d2..7471b0e1 100644
--- a/gpu/ipc/service/gpu_channel_manager.cc
+++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -20,7 +20,7 @@
 #include "gpu/command_buffer/common/sync_token.h"
 #include "gpu/command_buffer/service/feature_info.h"
 #include "gpu/command_buffer/service/gpu_tracer.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager_factory.h"
 #include "gpu/command_buffer/service/memory_program_cache.h"
 #include "gpu/command_buffer/service/passthrough_program_cache.h"
 #include "gpu/command_buffer/service/scheduler.h"
@@ -66,7 +66,7 @@
       delegate_(delegate),
       watchdog_(watchdog),
       share_group_(new gl::GLShareGroup()),
-      mailbox_manager_(gles2::MailboxManager::Create(gpu_preferences)),
+      mailbox_manager_(gles2::CreateMailboxManager(gpu_preferences)),
       gpu_memory_manager_(this),
       scheduler_(scheduler),
       sync_point_manager_(sync_point_manager),
diff --git a/gpu/ipc/service/gpu_channel_manager.h b/gpu/ipc/service/gpu_channel_manager.h
index d82ecd8..432910b03 100644
--- a/gpu/ipc/service/gpu_channel_manager.h
+++ b/gpu/ipc/service/gpu_channel_manager.h
@@ -48,11 +48,11 @@
 class GpuChannelManagerDelegate;
 class GpuMemoryBufferFactory;
 class GpuWatchdogThread;
+class MailboxManager;
 class Scheduler;
 class SyncPointManager;
 
 namespace gles2 {
-class MailboxManager;
 class Outputter;
 class ProgramCache;
 }  // namespace gles2
@@ -137,7 +137,7 @@
 
   bool is_exiting_for_lost_context() { return exiting_for_lost_context_; }
 
-  gles2::MailboxManager* mailbox_manager() { return mailbox_manager_.get(); }
+  MailboxManager* mailbox_manager() { return mailbox_manager_.get(); }
 
   gl::GLShareGroup* share_group() const { return share_group_.get(); }
 
@@ -174,7 +174,7 @@
 
   scoped_refptr<gl::GLShareGroup> share_group_;
 
-  std::unique_ptr<gles2::MailboxManager> mailbox_manager_;
+  std::unique_ptr<MailboxManager> mailbox_manager_;
   std::unique_ptr<gles2::Outputter> outputter_;
   GpuMemoryManager gpu_memory_manager_;
   Scheduler* scheduler_;
diff --git a/headless/lib/browser/headless_quota_permission_context.cc b/headless/lib/browser/headless_quota_permission_context.cc
index 185946d..89b0266 100644
--- a/headless/lib/browser/headless_quota_permission_context.cc
+++ b/headless/lib/browser/headless_quota_permission_context.cc
@@ -4,7 +4,7 @@
 
 #include "headless/lib/browser/headless_quota_permission_context.h"
 
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace headless {
 
@@ -14,7 +14,7 @@
     const content::StorageQuotaParams& params,
     int render_process_id,
     const PermissionCallback& callback) {
-  if (params.storage_type != blink::StorageType::kPersistent) {
+  if (params.storage_type != blink::mojom::StorageType::kPersistent) {
     // For now we only support requesting quota with this interface
     // for Persistent storage type.
     callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
diff --git a/headless/test/headless_render_browsertest.cc b/headless/test/headless_render_browsertest.cc
index f861ec3..a045db96 100644
--- a/headless/test/headless_render_browsertest.cc
+++ b/headless/test/headless_render_browsertest.cc
@@ -1174,4 +1174,69 @@
 };
 HEADLESS_RENDER_BROWSERTEST(CookieUpdatedFromJs);
 
+class InCrossOriginObject : public HeadlessRenderTest {
+ private:
+  GURL GetPageUrl(HeadlessDevToolsClient* client) override {
+    GetProtocolHandler()->InsertResponse("http://foo.com/", HttpOk(R"|(
+ <html><body>
+  <iframe id='myframe' src='http://bar.com/'></iframe>
+   <script>
+    window.onload = function() {
+      try {
+        var a = 0 in document.getElementById('myframe').contentWindow;
+      } catch (e) {
+        console.log(e.message);
+      }
+    };
+ </script><p>Pass</p></body></html>)|"));
+    GetProtocolHandler()->InsertResponse("http://bar.com/",
+                                         HttpOk(R"|(<html></html>)|"));
+    return GURL("http://foo.com/");
+  }
+
+  void VerifyDom(GetSnapshotResult* dom_snapshot) override {
+    EXPECT_THAT(NextNode(dom_snapshot, FindTag(dom_snapshot, "P")),
+                NodeValue("Pass"));
+    EXPECT_THAT(console_log_,
+                ElementsAre(StartsWith("L Blocked a frame with origin "
+                                       "\"http://foo.com\" from accessing")));
+  }
+};
+HEADLESS_RENDER_BROWSERTEST(InCrossOriginObject);
+
+class ContentSecurityPolicy : public HeadlessRenderTest {
+ private:
+  GURL GetPageUrl(HeadlessDevToolsClient* client) override {
+    // Only first 3 scripts of 4 on the page are whitelisted for execution.
+    // Therefore only 3 linest in the log are expected.
+    GetProtocolHandler()->InsertResponse(
+        "http://example.com/",
+        {"HTTP/1.1 200 OK\r\n"
+         "Content-Type: text/html\r\n"
+         "Content-Security-Policy: script-src"
+         " 'sha256-INSsCHXoo4K3+jDRF8FSvl13GP22I9vcqcJjkq35Y20='"
+         " 'sha384-77lSn5Q6V979pJ8W2TXc6Lrj98LughR0ofkFwa+"
+         "qOEtlcofEdLPkOPtpJF8QQMev'"
+         " 'sha512-"
+         "2cS3KZwfnxFo6lvBvAl113f5N3QCRgtRJBbtFaQHKOhk36sdYYKFvhCqGTvbN7pBKUfsj"
+         "fCQgFF4MSbCQuvT8A=='\r\n\r\n"
+         "<!DOCTYPE html>\n"
+         "<script>console.log('pass256');</script>\n"
+         "<script>console.log('pass384');</script>\n"
+         "<script>console.log('pass512');</script>\n"
+         "<script>console.log('fail');</script>"});
+    // For example, regenerate sha256 hash with:
+    // echo -n "console.log('pass256');" \
+    //   | openssl sha256 -binary \
+    //   | openssl base64
+    return GURL("http://example.com/");
+  }
+
+  void VerifyDom(GetSnapshotResult* dom_snapshot) override {
+    EXPECT_THAT(console_log_,
+                ElementsAre("L pass256", "L pass384", "L pass512"));
+  }
+};
+HEADLESS_RENDER_BROWSERTEST(ContentSecurityPolicy);
+
 }  // namespace headless
diff --git a/ios/build/bots/chromium.mac/ios-simulator-xcode-clang.json b/ios/build/bots/chromium.mac/ios-simulator-xcode-clang.json
index cef7504..e9bb28f5 100644
--- a/ios/build/bots/chromium.mac/ios-simulator-xcode-clang.json
+++ b/ios/build/bots/chromium.mac/ios-simulator-xcode-clang.json
@@ -16,6 +16,9 @@
     "use_goma=true",
     "use_xcode_clang=true"
   ],
+  "env": {
+    "FORCE_MAC_TOOLCHAIN": ""
+  },
   "additional_compile_targets": [
     "all"
   ],
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn
index abc845d..8314f041 100644
--- a/ios/chrome/app/BUILD.gn
+++ b/ios/chrome/app/BUILD.gn
@@ -203,6 +203,7 @@
     "//ios/chrome/browser/ui/tab_switcher",
     "//ios/chrome/browser/ui/tabs",
     "//ios/chrome/browser/ui/toolbar/clean:toolbar_ui",
+    "//ios/chrome/browser/ui/toolbar/public",
     "//ios/chrome/browser/ui/util",
     "//ios/chrome/browser/ui/webui:webui_internal",
     "//ios/chrome/browser/upgrade",
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index fc3d96a..9dacd33a 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -132,7 +132,7 @@
 #import "ios/chrome/browser/ui/signin_interaction/signin_interaction_coordinator.h"
 #import "ios/chrome/browser/ui/stack_view/stack_view_controller.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.h"
-#import "ios/chrome/browser/ui/toolbar/clean/omnibox_focuser.h"
+#import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/util/top_view_controller.h"
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index 8dbd00e9..173c434d 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -33,7 +33,7 @@
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/payments/core/features.h"
 #include "components/search_provider_logos/switches.h"
-#include "components/security_state/core/switches.h"
+#include "components/security_state/core/features.h"
 #include "components/signin/core/browser/signin_switches.h"
 #include "components/strings/grit/components_strings.h"
 #include "ios/chrome/browser/bookmarks/bookmark_new_generation_features.h"
@@ -66,11 +66,36 @@
 using flags_ui::FeatureEntry;
 
 namespace {
-const FeatureEntry::Choice kMarkHttpAsChoices[] = {
-    {flags_ui::kGenericExperimentChoiceDefault, "", ""},
-    {flag_descriptions::kMarkHttpAsDangerous,
-     security_state::switches::kMarkHttpAs,
-     security_state::switches::kMarkHttpAsDangerous}};
+
+const FeatureEntry::FeatureParam kMarkHttpAsDangerous[] = {
+    {security_state::features::kMarkHttpAsFeatureParameterName,
+     security_state::features::kMarkHttpAsParameterDangerous}};
+const FeatureEntry::FeatureParam kMarkHttpAsWarning[] = {
+    {security_state::features::kMarkHttpAsFeatureParameterName,
+     security_state::features::kMarkHttpAsParameterWarning}};
+const FeatureEntry::FeatureParam kMarkHttpAsWarningAndDangerousOnFormEdits[] = {
+    {security_state::features::kMarkHttpAsFeatureParameterName,
+     security_state::features::
+         kMarkHttpAsParameterWarningAndDangerousOnFormEdits}};
+const FeatureEntry::FeatureParam
+    kMarkHttpAsWarningAndDangerousOnPasswordsAndCreditCards[] = {
+        {security_state::features::kMarkHttpAsFeatureParameterName,
+         security_state::features::
+             kMarkHttpAsParameterWarningAndDangerousOnPasswordsAndCreditCards}};
+
+const FeatureEntry::FeatureVariation kMarkHttpAsFeatureVariations[] = {
+    {"(mark as actively dangerous)", kMarkHttpAsDangerous,
+     arraysize(kMarkHttpAsDangerous), nullptr},
+    {"(mark with a Not Secure warning)", kMarkHttpAsWarning,
+     arraysize(kMarkHttpAsWarning), nullptr},
+    {"(mark with a Not Secure warning and dangerous on form edits)",
+     kMarkHttpAsWarningAndDangerousOnFormEdits,
+     arraysize(kMarkHttpAsWarningAndDangerousOnFormEdits), nullptr},
+    {"(mark with a Not Secure warning and dangerous on passwords and credit "
+     "card fields)",
+     kMarkHttpAsWarningAndDangerousOnPasswordsAndCreditCards,
+     arraysize(kMarkHttpAsWarningAndDangerousOnPasswordsAndCreditCards),
+     nullptr}};
 
 const FeatureEntry::Choice kUseDdljsonApiChoices[] = {
     {flags_ui::kGenericExperimentChoiceDefault, "", ""},
@@ -110,9 +135,12 @@
 //
 // When adding a new choice, add it to the end of the list.
 const flags_ui::FeatureEntry kFeatureEntries[] = {
-    {"mark-non-secure-as", flag_descriptions::kMarkHttpAsName,
+    {"enable-mark-http-as", flag_descriptions::kMarkHttpAsName,
      flag_descriptions::kMarkHttpAsDescription, flags_ui::kOsIos,
-     MULTI_VALUE_TYPE(kMarkHttpAsChoices)},
+     FEATURE_WITH_PARAMS_VALUE_TYPE(
+         security_state::features::kMarkHttpAsFeature,
+         kMarkHttpAsFeatureVariations,
+         "MarkHttpAs")},
     {"web-payments", flag_descriptions::kWebPaymentsName,
      flag_descriptions::kWebPaymentsDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(payments::features::kWebPayments)},
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn
index 0bcc21c..8836221 100644
--- a/ios/chrome/browser/autofill/BUILD.gn
+++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -131,6 +131,7 @@
     "//ios/chrome/browser/ui/autofill",
     "//ios/chrome/browser/ui/settings:test_support",
     "//ios/chrome/browser/web:test_support",
+    "//ios/chrome/browser/web:web_internal",
     "//ios/chrome/test/base",
     "//ios/web",
     "//ios/web/public/test",
diff --git a/ios/chrome/browser/autofill/autofill_controller_js_unittest.mm b/ios/chrome/browser/autofill/autofill_controller_js_unittest.mm
index 1127dbe2..4b3bd63 100644
--- a/ios/chrome/browser/autofill/autofill_controller_js_unittest.mm
+++ b/ios/chrome/browser/autofill/autofill_controller_js_unittest.mm
@@ -8,6 +8,7 @@
 #include "base/ios/ios_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/autofill/core/common/autofill_constants.h"
+#include "ios/chrome/browser/web/chrome_web_client.h"
 #include "ios/chrome/browser/web/chrome_web_test.h"
 #import "ios/web/public/test/web_js_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -775,7 +776,7 @@
 class AutofillControllerJsTest : public web::WebJsTest<ChromeWebTest> {
  public:
   AutofillControllerJsTest()
-      : web::WebJsTest<ChromeWebTest>(@[ @"autofill_controller" ]) {}
+      : web::WebJsTest<ChromeWebTest>(std::make_unique<ChromeWebClient>()) {}
 
  protected:
   // Helper method that EXPECTs |javascript| evaluation on page
@@ -858,7 +859,7 @@
       {"submit", 0, -1},
   };
 
-  LoadHtmlAndInject(kHTMLForTestingElements);
+  LoadHtml(kHTMLForTestingElements);
   ExecuteBooleanJavaScriptOnElementsAndCheck(
       javascript,
       GetElementsByNameJavaScripts(elementsByName, arraysize(elementsByName)),
@@ -891,7 +892,7 @@
 }
 
 TEST_F(AutofillControllerJsTest, CombineAndCollapseWhitespace) {
-  LoadHtmlAndInject(@"<html><body></body></html>");
+  LoadHtml(@"<html><body></body></html>");
 
   EXPECT_NSEQ(@"foobar", ExecuteJavaScriptWithFormat(
                              @"__gCrWeb.autofill.combineAndCollapseWhitespace('"
@@ -926,7 +927,7 @@
     NSArray* test_data,
     NSString* tag_name) {
   NSString* html_fragment = [test_data objectAtIndex:0U];
-  LoadHtmlAndInject(html_fragment);
+  LoadHtml(html_fragment);
 
   for (NSUInteger i = 1; i < [test_data count]; ++i) {
     NSString* get_element_javascripts = [NSString
@@ -1079,7 +1080,7 @@
   ElementByName testing_elements[] = {
       {"state", 0, -1}, {"course", 0, -1}, {"cars", 0, -1}};
 
-  LoadHtmlAndInject(kHTMLForTestingElements);
+  LoadHtml(kHTMLForTestingElements);
   ExecuteJavaScriptOnElementsAndCheck(
       @"var field = {};"
        "__gCrWeb.autofill.getOptionStringsFromElement(%@, field);"
@@ -1106,7 +1107,7 @@
 }
 
 TEST_F(AutofillControllerJsTest, FillFormField) {
-  LoadHtmlAndInject(kHTMLForTestingElements);
+  LoadHtml(kHTMLForTestingElements);
 
   // Test text and select elements of which the value should be changed.
   const ElementByName elements[] = {
@@ -1219,7 +1220,7 @@
 }
 
 TEST_F(AutofillControllerJsTest, ExtractAutofillableElements) {
-  LoadHtmlAndInject(kHTMLForTestingElements);
+  LoadHtml(kHTMLForTestingElements);
   ElementByName expected_elements[] = {
       {"firstname", 0, -1}, {"lastname", 0, -1},
       {"email", 0, -1},     {"phone", 0, -1},
@@ -1246,7 +1247,7 @@
 void AutofillControllerJsTest::TestWebFormControlElementToFormField(
     NSArray* test_data,
     NSString* tag_name) {
-  LoadHtmlAndInject([test_data firstObject]);
+  LoadHtml([test_data firstObject]);
 
   for (NSUInteger i = 0; i < arraysize(kFormExtractMasks); ++i) {
     ExtractMask extract_mask = kFormExtractMasks[i];
@@ -1349,7 +1350,7 @@
                                     objectAtIndex:0U]];
   }
   form_html_fragment = [form_html_fragment stringByAppendingString:@"</form>"];
-  LoadHtmlAndInject(form_html_fragment);
+  LoadHtml(form_html_fragment);
 
   NSString* parameter = @"document.getElementsByTagName('form')[0]";
   for (NSUInteger extract_index = 0;
@@ -1413,7 +1414,7 @@
   }
   html_fragment = [html_fragment stringByAppendingFormat:@"</FORM>"];
 
-  LoadHtmlAndInject(html_fragment);
+  LoadHtml(html_fragment);
   TestWebFormElementToFormDataForOneForm(
       @"document.getElementsByTagName('form')[0]", 1, @"false", @"true");
 }
@@ -1423,7 +1424,7 @@
       @"<FORM name='Test' action='http://c.com' method='post'>";
   html_fragment = [html_fragment stringByAppendingFormat:@"</FORM>"];
 
-  LoadHtmlAndInject(html_fragment);
+  LoadHtml(html_fragment);
   TestWebFormElementToFormDataForOneForm(
       @"document.getElementsByTagName('form')[0]", 1, @"false", @"true");
 }
@@ -1432,7 +1433,7 @@
     NSString* html,
     BOOL is_origin_window_location,
     NSArray* expected_items) {
-  LoadHtmlAndInject(html);
+  LoadHtml(html);
   // Generates verifying javascripts.
   NSMutableArray* verifying_javascripts = [NSMutableArray array];
   for (NSUInteger i = 0U; i < [expected_items count]; ++i) {
@@ -1531,7 +1532,7 @@
                     "3 <input type='text' name='name3' form='testform'></input>"
                     "4 <input type='text' name='name4' form='testform'></input>"
                     "</body></html>";
-  LoadHtmlAndInject(html);
+  LoadHtml(html);
 
   NSString* verifying_javascript = @"forms[0]['fields'][0]['name']==='name1' &&"
                                    @"forms[0]['fields'][0]['label']==='1' &&"
@@ -1568,7 +1569,7 @@
   html = [html stringByAppendingFormat:@"</form>"];
   html = [html stringByAppendingFormat:@"</body></html>"];
 
-  LoadHtmlAndInject(html);
+  LoadHtml(html);
 
   NSDictionary* expected = @{
     @"name" : @"TestForm",
@@ -1703,7 +1704,7 @@
 }
 
 TEST_F(AutofillControllerJsTest, FillActiveFormField) {
-  LoadHtmlAndInject(kHTMLForTestingElements);
+  LoadHtml(kHTMLForTestingElements);
 
   NSString* newValue = @"new value";
   EXPECT_NSEQ(newValue,
@@ -1766,7 +1767,7 @@
   ];
 
   for (NSDictionary* testCase in testCases) {
-    LoadHtmlAndInject(testCase[@"html"]);
+    LoadHtml(testCase[@"html"]);
 
     NSString* result =
         ExecuteJavaScriptWithFormat(@"__gCrWeb.autofill.extractForms(%zu)",
diff --git a/ios/chrome/browser/autofill/autofill_controller_unittest.mm b/ios/chrome/browser/autofill/autofill_controller_unittest.mm
index 8b5a767..9dbab74 100644
--- a/ios/chrome/browser/autofill/autofill_controller_unittest.mm
+++ b/ios/chrome/browser/autofill/autofill_controller_unittest.mm
@@ -12,7 +12,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/task_scheduler/task_scheduler.h"
 #include "base/test/histogram_tester.h"
-#import "base/test/ios/wait_util.h"
 #include "components/autofill/core/browser/autofill_manager.h"
 #include "components/autofill/core/browser/autofill_metrics.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
@@ -30,6 +29,7 @@
 #include "ios/chrome/browser/infobars/infobar_manager_impl.h"
 #import "ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h"
 #include "ios/chrome/browser/ui/settings/personal_data_manager_data_changed_observer.h"
+#include "ios/chrome/browser/web/chrome_web_client.h"
 #import "ios/chrome/browser/web/chrome_web_test.h"
 #include "ios/chrome/browser/web_data_service_factory.h"
 #import "ios/web/public/navigation_item.h"
@@ -123,9 +123,6 @@
 NSString* const kCreditCardAutofocusFormHtml =
     @"<form><input type=\"text\" autofocus autocomplete=\"cc-number\"></form>";
 
-// Experiment preference key.
-NSString* const kAutofillVisible = @"AutofillVisible";
-
 // FAIL if a field with the supplied |name| and |fieldType| is not present on
 // the |form|.
 void CheckField(const FormStructure& form,
@@ -157,12 +154,14 @@
 // Text fixture to test autofill.
 class AutofillControllerTest : public ChromeWebTest {
  public:
-  AutofillControllerTest() = default;
+  AutofillControllerTest()
+      : ChromeWebTest(std::make_unique<ChromeWebClient>()) {}
   ~AutofillControllerTest() override {}
 
  protected:
   void SetUp() override;
   void TearDown() override;
+
   void SetUpForSuggestions(NSString* data);
 
   // Adds key value data to the Personal Data Manager and loads test page.
@@ -207,9 +206,6 @@
   // WebDataService; this is not initialized on a TestChromeBrowserState by
   // default.
   chrome_browser_state_->CreateWebDataService();
-  // Enable autofill experiment.
-  NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
-  [defaults setBool:YES forKey:kAutofillVisible];
 
   AutofillAgent* agent = [[AutofillAgent alloc]
       initWithPrefService:chrome_browser_state_->GetPrefs()
@@ -571,7 +567,7 @@
   ExecuteJavaScript(@"submit.click()");
   infobars::InfoBarManager* infobar_manager =
       InfoBarManagerImpl::FromWebState(web_state());
-  base::test::ios::WaitUntilCondition(^bool() {
+  WaitForCondition(^bool() {
     return infobar_manager->infobar_count();
   });
   ExpectMetric("Autofill.CreditCardInfoBar.Local",
diff --git a/ios/chrome/browser/autofill/form_structure_browsertest.mm b/ios/chrome/browser/autofill/form_structure_browsertest.mm
index 57378f40..e2cb06c 100644
--- a/ios/chrome/browser/autofill/form_structure_browsertest.mm
+++ b/ios/chrome/browser/autofill/form_structure_browsertest.mm
@@ -24,6 +24,7 @@
 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
 #include "ios/chrome/browser/chrome_paths.h"
 #include "ios/chrome/browser/infobars/infobar_manager_impl.h"
+#include "ios/chrome/browser/web/chrome_web_client.h"
 #import "ios/chrome/browser/web/chrome_web_test.h"
 #import "ios/web/public/web_state/web_state.h"
 
@@ -122,7 +123,8 @@
 };
 
 FormStructureBrowserTest::FormStructureBrowserTest()
-    : DataDrivenTest(GetTestDataDir()) {}
+    : ChromeWebTest(std::make_unique<ChromeWebClient>()),
+      DataDrivenTest(GetTestDataDir()) {}
 
 void FormStructureBrowserTest::SetUp() {
   ChromeWebTest::SetUp();
diff --git a/ios/chrome/browser/autofill/js_autofill_manager_unittest.mm b/ios/chrome/browser/autofill/js_autofill_manager_unittest.mm
index ea047b9..30a31f2 100644
--- a/ios/chrome/browser/autofill/js_autofill_manager_unittest.mm
+++ b/ios/chrome/browser/autofill/js_autofill_manager_unittest.mm
@@ -9,6 +9,8 @@
 #include "base/ios/ios_util.h"
 #import "base/test/ios/wait_util.h"
 #include "components/autofill/core/common/autofill_constants.h"
+#import "components/autofill/ios/browser/js_autofill_manager.h"
+#include "ios/chrome/browser/web/chrome_web_client.h"
 #import "ios/chrome/browser/web/chrome_web_test.h"
 #import "ios/web/public/test/js_test_util.h"
 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
@@ -31,13 +33,14 @@
 // Text fixture to test JsAutofillManager.
 class JsAutofillManagerTest : public ChromeWebTest {
  protected:
+  JsAutofillManagerTest()
+      : ChromeWebTest(std::make_unique<ChromeWebClient>()) {}
+
   // Loads the given HTML and initializes the Autofill JS scripts.
   void LoadHtml(NSString* html) {
     ChromeWebTest::LoadHtml(html);
-    CRWJSInjectionManager* manager = [web_state()->GetJSInjectionReceiver()
-        instanceOfClass:[JsAutofillManager class]];
-    manager_ = static_cast<JsAutofillManager*>(manager);
-    [manager_ inject];
+    manager_ = [[JsAutofillManager alloc]
+        initWithReceiver:web_state()->GetJSInjectionReceiver()];
   }
   // Testable autofill manager.
   JsAutofillManager* manager_;
@@ -46,7 +49,7 @@
 // Tests that |hasBeenInjected| returns YES after |inject| call.
 TEST_F(JsAutofillManagerTest, InitAndInject) {
   LoadHtml(@"<html></html>");
-  EXPECT_TRUE([manager_ hasBeenInjected]);
+  EXPECT_NSEQ(@"object", ExecuteJavaScript(@"typeof __gCrWeb.autofill"));
 }
 
 // Tests forms extraction method
@@ -128,7 +131,7 @@
   NSString* get_element_javascript = @"document.getElementsByName('email')[0]";
   NSString* focus_element_javascript =
       [NSString stringWithFormat:@"%@.focus()", get_element_javascript];
-  [manager_ executeJavaScript:focus_element_javascript completionHandler:nil];
+  ExecuteJavaScript(focus_element_javascript);
   [manager_
       fillActiveFormField:@"{\"name\":\"email\",\"value\":\"newemail@com\"}"
         completionHandler:^{
@@ -136,8 +139,7 @@
 
   NSString* element_value_javascript =
       [NSString stringWithFormat:@"%@.value", get_element_javascript];
-  EXPECT_NSEQ(@"newemail@com",
-              web::ExecuteJavaScript(manager_, element_value_javascript));
+  EXPECT_NSEQ(@"newemail@com", ExecuteJavaScript(element_value_javascript));
 }
 
 }  // namespace
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
index 788a47d37..52b4b127 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -64,7 +64,6 @@
 
 const char kMarkHttpAsName[] = "Mark non-secure origins as non-secure";
 const char kMarkHttpAsDescription[] = "Change the UI treatment for HTTP pages";
-const char kMarkHttpAsDangerous[] = "Always mark HTTP as actively dangerous";
 
 const char kNewFullscreenName[] = "Enable the new FullscreenController.";
 const char kNewFullscreenDescription[] =
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h
index 4b868893..bf8aaad 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -58,7 +58,6 @@
 // display of omnibox warnings about non-secure pages.
 extern const char kMarkHttpAsName[];
 extern const char kMarkHttpAsDescription[];
-extern const char kMarkHttpAsDangerous[];
 
 // Title and description for the flag to enable the new fullscreen
 // implementation.
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn
index 06451dc6..b7a6b86 100644
--- a/ios/chrome/browser/ui/BUILD.gn
+++ b/ios/chrome/browser/ui/BUILD.gn
@@ -353,6 +353,7 @@
     "//ios/chrome/browser/ui/toolbar:toolbar_ui",
     "//ios/chrome/browser/ui/toolbar:toolbar_ui_broadcasting_util",
     "//ios/chrome/browser/ui/toolbar/clean:toolbar_ui",
+    "//ios/chrome/browser/ui/toolbar/public",
     "//ios/chrome/browser/ui/toolbar/public:toolbar_base_feature",
     "//ios/chrome/browser/ui/tools_menu",
     "//ios/chrome/browser/ui/tools_menu:configuration",
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index ecdbe3a..faccf726 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -192,6 +192,7 @@
 #import "ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h"
 #include "ios/chrome/browser/ui/toolbar/legacy_toolbar_coordinator.h"
 #import "ios/chrome/browser/ui/toolbar/legacy_toolbar_ui_updater.h"
+#import "ios/chrome/browser/ui/toolbar/public/primary_toolbar_coordinator.h"
 #import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.h"
 #include "ios/chrome/browser/ui/toolbar/toolbar_model_delegate_ios.h"
 #include "ios/chrome/browser/ui/toolbar/toolbar_model_ios.h"
@@ -681,8 +682,18 @@
 @property(nonatomic, strong)
     BubbleViewControllerPresenter* incognitoTabTipBubblePresenter;
 
+// Primary toolbar.
+@property(nonatomic, readonly) id<PrimaryToolbarCoordinator>
+    primaryToolbarCoordinator;
+// TODO(crbug.com/788705): Removes this property and associated calls.
+// Returns the LegacyToolbarCoordinator. This property is here to separate
+// methods which will be removed during cleanup to other methods. Uses this
+// property only for deprecated methods.
+@property(nonatomic, readonly)
+    LegacyToolbarCoordinator* legacyToolbarCoordinator;
+
 // Vertical offset for fullscreen toolbar.
-@property(nonatomic, strong) NSLayoutConstraint* toolbarOffsetConstraint;
+@property(nonatomic, strong) NSLayoutConstraint* primaryToolbarOffsetConstraint;
 // Y-dimension offset for placement of the header.
 @property(nonatomic, readonly) CGFloat headerOffset;
 // Height of the header view for the tab model's current tab.
@@ -919,7 +930,7 @@
 @synthesize tabStripView = _tabStripView;
 @synthesize tabTipBubblePresenter = _tabTipBubblePresenter;
 @synthesize incognitoTabTipBubblePresenter = _incognitoTabTipBubblePresenter;
-@synthesize toolbarOffsetConstraint = _toolbarOffsetConstraint;
+@synthesize primaryToolbarOffsetConstraint = _primaryToolbarOffsetConstraint;
 @synthesize imageSaver = _imageSaver;
 // DialogPresenterDelegate property
 @synthesize dialogPresenterDelegateIsPresenting =
@@ -1081,7 +1092,8 @@
         [[SideSwipeController alloc] initWithTabModel:_model
                                          browserState:_browserState];
     [_sideSwipeController setSnapshotDelegate:self];
-    _sideSwipeController.toolbarInteractionHandler = _toolbarCoordinator;
+    _sideSwipeController.toolbarInteractionHandler =
+        self.primaryToolbarCoordinator;
     [_sideSwipeController setSwipeDelegate:self];
     [_sideSwipeController setTabStripDelegate:self.tabStripCoordinator];
   }
@@ -1239,9 +1251,9 @@
     return results;
 
   if (!IsIPadIdiom()) {
-    if (_toolbarCoordinator.toolbarViewController.view) {
+    if (self.primaryToolbarCoordinator.toolbarViewController.view) {
       [results addObject:[HeaderDefinition
-                             definitionWithView:_toolbarCoordinator
+                             definitionWithView:self.primaryToolbarCoordinator
                                                     .toolbarViewController.view
                                 headerBehaviour:Hideable
                                heightAdjustment:0.0
@@ -1254,9 +1266,9 @@
                                              heightAdjustment:0.0
                                                         inset:0.0]];
     }
-    if (_toolbarCoordinator.toolbarViewController.view) {
+    if (self.primaryToolbarCoordinator.toolbarViewController.view) {
       [results addObject:[HeaderDefinition
-                             definitionWithView:_toolbarCoordinator
+                             definitionWithView:self.primaryToolbarCoordinator
                                                     .toolbarViewController.view
                                 headerBehaviour:Hideable
                                heightAdjustment:0.0
@@ -1283,6 +1295,14 @@
   return [self headerHeightForTab:[_model currentTab]];
 }
 
+- (id<PrimaryToolbarCoordinator>)primaryToolbarCoordinator {
+  return _toolbarCoordinator;
+}
+
+- (LegacyToolbarCoordinator*)legacyToolbarCoordinator {
+  return _toolbarCoordinator;
+}
+
 - (web::WebState*)currentWebState {
   return [[_model currentTab] webState];
 }
@@ -1300,7 +1320,7 @@
 }
 
 - (void)shieldWasTapped:(id)sender {
-  [_toolbarCoordinator cancelOmniboxEdit];
+  [self.primaryToolbarCoordinator cancelOmniboxEdit];
 }
 
 - (void)userEnteredTabSwitcher {
@@ -1318,7 +1338,7 @@
   [self setActive:NO];
   [_paymentRequestManager close];
   _paymentRequestManager = nil;
-  [_toolbarCoordinator browserStateDestroyed];
+  [self.legacyToolbarCoordinator browserStateDestroyed];
   [_model browserStateDestroyed];
 
   // Disconnect child coordinators.
@@ -1387,7 +1407,7 @@
   // Present voice search.
   [_voiceSearchBar prepareToPresentVoiceSearch];
   _voiceSearchController->StartRecognition(self, [_model currentTab]);
-  [_toolbarCoordinator cancelOmniboxEdit];
+  [self.primaryToolbarCoordinator cancelOmniboxEdit];
 }
 
 - (void)clearPresentedStateWithCompletion:(ProceduralBlock)completion
@@ -1396,7 +1416,7 @@
   [_bookmarkInteractionController dismissBookmarkModalControllerAnimated:NO];
   [_bookmarkInteractionController dismissSnackbar];
   if (dismissOmnibox) {
-    [_toolbarCoordinator cancelOmniboxEdit];
+    [self.primaryToolbarCoordinator cancelOmniboxEdit];
   }
   [_dialogPresenter cancelAllDialogs];
   [self.dispatcher hidePageInfo];
@@ -1474,7 +1494,6 @@
   _bookmarkModelBridge.reset();
   [_model removeObserver:self];
   [[UpgradeCenter sharedInstance] unregisterClient:self];
-  [_toolbarCoordinator setToolbarDelegate:nil];
   if (_voiceSearchController)
     _voiceSearchController->SetDelegate(nil);
   [_rateThisAppDialog setDelegate:nil];
@@ -1902,23 +1921,23 @@
                           dispatcher:self.dispatcher
                         browserState:_browserState];
 
-  self.sideSwipeController.toolbarInteractionHandler = _toolbarCoordinator;
+  self.sideSwipeController.toolbarInteractionHandler =
+      self.primaryToolbarCoordinator;
 
-  _toolbarCoordinator.tabModel = _model;
   [_toolbarCoordinator
       setToolbarController:
           [_dependencyFactory
               newToolbarControllerWithDelegate:self
                                      urlLoader:self
                                     dispatcher:self.dispatcher]];
-  [_dispatcher startDispatchingToTarget:_toolbarCoordinator
+  [_dispatcher startDispatchingToTarget:self.primaryToolbarCoordinator
                             forProtocol:@protocol(OmniboxFocuser)];
-  [_toolbarCoordinator setTabCount:[_model count]];
+  [self.legacyToolbarCoordinator setTabCount:[_model count]];
   [_toolbarCoordinator start];
   [self updateBroadcastState];
   if (_voiceSearchController)
     _voiceSearchController->SetDelegate(
-        [_toolbarCoordinator voiceSearchDelegate]);
+        [self.primaryToolbarCoordinator voiceSearchDelegate]);
 
   if (IsIPadIdiom()) {
     self.tabStripCoordinator =
@@ -1950,16 +1969,16 @@
     topAnchor = [self view].topAnchor;
   }
 
-  [_toolbarCoordinator adjustToolbarHeight];
+  [self.legacyToolbarCoordinator adjustToolbarHeight];
 
-  self.toolbarOffsetConstraint =
-      [_toolbarCoordinator.toolbarViewController.view.topAnchor
+  self.primaryToolbarOffsetConstraint =
+      [self.primaryToolbarCoordinator.toolbarViewController.view.topAnchor
           constraintEqualToAnchor:topAnchor];
   [NSLayoutConstraint activateConstraints:@[
-    self.toolbarOffsetConstraint,
-    [_toolbarCoordinator.toolbarViewController.view.leadingAnchor
+    self.primaryToolbarOffsetConstraint,
+    [self.primaryToolbarCoordinator.toolbarViewController.view.leadingAnchor
         constraintEqualToAnchor:[self view].leadingAnchor],
-    [_toolbarCoordinator.toolbarViewController.view.trailingAnchor
+    [self.primaryToolbarCoordinator.toolbarViewController.view.trailingAnchor
         constraintEqualToAnchor:[self view].trailingAnchor],
   ]];
   [[self view] layoutIfNeeded];
@@ -1997,7 +2016,7 @@
       [[QRScannerLegacyCoordinator alloc] initWithBaseViewController:self];
   _qrScannerCoordinator.dispatcher = _dispatcher;
   _qrScannerCoordinator.loadProvider =
-      [_toolbarCoordinator QRScannerResultLoader];
+      [self.primaryToolbarCoordinator QRScannerResultLoader];
   _qrScannerCoordinator.presentationProvider = self;
 
   _tabHistoryCoordinator = [[LegacyTabHistoryCoordinator alloc]
@@ -2005,11 +2024,11 @@
                     browserState:_browserState];
   _tabHistoryCoordinator.dispatcher = _dispatcher;
   _tabHistoryCoordinator.positionProvider =
-      [_toolbarCoordinator tabHistoryPositioner];
+      [self.primaryToolbarCoordinator tabHistoryPositioner];
   _tabHistoryCoordinator.tabModel = _model;
   _tabHistoryCoordinator.presentationProvider = self;
   _tabHistoryCoordinator.tabHistoryUIUpdater =
-      [_toolbarCoordinator tabHistoryUIUpdater];
+      [self.primaryToolbarCoordinator tabHistoryUIUpdater];
 
   _sadTabCoordinator = [[SadTabLegacyCoordinator alloc] init];
   _sadTabCoordinator.baseViewController = self;
@@ -2051,25 +2070,25 @@
 - (void)setUpViewLayout:(BOOL)initialLayout {
   DCHECK([self isViewLoaded]);
   CGFloat widthOfView = CGRectGetWidth([self view].bounds);
-  CGFloat minY = self.headerOffset;
 
   // Update the fake toolbar background height.
   CGRect fakeStatusBarFrame = _fakeStatusBarView.frame;
   fakeStatusBarFrame.size.height = StatusBarHeight();
   _fakeStatusBarView.frame = fakeStatusBarFrame;
 
-  if (self.tabStripView) {
-    minY += CGRectGetHeight([self.tabStripView frame]);
-  }
 
   // Position the toolbar next, either at the top of the browser view or
   // directly under the tabstrip.
   if (initialLayout)
     [self addChildViewController:_toolbarCoordinator.toolbarViewController];
-  CGRect toolbarFrame = _toolbarCoordinator.toolbarViewController.view.frame;
-  toolbarFrame.origin = CGPointMake(0, minY);
-  toolbarFrame.size.width = widthOfView;
   if (!IsSafeAreaCompatibleToolbarEnabled()) {
+    CGFloat minY = self.headerOffset;
+    if (self.tabStripView) {
+      minY += CGRectGetHeight([self.tabStripView frame]);
+    }
+    CGRect toolbarFrame = _toolbarCoordinator.toolbarViewController.view.frame;
+    toolbarFrame.origin = CGPointMake(0, minY);
+    toolbarFrame.size.width = widthOfView;
     [_toolbarCoordinator.toolbarViewController.view setFrame:toolbarFrame];
   }
 
@@ -2089,15 +2108,10 @@
     AddNamedGuide(kToolsMenuGuide, self.view);
     AddNamedGuide(kTabSwitcherGuide, self.view);
   }
-  minY += CGRectGetHeight(toolbarFrame);
   if (initialLayout)
     [_toolbarCoordinator.toolbarViewController
         didMoveToParentViewController:self];
 
-  // Account for the toolbar's drop shadow.  The toolbar overlaps with the web
-  // content slightly.
-  minY -= 0.0;
-
   // Adjust the content area to be under the toolbar, for fullscreen or below
   // the toolbar is not fullscreen.
   CGRect contentFrame = [_contentArea frame];
@@ -2137,7 +2151,7 @@
   [self updateToolbar];
 
   if (newSelection)
-    [_toolbarCoordinator selectedTabChanged];
+    [self.legacyToolbarCoordinator selectedTabChanged];
 
   // Notify the Tab that it was displayed.
   [tab wasShown];
@@ -2182,10 +2196,10 @@
   if (![tab navigationManager])
     return;
   [_toolbarCoordinator updateToolbarState];
-  [_toolbarCoordinator setShareButtonEnabled:self.canShowShareMenu];
+  [self.legacyToolbarCoordinator setShareButtonEnabled:self.canShowShareMenu];
 
   if (_insertedTabWasPrerenderedTab && !_toolbarModelIOS->IsLoading())
-    [_toolbarCoordinator showPrerenderingAnimation];
+    [self.primaryToolbarCoordinator showPrerenderingAnimation];
 
   auto* findHelper = FindTabHelper::FromWebState(tab.webState);
   if (findHelper && findHelper->IsFindUIActive()) {
@@ -2202,10 +2216,11 @@
       GURL url = item->GetURL();
       BOOL isNTP = url.GetOrigin() == GURL(kChromeUINewTabURL);
       hideToolbar = isNTP && !_isOffTheRecord &&
-                    ![_toolbarCoordinator isOmniboxFirstResponder] &&
-                    ![_toolbarCoordinator showingOmniboxPopup];
+                    ![self.primaryToolbarCoordinator isOmniboxFirstResponder] &&
+                    ![self.primaryToolbarCoordinator showingOmniboxPopup];
     }
-    [_toolbarCoordinator.toolbarViewController.view setHidden:hideToolbar];
+    [self.primaryToolbarCoordinator.toolbarViewController.view
+        setHidden:hideToolbar];
   }
 }
 
@@ -2272,15 +2287,17 @@
   CGFloat height = self.headerOffset;
   for (HeaderDefinition* header in headers) {
     CGFloat yOrigin = height - headerOffset - header.inset;
+    BOOL isPrimaryToolbar =
+        header.view ==
+        self.primaryToolbarCoordinator.toolbarViewController.view;
     // Make sure the toolbarView's constraints are also updated.  Leaving the
     // -setFrame call to minimize changes in this CL -- otherwise the way
     // toolbar_view manages it's alpha changes would also need to be updated.
     // TODO(crbug.com/778822): This can be cleaned up when the new fullscreen
     // is enabled.
-    if (IsSafeAreaCompatibleToolbarEnabled() &&
-        header.view == _toolbarCoordinator.toolbarViewController.view &&
+    if (IsSafeAreaCompatibleToolbarEnabled() && isPrimaryToolbar &&
         !IsIPadIdiom()) {
-      self.toolbarOffsetConstraint.constant = yOrigin;
+      self.primaryToolbarOffsetConstraint.constant = yOrigin;
     }
     CGRect frame = [header.view frame];
     frame.origin.y = yOrigin;
@@ -2897,7 +2914,7 @@
       _voiceSearchController =
           provider->CreateVoiceSearchController(_browserState);
       _voiceSearchController->SetDelegate(
-          [_toolbarCoordinator voiceSearchDelegate]);
+          [self.primaryToolbarCoordinator voiceSearchDelegate]);
     }
   }
 }
@@ -3613,11 +3630,11 @@
 }
 
 - (UIView*)headerView {
-  return _toolbarCoordinator.toolbarViewController.view;
+  return self.primaryToolbarCoordinator.toolbarViewController.view;
 }
 
 - (UIView*)toolbarSnapshotView {
-  return [_toolbarCoordinator.toolbarViewController.view
+  return [self.primaryToolbarCoordinator.toolbarViewController.view
       snapshotViewAfterScreenUpdates:NO];
 }
 
@@ -3700,7 +3717,7 @@
     NewTabPageController* pageController =
         [[NewTabPageController alloc] initWithUrl:url
                                            loader:self
-                                          focuser:_toolbarCoordinator
+                                          focuser:self.primaryToolbarCoordinator
                                       ntpObserver:self
                                      browserState:_browserState
                                        colorCache:_dominantColorCache
@@ -4195,7 +4212,8 @@
         // on the omnibox again during this animation. If the animation is
         // interrupted and the toolbar controller is first responder, it's safe
         // to assume |self.typingShield| shouldn't be hidden here.
-        if (!finished && [_toolbarCoordinator isOmniboxFirstResponder])
+        if (!finished &&
+            [self.primaryToolbarCoordinator isOmniboxFirstResponder])
           return;
         [self.typingShield setHidden:YES];
       }];
@@ -4235,7 +4253,7 @@
   DCHECK(self.visible || self.dismissingModal);
 
   // Dismiss the omnibox (if open).
-  [_toolbarCoordinator cancelOmniboxEdit];
+  [self.primaryToolbarCoordinator cancelOmniboxEdit];
   // Dismiss the soft keyboard (if open).
   [[_model currentTab].webController dismissKeyboard];
   // Dismiss Find in Page focus.
@@ -4723,7 +4741,7 @@
 - (void)tabModel:(TabModel*)model didStartLoadingTab:(Tab*)tab {
   if (tab == [_model currentTab]) {
     if (![self isTabNativePage:tab]) {
-      [_toolbarCoordinator currentPageLoadStarted];
+      [self.legacyToolbarCoordinator currentPageLoadStarted];
     }
     [self updateVoiceSearchBarVisibilityAnimated:NO];
   }
@@ -4972,7 +4990,7 @@
 - (void)tabModel:(TabModel*)model willRemoveTab:(Tab*)tab {
   if (tab == [model currentTab]) {
     [_contentArea displayContentView:nil];
-    [_toolbarCoordinator selectedTabChanged];
+    [self.legacyToolbarCoordinator selectedTabChanged];
   }
 
   [_paymentRequestManager stopTrackingWebState:tab.webState];
@@ -4986,7 +5004,7 @@
 // Called when the number of tabs changes. Update the toolbar accordingly.
 - (void)tabModelDidChangeTabCount:(TabModel*)model {
   DCHECK(model == _model);
-  [_toolbarCoordinator setTabCount:[_model count]];
+  [self.legacyToolbarCoordinator setTabCount:[_model count]];
 }
 
 #pragma mark - UpgradeCenterClient
@@ -5354,7 +5372,7 @@
 - (void)prepareForTabHistoryPresentation {
   DCHECK(self.visible || self.dismissingModal);
   [[self.tabModel currentTab].webController dismissKeyboard];
-  [_toolbarCoordinator cancelOmniboxEdit];
+  [self.primaryToolbarCoordinator cancelOmniboxEdit];
 }
 
 #pragma mark - CaptivePortalDetectorTabHelperDelegate
@@ -5374,7 +5392,7 @@
 
 - (void)prepareForPageInfoPresentation {
   // Dismiss the omnibox (if open).
-  [_toolbarCoordinator cancelOmniboxEdit];
+  [self.primaryToolbarCoordinator cancelOmniboxEdit];
 }
 
 - (CGPoint)convertToPresentationCoordinatesForOrigin:(CGPoint)origin {
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
index 3f3af15..ca9c844 100644
--- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -66,6 +66,7 @@
     "//ios/chrome/browser/ui/toolbar",
     "//ios/chrome/browser/ui/toolbar:toolbar_ui",
     "//ios/chrome/browser/ui/toolbar/clean:toolbar_ui",
+    "//ios/chrome/browser/ui/toolbar/public",
     "//ios/chrome/browser/web_state_list",
     "//ios/chrome/common/app_group",
     "//ios/public/provider/chrome/browser",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm
index e65e15f..f08c232 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm
@@ -18,7 +18,7 @@
 #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_header_view.h"
-#import "ios/chrome/browser/ui/toolbar/clean/omnibox_focuser.h"
+#import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/url_loader.h"
 #import "ios/chrome/browser/ui/util/constraints_ui_util.h"
diff --git a/ios/chrome/browser/ui/key_commands_provider.h b/ios/chrome/browser/ui/key_commands_provider.h
index 4cc8e751..22972d7 100644
--- a/ios/chrome/browser/ui/key_commands_provider.h
+++ b/ios/chrome/browser/ui/key_commands_provider.h
@@ -9,7 +9,7 @@
 
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
-#import "ios/chrome/browser/ui/toolbar/clean/omnibox_focuser.h"
+#import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h"
 
 @protocol KeyCommandsPlumbing<NSObject>
 
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_view.mm b/ios/chrome/browser/ui/location_bar/location_bar_view.mm
index e0bb2a24..3f687c81 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_view.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_view.mm
@@ -28,6 +28,8 @@
 const CGFloat kTextFieldLeadingOffsetNoImage = 16;
 // Space between the leading button and the textfield when a button is shown.
 const CGFloat kTextFieldLeadingOffsetImage = 6;
+// Offset from the trailing edge to the textfield.
+const CGFloat kTextFieldTrailingOffset = 3;
 }  // namespace
 
 @interface OmniboxTextFieldIOS ()
@@ -146,7 +148,9 @@
                          constant:kTextFieldLeadingOffsetNoImage];
 
       [NSLayoutConstraint activateConstraints:@[
-        [_textField.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
+        [_textField.trailingAnchor
+            constraintEqualToAnchor:self.trailingAnchor
+                           constant:-kTextFieldTrailingOffset],
         [_textField.topAnchor constraintEqualToAnchor:self.topAnchor],
         [_textField.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
         _leadingTextfieldConstraint,
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_toolbar_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_toolbar_controller.mm
index 2f846fa..0ceb31a 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_toolbar_controller.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_toolbar_controller.mm
@@ -12,7 +12,7 @@
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/rtl_geometry.h"
-#import "ios/chrome/browser/ui/toolbar/clean/omnibox_focuser.h"
+#import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h"
 #import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_constants.h"
 #import "ios/chrome/browser/ui/toolbar/toolbar_controller+protected.h"
 #include "ios/chrome/browser/ui/toolbar/toolbar_resource_macros.h"
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_popup_row.mm b/ios/chrome/browser/ui/omnibox/omnibox_popup_row.mm
index 9603b81..0fed838 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_popup_row.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_popup_row.mm
@@ -107,16 +107,17 @@
 - (void)layoutAccessoryViews {
   LayoutRect imageViewLayout = LayoutRectMake(
       IsCompactTablet() ? kLeadingPaddingIpadCompact : kLeadingPaddingIpad,
-      CGRectGetWidth(self.bounds),
+      CGRectGetWidth(self.contentView.bounds),
       floor((_rowHeight - kImageDimensionLength) / 2), kImageDimensionLength,
       kImageDimensionLength);
   _imageView.frame = LayoutRectGetRect(imageViewLayout);
 
-  LayoutRect trailingAccessoryLayout = LayoutRectMake(
-      CGRectGetWidth(self.bounds) - kAppendButtonSize -
-          kAppendButtonTrailingMargin,
-      CGRectGetWidth(self.bounds), floor((_rowHeight - kAppendButtonSize) / 2),
-      kAppendButtonSize, kAppendButtonSize);
+  LayoutRect trailingAccessoryLayout =
+      LayoutRectMake(CGRectGetWidth(self.contentView.bounds) -
+                         kAppendButtonSize - kAppendButtonTrailingMargin,
+                     CGRectGetWidth(self.contentView.bounds),
+                     floor((_rowHeight - kAppendButtonSize) / 2),
+                     kAppendButtonSize, kAppendButtonSize);
   _appendButton.frame = LayoutRectGetRect(trailingAccessoryLayout);
 }
 
diff --git a/ios/chrome/browser/ui/payments/BUILD.gn b/ios/chrome/browser/ui/payments/BUILD.gn
index 822e1b23..96cf4739 100644
--- a/ios/chrome/browser/ui/payments/BUILD.gn
+++ b/ios/chrome/browser/ui/payments/BUILD.gn
@@ -219,6 +219,7 @@
     "//ios/third_party/material_components_ios",
     "//ios/web",
     "//ios/web/public/test",
+    "//ios/web/public/test/fakes",
     "//testing/gmock",
     "//testing/gtest",
     "//third_party/libaddressinput:strings_grit",
diff --git a/ios/chrome/browser/ui/payments/full_card_requester_unittest.mm b/ios/chrome/browser/ui/payments/full_card_requester_unittest.mm
index 6811d3ae..5728f310 100644
--- a/ios/chrome/browser/ui/payments/full_card_requester_unittest.mm
+++ b/ios/chrome/browser/ui/payments/full_card_requester_unittest.mm
@@ -19,6 +19,7 @@
 #include "ios/chrome/browser/payments/payment_request_unittest_base.h"
 #include "ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.h"
 #import "ios/chrome/test/scoped_key_window.h"
+#import "ios/web/public/test/fakes/crw_test_js_injection_receiver.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 #include "third_party/ocmock/gtest_support.h"
@@ -61,6 +62,10 @@
     AddCreditCard(autofill::test::GetCreditCard());  // Visa.
 
     // Set up what is needed to have an instance of autofill::AutofillManager.
+    CRWTestJSInjectionReceiver* injectionReceiver =
+        [[CRWTestJSInjectionReceiver alloc] init];
+    web_state()->SetJSInjectionReceiver(injectionReceiver);
+
     AutofillAgent* autofill_agent =
         [[AutofillAgent alloc] initWithPrefService:browser_state()->GetPrefs()
                                           webState:web_state()];
diff --git a/ios/chrome/browser/ui/side_swipe/BUILD.gn b/ios/chrome/browser/ui/side_swipe/BUILD.gn
index 246ba61..577191e 100644
--- a/ios/chrome/browser/ui/side_swipe/BUILD.gn
+++ b/ios/chrome/browser/ui/side_swipe/BUILD.gn
@@ -13,7 +13,6 @@
     "side_swipe_controller.mm",
     "side_swipe_navigation_view.h",
     "side_swipe_navigation_view.mm",
-    "side_swipe_toolbar_interacting.h",
     "side_swipe_util.h",
     "side_swipe_util.mm",
   ]
@@ -33,6 +32,7 @@
     "//ios/chrome/browser/ui/fullscreen:new_fullscreen",
     "//ios/chrome/browser/ui/ntp",
     "//ios/chrome/browser/ui/tabs/requirements",
+    "//ios/chrome/browser/ui/toolbar/public",
     "//ios/chrome/browser/web",
     "//ios/chrome/common",
     "//ios/web/public",
diff --git a/ios/chrome/browser/ui/side_swipe/card_side_swipe_view.mm b/ios/chrome/browser/ui/side_swipe/card_side_swipe_view.mm
index b29236c..a237bc9 100644
--- a/ios/chrome/browser/ui/side_swipe/card_side_swipe_view.mm
+++ b/ios/chrome/browser/ui/side_swipe/card_side_swipe_view.mm
@@ -17,9 +17,9 @@
 #import "ios/chrome/browser/ui/background_generator.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_panel_protocol.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
-#include "ios/chrome/browser/ui/side_swipe/side_swipe_toolbar_interacting.h"
 #import "ios/chrome/browser/ui/side_swipe/side_swipe_util.h"
 #import "ios/chrome/browser/ui/side_swipe_gesture_recognizer.h"
+#include "ios/chrome/browser/ui/toolbar/public/side_swipe_toolbar_interacting.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/util/constraints_ui_util.h"
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
index 6f346214..3c9afe43 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
+++ b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
@@ -26,10 +26,10 @@
 #import "ios/chrome/browser/ui/side_swipe/card_side_swipe_view.h"
 #import "ios/chrome/browser/ui/side_swipe/history_side_swipe_provider.h"
 #import "ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.h"
-#include "ios/chrome/browser/ui/side_swipe/side_swipe_toolbar_interacting.h"
 #import "ios/chrome/browser/ui/side_swipe/side_swipe_util.h"
 #import "ios/chrome/browser/ui/side_swipe_gesture_recognizer.h"
 #import "ios/chrome/browser/ui/tabs/requirements/tab_strip_highlighting.h"
+#include "ios/chrome/browser/ui/toolbar/public/side_swipe_toolbar_interacting.h"
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/web/page_placeholder_tab_helper.h"
 #import "ios/web/public/web_state/web_state_observer_bridge.h"
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h
index ed26e718..aa16928 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.h
@@ -35,7 +35,7 @@
 + (NSString*)identifier;
 
 // The cell delegate.
-@property(nonatomic, unsafe_unretained) id<SessionCellDelegate> delegate;
+@property(nonatomic, weak) id<SessionCellDelegate> delegate;
 
 @end
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.h
index ccd4e22e..66d5ea9 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_controller.h
@@ -55,9 +55,8 @@
 
 @interface TabSwitcherPanelController : NSObject
 
-@property(unsafe_unretained, nonatomic, readonly) TabSwitcherPanelView* view;
-@property(nonatomic, unsafe_unretained) id<TabSwitcherPanelControllerDelegate>
-    delegate;
+@property(nonatomic, readonly, weak) TabSwitcherPanelView* view;
+@property(nonatomic, weak) id<TabSwitcherPanelControllerDelegate> delegate;
 @property(nonatomic, readonly) TabSwitcherSessionType sessionType;
 @property(nonatomic, readonly, weak) id<SigninPresenter, SyncPresenter>
     presenter;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_view.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_view.h
index a6f680f2f..90e588f 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_view.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_view.h
@@ -25,11 +25,10 @@
 
 @interface TabSwitcherView : UIView<UIScrollViewDelegate>
 
-@property(unsafe_unretained, nonatomic, readonly)
-    TabSwitcherHeaderView* headerView;
-@property(unsafe_unretained, nonatomic, readonly) UIScrollView* scrollView;
+@property(nonatomic, readonly, weak) TabSwitcherHeaderView* headerView;
+@property(nonatomic, readonly, weak) UIScrollView* scrollView;
 
-@property(nonatomic, unsafe_unretained) id<TabSwitcherViewDelegate> delegate;
+@property(nonatomic, weak) id<TabSwitcherViewDelegate> delegate;
 
 // Select the panel at the given index, updating both the header and content.
 // The panel selection will be animated if VoiceOver is disabled.
diff --git a/ios/chrome/browser/ui/toolbar/clean/BUILD.gn b/ios/chrome/browser/ui/toolbar/clean/BUILD.gn
index b539d5fd..bb04df8 100644
--- a/ios/chrome/browser/ui/toolbar/clean/BUILD.gn
+++ b/ios/chrome/browser/ui/toolbar/clean/BUILD.gn
@@ -58,7 +58,6 @@
 
 source_set("toolbar_ui") {
   sources = [
-    "omnibox_focuser.h",
     "toolbar_button_updater.h",
     "toolbar_button_updater.mm",
     "toolbar_consumer.h",
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.h b/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.h
index b919e89..3ff93dff 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.h
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.h
@@ -8,7 +8,7 @@
 #import <UIKit/UIKit.h>
 
 #include "ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_result_loading.h"
-#import "ios/chrome/browser/ui/toolbar/clean/omnibox_focuser.h"
+#import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h"
 #import "ios/chrome/browser/ui/tools_menu/public/tools_menu_presentation_provider.h"
 #include "ios/public/provider/chrome/browser/voice/voice_search_controller_delegate.h"
 
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.mm
index b1e542e..fc4cc29 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.mm
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.mm
@@ -186,6 +186,7 @@
 
 - (void)stop {
   self.started = NO;
+  self.delegate = nil;
   [self.mediator disconnect];
   // The popup has to be destroyed before the location bar.
   [self.omniboxPopupCoordinator stop];
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
index 81e3d0a..c19e0423 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
@@ -12,7 +12,6 @@
 #import "ios/chrome/browser/ui/commands/start_voice_search_command.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_scroll_end_animator.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
-#import "ios/chrome/browser/ui/toolbar/clean/omnibox_focuser.h"
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_button.h"
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_button_factory.h"
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_button_updater.h"
@@ -21,6 +20,7 @@
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h"
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_tools_menu_button.h"
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_view.h"
+#import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h"
 #import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_constants.h"
 #import "ios/chrome/browser/ui/toolbar/public/web_toolbar_controller_constants.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
@@ -29,6 +29,7 @@
 #import "ios/chrome/common/material_timing.h"
 #include "ios/chrome/grit/ios_theme_resources.h"
 #import "ios/third_party/material_components_ios/src/components/ProgressView/src/MaterialProgressView.h"
+#import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -486,6 +487,7 @@
   // accessibility value will always be equal to |tabCount|.
   NSString* tabStripButtonValue = [NSString stringWithFormat:@"%d", tabCount];
   NSString* tabStripButtonTitle;
+  id<MDCTypographyFontLoading> fontLoader = [MDCTypography fontLoader];
   if (tabCount <= 0) {
     tabStripButtonTitle = @"";
   } else if (tabCount > kShowTabStripButtonMaxTabCount) {
@@ -493,15 +495,15 @@
     // more than 99 tabs open.
     tabStripButtonTitle = @":)";
     [[self.view.tabSwitchStripButton titleLabel]
-        setFont:[UIFont boldSystemFontOfSize:kFontSizeFewerThanTenTabs]];
+        setFont:[fontLoader boldFontOfSize:kFontSizeFewerThanTenTabs]];
   } else {
     tabStripButtonTitle = tabStripButtonValue;
     if (tabCount < 10) {
       [[self.view.tabSwitchStripButton titleLabel]
-          setFont:[UIFont boldSystemFontOfSize:kFontSizeFewerThanTenTabs]];
+          setFont:[fontLoader boldFontOfSize:kFontSizeFewerThanTenTabs]];
     } else {
       [[self.view.tabSwitchStripButton titleLabel]
-          setFont:[UIFont boldSystemFontOfSize:kFontSizeTenTabsOrMore]];
+          setFont:[fontLoader boldFontOfSize:kFontSizeTenTabsOrMore]];
     }
   }
 
diff --git a/ios/chrome/browser/ui/toolbar/legacy_toolbar_coordinator.h b/ios/chrome/browser/ui/toolbar/legacy_toolbar_coordinator.h
index b5e2f2f..cc3a1c9 100644
--- a/ios/chrome/browser/ui/toolbar/legacy_toolbar_coordinator.h
+++ b/ios/chrome/browser/ui/toolbar/legacy_toolbar_coordinator.h
@@ -11,20 +11,14 @@
 #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_ui_element.h"
 #import "ios/chrome/browser/ui/ntp/incognito_view_controller_delegate.h"
-#import "ios/chrome/browser/ui/side_swipe/side_swipe_toolbar_interacting.h"
-#import "ios/chrome/browser/ui/toolbar/clean/omnibox_focuser.h"
 #import "ios/chrome/browser/ui/toolbar/public/abstract_web_toolbar.h"
+#import "ios/chrome/browser/ui/toolbar/public/primary_toolbar_coordinator.h"
 #import "ios/chrome/browser/ui/toolbar/toolbar_snapshot_providing.h"
 #import "ios/chrome/browser/ui/tools_menu/public/tools_menu_presentation_provider.h"
 #import "ios/chrome/browser/ui/tools_menu/public/tools_menu_presentation_state_provider.h"
 
 @protocol ActivityServicePositioner;
-@protocol QRScannerResultLoading;
 @class Tab;
-@protocol TabHistoryPositioner;
-@protocol TabHistoryUIUpdater;
-@protocol VoiceSearchControllerDelegate;
-@protocol WebToolbarDelegate;
 @protocol ToolsMenuConfigurationProvider;
 
 @class CommandDispatcher;
@@ -47,16 +41,12 @@
 @end
 
 @interface LegacyToolbarCoordinator
-    : ChromeCoordinator<BubbleViewAnchorPointProvider,
+    : ChromeCoordinator<PrimaryToolbarCoordinator,
+                        BubbleViewAnchorPointProvider,
                         IncognitoViewControllerDelegate,
-                        OmniboxFocuser,
-                        SideSwipeToolbarInteracting,
                         ToolbarSnapshotProviding,
                         ToolsMenuPresentationStateProvider>
 
-@property(nonatomic, weak) TabModel* tabModel;
-@property(nonatomic, strong) UIViewController* toolbarViewController;
-
 - (instancetype)initWithBaseViewController:(UIViewController*)viewController
             toolsMenuConfigurationProvider:
                 (id<ToolsMenuConfigurationProvider>)configurationProvider
@@ -72,35 +62,27 @@
     NS_UNAVAILABLE;
 
 // Returns the different protocols and superclass now implemented by the
-- (id<VoiceSearchControllerDelegate>)voiceSearchDelegate;
+// internal ViewController.
 - (id<ActivityServicePositioner>)activityServicePositioner;
-- (id<TabHistoryPositioner>)tabHistoryPositioner;
-- (id<TabHistoryUIUpdater>)tabHistoryUIUpdater;
-- (id<QRScannerResultLoading>)QRScannerResultLoader;
 
 // Sets the toolbarController for this coordinator.
 - (void)setToolbarController:(id<Toolbar>)toolbarController;
 
-// Sets the delegate for the toolbar.
-- (void)setToolbarDelegate:(id<WebToolbarDelegate>)delegate;
-
-// TabModel callbacks.
-- (void)selectedTabChanged;
-- (void)setTabCount:(NSInteger)tabCount;
-
-// WebToolbarController public interface.
-- (void)browserStateDestroyed;
+// ToolbarController public interface.
 - (void)updateToolbarState;
-- (void)setShareButtonEnabled:(BOOL)enabled;
-- (void)showPrerenderingAnimation;
-- (BOOL)isOmniboxFirstResponder;
-- (BOOL)showingOmniboxPopup;
-- (void)currentPageLoadStarted;
 - (CGRect)visibleOmniboxFrame;
 - (void)triggerToolsMenuButtonAnimation;
-- (void)adjustToolbarHeight;
 - (BOOL)isShowingToolsMenu;
 
+// TODO(crbug.com/788705): Legacy interface. Removes those methods once the old
+// toolbar is removed.
+- (void)selectedTabChanged;
+- (void)setTabCount:(NSInteger)tabCount;
+- (void)browserStateDestroyed;
+- (void)setShareButtonEnabled:(BOOL)enabled;
+- (void)currentPageLoadStarted;
+- (void)adjustToolbarHeight;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_LEGACY_TOOLBAR_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/toolbar/legacy_toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/legacy_toolbar_coordinator.mm
index 0ddbc92..2a7cf77 100644
--- a/ios/chrome/browser/ui/toolbar/legacy_toolbar_coordinator.mm
+++ b/ios/chrome/browser/ui/toolbar/legacy_toolbar_coordinator.mm
@@ -11,8 +11,8 @@
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_controller_factory.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_features.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_ui_updater.h"
-#import "ios/chrome/browser/ui/toolbar/clean/omnibox_focuser.h"
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_button_updater.h"
+#import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h"
 #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h"
 #import "ios/chrome/browser/ui/tools_menu/public/tools_menu_constants.h"
 #import "ios/chrome/browser/ui/tools_menu/tools_menu_coordinator.h"
@@ -33,7 +33,6 @@
 @end
 
 @implementation LegacyToolbarCoordinator
-@synthesize tabModel = _tabModel;
 @synthesize toolbarViewController = _toolbarViewController;
 @synthesize toolbarController = _toolbarController;
 
@@ -118,10 +117,6 @@
   [toolbarController start];
 }
 
-- (void)setToolbarDelegate:(id<WebToolbarDelegate>)delegate {
-  self.toolbarController.delegate = delegate;
-}
-
 - (void)adjustToolbarHeight {
   [self.toolbarController adjustToolbarHeight];
 }
diff --git a/ios/chrome/browser/ui/toolbar/public/BUILD.gn b/ios/chrome/browser/ui/toolbar/public/BUILD.gn
index d34019d..612022bd 100644
--- a/ios/chrome/browser/ui/toolbar/public/BUILD.gn
+++ b/ios/chrome/browser/ui/toolbar/public/BUILD.gn
@@ -7,6 +7,9 @@
   sources = [
     "abstract_toolbar.h",
     "abstract_web_toolbar.h",
+    "omnibox_focuser.h",
+    "primary_toolbar_coordinator.h",
+    "side_swipe_toolbar_interacting.h",
     "toolbar_controller_constants.h",
     "toolbar_controller_constants.mm",
     "toolbar_utils.h",
diff --git a/ios/chrome/browser/ui/toolbar/clean/omnibox_focuser.h b/ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h
similarity index 80%
rename from ios/chrome/browser/ui/toolbar/clean/omnibox_focuser.h
rename to ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h
index 54340b7..10468fb 100644
--- a/ios/chrome/browser/ui/toolbar/clean/omnibox_focuser.h
+++ b/ios/chrome/browser/ui/toolbar/public/omnibox_focuser.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_TOOLBAR_CLEAN_OMNIBOX_FOCUSER_H_
-#define IOS_CHROME_BROWSER_UI_TOOLBAR_CLEAN_OMNIBOX_FOCUSER_H_
+#ifndef IOS_CHROME_BROWSER_UI_TOOLBAR_PUBLIC_OMNIBOX_FOCUSER_H_
+#define IOS_CHROME_BROWSER_UI_TOOLBAR_PUBLIC_OMNIBOX_FOCUSER_H_
 
 #import <Foundation/Foundation.h>
 
@@ -22,4 +22,4 @@
 - (void)onFakeboxAnimationComplete;
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_CLEAN_OMNIBOX_FOCUSER_H_
+#endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_PUBLIC_OMNIBOX_FOCUSER_H_
diff --git a/ios/chrome/browser/ui/toolbar/public/primary_toolbar_coordinator.h b/ios/chrome/browser/ui/toolbar/public/primary_toolbar_coordinator.h
new file mode 100644
index 0000000..04681b2
--- /dev/null
+++ b/ios/chrome/browser/ui/toolbar/public/primary_toolbar_coordinator.h
@@ -0,0 +1,40 @@
+// 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 IOS_CHROME_BROWSER_UI_TOOLBAR_PUBLIC_PRIMARY_TOOLBAR_COORDINATOR_H_
+#define IOS_CHROME_BROWSER_UI_TOOLBAR_PUBLIC_PRIMARY_TOOLBAR_COORDINATOR_H_
+
+#import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h"
+#import "ios/chrome/browser/ui/toolbar/public/side_swipe_toolbar_interacting.h"
+
+@protocol QRScannerResultLoading;
+@protocol TabHistoryPositioner;
+@protocol TabHistoryUIUpdater;
+@protocol VoiceSearchControllerDelegate;
+@protocol WebToolbarDelegate;
+
+// Protocol defining a primary toolbar, in a paradigm where the toolbar can be
+// split between primary and secondary.
+@protocol PrimaryToolbarCoordinator<OmniboxFocuser, SideSwipeToolbarInteracting>
+
+// The toolbar ViewController.
+@property(nonatomic, strong) UIViewController* toolbarViewController;
+
+// Returns the different protocols and superclass now implemented by the
+// internal ViewController.
+- (id<VoiceSearchControllerDelegate>)voiceSearchDelegate;
+- (id<QRScannerResultLoading>)QRScannerResultLoader;
+- (id<TabHistoryPositioner>)tabHistoryPositioner;
+- (id<TabHistoryUIUpdater>)tabHistoryUIUpdater;
+
+// Show the animation when transitioning to a prerendered page.
+- (void)showPrerenderingAnimation;
+// Whether the omnibox is currently the first responder.
+- (BOOL)isOmniboxFirstResponder;
+// Whether the omnibox popup is currently presented.
+- (BOOL)showingOmniboxPopup;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_PUBLIC_PRIMARY_TOOLBAR_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_toolbar_interacting.h b/ios/chrome/browser/ui/toolbar/public/side_swipe_toolbar_interacting.h
similarity index 70%
rename from ios/chrome/browser/ui/side_swipe/side_swipe_toolbar_interacting.h
rename to ios/chrome/browser/ui/toolbar/public/side_swipe_toolbar_interacting.h
index 51b1394b..857f724 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_toolbar_interacting.h
+++ b/ios/chrome/browser/ui/toolbar/public/side_swipe_toolbar_interacting.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_SIDE_SWIPE_SIDE_SWIPE_TOOLBAR_INTERACTING_H_
-#define IOS_CHROME_BROWSER_UI_SIDE_SWIPE_SIDE_SWIPE_TOOLBAR_INTERACTING_H_
+#ifndef IOS_CHROME_BROWSER_UI_TOOLBAR_PUBLIC_SIDE_SWIPE_TOOLBAR_INTERACTING_H_
+#define IOS_CHROME_BROWSER_UI_TOOLBAR_PUBLIC_SIDE_SWIPE_TOOLBAR_INTERACTING_H_
 
 #import <UIKit/UIKit.h>
 
@@ -22,4 +22,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_SIDE_SWIPE_SIDE_SWIPE_TOOLBAR_INTERACTING_H_
+#endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_PUBLIC_SIDE_SWIPE_TOOLBAR_INTERACTING_H_
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h
index 504f5e47..5669954 100644
--- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h
+++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h
@@ -9,8 +9,8 @@
 
 #include "ios/chrome/browser/ui/omnibox/omnibox_popup_positioner.h"
 #include "ios/chrome/browser/ui/qr_scanner/requirements/qr_scanner_result_loading.h"
-#import "ios/chrome/browser/ui/toolbar/clean/omnibox_focuser.h"
 #import "ios/chrome/browser/ui/toolbar/public/abstract_web_toolbar.h"
+#import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h"
 #import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
 #include "ios/public/provider/chrome/browser/voice/voice_search_controller_delegate.h"
 #include "ios/web/public/navigation_item_list.h"
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_delegate.h b/ios/chrome/browser/ui/toolbar/web_toolbar_delegate.h
index ed8b2024..34f025c 100644
--- a/ios/chrome/browser/ui/toolbar/web_toolbar_delegate.h
+++ b/ios/chrome/browser/ui/toolbar/web_toolbar_delegate.h
@@ -13,6 +13,8 @@
 class WebState;
 }
 
+// TODO(crbug.com/788705): Replace uses of this protocol by
+// ToolbarCoordinatorDelegate.
 // Delegate interface, to be implemented by the WebToolbarController's delegate.
 @protocol WebToolbarDelegate<ToolbarCoordinatorDelegate>
 // Returns the WebState.
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.mm b/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.mm
index 23f937c..5fedd8f 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h"
 
+#import <QuartzCore/QuartzCore.h>
 #include <stdint.h>
 
 #include "base/ios/ios_util.h"
@@ -693,20 +694,19 @@
       // Set the label's background color to be clear so that the highlight is
       // is not covered by the label.
       visibleCell.title.backgroundColor = [UIColor clearColor];
-      [UIView animateWithDuration:ios::material::kDuration5
-          delay:0.0
-          options:UIViewAnimationOptionAllowUserInteraction |
-                  UIViewAnimationOptionRepeat |
-                  UIViewAnimationOptionAutoreverse |
-                  UIViewAnimationOptionCurveEaseInOut
-          animations:^{
-            [UIView setAnimationRepeatCount:2];
-            visibleCell.contentView.backgroundColor =
-                [[MDCPalette cr_bluePalette] tint100];
-          }
-          completion:^(BOOL finished) {
-            visibleCell.contentView.backgroundColor = [UIColor whiteColor];
-          }];
+
+      CABasicAnimation* highlightAnimation =
+          [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
+      highlightAnimation.duration = ios::material::kDuration5;
+      highlightAnimation.repeatCount = 2;
+      highlightAnimation.autoreverses = YES;
+      highlightAnimation.toValue =
+          static_cast<id>([[MDCPalette cr_bluePalette] tint100].CGColor);
+      highlightAnimation.timingFunction = [CAMediaTimingFunction
+          functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
+      [visibleCell.contentView.layer addAnimation:highlightAnimation
+                                           forKey:nil];
+
       self.highlightNewIncognitoTabCell = NO;
       break;
     }
diff --git a/ios/chrome/browser/ui/util/label_link_controller.mm b/ios/chrome/browser/ui/util/label_link_controller.mm
index 2baf05d..bb9cd53 100644
--- a/ios/chrome/browser/ui/util/label_link_controller.mm
+++ b/ios/chrome/browser/ui/util/label_link_controller.mm
@@ -60,7 +60,7 @@
 
 @interface LabelLinkController ()
 // Private property exposed publically in testing interface.
-@property(nonatomic, unsafe_unretained) Class textMapperClass;
+@property(nonatomic, weak) Class textMapperClass;
 
 // The original attributed text set on the label.  This may be different from
 // the label's |attributedText| property, as additional style attributes may be
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn
index 77a12f4d..bc34096 100644
--- a/ios/chrome/browser/web/BUILD.gn
+++ b/ios/chrome/browser/web/BUILD.gn
@@ -112,6 +112,7 @@
 js_compile_bundle("chrome_bundle") {
   closure_entry_point = "__crWeb.chromeBundle"
   sources = [
+    "//components/autofill/ios/browser/resources/autofill_controller.js",
     "resources/chrome_bundle.js",
     "resources/print.js",
   ]
@@ -122,7 +123,7 @@
   ]
 }
 
-js_compile_unchecked("payment_request") {
+js_compile_checked("payment_request") {
   sources = [
     "resources/payment_request.js",
   ]
diff --git a/ios/chrome/browser/web/chrome_web_client_unittest.mm b/ios/chrome/browser/web/chrome_web_client_unittest.mm
index 187726ce..eab108d7 100644
--- a/ios/chrome/browser/web/chrome_web_client_unittest.mm
+++ b/ios/chrome/browser/web/chrome_web_client_unittest.mm
@@ -103,6 +103,20 @@
               web::ExecuteJavaScript(web_view, @"typeof __gCrWeb.print"));
 }
 
+// Tests that ChromeWebClient provides autofill controller script for WKWebView.
+TEST_F(ChromeWebClientTest, WKWebViewEarlyPageScriptAutofillController) {
+  // Chrome scripts rely on __gCrWeb object presence.
+  WKWebView* web_view = web::BuildWKWebView(CGRectZero, browser_state());
+  web::ExecuteJavaScript(web_view, @"__gCrWeb = {};");
+
+  web::ScopedTestingWebClient web_client(base::MakeUnique<ChromeWebClient>());
+  NSString* script =
+      web_client.Get()->GetEarlyPageScriptForMainFrame(browser_state());
+  web::ExecuteJavaScript(web_view, script);
+  EXPECT_NSEQ(@"object",
+              web::ExecuteJavaScript(web_view, @"typeof __gCrWeb.autofill"));
+}
+
 // Tests that ChromeWebClient provides credential manager script for WKWebView
 // if and only if the feature is enabled.
 TEST_F(ChromeWebClientTest, WKWebViewEarlyPageScriptCredentialManager) {
diff --git a/ios/chrome/browser/web/resources/chrome_bundle.js b/ios/chrome/browser/web/resources/chrome_bundle.js
index 8e4146e..f5961c8 100644
--- a/ios/chrome/browser/web/resources/chrome_bundle.js
+++ b/ios/chrome/browser/web/resources/chrome_bundle.js
@@ -6,3 +6,4 @@
 goog.provide('__crWeb.chromeBundle');
 
 goog.require('__crWeb.print');
+goog.require('__crWeb.autofill');
diff --git a/ios/third_party/material_components_ios/README.chromium b/ios/third_party/material_components_ios/README.chromium
index 33efd4d2..a90778c6 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: 7e090434dde5009a693101a63864ab47b895e87f
+Revision: e6f6b5f6a28df8c2212441978394f77725e4e9c3
 License: Apache 2.0
 License File: LICENSE
 Security Critical: yes
diff --git a/ios/web/navigation/navigation_manager_impl_unittest.mm b/ios/web/navigation/navigation_manager_impl_unittest.mm
index a13af61b..f184ae7 100644
--- a/ios/web/navigation/navigation_manager_impl_unittest.mm
+++ b/ios/web/navigation/navigation_manager_impl_unittest.mm
@@ -2227,6 +2227,8 @@
 
   EXPECT_EQ(1, navigation_manager()->GetLastCommittedItemIndex());
   EXPECT_EQ(-1, navigation_manager()->GetPendingItemIndex());
+  EXPECT_FALSE(navigation_manager()->GetItemAtIndex(0)->GetTransitionType() &
+               ui::PAGE_TRANSITION_FORWARD_BACK);
 
   EXPECT_CALL(navigation_manager_delegate(), RecordPageStateInNavigationItem());
   EXPECT_CALL(navigation_manager_delegate(), ClearTransientContent());
@@ -2240,6 +2242,8 @@
   }
 
   navigation_manager()->GoToIndex(0);
+  EXPECT_TRUE(navigation_manager()->GetItemAtIndex(0)->GetTransitionType() &
+              ui::PAGE_TRANSITION_FORWARD_BACK);
 
   if (GetParam() == TEST_LEGACY_NAVIGATION_MANAGER) {
     // Since LoadCurrentItem() is noop in test, we can only verify that the
@@ -2270,6 +2274,8 @@
 
   EXPECT_EQ(1, navigation_manager()->GetLastCommittedItemIndex());
   EXPECT_EQ(-1, navigation_manager()->GetPendingItemIndex());
+  EXPECT_FALSE(navigation_manager()->GetItemAtIndex(0)->GetTransitionType() &
+               ui::PAGE_TRANSITION_FORWARD_BACK);
 
   EXPECT_CALL(navigation_manager_delegate(), RecordPageStateInNavigationItem());
   EXPECT_CALL(navigation_manager_delegate(), ClearTransientContent());
@@ -2282,6 +2288,12 @@
   }
 
   navigation_manager()->GoToIndex(0);
+  // Preserve the existing behavior of legacy navigation manager for change
+  // management, even though it seems like a bug that the back-forward
+  // transition bit is not set for same-document history navigation.
+  EXPECT_EQ(GetParam() == TEST_WK_BASED_NAVIGATION_MANAGER,
+            (navigation_manager()->GetItemAtIndex(0)->GetTransitionType() &
+             ui::PAGE_TRANSITION_FORWARD_BACK) > 0);
 
   if (GetParam() == TEST_LEGACY_NAVIGATION_MANAGER) {
     EXPECT_EQ(0, navigation_manager()->GetLastCommittedItemIndex());
@@ -2309,6 +2321,8 @@
 
   EXPECT_CALL(navigation_manager_delegate(), WillChangeUserAgentType());
   navigation_manager()->GoToIndex(0);
+  EXPECT_TRUE(navigation_manager()->GetItemAtIndex(0)->GetTransitionType() &
+              ui::PAGE_TRANSITION_FORWARD_BACK);
 }
 
 TEST_P(NavigationManagerTest, LoadIfNecessary) {
diff --git a/ios/web/navigation/wk_based_navigation_manager_impl.mm b/ios/web/navigation/wk_based_navigation_manager_impl.mm
index cbcf1b2..dea06a7 100644
--- a/ios/web/navigation/wk_based_navigation_manager_impl.mm
+++ b/ios/web/navigation/wk_based_navigation_manager_impl.mm
@@ -456,6 +456,9 @@
 
 void WKBasedNavigationManagerImpl::FinishGoToIndex(int index) {
   DiscardNonCommittedItems();
+  NavigationItem* item = GetItemAtIndex(index);
+  item->SetTransitionType(ui::PageTransitionFromInt(
+      item->GetTransitionType() | ui::PAGE_TRANSITION_FORWARD_BACK));
   WKBackForwardListItem* wk_item = GetWKItemAtIndex(index);
   DCHECK(wk_item);
   [delegate_->GetWebViewNavigationProxy() goToBackForwardListItem:wk_item];
diff --git a/ios/web/public/test/web_js_test.h b/ios/web/public/test/web_js_test.h
index 481c320..d878fde 100644
--- a/ios/web/public/test/web_js_test.h
+++ b/ios/web/public/test/web_js_test.h
@@ -7,7 +7,10 @@
 
 #import <Foundation/Foundation.h>
 
+#include <memory>
+
 #import "base/mac/bundle_locations.h"
+#include "ios/web/public/web_client.h"
 #import "testing/gtest_mac.h"
 
 namespace web {
@@ -18,6 +21,8 @@
  public:
   WebJsTest(NSArray* java_script_paths)
       : java_script_paths_([java_script_paths copy]) {}
+  WebJsTest(std::unique_ptr<web::WebClient> web_client)
+      : WebTestT(std::move(web_client)) {}
 
  protected:
   // Loads |html| and inject JavaScripts at |javaScriptPaths_|.
diff --git a/ios/web_view/internal/autofill/cwv_autofill_controller_unittest.mm b/ios/web_view/internal/autofill/cwv_autofill_controller_unittest.mm
index cbbb468..f7e95ac6 100644
--- a/ios/web_view/internal/autofill/cwv_autofill_controller_unittest.mm
+++ b/ios/web_view/internal/autofill/cwv_autofill_controller_unittest.mm
@@ -46,12 +46,7 @@
 
 class CWVAutofillControllerTest : public PlatformTest {
  protected:
-  CWVAutofillControllerTest()
-      : browser_state_(/*off_the_record=*/false),
-        autofill_agent_([[FakeAutofillAgent alloc]
-            initWithPrefService:browser_state_.GetPrefs()
-                       webState:&web_state_]),
-        js_autofill_manager_([[FakeJSAutofillManager alloc] init]) {
+  CWVAutofillControllerTest() : browser_state_(/*off_the_record=*/false) {
     l10n_util::OverrideLocaleWithCocoaLocale();
 
     web_state_.SetBrowserState(&browser_state_);
@@ -59,6 +54,13 @@
         [[CRWTestJSInjectionReceiver alloc] init];
     web_state_.SetJSInjectionReceiver(injectionReceiver);
 
+    js_autofill_manager_ =
+        [[FakeJSAutofillManager alloc] initWithReceiver:injectionReceiver];
+
+    autofill_agent_ =
+        [[FakeAutofillAgent alloc] initWithPrefService:browser_state_.GetPrefs()
+                                              webState:&web_state_];
+
     autofill_controller_ =
         [[CWVAutofillController alloc] initWithWebState:&web_state_
                                           autofillAgent:autofill_agent_
diff --git a/ipc/ipc_platform_file.cc b/ipc/ipc_platform_file.cc
index 72ed737..d8108b3 100644
--- a/ipc/ipc_platform_file.cc
+++ b/ipc/ipc_platform_file.cc
@@ -9,6 +9,8 @@
 #include <unistd.h>
 
 #include "base/posix/eintr_wrapper.h"
+#elif defined(OS_WIN)
+#include <windows.h>
 #endif
 
 namespace IPC {
diff --git a/ipc/ipc_sync_message.h b/ipc/ipc_sync_message.h
index c9a1287..cfac2de 100644
--- a/ipc/ipc_sync_message.h
+++ b/ipc/ipc_sync_message.h
@@ -8,7 +8,7 @@
 #include <stdint.h>
 
 #if defined(OS_WIN)
-#include <windows.h>
+#include "base/win/windows_types.h"
 #endif
 
 #include <memory>
diff --git a/media/base/mime_util_internal.cc b/media/base/mime_util_internal.cc
index 9c929b21..bd11067 100644
--- a/media/base/mime_util_internal.cc
+++ b/media/base/mime_util_internal.cc
@@ -864,24 +864,6 @@
   return false;
 }
 
-SupportsType MimeUtil::IsSimpleCodecSupported(
-    const std::string& mime_type_lower_case,
-    Codec codec,
-    bool is_encrypted) const {
-  // Video codecs are not "simple" because they require a profile and level to
-  // be specified. There is no "default" video codec for a given container.
-  DCHECK_EQ(MimeUtilToVideoCodec(codec), kUnknownVideoCodec);
-
-  SupportsType result = IsCodecSupported(
-      mime_type_lower_case, codec, VIDEO_CODEC_PROFILE_UNKNOWN,
-      0 /* video_level */, VideoColorSpace::REC709(), is_encrypted);
-
-  // Platform support should never be ambiguous for simple codecs (no range of
-  // profiles to consider).
-  DCHECK_NE(result, MayBeSupported);
-  return result;
-}
-
 SupportsType MimeUtil::IsCodecSupported(const std::string& mime_type_lower_case,
                                         Codec codec,
                                         VideoCodecProfile video_profile,
diff --git a/media/base/mime_util_internal.h b/media/base/mime_util_internal.h
index d8677316..232f065 100644
--- a/media/base/mime_util_internal.h
+++ b/media/base/mime_util_internal.h
@@ -174,12 +174,6 @@
                                 const VideoColorSpace& eotf,
                                 bool is_encrypted) const;
 
-  // Wrapper around IsCodecSupported for simple codecs that are entirely
-  // described (or implied) by the container mime-type.
-  SupportsType IsSimpleCodecSupported(const std::string& mime_type_lower_case,
-                                      Codec codec,
-                                      bool is_encrypted) const;
-
   // Returns true if |codec| refers to a proprietary codec.
   bool IsCodecProprietary(Codec codec) const;
 
diff --git a/media/cdm/BUILD.gn b/media/cdm/BUILD.gn
index a3287d1..37e737c 100644
--- a/media/cdm/BUILD.gn
+++ b/media/cdm/BUILD.gn
@@ -31,6 +31,7 @@
 
     # TODO(crbug.com/676224): Move this to |enable_library_cdms| block below
     # when EnabledIf attribute is supported in mojom.
+    "cdm_proxy.cc",
     "cdm_proxy.h",
     "cenc_utils.cc",
     "cenc_utils.h",
diff --git a/media/cdm/cdm_proxy.cc b/media/cdm/cdm_proxy.cc
index 033ff63..3106351 100644
--- a/media/cdm/cdm_proxy.cc
+++ b/media/cdm/cdm_proxy.cc
@@ -6,7 +6,9 @@
 
 namespace media {
 
-CdmProxyKeyInfo::CdmProxyKeyInfo() = default;
-CdmProxyKeyInfo::~CdmProxyKeyInfo() = default;
+CdmProxy::Client::Client() = default;
+CdmProxy::Client::~Client() = default;
+CdmProxy::CdmProxy() = default;
+CdmProxy::~CdmProxy() = default;
 
-}  // namespace media
\ No newline at end of file
+}  // namespace media
diff --git a/media/cdm/cdm_proxy.h b/media/cdm/cdm_proxy.h
index 47094db..34599ba 100644
--- a/media/cdm/cdm_proxy.h
+++ b/media/cdm/cdm_proxy.h
@@ -23,10 +23,10 @@
 class MEDIA_EXPORT CdmProxy {
  public:
   // Client of the proxy.
-  class Client {
+  class MEDIA_EXPORT Client {
    public:
-    Client() {}
-    virtual ~Client() {}
+    Client();
+    virtual ~Client();
     // Called when there is a hardware reset and all the hardware context is
     // lost.
     virtual void NotifyHardwareReset() = 0;
@@ -54,8 +54,8 @@
     kMax = kIntelNegotiateCryptoSessionKeyExchange,
   };
 
-  CdmProxy() {}
-  virtual ~CdmProxy() {}
+  CdmProxy();
+  virtual ~CdmProxy();
 
   // Callback for Initialize(). If the proxy created a crypto session, then the
   // ID for the crypto session is |crypto_session_id|.
diff --git a/media/gpu/gles2_decoder_helper.cc b/media/gpu/gles2_decoder_helper.cc
index 25726f9a..62d061af 100644
--- a/media/gpu/gles2_decoder_helper.cc
+++ b/media/gpu/gles2_decoder_helper.cc
@@ -100,7 +100,7 @@
   gpu::Mailbox CreateMailbox(gpu::gles2::TextureRef* texture_ref) override {
     DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
     gpu::gles2::ContextGroup* group = decoder_->GetContextGroup();
-    gpu::gles2::MailboxManager* mailbox_manager = group->mailbox_manager();
+    gpu::MailboxManager* mailbox_manager = group->mailbox_manager();
     gpu::Mailbox mailbox = gpu::Mailbox::Generate();
     mailbox_manager->ProduceTexture(mailbox, texture_ref->texture());
     return mailbox;
diff --git a/media/gpu/ipc/service/gpu_video_decode_accelerator.cc b/media/gpu/ipc/service/gpu_video_decode_accelerator.cc
index c3be705..96b8d379 100644
--- a/media/gpu/ipc/service/gpu_video_decode_accelerator.cc
+++ b/media/gpu/ipc/service/gpu_video_decode_accelerator.cc
@@ -422,7 +422,7 @@
       return;
     }
     for (size_t j = 0; j < textures_per_buffer_; j++) {
-      gpu::gles2::TextureBase* texture_base =
+      gpu::TextureBase* texture_base =
           command_decoder->GetTextureBase(buffer_texture_ids[j]);
       if (!texture_base) {
         DLOG(ERROR) << "Failed to find texture id " << buffer_texture_ids[j];
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc
index 83c5c736..d85ea16 100644
--- a/media/gpu/vaapi/vaapi_wrapper.cc
+++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -633,25 +633,6 @@
 
 }  // namespace
 
-VaapiWrapper::VaapiWrapper()
-    : va_surface_format_(0),
-      va_display_(NULL),
-      va_config_id_(VA_INVALID_ID),
-      va_context_id_(VA_INVALID_ID),
-      va_vpp_config_id_(VA_INVALID_ID),
-      va_vpp_context_id_(VA_INVALID_ID),
-      va_vpp_buffer_id_(VA_INVALID_ID) {
-  va_lock_ = VADisplayState::Get()->va_lock();
-}
-
-VaapiWrapper::~VaapiWrapper() {
-  DestroyPendingBuffers();
-  DestroyCodedBuffers();
-  DestroySurfaces();
-  DeinitializeVpp();
-  Deinitialize();
-}
-
 // static
 scoped_refptr<VaapiWrapper> VaapiWrapper::Create(
     CodecMode mode,
@@ -743,63 +724,6 @@
                                                         VAProfileJPEGBaseline);
 }
 
-void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
-  base::AutoLock auto_lock(*va_lock_);
-  VADisplayAttribute item = {VADisplayAttribRenderMode,
-                             1,   // At least support '_LOCAL_OVERLAY'.
-                             -1,  // The maximum possible support 'ALL'.
-                             VA_RENDER_MODE_LOCAL_GPU,
-                             VA_DISPLAY_ATTRIB_SETTABLE};
-
-  VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1);
-  if (va_res != VA_STATUS_SUCCESS)
-    DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
-}
-
-bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) {
-  report_error_to_uma_cb_ = report_error_to_uma_cb;
-  {
-    base::AutoLock auto_lock(*va_lock_);
-    if (!VADisplayState::Get()->Initialize())
-      return false;
-  }
-
-  va_display_ = VADisplayState::Get()->va_display();
-  DCHECK(va_display_) << "VADisplayState hasn't been properly Initialize()d";
-  return true;
-}
-
-bool VaapiWrapper::Initialize(CodecMode mode, VAProfile va_profile) {
-  TryToSetVADisplayAttributeToLocalGPU();
-
-  VAEntrypoint entrypoint = GetVaEntryPoint(mode, va_profile);
-  std::vector<VAConfigAttrib> required_attribs =
-      GetRequiredAttribs(mode, va_profile);
-  base::AutoLock auto_lock(*va_lock_);
-  VAStatus va_res =
-      vaCreateConfig(va_display_, va_profile, entrypoint, &required_attribs[0],
-                     required_attribs.size(), &va_config_id_);
-  VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false);
-
-  return true;
-}
-
-void VaapiWrapper::Deinitialize() {
-  base::AutoLock auto_lock(*va_lock_);
-
-  if (va_config_id_ != VA_INVALID_ID) {
-    VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_);
-    VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed");
-  }
-
-  VAStatus va_res = VA_STATUS_SUCCESS;
-  VADisplayState::Get()->Deinitialize(&va_res);
-  VA_LOG_ON_ERROR(va_res, "vaTerminate failed");
-
-  va_config_id_ = VA_INVALID_ID;
-  va_display_ = NULL;
-}
-
 bool VaapiWrapper::CreateSurfaces(unsigned int va_format,
                                   const gfx::Size& size,
                                   size_t num_surfaces,
@@ -846,25 +770,6 @@
   DestroySurfaces_Locked();
 }
 
-void VaapiWrapper::DestroySurfaces_Locked() {
-  va_lock_->AssertAcquired();
-
-  if (va_context_id_ != VA_INVALID_ID) {
-    VAStatus va_res = vaDestroyContext(va_display_, va_context_id_);
-    VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed");
-  }
-
-  if (!va_surface_ids_.empty()) {
-    VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0],
-                                        va_surface_ids_.size());
-    VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed");
-  }
-
-  va_surface_ids_.clear();
-  va_context_id_ = VA_INVALID_ID;
-  va_surface_format_ = 0;
-}
-
 scoped_refptr<VASurface> VaapiWrapper::CreateUnownedSurface(
     unsigned int va_format,
     const gfx::Size& size,
@@ -957,13 +862,6 @@
   return va_surface;
 }
 
-void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface_id) {
-  base::AutoLock auto_lock(*va_lock_);
-
-  VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1);
-  VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on surface failed");
-}
-
 bool VaapiWrapper::SubmitBuffer(VABufferType va_buffer_type,
                                 size_t size,
                                 void* buffer) {
@@ -1039,63 +937,6 @@
   pending_slice_bufs_.clear();
 }
 
-bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) {
-  base::AutoLock auto_lock(*va_lock_);
-  VAStatus va_res =
-      vaCreateBuffer(va_display_, va_context_id_, VAEncCodedBufferType, size, 1,
-                     NULL, buffer_id);
-  VA_SUCCESS_OR_RETURN(va_res, "Failed to create a coded buffer", false);
-
-  const auto is_new_entry = coded_buffers_.insert(*buffer_id).second;
-  DCHECK(is_new_entry);
-  return true;
-}
-
-void VaapiWrapper::DestroyCodedBuffers() {
-  base::AutoLock auto_lock(*va_lock_);
-
-  for (std::set<VABufferID>::const_iterator iter = coded_buffers_.begin();
-       iter != coded_buffers_.end(); ++iter) {
-    VAStatus va_res = vaDestroyBuffer(va_display_, *iter);
-    VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
-  }
-
-  coded_buffers_.clear();
-}
-
-bool VaapiWrapper::Execute(VASurfaceID va_surface_id) {
-  base::AutoLock auto_lock(*va_lock_);
-
-  DVLOG(4) << "Pending VA bufs to commit: " << pending_va_bufs_.size();
-  DVLOG(4) << "Pending slice bufs to commit: " << pending_slice_bufs_.size();
-  DVLOG(4) << "Target VA surface " << va_surface_id;
-
-  // Get ready to execute for given surface.
-  VAStatus va_res = vaBeginPicture(va_display_, va_context_id_, va_surface_id);
-  VA_SUCCESS_OR_RETURN(va_res, "vaBeginPicture failed", false);
-
-  if (pending_va_bufs_.size() > 0) {
-    // Commit parameter and slice buffers.
-    va_res = vaRenderPicture(va_display_, va_context_id_, &pending_va_bufs_[0],
-                             pending_va_bufs_.size());
-    VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for va_bufs failed", false);
-  }
-
-  if (pending_slice_bufs_.size() > 0) {
-    va_res =
-        vaRenderPicture(va_display_, va_context_id_, &pending_slice_bufs_[0],
-                        pending_slice_bufs_.size());
-    VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for slices failed", false);
-  }
-
-  // Instruct HW codec to start processing committed buffers.
-  // Does not block and the job is not finished after this returns.
-  va_res = vaEndPicture(va_display_, va_context_id_);
-  VA_SUCCESS_OR_RETURN(va_res, "vaEndPicture failed", false);
-
-  return true;
-}
-
 bool VaapiWrapper::ExecuteAndDestroyPendingBuffers(VASurfaceID va_surface_id) {
   bool result = Execute(va_surface_id);
   DestroyPendingBuffers();
@@ -1210,6 +1051,18 @@
   return ret == 0;
 }
 
+bool VaapiWrapper::CreateCodedBuffer(size_t size, VABufferID* buffer_id) {
+  base::AutoLock auto_lock(*va_lock_);
+  VAStatus va_res =
+      vaCreateBuffer(va_display_, va_context_id_, VAEncCodedBufferType, size, 1,
+                     NULL, buffer_id);
+  VA_SUCCESS_OR_RETURN(va_res, "Failed to create a coded buffer", false);
+
+  const auto is_new_entry = coded_buffers_.insert(*buffer_id).second;
+  DCHECK(is_new_entry);
+  return true;
+}
+
 bool VaapiWrapper::DownloadFromCodedBuffer(VABufferID buffer_id,
                                            VASurfaceID sync_surface_id,
                                            uint8_t* target_ptr,
@@ -1270,6 +1123,18 @@
   return result;
 }
 
+void VaapiWrapper::DestroyCodedBuffers() {
+  base::AutoLock auto_lock(*va_lock_);
+
+  for (std::set<VABufferID>::const_iterator iter = coded_buffers_.begin();
+       iter != coded_buffers_.end(); ++iter) {
+    VAStatus va_res = vaDestroyBuffer(va_display_, *iter);
+    VA_LOG_ON_ERROR(va_res, "vaDestroyBuffer failed");
+  }
+
+  coded_buffers_.clear();
+}
+
 bool VaapiWrapper::BlitSurface(
     const scoped_refptr<VASurface>& va_surface_src,
     const scoped_refptr<VASurface>& va_surface_dest) {
@@ -1324,6 +1189,100 @@
   return true;
 }
 
+// static
+void VaapiWrapper::PreSandboxInitialization() {
+  VADisplayState::PreSandboxInitialization();
+}
+
+VaapiWrapper::VaapiWrapper()
+    : va_surface_format_(0),
+      va_display_(NULL),
+      va_config_id_(VA_INVALID_ID),
+      va_context_id_(VA_INVALID_ID),
+      va_vpp_config_id_(VA_INVALID_ID),
+      va_vpp_context_id_(VA_INVALID_ID),
+      va_vpp_buffer_id_(VA_INVALID_ID) {
+  va_lock_ = VADisplayState::Get()->va_lock();
+}
+
+VaapiWrapper::~VaapiWrapper() {
+  DestroyPendingBuffers();
+  DestroyCodedBuffers();
+  DestroySurfaces();
+  DeinitializeVpp();
+  Deinitialize();
+}
+
+bool VaapiWrapper::Initialize(CodecMode mode, VAProfile va_profile) {
+  TryToSetVADisplayAttributeToLocalGPU();
+
+  VAEntrypoint entrypoint = GetVaEntryPoint(mode, va_profile);
+  std::vector<VAConfigAttrib> required_attribs =
+      GetRequiredAttribs(mode, va_profile);
+  base::AutoLock auto_lock(*va_lock_);
+  VAStatus va_res =
+      vaCreateConfig(va_display_, va_profile, entrypoint, &required_attribs[0],
+                     required_attribs.size(), &va_config_id_);
+  VA_SUCCESS_OR_RETURN(va_res, "vaCreateConfig failed", false);
+
+  return true;
+}
+
+void VaapiWrapper::Deinitialize() {
+  base::AutoLock auto_lock(*va_lock_);
+
+  if (va_config_id_ != VA_INVALID_ID) {
+    VAStatus va_res = vaDestroyConfig(va_display_, va_config_id_);
+    VA_LOG_ON_ERROR(va_res, "vaDestroyConfig failed");
+  }
+
+  VAStatus va_res = VA_STATUS_SUCCESS;
+  VADisplayState::Get()->Deinitialize(&va_res);
+  VA_LOG_ON_ERROR(va_res, "vaTerminate failed");
+
+  va_config_id_ = VA_INVALID_ID;
+  va_display_ = NULL;
+}
+
+bool VaapiWrapper::VaInitialize(const base::Closure& report_error_to_uma_cb) {
+  report_error_to_uma_cb_ = report_error_to_uma_cb;
+  {
+    base::AutoLock auto_lock(*va_lock_);
+    if (!VADisplayState::Get()->Initialize())
+      return false;
+  }
+
+  va_display_ = VADisplayState::Get()->va_display();
+  DCHECK(va_display_) << "VADisplayState hasn't been properly Initialize()d";
+  return true;
+}
+
+void VaapiWrapper::DestroySurfaces_Locked() {
+  va_lock_->AssertAcquired();
+
+  if (va_context_id_ != VA_INVALID_ID) {
+    VAStatus va_res = vaDestroyContext(va_display_, va_context_id_);
+    VA_LOG_ON_ERROR(va_res, "vaDestroyContext failed");
+  }
+
+  if (!va_surface_ids_.empty()) {
+    VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_ids_[0],
+                                        va_surface_ids_.size());
+    VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces failed");
+  }
+
+  va_surface_ids_.clear();
+  va_context_id_ = VA_INVALID_ID;
+  va_surface_format_ = 0;
+}
+
+void VaapiWrapper::DestroyUnownedSurface(VASurfaceID va_surface_id) {
+  base::AutoLock auto_lock(*va_lock_);
+
+  VAStatus va_res = vaDestroySurfaces(va_display_, &va_surface_id, 1);
+  VA_LOG_ON_ERROR(va_res, "vaDestroySurfaces on surface failed");
+}
+
 bool VaapiWrapper::InitializeVpp_Locked() {
   va_lock_->AssertAcquired();
 
@@ -1364,9 +1323,50 @@
   }
 }
 
-// static
-void VaapiWrapper::PreSandboxInitialization() {
-  VADisplayState::PreSandboxInitialization();
+bool VaapiWrapper::Execute(VASurfaceID va_surface_id) {
+  base::AutoLock auto_lock(*va_lock_);
+
+  DVLOG(4) << "Pending VA bufs to commit: " << pending_va_bufs_.size();
+  DVLOG(4) << "Pending slice bufs to commit: " << pending_slice_bufs_.size();
+  DVLOG(4) << "Target VA surface " << va_surface_id;
+
+  // Get ready to execute for given surface.
+  VAStatus va_res = vaBeginPicture(va_display_, va_context_id_, va_surface_id);
+  VA_SUCCESS_OR_RETURN(va_res, "vaBeginPicture failed", false);
+
+  if (pending_va_bufs_.size() > 0) {
+    // Commit parameter and slice buffers.
+    va_res = vaRenderPicture(va_display_, va_context_id_, &pending_va_bufs_[0],
+                             pending_va_bufs_.size());
+    VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for va_bufs failed", false);
+  }
+
+  if (pending_slice_bufs_.size() > 0) {
+    va_res =
+        vaRenderPicture(va_display_, va_context_id_, &pending_slice_bufs_[0],
+                        pending_slice_bufs_.size());
+    VA_SUCCESS_OR_RETURN(va_res, "vaRenderPicture for slices failed", false);
+  }
+
+  // Instruct HW codec to start processing committed buffers.
+  // Does not block and the job is not finished after this returns.
+  va_res = vaEndPicture(va_display_, va_context_id_);
+  VA_SUCCESS_OR_RETURN(va_res, "vaEndPicture failed", false);
+
+  return true;
+}
+
+void VaapiWrapper::TryToSetVADisplayAttributeToLocalGPU() {
+  base::AutoLock auto_lock(*va_lock_);
+  VADisplayAttribute item = {VADisplayAttribRenderMode,
+                             1,   // At least support '_LOCAL_OVERLAY'.
+                             -1,  // The maximum possible support 'ALL'.
+                             VA_RENDER_MODE_LOCAL_GPU,
+                             VA_DISPLAY_ATTRIB_SETTABLE};
+
+  VAStatus va_res = vaSetDisplayAttributes(va_display_, &item, 1);
+  if (va_res != VA_STATUS_SUCCESS)
+    DVLOG(2) << "vaSetDisplayAttributes unsupported, ignoring by default.";
 }
 
 }  // namespace media
diff --git a/mojo/common/logfont_win.typemap b/mojo/common/logfont_win.typemap
index 71057708..488d22e 100644
--- a/mojo/common/logfont_win.typemap
+++ b/mojo/common/logfont_win.typemap
@@ -4,7 +4,7 @@
 
 mojom = "//mojo/common/logfont_win.mojom"
 os_whitelist = [ "win" ]
-public_headers = []
+public_headers = [ "//base/win/windows_full.h" ]
 traits_headers = [ "//ipc/ipc_message_utils.h" ]
 public_deps = [
   "//ipc",
diff --git a/mojo/public/tools/bindings/BUILD.gn b/mojo/public/tools/bindings/BUILD.gn
index 5be5586e..500ae54 100644
--- a/mojo/public/tools/bindings/BUILD.gn
+++ b/mojo/public/tools/bindings/BUILD.gn
@@ -29,6 +29,7 @@
     "$mojom_generator_root/generators/cpp_templates/struct_serialization_declaration.tmpl",
     "$mojom_generator_root/generators/cpp_templates/struct_traits_declaration.tmpl",
     "$mojom_generator_root/generators/cpp_templates/struct_traits_definition.tmpl",
+    "$mojom_generator_root/generators/cpp_templates/struct_unserialized_message_context.tmpl",
     "$mojom_generator_root/generators/cpp_templates/union_data_view_declaration.tmpl",
     "$mojom_generator_root/generators/cpp_templates/union_data_view_definition.tmpl",
     "$mojom_generator_root/generators/cpp_templates/union_declaration.tmpl",
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
index 21e5025..fd6c27ce 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
@@ -76,6 +76,7 @@
 {%- for struct in structs %}
 {%-   if not struct|is_native_only_kind %}
 {%      include "struct_declaration.tmpl" %}
+{%      include "struct_unserialized_message_context.tmpl" %}
 {%-   endif %}
 {%- endfor %}
 
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_unserialized_message_context.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_unserialized_message_context.tmpl
new file mode 100644
index 0000000..2ee085d5
--- /dev/null
+++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_unserialized_message_context.tmpl
@@ -0,0 +1,33 @@
+// Used by {{struct.name}}::WrapAsMessage to lazily serialize the struct.
+template <typename UserType, typename DataView>
+struct {{struct.name}}_UnserializedMessageContext
+    : public mojo::internal::UnserializedMessageContext {
+ public:
+  static const mojo::internal::UnserializedMessageContext::Tag kMessageTag;
+
+  {{struct.name}}_UnserializedMessageContext(
+    uint32_t message_name,
+    uint32_t message_flags,
+    UserType input)
+      : mojo::internal::UnserializedMessageContext(&kMessageTag, message_name, message_flags)
+      , user_data_(std::move(input)) {}
+  ~{{struct.name}}_UnserializedMessageContext() override = default;
+
+  UserType TakeData() {
+    return std::move(user_data_);
+  }
+
+ private:
+  // mojo::internal::UnserializedMessageContext:
+  void Serialize(mojo::internal::SerializationContext* context,
+                 mojo::internal::Buffer* buffer) override {
+    {{struct.name}}_Data::BufferWriter writer;
+    mojo::internal::Serialize<DataView>(user_data_, buffer, &writer, context);
+  }
+
+  UserType user_data_;
+};
+
+template <typename UserType, typename DataView>
+const mojo::internal::UnserializedMessageContext::Tag
+    {{struct.name}}_UnserializedMessageContext<UserType, DataView>::kMessageTag = {};
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
index 545dd35..e9092da8 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
@@ -77,6 +77,17 @@
         {{struct.name}}::DataView>(input);
   }
 
+  // The returned Message is serialized only if the message is moved
+  // cross-process or cross-language. Otherwise if the message is Deserialized
+  // as the same UserType |input| will just be moved to |output| in
+  // DeserializeFromMessage.
+  template <typename UserType>
+  static mojo::Message WrapAsMessage(UserType input) {
+    return mojo::Message(std::make_unique<
+        internal::{{struct.name}}_UnserializedMessageContext<
+            UserType, {{struct.name}}::DataView>>(0, 0, std::move(input)));
+  }
+
   template <typename UserType>
   static bool Deserialize(const void* data,
                           size_t data_num_bytes,
@@ -95,6 +106,14 @@
   template <typename UserType>
   static bool DeserializeFromMessage(mojo::Message input,
                                      UserType* output) {
+    auto context = input.TakeUnserializedContext<
+        internal::{{struct.name}}_UnserializedMessageContext<
+            UserType, {{struct.name}}::DataView>>();
+    if (context) {
+      *output = std::move(context->TakeData());
+      return true;
+    }
+    input.SerializeIfNecessary();
     return mojo::internal::StructDeserializeImpl<{{struct.name}}::DataView>(
         input.payload(), input.payload_num_bytes(),
         std::move(*input.mutable_handles()), output, Validate);
diff --git a/net/base/platform_mime_util_win.cc b/net/base/platform_mime_util_win.cc
index d68aa8c..89b36ec 100644
--- a/net/base/platform_mime_util_win.cc
+++ b/net/base/platform_mime_util_win.cc
@@ -9,6 +9,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/registry.h"
 
+#include <windows.h>
+
 namespace net {
 
 bool PlatformMimeUtil::GetPlatformMimeTypeFromExtension(
diff --git a/net/disk_cache/blockfile/mapped_file_win.cc b/net/disk_cache/blockfile/mapped_file_win.cc
index 9a128a3..706ae09 100644
--- a/net/disk_cache/blockfile/mapped_file_win.cc
+++ b/net/disk_cache/blockfile/mapped_file_win.cc
@@ -10,6 +10,8 @@
 #include "base/logging.h"
 #include "net/disk_cache/disk_cache.h"
 
+#include <windows.h>
+
 namespace disk_cache {
 
 void* MappedFile::Init(const base::FilePath& name, size_t size) {
diff --git a/net/disk_cache/blockfile/rankings.cc b/net/disk_cache/blockfile/rankings.cc
index 68d2c3b..41a47a3 100644
--- a/net/disk_cache/blockfile/rankings.cc
+++ b/net/disk_cache/blockfile/rankings.cc
@@ -9,6 +9,7 @@
 #include <limits>
 
 #include "base/macros.h"
+#include "build/build_config.h"
 #include "net/base/net_export.h"
 #include "net/disk_cache/blockfile/backend_impl.h"
 #include "net/disk_cache/blockfile/disk_format.h"
@@ -17,6 +18,10 @@
 #include "net/disk_cache/blockfile/histogram_macros.h"
 #include "net/disk_cache/blockfile/stress_support.h"
 
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
 // Provide a BackendImpl object to macros from histogram_macros.h.
 #define CACHE_UMA_BACKEND_IMPL_OBJ backend_
 
diff --git a/net/http2/decoder/http2_frame_decoder_test.cc b/net/http2/decoder/http2_frame_decoder_test.cc
index a1d8483..d81c7ac 100644
--- a/net/http2/decoder/http2_frame_decoder_test.cc
+++ b/net/http2/decoder/http2_frame_decoder_test.cc
@@ -196,7 +196,7 @@
   template <size_t N>
   AssertionResult DecodePayloadExpectingFrameSizeError(const char (&buf)[N],
                                                        FrameParts expected) {
-    expected.has_frame_size_error = true;
+    expected.SetHasFrameSizeError(true);
     VERIFY_AND_RETURN_SUCCESS(DecodePayloadExpectingError(buf, expected));
   }
 
@@ -260,7 +260,7 @@
   };
   Http2FrameHeader header(5, Http2FrameType::PRIORITY, 0, 2);
   FrameParts expected(header);
-  expected.opt_priority = Http2PriorityFields(1, 17, true);
+  expected.SetOptPriority(Http2PriorityFields(1, 17, true));
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -274,7 +274,7 @@
   };
   Http2FrameHeader header(4, Http2FrameType::RST_STREAM, 0, 1);
   FrameParts expected(header);
-  expected.opt_rst_stream_error_code = Http2ErrorCode::PROTOCOL_ERROR;
+  expected.SetOptRstStreamErrorCode(Http2ErrorCode::PROTOCOL_ERROR);
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -312,7 +312,7 @@
   Http2FrameHeader header(4, Http2FrameType::PUSH_PROMISE,
                           Http2FrameFlag::END_HEADERS, 2);
   FrameParts expected(header, "");
-  expected.opt_push_promise = Http2PushPromiseFields{1};
+  expected.SetOptPushPromise(Http2PushPromiseFields{1});
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -327,7 +327,8 @@
   };
   Http2FrameHeader header(8, Http2FrameType::PING, 0, 0);
   FrameParts expected(header);
-  expected.opt_ping = Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}};
+  expected.SetOptPing(
+      Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}});
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -342,7 +343,8 @@
   };
   Http2FrameHeader header(8, Http2FrameType::PING, Http2FrameFlag::ACK, 0);
   FrameParts expected(header);
-  expected.opt_ping = Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}};
+  expected.SetOptPing(
+      Http2PingFields{{'s', 'o', 'm', 'e', 'd', 'a', 't', 'a'}});
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -357,8 +359,8 @@
   };
   Http2FrameHeader header(8, Http2FrameType::GOAWAY, 0, 1);
   FrameParts expected(header);
-  expected.opt_goaway =
-      Http2GoAwayFields(255, Http2ErrorCode::COMPRESSION_ERROR);
+  expected.SetOptGoaway(
+      Http2GoAwayFields(255, Http2ErrorCode::COMPRESSION_ERROR));
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -372,7 +374,7 @@
   };
   Http2FrameHeader header(4, Http2FrameType::WINDOW_UPDATE, 0, 1);
   FrameParts expected(header);
-  expected.opt_window_update_increment = 1024;
+  expected.SetOptWindowUpdateIncrement(1024);
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -398,8 +400,8 @@
   };
   Http2FrameHeader header(2, Http2FrameType::ALTSVC, 0, 0);
   FrameParts expected(header);
-  expected.opt_altsvc_origin_length = 0;
-  expected.opt_altsvc_value_length = 0;
+  expected.SetOptAltsvcOriginLength(0);
+  expected.SetOptAltsvcValueLength(0);
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -458,7 +460,7 @@
   Http2FrameHeader header(5, Http2FrameType::HEADERS, Http2FrameFlag::PRIORITY,
                           2);
   FrameParts expected(header);
-  expected.opt_priority = Http2PriorityFields(1, 256, false);
+  expected.SetOptPriority(Http2PriorityFields(1, 256, false));
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -475,9 +477,9 @@
   };
   Http2FrameHeader header(12, Http2FrameType::SETTINGS, 0, 0);
   FrameParts expected(header);
-  expected.settings.push_back(Http2SettingFields(
+  expected.AppendSetting(Http2SettingFields(
       Http2SettingsParameter::INITIAL_WINDOW_SIZE, 168496141));
-  expected.settings.push_back(
+  expected.AppendSetting(
       Http2SettingFields(Http2SettingsParameter::ENABLE_PUSH, 3));
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
@@ -494,7 +496,7 @@
   Http2FrameHeader header(7, Http2FrameType::PUSH_PROMISE,
                           Http2FrameFlag::END_HEADERS, 255);
   FrameParts expected(header, "abc");
-  expected.opt_push_promise = Http2PushPromiseFields{256};
+  expected.SetOptPushPromise(Http2PushPromiseFields{256});
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -510,8 +512,8 @@
   };
   Http2FrameHeader header(14, Http2FrameType::GOAWAY, 0, 0);
   FrameParts expected(header, "opaque");
-  expected.opt_goaway =
-      Http2GoAwayFields(256, Http2ErrorCode::FLOW_CONTROL_ERROR);
+  expected.SetOptGoaway(
+      Http2GoAwayFields(256, Http2ErrorCode::FLOW_CONTROL_ERROR));
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -615,7 +617,7 @@
                           2);
   size_t total_pad_length = 4;  // Including the Pad Length field.
   FrameParts expected(header, "abc", total_pad_length);
-  expected.opt_priority = Http2PriorityFields(1, 17, true);
+  expected.SetOptPriority(Http2PriorityFields(1, 17, true));
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -635,7 +637,7 @@
                           1);
   size_t total_pad_length = 4;  // Including the Pad Length field.
   FrameParts expected(header, "abc", total_pad_length);
-  expected.opt_push_promise = Http2PushPromiseFields{2};
+  expected.SetOptPushPromise(Http2PushPromiseFields{2});
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(kFrameData, expected));
 }
 
@@ -651,7 +653,7 @@
   };
   Http2FrameHeader header(0, Http2FrameType::DATA, Http2FrameFlag::PADDED, 1);
   FrameParts expected(header);
-  expected.opt_missing_length = 1;
+  expected.SetOptMissingLength(1);
   EXPECT_TRUE(DecodePayloadExpectingError(kFrameData, expected));
 }
 
@@ -667,7 +669,7 @@
   Http2FrameHeader header(2, Http2FrameType::HEADERS, Http2FrameFlag::PADDED,
                           65536);
   FrameParts expected(header);
-  expected.opt_missing_length = 254;
+  expected.SetOptMissingLength(254);
   EXPECT_TRUE(DecodePayloadExpectingError(kFrameData, expected));
 }
 
@@ -723,7 +725,7 @@
   };
   Http2FrameHeader header(9, Http2FrameType::SETTINGS, 0, 0);
   FrameParts expected(header);
-  expected.settings.push_back(
+  expected.AppendSetting(
       Http2SettingFields(Http2SettingsParameter::ENABLE_PUSH, 3));
   EXPECT_TRUE(DecodePayloadExpectingFrameSizeError(kFrameData, expected));
 }
@@ -835,7 +837,7 @@
                           Http2FrameFlag::END_STREAM | Http2FrameFlag::PADDED,
                           2);
   FrameParts expected(header);
-  expected.has_frame_size_error = true;
+  expected.SetHasFrameSizeError(true);
   auto validator = [&expected, this](const DecodeBuffer& input,
                                      DecodeStatus status) -> AssertionResult {
     VERIFY_EQ(status, DecodeStatus::kDecodeError);
diff --git a/net/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc b/net/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc
index 74bcd18b..42b359f7 100644
--- a/net/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc
+++ b/net/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc
@@ -98,7 +98,7 @@
                           RandStreamId());
   set_frame_header(header);
   FrameParts expected(header, opaque_data);
-  expected.opt_goaway = goaway;
+  expected.SetOptGoaway(goaway);
   ASSERT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
 }
 
diff --git a/net/http2/decoder/payload_decoders/headers_payload_decoder_test.cc b/net/http2/decoder/payload_decoders/headers_payload_decoder_test.cc
index 75282d9..1889dde 100644
--- a/net/http2/decoder/payload_decoders/headers_payload_decoder_test.cc
+++ b/net/http2/decoder/payload_decoders/headers_payload_decoder_test.cc
@@ -126,7 +126,7 @@
       ScrubFlagsOfHeader(&frame_header);
       FrameParts expected(frame_header, hpack_payload, total_pad_length_);
       if (has_priority) {
-        expected.opt_priority = priority;
+        expected.SetOptPriority(priority);
       }
       EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(frame_builder_.buffer(),
                                                       expected));
diff --git a/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h b/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
index 43be7b5..67033fa 100644
--- a/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
+++ b/net/http2/decoder/payload_decoders/payload_decoder_base_test_util.h
@@ -232,11 +232,11 @@
       VERIFY_FALSE(listener_.IsInProgress());
       VERIFY_EQ(1u, listener_.size());
       const FrameParts* frame = listener_.frame(0);
-      VERIFY_EQ(header, frame->frame_header);
-      VERIFY_TRUE(frame->has_frame_size_error);
+      VERIFY_EQ(header, frame->GetFrameHeader());
+      VERIFY_TRUE(frame->GetHasFrameSizeError());
       // Verify did not get OnPaddingTooLong, as we should only ever produce
       // one of these two errors for a single frame.
-      VERIFY_FALSE(frame->opt_missing_length);
+      VERIFY_FALSE(frame->GetOptMissingLength());
       return validator(input, status);
     };
     VERIFY_AND_RETURN_SUCCESS(
@@ -403,11 +403,11 @@
       VERIFY_FALSE(listener.IsInProgress());
       VERIFY_EQ(1u, listener.size());
       const FrameParts* frame = listener.frame(0);
-      VERIFY_EQ(header, frame->frame_header);
-      VERIFY_TRUE(frame->opt_missing_length);
-      VERIFY_EQ(expected_missing_length, frame->opt_missing_length.value());
+      VERIFY_EQ(header, frame->GetFrameHeader());
+      VERIFY_TRUE(frame->GetOptMissingLength());
+      VERIFY_EQ(expected_missing_length, frame->GetOptMissingLength().value());
       // Verify did not get OnFrameSizeError.
-      VERIFY_FALSE(frame->has_frame_size_error);
+      VERIFY_FALSE(frame->GetHasFrameSizeError());
       return ::testing::AssertionSuccess();
     };
     VERIFY_AND_RETURN_SUCCESS(
diff --git a/net/http2/decoder/payload_decoders/ping_payload_decoder_test.cc b/net/http2/decoder/payload_decoders/ping_payload_decoder_test.cc
index 04e0b44..fbe5fef 100644
--- a/net/http2/decoder/payload_decoders/ping_payload_decoder_test.cc
+++ b/net/http2/decoder/payload_decoders/ping_payload_decoder_test.cc
@@ -85,7 +85,7 @@
                             RandFlags() & ~Http2FrameFlag::ACK, RandStreamId());
     set_frame_header(header);
     FrameParts expected(header);
-    expected.opt_ping = fields;
+    expected.SetOptPing(fields);
     EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
   }
 }
@@ -100,7 +100,7 @@
                             RandFlags() | Http2FrameFlag::ACK, RandStreamId());
     set_frame_header(header);
     FrameParts expected(header);
-    expected.opt_ping = fields;
+    expected.SetOptPing(fields);
     EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
   }
 }
diff --git a/net/http2/decoder/payload_decoders/priority_payload_decoder_test.cc b/net/http2/decoder/payload_decoders/priority_payload_decoder_test.cc
index 53123631..b9229ad 100644
--- a/net/http2/decoder/payload_decoders/priority_payload_decoder_test.cc
+++ b/net/http2/decoder/payload_decoders/priority_payload_decoder_test.cc
@@ -80,7 +80,7 @@
                             RandStreamId());
     set_frame_header(header);
     FrameParts expected(header);
-    expected.opt_priority = fields;
+    expected.SetOptPriority(fields);
     EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
   }
 }
diff --git a/net/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc b/net/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc
index 92fd183c..537439f 100644
--- a/net/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc
+++ b/net/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc
@@ -108,7 +108,7 @@
                                   RandStreamId());
     set_frame_header(frame_header);
     FrameParts expected(frame_header, hpack_payload, total_pad_length_);
-    expected.opt_push_promise = push_promise;
+    expected.SetOptPushPromise(push_promise);
     EXPECT_TRUE(
         DecodePayloadAndValidateSeveralWays(frame_builder_.buffer(), expected));
   }
diff --git a/net/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc b/net/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc
index 741c444..c28decb 100644
--- a/net/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc
+++ b/net/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc
@@ -82,7 +82,7 @@
                             RandStreamId());
     set_frame_header(header);
     FrameParts expected(header);
-    expected.opt_rst_stream_error_code = error_code;
+    expected.SetOptRstStreamErrorCode(error_code);
     EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
   }
 }
diff --git a/net/http2/decoder/payload_decoders/settings_payload_decoder_test.cc b/net/http2/decoder/payload_decoders/settings_payload_decoder_test.cc
index 1764dc2..6f81f8e7 100644
--- a/net/http2/decoder/payload_decoders/settings_payload_decoder_test.cc
+++ b/net/http2/decoder/payload_decoders/settings_payload_decoder_test.cc
@@ -129,7 +129,7 @@
                               RandStreamId());
       set_frame_header(header);
       FrameParts expected(header);
-      expected.settings.push_back(fields);
+      expected.AppendSetting(fields);
       EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
     }
   }
@@ -149,7 +149,7 @@
     Http2SettingFields fields(static_cast<Http2SettingsParameter>(n),
                               Random().Rand32());
     fb.Append(fields);
-    expected.settings.push_back(fields);
+    expected.AppendSetting(fields);
   }
   ASSERT_EQ(size, fb.size());
   EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
diff --git a/net/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc b/net/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc
index e46d55bd..4626b36 100644
--- a/net/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc
+++ b/net/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc
@@ -86,7 +86,7 @@
                             RandFlags(), stream_id);
     set_frame_header(header);
     FrameParts expected(header);
-    expected.opt_window_update_increment = fields.window_size_increment;
+    expected.SetOptWindowUpdateIncrement(fields.window_size_increment);
     EXPECT_TRUE(DecodePayloadAndValidateSeveralWays(fb.buffer(), expected));
   }
 }
diff --git a/net/http2/hpack/decoder/hpack_decoder_state_test.cc b/net/http2/hpack/decoder/hpack_decoder_state_test.cc
index 3674db0..22a8179e 100644
--- a/net/http2/hpack/decoder/hpack_decoder_state_test.cc
+++ b/net/http2/hpack/decoder/hpack_decoder_state_test.cc
@@ -11,6 +11,7 @@
 
 #include "base/logging.h"
 #include "net/http2/hpack/hpack_string.h"
+#include "net/http2/hpack/http2_hpack_constants.h"
 #include "net/http2/http2_constants.h"
 #include "net/http2/platform/api/http2_string.h"
 #include "net/http2/tools/failure.h"
diff --git a/net/http2/hpack/decoder/hpack_decoder_tables.cc b/net/http2/hpack/decoder/hpack_decoder_tables.cc
index c185dfc..4ff2b06a 100644
--- a/net/http2/hpack/decoder/hpack_decoder_tables.cc
+++ b/net/http2/hpack/decoder/hpack_decoder_tables.cc
@@ -5,6 +5,7 @@
 #include "net/http2/hpack/decoder/hpack_decoder_tables.h"
 
 #include "base/logging.h"
+#include "net/http2/hpack/http2_hpack_constants.h"
 
 namespace net {
 namespace {
diff --git a/net/http2/hpack/decoder/hpack_decoder_tables.h b/net/http2/hpack/decoder/hpack_decoder_tables.h
index 1de2814..35c2505 100644
--- a/net/http2/hpack/decoder/hpack_decoder_tables.h
+++ b/net/http2/hpack/decoder/hpack_decoder_tables.h
@@ -31,9 +31,6 @@
 class HpackDecoderTablesPeer;
 }  // namespace test
 
-// TODO(jamessynge): Move to hpack_constants.h
-const size_t kFirstDynamicTableIndex = 62;
-
 // HpackDecoderTablesDebugListener supports a QUIC experiment, enabling
 // the gathering of information about the time-line of use of HPACK
 // dynamic table entries.
diff --git a/net/http2/hpack/decoder/hpack_decoder_tables_test.cc b/net/http2/hpack/decoder/hpack_decoder_tables_test.cc
index 77c2413..8e47aba 100644
--- a/net/http2/hpack/decoder/hpack_decoder_tables_test.cc
+++ b/net/http2/hpack/decoder/hpack_decoder_tables_test.cc
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/logging.h"
+#include "net/http2/hpack/http2_hpack_constants.h"
 #include "net/http2/platform/api/http2_string.h"
 #include "net/http2/tools/failure.h"
 #include "net/http2/tools/http2_random.h"
diff --git a/net/http2/hpack/http2_hpack_constants.h b/net/http2/hpack/http2_hpack_constants.h
index a2a29e32..38d5812f 100644
--- a/net/http2/hpack/http2_hpack_constants.h
+++ b/net/http2/hpack/http2_hpack_constants.h
@@ -17,6 +17,8 @@
 
 namespace net {
 
+const size_t kFirstDynamicTableIndex = 62;
+
 enum class HpackEntryType {
   // Entry is an index into the static or dynamic table. Decoding it has no
   // effect on the dynamic table.
@@ -55,7 +57,6 @@
 // Inserts the name of the enum member into |out|.
 HTTP2_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
                                               HpackEntryType v);
-
 }  // namespace net
 
 #endif  // NET_HTTP2_HPACK_HTTP2_HPACK_CONSTANTS_H_
diff --git a/net/http2/test_tools/frame_parts.cc b/net/http2/test_tools/frame_parts.cc
index 399c3fd7..95b8466 100644
--- a/net/http2/test_tools/frame_parts.cc
+++ b/net/http2/test_tools/frame_parts.cc
@@ -46,15 +46,15 @@
 
 }  // namespace
 
-FrameParts::FrameParts(const Http2FrameHeader& header) : frame_header(header) {
-  VLOG(1) << "FrameParts, header: " << frame_header;
+FrameParts::FrameParts(const Http2FrameHeader& header) : frame_header_(header) {
+  VLOG(1) << "FrameParts, header: " << frame_header_;
 }
 
 FrameParts::FrameParts(const Http2FrameHeader& header, Http2StringPiece payload)
     : FrameParts(header) {
   VLOG(1) << "FrameParts with payload.size() = " << payload.size();
-  this->payload.append(payload.data(), payload.size());
-  opt_payload_length = payload.size();
+  this->payload_.append(payload.data(), payload.size());
+  opt_payload_length_ = payload.size();
 }
 FrameParts::FrameParts(const Http2FrameHeader& header,
                        Http2StringPiece payload,
@@ -71,26 +71,26 @@
 AssertionResult FrameParts::VerifyEquals(const FrameParts& that) const {
 #define COMMON_MESSAGE "\n  this: " << *this << "\n  that: " << that
 
-  VERIFY_EQ(frame_header, that.frame_header) << COMMON_MESSAGE;
-  VERIFY_EQ(payload, that.payload) << COMMON_MESSAGE;
-  VERIFY_EQ(padding, that.padding) << COMMON_MESSAGE;
-  VERIFY_EQ(altsvc_origin, that.altsvc_origin) << COMMON_MESSAGE;
-  VERIFY_EQ(altsvc_value, that.altsvc_value) << COMMON_MESSAGE;
-  VERIFY_EQ(settings, that.settings) << COMMON_MESSAGE;
+  VERIFY_EQ(frame_header_, that.frame_header_) << COMMON_MESSAGE;
+  VERIFY_EQ(payload_, that.payload_) << COMMON_MESSAGE;
+  VERIFY_EQ(padding_, that.padding_) << COMMON_MESSAGE;
+  VERIFY_EQ(altsvc_origin_, that.altsvc_origin_) << COMMON_MESSAGE;
+  VERIFY_EQ(altsvc_value_, that.altsvc_value_) << COMMON_MESSAGE;
+  VERIFY_EQ(settings_, that.settings_) << COMMON_MESSAGE;
 
 #define VERIFY_OPTIONAL_FIELD(field_name) \
   VERIFY_SUCCESS(VerifyOptionalEq(field_name, that.field_name))
 
-  VERIFY_OPTIONAL_FIELD(opt_altsvc_origin_length) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_altsvc_value_length) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_goaway) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_missing_length) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_pad_length) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_ping) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_priority) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_push_promise) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_rst_stream_error_code) << COMMON_MESSAGE;
-  VERIFY_OPTIONAL_FIELD(opt_window_update_increment) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_altsvc_origin_length_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_altsvc_value_length_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_goaway_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_missing_length_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_pad_length_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_ping_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_priority_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_push_promise_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_rst_stream_error_code_) << COMMON_MESSAGE;
+  VERIFY_OPTIONAL_FIELD(opt_window_update_increment_) << COMMON_MESSAGE;
 
 #undef VERIFY_OPTIONAL_FIELD
 
@@ -98,18 +98,18 @@
 }
 
 void FrameParts::SetTotalPadLength(size_t total_pad_length) {
-  opt_pad_length.reset();
-  padding.clear();
+  opt_pad_length_.reset();
+  padding_.clear();
   if (total_pad_length > 0) {
     ASSERT_LE(total_pad_length, 256u);
-    ASSERT_TRUE(frame_header.IsPadded());
-    opt_pad_length = total_pad_length - 1;
+    ASSERT_TRUE(frame_header_.IsPadded());
+    opt_pad_length_ = total_pad_length - 1;
     char zero = 0;
-    padding.append(opt_pad_length.value(), zero);
+    padding_.append(opt_pad_length_.value(), zero);
   }
 
-  if (opt_pad_length) {
-    VLOG(1) << "SetTotalPadLength: pad_length=" << opt_pad_length.value();
+  if (opt_pad_length_) {
+    VLOG(1) << "SetTotalPadLength: pad_length=" << opt_pad_length_.value();
   } else {
     VLOG(1) << "SetTotalPadLength: has no pad length";
   }
@@ -117,10 +117,10 @@
 
 void FrameParts::SetAltSvcExpected(Http2StringPiece origin,
                                    Http2StringPiece value) {
-  altsvc_origin.append(origin.data(), origin.size());
-  altsvc_value.append(value.data(), value.size());
-  opt_altsvc_origin_length = origin.size();
-  opt_altsvc_value_length = value.size();
+  altsvc_origin_.append(origin.data(), origin.size());
+  altsvc_value_.append(value.data(), value.size());
+  opt_altsvc_origin_length_ = origin.size();
+  opt_altsvc_value_length_ = value.size();
 }
 
 bool FrameParts::OnFrameHeader(const Http2FrameHeader& header) {
@@ -131,50 +131,51 @@
 void FrameParts::OnDataStart(const Http2FrameHeader& header) {
   VLOG(1) << "OnDataStart: " << header;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::DATA)) << *this;
-  opt_payload_length = header.payload_length;
+  opt_payload_length_ = header.payload_length;
 }
 
 void FrameParts::OnDataPayload(const char* data, size_t len) {
-  VLOG(1) << "OnDataPayload: len=" << len << "; frame_header: " << frame_header;
+  VLOG(1) << "OnDataPayload: len=" << len
+          << "; frame_header_: " << frame_header_;
   ASSERT_TRUE(InFrameOfType(Http2FrameType::DATA)) << *this;
-  ASSERT_TRUE(
-      AppendString(Http2StringPiece(data, len), &payload, &opt_payload_length));
+  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &payload_,
+                           &opt_payload_length_));
 }
 
 void FrameParts::OnDataEnd() {
-  VLOG(1) << "OnDataEnd; frame_header: " << frame_header;
+  VLOG(1) << "OnDataEnd; frame_header_: " << frame_header_;
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::DATA)) << *this;
 }
 
 void FrameParts::OnHeadersStart(const Http2FrameHeader& header) {
   VLOG(1) << "OnHeadersStart: " << header;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::HEADERS)) << *this;
-  opt_payload_length = header.payload_length;
+  opt_payload_length_ = header.payload_length;
 }
 
 void FrameParts::OnHeadersPriority(const Http2PriorityFields& priority) {
   VLOG(1) << "OnHeadersPriority: priority: " << priority
-          << "; frame_header: " << frame_header;
+          << "; frame_header_: " << frame_header_;
   ASSERT_TRUE(InFrameOfType(Http2FrameType::HEADERS)) << *this;
-  ASSERT_FALSE(opt_priority);
-  opt_priority = priority;
-  ASSERT_TRUE(opt_payload_length);
-  opt_payload_length =
-      opt_payload_length.value() - Http2PriorityFields::EncodedSize();
+  ASSERT_FALSE(opt_priority_);
+  opt_priority_ = priority;
+  ASSERT_TRUE(opt_payload_length_);
+  opt_payload_length_ =
+      opt_payload_length_.value() - Http2PriorityFields::EncodedSize();
 }
 
 void FrameParts::OnHpackFragment(const char* data, size_t len) {
   VLOG(1) << "OnHpackFragment: len=" << len
-          << "; frame_header: " << frame_header;
-  ASSERT_TRUE(got_start_callback);
-  ASSERT_FALSE(got_end_callback);
-  ASSERT_TRUE(FrameCanHaveHpackPayload(frame_header)) << *this;
-  ASSERT_TRUE(
-      AppendString(Http2StringPiece(data, len), &payload, &opt_payload_length));
+          << "; frame_header_: " << frame_header_;
+  ASSERT_TRUE(got_start_callback_);
+  ASSERT_FALSE(got_end_callback_);
+  ASSERT_TRUE(FrameCanHaveHpackPayload(frame_header_)) << *this;
+  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &payload_,
+                           &opt_payload_length_));
 }
 
 void FrameParts::OnHeadersEnd() {
-  VLOG(1) << "OnHeadersEnd; frame_header: " << frame_header;
+  VLOG(1) << "OnHeadersEnd; frame_header_: " << frame_header_;
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::HEADERS)) << *this;
 }
 
@@ -182,72 +183,72 @@
                                  const Http2PriorityFields& priority) {
   VLOG(1) << "OnPriorityFrame: " << header << "; priority: " << priority;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PRIORITY)) << *this;
-  ASSERT_FALSE(opt_priority);
-  opt_priority = priority;
+  ASSERT_FALSE(opt_priority_);
+  opt_priority_ = priority;
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::PRIORITY)) << *this;
 }
 
 void FrameParts::OnContinuationStart(const Http2FrameHeader& header) {
   VLOG(1) << "OnContinuationStart: " << header;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::CONTINUATION)) << *this;
-  opt_payload_length = header.payload_length;
+  opt_payload_length_ = header.payload_length;
 }
 
 void FrameParts::OnContinuationEnd() {
-  VLOG(1) << "OnContinuationEnd; frame_header: " << frame_header;
+  VLOG(1) << "OnContinuationEnd; frame_header_: " << frame_header_;
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::CONTINUATION)) << *this;
 }
 
 void FrameParts::OnPadLength(size_t trailing_length) {
   VLOG(1) << "OnPadLength: trailing_length=" << trailing_length;
   ASSERT_TRUE(InPaddedFrame()) << *this;
-  ASSERT_FALSE(opt_pad_length);
-  ASSERT_TRUE(opt_payload_length);
+  ASSERT_FALSE(opt_pad_length_);
+  ASSERT_TRUE(opt_payload_length_);
   size_t total_padding_length = trailing_length + 1;
-  ASSERT_GE(opt_payload_length.value(), total_padding_length);
-  opt_payload_length = opt_payload_length.value() - total_padding_length;
-  opt_pad_length = trailing_length;
+  ASSERT_GE(opt_payload_length_.value(), total_padding_length);
+  opt_payload_length_ = opt_payload_length_.value() - total_padding_length;
+  opt_pad_length_ = trailing_length;
 }
 
 void FrameParts::OnPadding(const char* pad, size_t skipped_length) {
   VLOG(1) << "OnPadding: skipped_length=" << skipped_length;
   ASSERT_TRUE(InPaddedFrame()) << *this;
-  ASSERT_TRUE(opt_pad_length);
-  ASSERT_TRUE(AppendString(Http2StringPiece(pad, skipped_length), &padding,
-                           &opt_pad_length));
+  ASSERT_TRUE(opt_pad_length_);
+  ASSERT_TRUE(AppendString(Http2StringPiece(pad, skipped_length), &padding_,
+                           &opt_pad_length_));
 }
 
 void FrameParts::OnRstStream(const Http2FrameHeader& header,
                              Http2ErrorCode error_code) {
   VLOG(1) << "OnRstStream: " << header << "; code=" << error_code;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::RST_STREAM)) << *this;
-  ASSERT_FALSE(opt_rst_stream_error_code);
-  opt_rst_stream_error_code = error_code;
+  ASSERT_FALSE(opt_rst_stream_error_code_);
+  opt_rst_stream_error_code_ = error_code;
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::RST_STREAM)) << *this;
 }
 
 void FrameParts::OnSettingsStart(const Http2FrameHeader& header) {
   VLOG(1) << "OnSettingsStart: " << header;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this;
-  ASSERT_EQ(0u, settings.size());
+  ASSERT_EQ(0u, settings_.size());
   ASSERT_FALSE(header.IsAck()) << header;
 }
 
 void FrameParts::OnSetting(const Http2SettingFields& setting_fields) {
   VLOG(1) << "OnSetting: " << setting_fields;
   ASSERT_TRUE(InFrameOfType(Http2FrameType::SETTINGS)) << *this;
-  settings.push_back(setting_fields);
+  settings_.push_back(setting_fields);
 }
 
 void FrameParts::OnSettingsEnd() {
-  VLOG(1) << "OnSettingsEnd; frame_header: " << frame_header;
+  VLOG(1) << "OnSettingsEnd; frame_header_: " << frame_header_;
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this;
 }
 
 void FrameParts::OnSettingsAck(const Http2FrameHeader& header) {
   VLOG(1) << "OnSettingsAck: " << header;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this;
-  ASSERT_EQ(0u, settings.size());
+  ASSERT_EQ(0u, settings_.size());
   ASSERT_TRUE(header.IsAck());
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this;
 }
@@ -259,12 +260,12 @@
           << "; total_padding_length: " << total_padding_length;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PUSH_PROMISE)) << *this;
   ASSERT_GE(header.payload_length, Http2PushPromiseFields::EncodedSize());
-  opt_payload_length =
+  opt_payload_length_ =
       header.payload_length - Http2PushPromiseFields::EncodedSize();
-  ASSERT_FALSE(opt_push_promise);
-  opt_push_promise = promise;
+  ASSERT_FALSE(opt_push_promise_);
+  opt_push_promise_ = promise;
   if (total_padding_length > 0) {
-    ASSERT_GE(opt_payload_length.value(), total_padding_length);
+    ASSERT_GE(opt_payload_length_.value(), total_padding_length);
     OnPadLength(total_padding_length - 1);
   } else {
     ASSERT_FALSE(header.IsPadded());
@@ -272,7 +273,7 @@
 }
 
 void FrameParts::OnPushPromiseEnd() {
-  VLOG(1) << "OnPushPromiseEnd; frame_header: " << frame_header;
+  VLOG(1) << "OnPushPromiseEnd; frame_header_: " << frame_header_;
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::PUSH_PROMISE)) << *this;
 }
 
@@ -281,8 +282,8 @@
   VLOG(1) << "OnPing header: " << header << "   ping: " << ping;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this;
   ASSERT_FALSE(header.IsAck());
-  ASSERT_FALSE(opt_ping);
-  opt_ping = ping;
+  ASSERT_FALSE(opt_ping_);
+  opt_ping_ = ping;
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this;
 }
 
@@ -291,8 +292,8 @@
   VLOG(1) << "OnPingAck header: " << header << "   ping: " << ping;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this;
   ASSERT_TRUE(header.IsAck());
-  ASSERT_FALSE(opt_ping);
-  opt_ping = ping;
+  ASSERT_FALSE(opt_ping_);
+  opt_ping_ = ping;
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this;
 }
 
@@ -300,20 +301,21 @@
                                const Http2GoAwayFields& goaway) {
   VLOG(1) << "OnGoAwayStart: " << goaway;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::GOAWAY)) << *this;
-  ASSERT_FALSE(opt_goaway);
-  opt_goaway = goaway;
-  opt_payload_length = header.payload_length - Http2GoAwayFields::EncodedSize();
+  ASSERT_FALSE(opt_goaway_);
+  opt_goaway_ = goaway;
+  opt_payload_length_ =
+      header.payload_length - Http2GoAwayFields::EncodedSize();
 }
 
 void FrameParts::OnGoAwayOpaqueData(const char* data, size_t len) {
   VLOG(1) << "OnGoAwayOpaqueData: len=" << len;
   ASSERT_TRUE(InFrameOfType(Http2FrameType::GOAWAY)) << *this;
-  ASSERT_TRUE(
-      AppendString(Http2StringPiece(data, len), &payload, &opt_payload_length));
+  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &payload_,
+                           &opt_payload_length_));
 }
 
 void FrameParts::OnGoAwayEnd() {
-  VLOG(1) << "OnGoAwayEnd; frame_header: " << frame_header;
+  VLOG(1) << "OnGoAwayEnd; frame_header_: " << frame_header_;
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::GOAWAY)) << *this;
 }
 
@@ -322,8 +324,8 @@
   VLOG(1) << "OnWindowUpdate header: " << header
           << "     increment=" << increment;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::WINDOW_UPDATE)) << *this;
-  ASSERT_FALSE(opt_window_update_increment);
-  opt_window_update_increment = increment;
+  ASSERT_FALSE(opt_window_update_increment_);
+  opt_window_update_increment_ = increment;
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::WINDOW_UPDATE)) << *this;
 }
 
@@ -334,140 +336,140 @@
           << "    origin_length: " << origin_length
           << "    value_length: " << value_length;
   ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::ALTSVC)) << *this;
-  ASSERT_FALSE(opt_altsvc_origin_length);
-  opt_altsvc_origin_length = origin_length;
-  ASSERT_FALSE(opt_altsvc_value_length);
-  opt_altsvc_value_length = value_length;
+  ASSERT_FALSE(opt_altsvc_origin_length_);
+  opt_altsvc_origin_length_ = origin_length;
+  ASSERT_FALSE(opt_altsvc_value_length_);
+  opt_altsvc_value_length_ = value_length;
 }
 
 void FrameParts::OnAltSvcOriginData(const char* data, size_t len) {
   VLOG(1) << "OnAltSvcOriginData: len=" << len;
   ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this;
-  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &altsvc_origin,
-                           &opt_altsvc_origin_length));
+  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &altsvc_origin_,
+                           &opt_altsvc_origin_length_));
 }
 
 void FrameParts::OnAltSvcValueData(const char* data, size_t len) {
   VLOG(1) << "OnAltSvcValueData: len=" << len;
   ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this;
-  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &altsvc_value,
-                           &opt_altsvc_value_length));
+  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &altsvc_value_,
+                           &opt_altsvc_value_length_));
 }
 
 void FrameParts::OnAltSvcEnd() {
-  VLOG(1) << "OnAltSvcEnd; frame_header: " << frame_header;
+  VLOG(1) << "OnAltSvcEnd; frame_header_: " << frame_header_;
   ASSERT_TRUE(EndFrameOfType(Http2FrameType::ALTSVC)) << *this;
 }
 
 void FrameParts::OnUnknownStart(const Http2FrameHeader& header) {
   VLOG(1) << "OnUnknownStart: " << header;
   ASSERT_FALSE(IsSupportedHttp2FrameType(header.type)) << header;
-  ASSERT_FALSE(got_start_callback);
-  ASSERT_EQ(frame_header, header);
-  got_start_callback = true;
-  opt_payload_length = header.payload_length;
+  ASSERT_FALSE(got_start_callback_);
+  ASSERT_EQ(frame_header_, header);
+  got_start_callback_ = true;
+  opt_payload_length_ = header.payload_length;
 }
 
 void FrameParts::OnUnknownPayload(const char* data, size_t len) {
   VLOG(1) << "OnUnknownPayload: len=" << len;
-  ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header.type)) << *this;
-  ASSERT_TRUE(got_start_callback);
-  ASSERT_FALSE(got_end_callback);
-  ASSERT_TRUE(
-      AppendString(Http2StringPiece(data, len), &payload, &opt_payload_length));
+  ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header_.type)) << *this;
+  ASSERT_TRUE(got_start_callback_);
+  ASSERT_FALSE(got_end_callback_);
+  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &payload_,
+                           &opt_payload_length_));
 }
 
 void FrameParts::OnUnknownEnd() {
-  VLOG(1) << "OnUnknownEnd; frame_header: " << frame_header;
-  ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header.type)) << *this;
-  ASSERT_TRUE(got_start_callback);
-  ASSERT_FALSE(got_end_callback);
-  got_end_callback = true;
+  VLOG(1) << "OnUnknownEnd; frame_header_: " << frame_header_;
+  ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header_.type)) << *this;
+  ASSERT_TRUE(got_start_callback_);
+  ASSERT_FALSE(got_end_callback_);
+  got_end_callback_ = true;
 }
 
 void FrameParts::OnPaddingTooLong(const Http2FrameHeader& header,
                                   size_t missing_length) {
   VLOG(1) << "OnPaddingTooLong: " << header
           << "; missing_length: " << missing_length;
-  ASSERT_EQ(frame_header, header);
-  ASSERT_FALSE(got_end_callback);
+  ASSERT_EQ(frame_header_, header);
+  ASSERT_FALSE(got_end_callback_);
   ASSERT_TRUE(FrameIsPadded(header));
-  ASSERT_FALSE(opt_pad_length);
-  ASSERT_FALSE(opt_missing_length);
-  opt_missing_length = missing_length;
-  got_start_callback = true;
-  got_end_callback = true;
+  ASSERT_FALSE(opt_pad_length_);
+  ASSERT_FALSE(opt_missing_length_);
+  opt_missing_length_ = missing_length;
+  got_start_callback_ = true;
+  got_end_callback_ = true;
 }
 
 void FrameParts::OnFrameSizeError(const Http2FrameHeader& header) {
   VLOG(1) << "OnFrameSizeError: " << header;
-  ASSERT_EQ(frame_header, header);
-  ASSERT_FALSE(got_end_callback);
-  ASSERT_FALSE(has_frame_size_error);
-  has_frame_size_error = true;
-  got_end_callback = true;
+  ASSERT_EQ(frame_header_, header);
+  ASSERT_FALSE(got_end_callback_);
+  ASSERT_FALSE(has_frame_size_error_);
+  has_frame_size_error_ = true;
+  got_end_callback_ = true;
 }
 
 void FrameParts::OutputTo(std::ostream& out) const {
-  out << "FrameParts{\n  frame_header: " << frame_header << "\n";
-  if (!payload.empty()) {
-    out << "  payload=\"" << EscapeQueryParamValue(payload, false) << "\"\n";
+  out << "FrameParts{\n  frame_header_: " << frame_header_ << "\n";
+  if (!payload_.empty()) {
+    out << "  payload_=\"" << EscapeQueryParamValue(payload_, false) << "\"\n";
   }
-  if (!padding.empty()) {
-    out << "  padding=\"" << EscapeQueryParamValue(padding, false) << "\"\n";
+  if (!padding_.empty()) {
+    out << "  padding_=\"" << EscapeQueryParamValue(padding_, false) << "\"\n";
   }
-  if (!altsvc_origin.empty()) {
-    out << "  altsvc_origin=\"" << EscapeQueryParamValue(altsvc_origin, false)
+  if (!altsvc_origin_.empty()) {
+    out << "  altsvc_origin_=\"" << EscapeQueryParamValue(altsvc_origin_, false)
         << "\"\n";
   }
-  if (!altsvc_value.empty()) {
-    out << "  altsvc_value=\"" << EscapeQueryParamValue(altsvc_value, false)
+  if (!altsvc_value_.empty()) {
+    out << "  altsvc_value_=\"" << EscapeQueryParamValue(altsvc_value_, false)
         << "\"\n";
   }
-  if (opt_priority) {
-    out << "  priority=" << opt_priority.value() << "\n";
+  if (opt_priority_) {
+    out << "  priority=" << opt_priority_.value() << "\n";
   }
-  if (opt_rst_stream_error_code) {
-    out << "  rst_stream=" << opt_rst_stream_error_code.value() << "\n";
+  if (opt_rst_stream_error_code_) {
+    out << "  rst_stream=" << opt_rst_stream_error_code_.value() << "\n";
   }
-  if (opt_push_promise) {
-    out << "  push_promise=" << opt_push_promise.value() << "\n";
+  if (opt_push_promise_) {
+    out << "  push_promise=" << opt_push_promise_.value() << "\n";
   }
-  if (opt_ping) {
-    out << "  ping=" << opt_ping.value() << "\n";
+  if (opt_ping_) {
+    out << "  ping=" << opt_ping_.value() << "\n";
   }
-  if (opt_goaway) {
-    out << "  goaway=" << opt_goaway.value() << "\n";
+  if (opt_goaway_) {
+    out << "  goaway=" << opt_goaway_.value() << "\n";
   }
-  if (opt_window_update_increment) {
-    out << "  window_update=" << opt_window_update_increment.value() << "\n";
+  if (opt_window_update_increment_) {
+    out << "  window_update=" << opt_window_update_increment_.value() << "\n";
   }
-  if (opt_payload_length) {
-    out << "  payload_length=" << opt_payload_length.value() << "\n";
+  if (opt_payload_length_) {
+    out << "  payload_length=" << opt_payload_length_.value() << "\n";
   }
-  if (opt_pad_length) {
-    out << "  pad_length=" << opt_pad_length.value() << "\n";
+  if (opt_pad_length_) {
+    out << "  pad_length=" << opt_pad_length_.value() << "\n";
   }
-  if (opt_missing_length) {
-    out << "  missing_length=" << opt_missing_length.value() << "\n";
+  if (opt_missing_length_) {
+    out << "  missing_length=" << opt_missing_length_.value() << "\n";
   }
-  if (opt_altsvc_origin_length) {
-    out << "  origin_length=" << opt_altsvc_origin_length.value() << "\n";
+  if (opt_altsvc_origin_length_) {
+    out << "  origin_length=" << opt_altsvc_origin_length_.value() << "\n";
   }
-  if (opt_altsvc_value_length) {
-    out << "  value_length=" << opt_altsvc_value_length.value() << "\n";
+  if (opt_altsvc_value_length_) {
+    out << "  value_length=" << opt_altsvc_value_length_.value() << "\n";
   }
-  if (has_frame_size_error) {
+  if (has_frame_size_error_) {
     out << "  has_frame_size_error\n";
   }
-  if (got_start_callback) {
+  if (got_start_callback_) {
     out << "  got_start_callback\n";
   }
-  if (got_end_callback) {
+  if (got_end_callback_) {
     out << "  got_end_callback\n";
   }
-  for (size_t ndx = 0; ndx < settings.size(); ++ndx) {
-    out << "  setting[" << ndx << "]=" << settings[ndx];
+  for (size_t ndx = 0; ndx < settings_.size(); ++ndx) {
+    out << "  setting[" << ndx << "]=" << settings_[ndx];
   }
   out << "}";
 }
@@ -476,30 +478,30 @@
     const Http2FrameHeader& header,
     Http2FrameType expected_frame_type) {
   VERIFY_EQ(header.type, expected_frame_type);
-  VERIFY_FALSE(got_start_callback);
-  VERIFY_FALSE(got_end_callback);
-  VERIFY_EQ(frame_header, header);
-  got_start_callback = true;
+  VERIFY_FALSE(got_start_callback_);
+  VERIFY_FALSE(got_end_callback_);
+  VERIFY_EQ(frame_header_, header);
+  got_start_callback_ = true;
   return AssertionSuccess();
 }
 
 AssertionResult FrameParts::InFrameOfType(Http2FrameType expected_frame_type) {
-  VERIFY_TRUE(got_start_callback);
-  VERIFY_FALSE(got_end_callback);
-  VERIFY_EQ(frame_header.type, expected_frame_type);
+  VERIFY_TRUE(got_start_callback_);
+  VERIFY_FALSE(got_end_callback_);
+  VERIFY_EQ(frame_header_.type, expected_frame_type);
   return AssertionSuccess();
 }
 
 AssertionResult FrameParts::EndFrameOfType(Http2FrameType expected_frame_type) {
   VERIFY_SUCCESS(InFrameOfType(expected_frame_type));
-  got_end_callback = true;
+  got_end_callback_ = true;
   return AssertionSuccess();
 }
 
 AssertionResult FrameParts::InPaddedFrame() {
-  VERIFY_TRUE(got_start_callback);
-  VERIFY_FALSE(got_end_callback);
-  VERIFY_TRUE(FrameIsPadded(frame_header));
+  VERIFY_TRUE(got_start_callback_);
+  VERIFY_FALSE(got_end_callback_);
+  VERIFY_TRUE(FrameIsPadded(frame_header_));
   return AssertionSuccess();
 }
 
diff --git a/net/http2/test_tools/frame_parts.h b/net/http2/test_tools/frame_parts.h
index 1846929b..7ef392f7 100644
--- a/net/http2/test_tools/frame_parts.h
+++ b/net/http2/test_tools/frame_parts.h
@@ -10,9 +10,6 @@
 // info that a test expects to be recorded during the decoding of a frame
 // with the actual recorded value (i.e. by providing a comparator).
 
-// TODO(jamessynge): Convert FrameParts to a class, hide the members, add
-// getters/setters.
-
 #include <stddef.h>
 
 #include <vector>
@@ -29,11 +26,8 @@
 namespace net {
 namespace test {
 
-// Forward declarations.
-struct FrameParts;
-std::ostream& operator<<(std::ostream& out, const FrameParts& v);
-
-struct FrameParts : public Http2FrameDecoderListener {
+class FrameParts : public Http2FrameDecoderListener {
+ public:
   // The first callback for every type of frame includes the frame header; this
   // is the only constructor used during decoding of a frame.
   explicit FrameParts(const Http2FrameHeader& header);
@@ -113,36 +107,82 @@
                         size_t missing_length) override;
   void OnFrameSizeError(const Http2FrameHeader& header) override;
 
-  // The fields are public for access by tests.
+  void AppendSetting(const Http2SettingFields& setting_fields) {
+    settings_.push_back(setting_fields);
+  }
 
-  const Http2FrameHeader frame_header;
+  const Http2FrameHeader& GetFrameHeader() const { return frame_header_; }
 
-  Http2String payload;
-  Http2String padding;
-  Http2String altsvc_origin;
-  Http2String altsvc_value;
+  base::Optional<Http2PriorityFields> GetOptPriority() const {
+    return opt_priority_;
+  }
+  base::Optional<Http2ErrorCode> GetOptRstStreamErrorCode() const {
+    return opt_rst_stream_error_code_;
+  }
+  base::Optional<Http2PushPromiseFields> GetOptPushPromise() const {
+    return opt_push_promise_;
+  }
+  base::Optional<Http2PingFields> GetOptPing() const { return opt_ping_; }
+  base::Optional<Http2GoAwayFields> GetOptGoaway() const { return opt_goaway_; }
+  base::Optional<size_t> GetOptPadLength() const { return opt_pad_length_; }
+  base::Optional<size_t> GetOptPayloadLength() const {
+    return opt_payload_length_;
+  }
+  base::Optional<size_t> GetOptMissingLength() const {
+    return opt_missing_length_;
+  }
+  base::Optional<size_t> GetOptAltsvcOriginLength() const {
+    return opt_altsvc_origin_length_;
+  }
+  base::Optional<size_t> GetOptAltsvcValueLength() const {
+    return opt_altsvc_value_length_;
+  }
+  base::Optional<size_t> GetOptWindowUpdateIncrement() const {
+    return opt_window_update_increment_;
+  }
+  bool GetHasFrameSizeError() const { return has_frame_size_error_; }
 
-  base::Optional<Http2PriorityFields> opt_priority;
-  base::Optional<Http2ErrorCode> opt_rst_stream_error_code;
-  base::Optional<Http2PushPromiseFields> opt_push_promise;
-  base::Optional<Http2PingFields> opt_ping;
-  base::Optional<Http2GoAwayFields> opt_goaway;
+  void SetOptPriority(base::Optional<Http2PriorityFields> opt_priority) {
+    opt_priority_ = opt_priority;
+  }
+  void SetOptRstStreamErrorCode(
+      base::Optional<Http2ErrorCode> opt_rst_stream_error_code) {
+    opt_rst_stream_error_code_ = opt_rst_stream_error_code;
+  }
+  void SetOptPushPromise(
+      base::Optional<Http2PushPromiseFields> opt_push_promise) {
+    opt_push_promise_ = opt_push_promise;
+  }
+  void SetOptPing(base::Optional<Http2PingFields> opt_ping) {
+    opt_ping_ = opt_ping;
+  }
+  void SetOptGoaway(base::Optional<Http2GoAwayFields> opt_goaway) {
+    opt_goaway_ = opt_goaway;
+  }
+  void SetOptPadLength(base::Optional<size_t> opt_pad_length) {
+    opt_pad_length_ = opt_pad_length;
+  }
+  void SetOptPayloadLength(base::Optional<size_t> opt_payload_length) {
+    opt_payload_length_ = opt_payload_length;
+  }
+  void SetOptMissingLength(base::Optional<size_t> opt_missing_length) {
+    opt_missing_length_ = opt_missing_length;
+  }
+  void SetOptAltsvcOriginLength(
+      base::Optional<size_t> opt_altsvc_origin_length) {
+    opt_altsvc_origin_length_ = opt_altsvc_origin_length;
+  }
+  void SetOptAltsvcValueLength(base::Optional<size_t> opt_altsvc_value_length) {
+    opt_altsvc_value_length_ = opt_altsvc_value_length;
+  }
+  void SetOptWindowUpdateIncrement(
+      base::Optional<size_t> opt_window_update_increment) {
+    opt_window_update_increment_ = opt_window_update_increment;
+  }
 
-  base::Optional<size_t> opt_pad_length;
-  base::Optional<size_t> opt_payload_length;
-  base::Optional<size_t> opt_missing_length;
-  base::Optional<size_t> opt_altsvc_origin_length;
-  base::Optional<size_t> opt_altsvc_value_length;
-
-  base::Optional<size_t> opt_window_update_increment;
-
-  bool has_frame_size_error = false;
-
-  std::vector<Http2SettingFields> settings;
-
-  // These booleans are not checked by CompareCollectedFrames.
-  bool got_start_callback = false;
-  bool got_end_callback = false;
+  void SetHasFrameSizeError(bool has_frame_size_error) {
+    has_frame_size_error_ = has_frame_size_error;
+  }
 
  private:
   // ASSERT during an On* method that we're handling a frame of type
@@ -169,8 +209,39 @@
   ::testing::AssertionResult AppendString(Http2StringPiece source,
                                           Http2String* target,
                                           base::Optional<size_t>* opt_length);
+
+  const Http2FrameHeader frame_header_;
+
+  Http2String payload_;
+  Http2String padding_;
+  Http2String altsvc_origin_;
+  Http2String altsvc_value_;
+
+  base::Optional<Http2PriorityFields> opt_priority_;
+  base::Optional<Http2ErrorCode> opt_rst_stream_error_code_;
+  base::Optional<Http2PushPromiseFields> opt_push_promise_;
+  base::Optional<Http2PingFields> opt_ping_;
+  base::Optional<Http2GoAwayFields> opt_goaway_;
+
+  base::Optional<size_t> opt_pad_length_;
+  base::Optional<size_t> opt_payload_length_;
+  base::Optional<size_t> opt_missing_length_;
+  base::Optional<size_t> opt_altsvc_origin_length_;
+  base::Optional<size_t> opt_altsvc_value_length_;
+
+  base::Optional<size_t> opt_window_update_increment_;
+
+  bool has_frame_size_error_ = false;
+
+  std::vector<Http2SettingFields> settings_;
+
+  // These booleans are not checked by CompareCollectedFrames.
+  bool got_start_callback_ = false;
+  bool got_end_callback_ = false;
 };
 
+std::ostream& operator<<(std::ostream& out, const FrameParts& v);
+
 }  // namespace test
 }  // namespace net
 
diff --git a/net/http2/test_tools/frame_parts_collector.cc b/net/http2/test_tools/frame_parts_collector.cc
index 7128edf0..9a727d43 100644
--- a/net/http2/test_tools/frame_parts_collector.cc
+++ b/net/http2/test_tools/frame_parts_collector.cc
@@ -101,7 +101,7 @@
     // frame before detecting the error; for example, the DATA payload decoder
     // calls OnDataStart before it can detect padding errors, hence before it
     // can call OnPaddingTooLong.
-    EXPECT_EQ(header, current_frame_->frame_header);
+    EXPECT_EQ(header, current_frame_->GetFrameHeader());
   }
   Http2FrameDecoderListener* result = current_frame();
   collected_frames_.push_back(std::move(current_frame_));
diff --git a/net/nqe/network_quality.cc b/net/nqe/network_quality.cc
index cff98ab..d9f23182 100644
--- a/net/nqe/network_quality.cc
+++ b/net/nqe/network_quality.cc
@@ -13,7 +13,10 @@
 }
 
 NetworkQuality::NetworkQuality()
-    : NetworkQuality(InvalidRTT(), InvalidRTT(), INVALID_RTT_THROUGHPUT) {}
+    : NetworkQuality(InvalidRTT(), InvalidRTT(), INVALID_RTT_THROUGHPUT) {
+  VerifyValueCorrectness();
+  DETACH_FROM_SEQUENCE(sequence_checker_);
+}
 
 NetworkQuality::NetworkQuality(const base::TimeDelta& http_rtt,
                                const base::TimeDelta& transport_rtt,
@@ -21,13 +24,17 @@
     : http_rtt_(http_rtt),
       transport_rtt_(transport_rtt),
       downstream_throughput_kbps_(downstream_throughput_kbps) {
-  DCHECK_GE(downstream_throughput_kbps_, INVALID_RTT_THROUGHPUT);
+  VerifyValueCorrectness();
+  DETACH_FROM_SEQUENCE(sequence_checker_);
 }
 
 NetworkQuality::NetworkQuality(const NetworkQuality& other)
     : NetworkQuality(other.http_rtt_,
                      other.transport_rtt_,
-                     other.downstream_throughput_kbps_) {}
+                     other.downstream_throughput_kbps_) {
+  VerifyValueCorrectness();
+  DETACH_FROM_SEQUENCE(sequence_checker_);
+}
 
 NetworkQuality::~NetworkQuality() = default;
 
@@ -35,16 +42,20 @@
   http_rtt_ = other.http_rtt_;
   transport_rtt_ = other.transport_rtt_;
   downstream_throughput_kbps_ = other.downstream_throughput_kbps_;
+  VerifyValueCorrectness();
+  DETACH_FROM_SEQUENCE(sequence_checker_);
   return *this;
 }
 
 bool NetworkQuality::operator==(const NetworkQuality& other) const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return http_rtt_ == other.http_rtt_ &&
          transport_rtt_ == other.transport_rtt_ &&
          downstream_throughput_kbps_ == other.downstream_throughput_kbps_;
 }
 
 bool NetworkQuality::IsFaster(const NetworkQuality& other) const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return (http_rtt() == InvalidRTT() || other.http_rtt() == InvalidRTT() ||
           http_rtt() <= other.http_rtt()) &&
          (transport_rtt() == InvalidRTT() ||
@@ -55,6 +66,13 @@
           downstream_throughput_kbps() >= other.downstream_throughput_kbps());
 }
 
+void NetworkQuality::VerifyValueCorrectness() const {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK_LE(INVALID_RTT_THROUGHPUT, http_rtt_.InMilliseconds());
+  DCHECK_LE(INVALID_RTT_THROUGHPUT, transport_rtt_.InMilliseconds());
+  DCHECK_LE(INVALID_RTT_THROUGHPUT, downstream_throughput_kbps_);
+}
+
 }  // namespace internal
 }  // namespace nqe
 }  // namespace net
diff --git a/net/nqe/network_quality.h b/net/nqe/network_quality.h
index 73afb69..de9d275 100644
--- a/net/nqe/network_quality.h
+++ b/net/nqe/network_quality.h
@@ -9,6 +9,7 @@
 
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
+#include "base/sequence_checker.h"
 #include "base/time/time.h"
 #include "net/base/net_export.h"
 
@@ -53,28 +54,46 @@
   bool IsFaster(const NetworkQuality& other) const;
 
   // Returns the estimate of the round trip time at the HTTP layer.
-  const base::TimeDelta& http_rtt() const { return http_rtt_; }
+  const base::TimeDelta& http_rtt() const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return http_rtt_;
+  }
 
-  void set_http_rtt(const base::TimeDelta& http_rtt) { http_rtt_ = http_rtt; }
+  void set_http_rtt(base::TimeDelta http_rtt) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    http_rtt_ = http_rtt;
+    DCHECK_LE(INVALID_RTT_THROUGHPUT, http_rtt_.InMilliseconds());
+  }
 
   // Returns the estimate of the round trip time at the transport layer.
-  const base::TimeDelta& transport_rtt() const { return transport_rtt_; }
+  const base::TimeDelta& transport_rtt() const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return transport_rtt_;
+  }
 
-  void set_transport_rtt(const base::TimeDelta& transport_rtt) {
+  void set_transport_rtt(base::TimeDelta transport_rtt) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
     transport_rtt_ = transport_rtt;
+    DCHECK_LE(INVALID_RTT_THROUGHPUT, transport_rtt_.InMilliseconds());
   }
 
   // Returns the estimate of the downstream throughput in Kbps (Kilobits per
   // second).
   int32_t downstream_throughput_kbps() const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
     return downstream_throughput_kbps_;
   }
 
   void set_downstream_throughput_kbps(int32_t downstream_throughput_kbps) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
     downstream_throughput_kbps_ = downstream_throughput_kbps;
+    DCHECK_LE(INVALID_RTT_THROUGHPUT, downstream_throughput_kbps_);
   }
 
  private:
+  // Verifies that the value of network quality is within the expected range.
+  void VerifyValueCorrectness() const;
+
   // Estimated round trip time at the HTTP layer.
   base::TimeDelta http_rtt_;
 
@@ -83,6 +102,8 @@
 
   // Estimated downstream throughput in kilobits per second.
   int32_t downstream_throughput_kbps_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
 };
 
 }  // namespace internal
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc
index 0ccfc6d..8dca5156 100644
--- a/net/nqe/network_quality_estimator.cc
+++ b/net/nqe/network_quality_estimator.cc
@@ -1622,7 +1622,7 @@
     const base::TimeDelta& rtt,
     const base::Optional<nqe::internal::IPHash>& host) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK_NE(nqe::internal::InvalidRTT(), rtt);
+  DCHECK_LT(nqe::internal::INVALID_RTT_THROUGHPUT, rtt.InMilliseconds());
 
   Observation observation(rtt.InMilliseconds(), tick_clock_->NowTicks(),
                           current_network_id_.signal_strength,
diff --git a/net/proxy/dhcpcsvc_init_win.cc b/net/proxy/dhcpcsvc_init_win.cc
index d243f18..d907960 100644
--- a/net/proxy/dhcpcsvc_init_win.cc
+++ b/net/proxy/dhcpcsvc_init_win.cc
@@ -7,6 +7,8 @@
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 
+#include <windows.h>  // Must be in front of other Windows header files.
+
 #include <dhcpcsdk.h>
 #include <dhcpv6csdk.h>
 
diff --git a/net/proxy/proxy_script_fetcher_impl.cc b/net/proxy/proxy_script_fetcher_impl.cc
index c736c59..0321f286 100644
--- a/net/proxy/proxy_script_fetcher_impl.cc
+++ b/net/proxy/proxy_script_fetcher_impl.cc
@@ -35,7 +35,17 @@
 
 // The maximum duration (in milliseconds) allowed for fetching the PAC script.
 // Responses exceeding this will fail with ERR_TIMED_OUT.
-const int kDefaultMaxDurationMs = 300000;  // 5 minutes
+//
+// This timeout applies to both scripts fetched in the course of WPAD, as well
+// as explicitly configured ones.
+//
+// If the default timeout is too high, auto-detect can stall for a long time,
+// and if it is too low then slow loading scripts may be skipped.
+//
+// 30 seconds is a compromise between those competing goals. This value also
+// appears to match Microsoft Edge (based on testing).
+constexpr base::TimeDelta kDefaultMaxDuration =
+    base::TimeDelta::FromSeconds(30);
 
 // Returns true if |mime_type| is one of the known PAC mime type.
 bool IsPacMimeType(const std::string& mime_type) {
@@ -82,7 +92,7 @@
       result_code_(OK),
       result_text_(NULL),
       max_response_bytes_(kDefaultMaxResponseBytes),
-      max_duration_(base::TimeDelta::FromMilliseconds(kDefaultMaxDurationMs)),
+      max_duration_(kDefaultMaxDuration),
       weak_factory_(this) {
   DCHECK(url_request_context);
 }
diff --git a/net/test/spawned_test_server/base_test_server.cc b/net/test/spawned_test_server/base_test_server.cc
index 75a4cf8..4171bbc 100644
--- a/net/test/spawned_test_server/base_test_server.cc
+++ b/net/test/spawned_test_server/base_test_server.cc
@@ -508,12 +508,6 @@
     arguments->Set("no-anonymous-ftp-user", std::make_unique<base::Value>());
   }
 
-  if (redirect_connect_to_localhost_) {
-    DCHECK_EQ(TYPE_BASIC_AUTH_PROXY, type_);
-    arguments->Set("redirect-connect-to-localhost",
-                   std::make_unique<base::Value>());
-  }
-
   if (UsingSSL(type_)) {
     // Check the certificate arguments of the HTTPS server.
     base::FilePath certificate_path(certificates_dir_);
diff --git a/net/test/spawned_test_server/base_test_server.h b/net/test/spawned_test_server/base_test_server.h
index c279b6c..a3592ac4 100644
--- a/net/test/spawned_test_server/base_test_server.h
+++ b/net/test/spawned_test_server/base_test_server.h
@@ -370,11 +370,6 @@
     no_anonymous_ftp_user_ = no_anonymous_ftp_user;
   }
 
-  // Redirect proxied CONNECT requests to localhost.
-  void set_redirect_connect_to_localhost(bool redirect_connect_to_localhost) {
-    redirect_connect_to_localhost_ = redirect_connect_to_localhost;
-  }
-
   // Marks the root certificate of an HTTPS test server as trusted for
   // the duration of tests.
   bool LoadTestRootCert() const WARN_UNUSED_RESULT;
@@ -459,9 +454,6 @@
   // Disable creation of anonymous FTP user?
   bool no_anonymous_ftp_user_ = false;
 
-  // Redirect proxied CONNECT requests to localhost?
-  bool redirect_connect_to_localhost_ = false;
-
   std::unique_ptr<ScopedPortException> allowed_port_;
 
   DISALLOW_COPY_AND_ASSIGN(BaseTestServer);
diff --git a/net/tools/testserver/testserver.py b/net/tools/testserver/testserver.py
index 0576ac6..634b41e 100755
--- a/net/tools/testserver/testserver.py
+++ b/net/tools/testserver/testserver.py
@@ -1765,7 +1765,6 @@
   """
 
   _AUTH_CREDENTIAL = 'Basic Zm9vOmJhcg==' # foo:bar
-  redirect_connect_to_localhost = False;
 
   def parse_request(self):
     """Overrides parse_request to check credential."""
@@ -1851,9 +1850,6 @@
       self.send_response(400)
       self.end_headers()
 
-    if BasicAuthProxyRequestHandler.redirect_connect_to_localhost:
-      host = "127.0.0.1"
-
     try:
       sock = socket.create_connection((host, port))
       self.send_response(200, 'Connection established')
@@ -2112,8 +2108,6 @@
       print 'Echo UDP server started on port %d...' % server.server_port
       server_data['port'] = server.server_port
     elif self.options.server_type == SERVER_BASIC_AUTH_PROXY:
-      BasicAuthProxyRequestHandler.redirect_connect_to_localhost = \
-          self.options.redirect_connect_to_localhost
       server = HTTPServer((host, port), BasicAuthProxyRequestHandler)
       print 'BasicAuthProxy server started on port %d...' % server.server_port
       server_data['port'] = server.server_port
@@ -2329,12 +2323,6 @@
                                   action='store_true')
     self.option_parser.add_option('--token-binding-params', action='append',
                                   default=[], type='int')
-    self.option_parser.add_option('--redirect-connect-to-localhost',
-                                  dest='redirect_connect_to_localhost',
-                                  default=False, action='store_true',
-                                  help='If set, the Proxy server will connect '
-                                  'to localhost instead of the requested URL '
-                                  'on CONNECT requests')
 
 
 if __name__ == '__main__':
diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h
index 1b266dcb..af6ae90 100644
--- a/ppapi/thunk/resource_creation_api.h
+++ b/ppapi/thunk/resource_creation_api.h
@@ -28,6 +28,11 @@
 #include "ppapi/shared_impl/api_id.h"
 #include "ppapi/shared_impl/ppb_image_data_shared.h"
 
+// Windows defines 'PostMessage', so we have to undef it.
+#ifdef PostMessage
+#undef PostMessage
+#endif
+
 struct PP_Flash_Menu;
 struct PP_BrowserFont_Trusted_Description;
 struct PP_NetAddress_IPv4;
diff --git a/remoting/host/curtain_mode_win.cc b/remoting/host/curtain_mode_win.cc
index 0be0bdf5..564fb0c 100644
--- a/remoting/host/curtain_mode_win.cc
+++ b/remoting/host/curtain_mode_win.cc
@@ -10,6 +10,8 @@
 #include "base/single_thread_task_runner.h"
 #include "remoting/host/client_session_control.h"
 
+#include <windows.h>
+
 namespace remoting {
 
 class CurtainModeWin : public CurtainMode {
diff --git a/remoting/host/heartbeat_sender.cc b/remoting/host/heartbeat_sender.cc
index 9333fbfe..6d288c0 100644
--- a/remoting/host/heartbeat_sender.cc
+++ b/remoting/host/heartbeat_sender.cc
@@ -25,6 +25,10 @@
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
 #include "third_party/libjingle_xmpp/xmpp/constants.h"
 
+#ifdef ERROR
+#undef ERROR  // Defined by windows.h
+#endif
+
 using buzz::QName;
 using buzz::XmlElement;
 
diff --git a/remoting/host/pairing_registry_delegate_win.cc b/remoting/host/pairing_registry_delegate_win.cc
index b717f15..4a947063 100644
--- a/remoting/host/pairing_registry_delegate_win.cc
+++ b/remoting/host/pairing_registry_delegate_win.cc
@@ -13,6 +13,8 @@
 #include "base/values.h"
 #include "base/win/registry.h"
 
+#include <windows.h>
+
 namespace remoting {
 
 namespace {
diff --git a/remoting/host/win/unprivileged_process_delegate.cc b/remoting/host/win/unprivileged_process_delegate.cc
index 277bb20..89ad4af 100644
--- a/remoting/host/win/unprivileged_process_delegate.cc
+++ b/remoting/host/win/unprivileged_process_delegate.cc
@@ -8,6 +8,8 @@
 
 #include "remoting/host/win/unprivileged_process_delegate.h"
 
+#include <windows.h>  // Must be in front of other Windows header files.
+
 #include <sddl.h>
 
 #include <utility>
diff --git a/rlz/win/lib/registry_util.cc b/rlz/win/lib/registry_util.cc
index 6feaea4..5c290b3 100644
--- a/rlz/win/lib/registry_util.cc
+++ b/rlz/win/lib/registry_util.cc
@@ -14,6 +14,8 @@
 #include "rlz/lib/assert.h"
 #include "rlz/win/lib/process_info.h"
 
+#include <windows.h>
+
 namespace rlz_lib {
 
 bool RegKeyReadValue(const base::win::RegKey& key, const wchar_t* name,
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc
index ca6f08a2..9a37225 100644
--- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc
@@ -205,6 +205,7 @@
     return If(AllOf(level == SOL_SOCKET,
                     AnyOf(option == SO_SNDTIMEO,
                           option == SO_RCVTIMEO,
+                          option == SO_SNDBUF,
                           option == SO_REUSEADDR)),
               Allow())
            .Else(BaselinePolicy::EvaluateSyscall(sysno));
diff --git a/sandbox/win/src/crosscall_server.cc b/sandbox/win/src/crosscall_server.cc
index 0125a52..15cfa5f4 100644
--- a/sandbox/win/src/crosscall_server.cc
+++ b/sandbox/win/src/crosscall_server.cc
@@ -16,6 +16,10 @@
 #include "sandbox/win/src/crosscall_client.h"
 #include "sandbox/win/src/crosscall_params.h"
 
+// See comment in atomicops.h. This is needed any time windows.h is included
+// after atomicops.h.
+#undef MemoryBarrier
+
 // This code performs the ipc message validation. Potential security flaws
 // on the ipc are likelier to be found in this code than in the rest of
 // the ipc code.
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
index bd3b6db..81002daf 100644
--- a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
+++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
@@ -239,7 +239,7 @@
   auto chrome_callback = base::Bind(
       &CoordinatorImpl::OnChromeMemoryDumpResponse, base::Unretained(this));
   auto os_callback = base::Bind(&CoordinatorImpl::OnOSMemoryDumpResponse,
-                                base::Unretained(this));
+                                base::Unretained(this), request->dump_guid);
   QueuedRequestDispatcher::SetUpAndDispatch(request, clients, chrome_callback,
                                             os_callback);
 
@@ -268,8 +268,7 @@
   using ResponseType = QueuedRequest::PendingResponse::Type;
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   QueuedRequest* request = GetCurrentRequest();
-  if (request == nullptr) {
-    NOTREACHED() << "No current dump request.";
+  if (request == nullptr || request->dump_guid != dump_guid) {
     return;
   }
 
@@ -290,14 +289,14 @@
   FinalizeGlobalMemoryDumpIfAllManagersReplied();
 }
 
-void CoordinatorImpl::OnOSMemoryDumpResponse(mojom::ClientProcess* client,
+void CoordinatorImpl::OnOSMemoryDumpResponse(uint64_t dump_guid,
+                                             mojom::ClientProcess* client,
                                              bool success,
                                              OSMemDumpMap os_dumps) {
   using ResponseType = QueuedRequest::PendingResponse::Type;
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   QueuedRequest* request = GetCurrentRequest();
-  if (request == nullptr) {
-    NOTREACHED() << "No current dump request.";
+  if (request == nullptr || request->dump_guid != dump_guid) {
     return;
   }
 
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl.h b/services/resource_coordinator/memory_instrumentation/coordinator_impl.h
index 584a4df7..14680739 100644
--- a/services/resource_coordinator/memory_instrumentation/coordinator_impl.h
+++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl.h
@@ -102,7 +102,8 @@
       std::unique_ptr<base::trace_event::ProcessMemoryDump> chrome_memory_dump);
 
   // Callback of RequestOSMemoryDump.
-  void OnOSMemoryDumpResponse(mojom::ClientProcess*,
+  void OnOSMemoryDumpResponse(uint64_t dump_guid,
+                              mojom::ClientProcess*,
                               bool success,
                               OSMemDumpMap);
 
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_unittest.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_unittest.cc
index f6a0232..5026efc 100644
--- a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_unittest.cc
+++ b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_unittest.cc
@@ -15,6 +15,7 @@
 
 #if defined(OS_WIN)
 #include <base/strings/sys_string_conversions.h>
+#include <windows.h>
 #endif
 
 namespace memory_instrumentation {
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_win.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_win.cc
index 2b26380..4c6c2525 100644
--- a/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_win.cc
+++ b/services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics_win.cc
@@ -4,9 +4,10 @@
 
 #include "services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics.h"
 
+#include <windows.h>  // Must be in front of other Windows header files.
+
 #include <psapi.h>
 #include <tchar.h>
-#include <windows.h>
 
 #include <base/strings/sys_string_conversions.h>
 #include <base/win/pe_image.h>
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 22692b4..60827e57 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -237,6 +237,10 @@
 #define SK_SUPPORT_LEGACY_DASH_CULL_PATH
 #endif
 
+#ifndef SK_SUPPORT_LEGACY_CONTAINED_IN_CLIP
+#define SK_SUPPORT_LEGACY_CONTAINED_IN_CLIP
+#endif
+
 ///////////////////////// Imported from BUILD.gn and skia_common.gypi
 
 /* In some places Skia can use static initializers for global initialization,
diff --git a/storage/browser/database/database_quota_client.cc b/storage/browser/database/database_quota_client.cc
index 67da171..91f2dea 100644
--- a/storage/browser/database/database_quota_client.cc
+++ b/storage/browser/database/database_quota_client.cc
@@ -20,9 +20,9 @@
 #include "storage/browser/database/database_tracker.h"
 #include "storage/browser/database/database_util.h"
 #include "storage/common/database/database_identifier.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 using storage::QuotaClient;
 
 namespace storage {
@@ -83,11 +83,11 @@
     return;
   }
 
-  blink::QuotaStatusCode status;
+  blink::mojom::QuotaStatusCode status;
   if (result == net::OK)
-    status = blink::QuotaStatusCode::kOk;
+    status = blink::mojom::QuotaStatusCode::kOk;
   else
-    status = blink::QuotaStatusCode::kUnknown;
+    status = blink::mojom::QuotaStatusCode::kUnknown;
 
   original_task_runner->PostTask(FROM_HERE, base::BindOnce(callback, status));
 }
@@ -185,12 +185,12 @@
 
   // All databases are in the temp namespace for now, so nothing to delete.
   if (type != StorageType::kTemporary) {
-    callback.Run(blink::QuotaStatusCode::kOk);
+    callback.Run(blink::mojom::QuotaStatusCode::kOk);
     return;
   }
 
   // DidDeleteOriginData() translates the net::Error response to a
-  // blink::QuotaStatusCode if necessary, and no-ops as appropriate if
+  // blink::mojom::QuotaStatusCode if necessary, and no-ops as appropriate if
   // DatabaseTracker::ScheduleDatabasesForDeletion will also invoke the
   // callback.
   auto delete_callback = base::BindRepeating(
diff --git a/storage/browser/database/database_quota_client.h b/storage/browser/database/database_quota_client.h
index e20c18bf..4864725 100644
--- a/storage/browser/database/database_quota_client.h
+++ b/storage/browser/database/database_quota_client.h
@@ -13,7 +13,7 @@
 #include "base/single_thread_task_runner.h"
 #include "storage/browser/quota/quota_client.h"
 #include "storage/browser/storage_browser_export.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace storage {
 
@@ -31,17 +31,17 @@
   ID id() const override;
   void OnQuotaManagerDestroyed() override;
   void GetOriginUsage(const GURL& origin_url,
-                      blink::StorageType type,
+                      blink::mojom::StorageType type,
                       const GetUsageCallback& callback) override;
-  void GetOriginsForType(blink::StorageType type,
+  void GetOriginsForType(blink::mojom::StorageType type,
                          const GetOriginsCallback& callback) override;
-  void GetOriginsForHost(blink::StorageType type,
+  void GetOriginsForHost(blink::mojom::StorageType type,
                          const std::string& host,
                          const GetOriginsCallback& callback) override;
   void DeleteOriginData(const GURL& origin,
-                        blink::StorageType type,
+                        blink::mojom::StorageType type,
                         const DeletionCallback& callback) override;
-  bool DoesSupport(blink::StorageType type) const override;
+  bool DoesSupport(blink::mojom::StorageType type) const override;
 
  private:
   scoped_refptr<DatabaseTracker> db_tracker_;  // only used on its sequence
diff --git a/storage/browser/database/database_quota_client_unittest.cc b/storage/browser/database/database_quota_client_unittest.cc
index ef38638..be3e8c1 100644
--- a/storage/browser/database/database_quota_client_unittest.cc
+++ b/storage/browser/database/database_quota_client_unittest.cc
@@ -30,8 +30,10 @@
 namespace content {
 
 // Declared to shorten the line lengths.
-static const blink::StorageType kTemp = blink::StorageType::kTemporary;
-static const blink::StorageType kPerm = blink::StorageType::kPersistent;
+static const blink::mojom::StorageType kTemp =
+    blink::mojom::StorageType::kTemporary;
+static const blink::mojom::StorageType kPerm =
+    blink::mojom::StorageType::kPersistent;
 
 // Mock tracker class the mocks up those methods of the tracker
 // that are used by the QuotaClient.
@@ -140,7 +142,7 @@
 
   int64_t GetOriginUsage(storage::QuotaClient* client,
                          const GURL& origin,
-                         blink::StorageType type) {
+                         blink::mojom::StorageType type) {
     usage_ = 0;
     client->GetOriginUsage(
         origin, type,
@@ -152,7 +154,7 @@
   }
 
   const std::set<GURL>& GetOriginsForType(storage::QuotaClient* client,
-                                          blink::StorageType type) {
+                                          blink::mojom::StorageType type) {
     origins_.clear();
     client->GetOriginsForType(
         type, base::AdaptCallbackForRepeating(
@@ -163,7 +165,7 @@
   }
 
   const std::set<GURL>& GetOriginsForHost(storage::QuotaClient* client,
-                                          blink::StorageType type,
+                                          blink::mojom::StorageType type,
                                           const std::string& host) {
     origins_.clear();
     client->GetOriginsForHost(
@@ -176,16 +178,16 @@
   }
 
   bool DeleteOriginData(storage::QuotaClient* client,
-                        blink::StorageType type,
+                        blink::mojom::StorageType type,
                         const GURL& origin) {
-    delete_status_ = blink::QuotaStatusCode::kUnknown;
+    delete_status_ = blink::mojom::QuotaStatusCode::kUnknown;
     client->DeleteOriginData(
         origin, type,
         base::AdaptCallbackForRepeating(
             base::BindOnce(&DatabaseQuotaClientTest::OnDeleteOriginDataComplete,
                            weak_factory_.GetWeakPtr())));
     base::RunLoop().RunUntilIdle();
-    return delete_status_ == blink::QuotaStatusCode::kOk;
+    return delete_status_ == blink::mojom::QuotaStatusCode::kOk;
   }
 
   MockDatabaseTracker* mock_tracker() { return mock_tracker_.get(); }
@@ -197,14 +199,14 @@
     origins_ = origins;
   }
 
-  void OnDeleteOriginDataComplete(blink::QuotaStatusCode status) {
+  void OnDeleteOriginDataComplete(blink::mojom::QuotaStatusCode status) {
     delete_status_ = status;
   }
 
   base::test::ScopedTaskEnvironment scoped_task_environment_;
   int64_t usage_;
   std::set<GURL> origins_;
-  blink::QuotaStatusCode delete_status_;
+  blink::mojom::QuotaStatusCode delete_status_;
   scoped_refptr<MockDatabaseTracker> mock_tracker_;
   base::WeakPtrFactory<DatabaseQuotaClientTest> weak_factory_;
 };
diff --git a/storage/browser/database/database_tracker.cc b/storage/browser/database/database_tracker.cc
index ca5db00..e1e508e 100644
--- a/storage/browser/database/database_tracker.cc
+++ b/storage/browser/database/database_tracker.cc
@@ -25,7 +25,7 @@
 #include "storage/browser/quota/quota_manager_proxy.h"
 #include "storage/browser/quota/special_storage_policy.h"
 #include "storage/common/database/database_identifier.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "third_party/sqlite/sqlite3.h"
 
 namespace storage {
@@ -118,7 +118,7 @@
     quota_manager_proxy_->NotifyStorageAccessed(
         storage::QuotaClient::kDatabase,
         storage::GetOriginFromIdentifier(origin_identifier),
-        blink::StorageType::kTemporary);
+        blink::mojom::StorageType::kTemporary);
 
   InsertOrUpdateDatabaseDetails(origin_identifier, database_name,
                                 database_description, estimated_size);
@@ -155,7 +155,7 @@
     quota_manager_proxy_->NotifyStorageAccessed(
         storage::QuotaClient::kDatabase,
         storage::GetOriginFromIdentifier(origin_identifier),
-        blink::StorageType::kTemporary);
+        blink::mojom::StorageType::kTemporary);
 
   UpdateOpenDatabaseSizeAndNotify(origin_identifier, database_name);
   if (database_connections_.RemoveConnection(origin_identifier, database_name))
@@ -373,7 +373,7 @@
     quota_manager_proxy_->NotifyStorageModified(
         storage::QuotaClient::kDatabase,
         storage::GetOriginFromIdentifier(origin_identifier),
-        blink::StorageType::kTemporary, -db_file_size);
+        blink::mojom::StorageType::kTemporary, -db_file_size);
 
   // Clean up the main database and invalidate the cached record.
   databases_table_->DeleteDatabaseDetails(origin_identifier, database_name);
@@ -433,7 +433,7 @@
     quota_manager_proxy_->NotifyStorageModified(
         storage::QuotaClient::kDatabase,
         storage::GetOriginFromIdentifier(origin_identifier),
-        blink::StorageType::kTemporary, -deleted_size);
+        blink::mojom::StorageType::kTemporary, -deleted_size);
   }
 
   return true;
@@ -630,7 +630,7 @@
       quota_manager_proxy_->NotifyStorageModified(
           storage::QuotaClient::kDatabase,
           storage::GetOriginFromIdentifier(origin_id),
-          blink::StorageType::kTemporary, new_size - old_size);
+          blink::mojom::StorageType::kTemporary, new_size - old_size);
     for (auto& observer : observers_)
       observer.OnDatabaseSizeChanged(origin_id, name, new_size);
   }
diff --git a/storage/browser/database/database_tracker_unittest.cc b/storage/browser/database/database_tracker_unittest.cc
index 441461e..d0953eb 100644
--- a/storage/browser/database/database_tracker_unittest.cc
+++ b/storage/browser/database/database_tracker_unittest.cc
@@ -107,18 +107,18 @@
 
   void NotifyStorageAccessed(storage::QuotaClient::ID client_id,
                              const GURL& origin,
-                             blink::StorageType type) override {
+                             blink::mojom::StorageType type) override {
     EXPECT_EQ(storage::QuotaClient::kDatabase, client_id);
-    EXPECT_EQ(blink::StorageType::kTemporary, type);
+    EXPECT_EQ(blink::mojom::StorageType::kTemporary, type);
     accesses_[origin] += 1;
   }
 
   void NotifyStorageModified(storage::QuotaClient::ID client_id,
                              const GURL& origin,
-                             blink::StorageType type,
+                             blink::mojom::StorageType type,
                              int64_t delta) override {
     EXPECT_EQ(storage::QuotaClient::kDatabase, client_id);
-    EXPECT_EQ(blink::StorageType::kTemporary, type);
+    EXPECT_EQ(blink::mojom::StorageType::kTemporary, type);
     modifications_[origin].first += 1;
     modifications_[origin].second += delta;
   }
@@ -128,11 +128,11 @@
   void NotifyOriginNoLongerInUse(const GURL& origin) override {}
   void SetUsageCacheEnabled(storage::QuotaClient::ID client_id,
                             const GURL& origin,
-                            blink::StorageType type,
+                            blink::mojom::StorageType type,
                             bool enabled) override {}
   void GetUsageAndQuota(base::SequencedTaskRunner* original_task_runner,
                         const GURL& origin,
-                        blink::StorageType type,
+                        blink::mojom::StorageType type,
                         const UsageAndQuotaCallback& callback) override {}
 
   void SimulateQuotaManagerDestroyed() {
diff --git a/storage/browser/database/vfs_backend.cc b/storage/browser/database/vfs_backend.cc
index e7282f1e..411872f8 100644
--- a/storage/browser/database/vfs_backend.cc
+++ b/storage/browser/database/vfs_backend.cc
@@ -9,8 +9,13 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
+#include "build/build_config.h"
 #include "third_party/sqlite/sqlite3.h"
 
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
 namespace storage {
 
 static const int kFileTypeMask = 0x00007F00;
diff --git a/storage/browser/fileapi/copy_or_move_operation_delegate_unittest.cc b/storage/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
index df6d4d37..efdd374 100644
--- a/storage/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
+++ b/storage/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
@@ -387,9 +387,10 @@
   void GetUsageAndQuota(storage::FileSystemType type,
                         int64_t* usage,
                         int64_t* quota) {
-    blink::QuotaStatusCode status = AsyncFileTestHelper::GetUsageAndQuota(
-        quota_manager_.get(), origin_, type, usage, quota);
-    ASSERT_EQ(blink::QuotaStatusCode::kOk, status);
+    blink::mojom::QuotaStatusCode status =
+        AsyncFileTestHelper::GetUsageAndQuota(quota_manager_.get(), origin_,
+                                              type, usage, quota);
+    ASSERT_EQ(blink::mojom::QuotaStatusCode::kOk, status);
   }
 
  private:
diff --git a/storage/browser/fileapi/file_system_operation_impl.cc b/storage/browser/fileapi/file_system_operation_impl.cc
index 5791ffa2..88c569e 100644
--- a/storage/browser/fileapi/file_system_operation_impl.cc
+++ b/storage/browser/fileapi/file_system_operation_impl.cc
@@ -416,10 +416,10 @@
 void FileSystemOperationImpl::DidGetUsageAndQuotaAndRunTask(
     const base::Closure& task,
     const base::Closure& error_callback,
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     int64_t usage,
     int64_t quota) {
-  if (status != blink::QuotaStatusCode::kOk) {
+  if (status != blink::mojom::QuotaStatusCode::kOk) {
     LOG(WARNING) << "Got unexpected quota error : " << static_cast<int>(status);
     error_callback.Run();
     return;
diff --git a/storage/browser/fileapi/file_system_operation_impl.h b/storage/browser/fileapi/file_system_operation_impl.h
index 1a625dc7..99de22c 100644
--- a/storage/browser/fileapi/file_system_operation_impl.h
+++ b/storage/browser/fileapi/file_system_operation_impl.h
@@ -19,7 +19,7 @@
 #include "storage/browser/fileapi/file_system_url.h"
 #include "storage/browser/fileapi/file_writer_delegate.h"
 #include "storage/browser/storage_browser_export.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace storage {
 
@@ -124,7 +124,7 @@
   // |error_callback|.
   void DidGetUsageAndQuotaAndRunTask(const base::Closure& task,
                                      const base::Closure& error_callback,
-                                     blink::QuotaStatusCode status,
+                                     blink::mojom::QuotaStatusCode status,
                                      int64_t usage,
                                      int64_t quota);
 
diff --git a/storage/browser/fileapi/file_system_operation_impl_unittest.cc b/storage/browser/fileapi/file_system_operation_impl_unittest.cc
index d9dc80f..a09834f 100644
--- a/storage/browser/fileapi/file_system_operation_impl_unittest.cc
+++ b/storage/browser/fileapi/file_system_operation_impl_unittest.cc
@@ -253,11 +253,12 @@
   }
 
   void GetUsageAndQuota(int64_t* usage, int64_t* quota) {
-    blink::QuotaStatusCode status = AsyncFileTestHelper::GetUsageAndQuota(
-        quota_manager_.get(), sandbox_file_system_.origin(),
-        sandbox_file_system_.type(), usage, quota);
+    blink::mojom::QuotaStatusCode status =
+        AsyncFileTestHelper::GetUsageAndQuota(
+            quota_manager_.get(), sandbox_file_system_.origin(),
+            sandbox_file_system_.type(), usage, quota);
     scoped_task_environment_.RunUntilIdle();
-    ASSERT_EQ(blink::QuotaStatusCode::kOk, status);
+    ASSERT_EQ(blink::mojom::QuotaStatusCode::kOk, status);
   }
 
   int64_t ComputePathCost(const FileSystemURL& url) {
diff --git a/storage/browser/fileapi/file_system_quota_client.cc b/storage/browser/fileapi/file_system_quota_client.cc
index 81e2ec2..31b6dbe 100644
--- a/storage/browser/fileapi/file_system_quota_client.cc
+++ b/storage/browser/fileapi/file_system_quota_client.cc
@@ -18,10 +18,10 @@
 #include "storage/browser/fileapi/file_system_usage_cache.h"
 #include "storage/browser/fileapi/sandbox_file_system_backend.h"
 #include "storage/common/fileapi/file_system_util.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 
 namespace storage {
 
@@ -59,18 +59,19 @@
   callback.Run(*origins_ptr);
 }
 
-blink::QuotaStatusCode DeleteOriginOnFileTaskRunner(FileSystemContext* context,
-                                                    const GURL& origin,
-                                                    FileSystemType type) {
+blink::mojom::QuotaStatusCode DeleteOriginOnFileTaskRunner(
+    FileSystemContext* context,
+    const GURL& origin,
+    FileSystemType type) {
   FileSystemBackend* provider = context->GetFileSystemBackend(type);
   if (!provider || !provider->GetQuotaUtil())
-    return blink::QuotaStatusCode::kErrorNotSupported;
+    return blink::mojom::QuotaStatusCode::kErrorNotSupported;
   base::File::Error result =
       provider->GetQuotaUtil()->DeleteOriginDataOnFileTaskRunner(
           context, context->quota_manager_proxy(), origin, type);
   if (result == base::File::FILE_OK)
-    return blink::QuotaStatusCode::kOk;
-  return blink::QuotaStatusCode::kErrorInvalidModification;
+    return blink::mojom::QuotaStatusCode::kOk;
+  return blink::mojom::QuotaStatusCode::kErrorInvalidModification;
 }
 
 }  // namespace
diff --git a/storage/browser/fileapi/file_system_quota_client.h b/storage/browser/fileapi/file_system_quota_client.h
index bfd975c..41d8b1f4 100644
--- a/storage/browser/fileapi/file_system_quota_client.h
+++ b/storage/browser/fileapi/file_system_quota_client.h
@@ -17,7 +17,7 @@
 #include "storage/browser/quota/quota_client.h"
 #include "storage/browser/storage_browser_export.h"
 #include "storage/common/fileapi/file_system_types.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace base {
 class SequencedTaskRunner;
@@ -43,17 +43,17 @@
   storage::QuotaClient::ID id() const override;
   void OnQuotaManagerDestroyed() override;
   void GetOriginUsage(const GURL& origin_url,
-                      blink::StorageType type,
+                      blink::mojom::StorageType type,
                       const GetUsageCallback& callback) override;
-  void GetOriginsForType(blink::StorageType type,
+  void GetOriginsForType(blink::mojom::StorageType type,
                          const GetOriginsCallback& callback) override;
-  void GetOriginsForHost(blink::StorageType type,
+  void GetOriginsForHost(blink::mojom::StorageType type,
                          const std::string& host,
                          const GetOriginsCallback& callback) override;
   void DeleteOriginData(const GURL& origin,
-                        blink::StorageType type,
+                        blink::mojom::StorageType type,
                         const DeletionCallback& callback) override;
-  bool DoesSupport(blink::StorageType type) const override;
+  bool DoesSupport(blink::mojom::StorageType type) const override;
 
  private:
   base::SequencedTaskRunner* file_task_runner() const;
diff --git a/storage/browser/fileapi/file_system_quota_client_unittest.cc b/storage/browser/fileapi/file_system_quota_client_unittest.cc
index bddc906..b7d486e 100644
--- a/storage/browser/fileapi/file_system_quota_client_unittest.cc
+++ b/storage/browser/fileapi/file_system_quota_client_unittest.cc
@@ -21,11 +21,10 @@
 #include "storage/common/fileapi/file_system_types.h"
 #include "storage/common/fileapi/file_system_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 using content::AsyncFileTestHelper;
 using storage::FileSystemQuotaClient;
 using storage::FileSystemURL;
@@ -47,7 +46,7 @@
  public:
   FileSystemQuotaClientTest()
       : additional_callback_count_(0),
-        deletion_status_(blink::QuotaStatusCode::kUnknown),
+        deletion_status_(blink::mojom::QuotaStatusCode::kUnknown),
         weak_factory_(this) {}
 
   void SetUp() override {
@@ -202,7 +201,7 @@
   void DeleteOriginData(FileSystemQuotaClient* quota_client,
                         const std::string& origin,
                         StorageType type) {
-    deletion_status_ = blink::QuotaStatusCode::kUnknown;
+    deletion_status_ = blink::mojom::QuotaStatusCode::kUnknown;
     quota_client->DeleteOriginData(
         GURL(origin), type,
         base::Bind(&FileSystemQuotaClientTest::OnDeleteOrigin,
@@ -210,7 +209,7 @@
   }
 
   int64_t usage() const { return usage_; }
-  blink::QuotaStatusCode status() { return deletion_status_; }
+  blink::mojom::QuotaStatusCode status() { return deletion_status_; }
   int additional_callback_count() const { return additional_callback_count_; }
   void set_additional_callback_count(int count) {
     additional_callback_count_ = count;
@@ -227,7 +226,7 @@
     ++additional_callback_count_;
   }
 
-  void OnDeleteOrigin(blink::QuotaStatusCode status) {
+  void OnDeleteOrigin(blink::mojom::QuotaStatusCode status) {
     deletion_status_ = status;
   }
 
@@ -237,7 +236,7 @@
   int64_t usage_;
   int additional_callback_count_;
   std::set<GURL> origins_;
-  blink::QuotaStatusCode deletion_status_;
+  blink::mojom::QuotaStatusCode deletion_status_;
   base::WeakPtrFactory<FileSystemQuotaClientTest> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(FileSystemQuotaClientTest);
@@ -532,15 +531,15 @@
 
   DeleteOriginData(quota_client.get(), "http://foo.com/", kTemporary);
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(blink::QuotaStatusCode::kOk, status());
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status());
 
   DeleteOriginData(quota_client.get(), "http://bar.com/", kPersistent);
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(blink::QuotaStatusCode::kOk, status());
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status());
 
   DeleteOriginData(quota_client.get(), "http://buz.com/", kTemporary);
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(blink::QuotaStatusCode::kOk, status());
+  EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status());
 
   EXPECT_EQ(0, GetOriginUsage(
       quota_client.get(), "http://foo.com/", kTemporary));
diff --git a/storage/browser/fileapi/obfuscated_file_util_unittest.cc b/storage/browser/fileapi/obfuscated_file_util_unittest.cc
index 2a937875..a5d11990 100644
--- a/storage/browser/fileapi/obfuscated_file_util_unittest.cc
+++ b/storage/browser/fileapi/obfuscated_file_util_unittest.cc
@@ -158,7 +158,7 @@
         origin_(GURL("http://www.example.com")),
         type_(storage::kFileSystemTypeTemporary),
         sandbox_file_system_(origin_, type_),
-        quota_status_(blink::QuotaStatusCode::kUnknown),
+        quota_status_(blink::mojom::QuotaStatusCode::kUnknown),
         usage_(-1),
         weak_factory_(this) {}
 
@@ -281,7 +281,7 @@
                                               sandbox_file_system_.type(),
                                               &usage_,
                                               &quota);
-    EXPECT_EQ(blink::QuotaStatusCode::kOk, quota_status_);
+    EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, quota_status_);
   }
 
   void RevokeUsageCache() {
@@ -822,7 +822,7 @@
   GURL origin_;
   storage::FileSystemType type_;
   SandboxFileSystemTestHelper sandbox_file_system_;
-  blink::QuotaStatusCode quota_status_;
+  blink::mojom::QuotaStatusCode quota_status_;
   int64_t usage_;
   storage::MockFileChangeObserver change_observer_;
   storage::ChangeObserverList change_observers_;
diff --git a/storage/browser/fileapi/quota/quota_backend_impl.cc b/storage/browser/fileapi/quota/quota_backend_impl.cc
index e777687c9..1e47e2e 100644
--- a/storage/browser/fileapi/quota/quota_backend_impl.cc
+++ b/storage/browser/fileapi/quota/quota_backend_impl.cc
@@ -106,14 +106,14 @@
 void QuotaBackendImpl::DidGetUsageAndQuotaForReserveQuota(
     const QuotaReservationInfo& info,
     const ReserveQuotaCallback& callback,
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     int64_t usage,
     int64_t quota) {
   DCHECK(file_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(info.origin.is_valid());
   DCHECK_LE(0, usage);
   DCHECK_LE(0, quota);
-  if (status != blink::QuotaStatusCode::kOk) {
+  if (status != blink::mojom::QuotaStatusCode::kOk) {
     callback.Run(base::File::FILE_ERROR_FAILED, 0);
     return;
   }
diff --git a/storage/browser/fileapi/quota/quota_backend_impl.h b/storage/browser/fileapi/quota/quota_backend_impl.h
index ed364bd6..1a3edcf 100644
--- a/storage/browser/fileapi/quota/quota_backend_impl.h
+++ b/storage/browser/fileapi/quota/quota_backend_impl.h
@@ -13,7 +13,7 @@
 #include "storage/browser/fileapi/quota/quota_reservation_manager.h"
 #include "storage/browser/fileapi/sandbox_file_system_backend_delegate.h"
 #include "storage/browser/storage_browser_export.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace base {
 class SequencedTaskRunner;
@@ -75,7 +75,7 @@
 
   void DidGetUsageAndQuotaForReserveQuota(const QuotaReservationInfo& info,
                                           const ReserveQuotaCallback& callback,
-                                          blink::QuotaStatusCode status,
+                                          blink::mojom::QuotaStatusCode status,
                                           int64_t usage,
                                           int64_t quota);
 
diff --git a/storage/browser/fileapi/quota/quota_backend_impl_unittest.cc b/storage/browser/fileapi/quota/quota_backend_impl_unittest.cc
index e1e7cbb..fe74ddd 100644
--- a/storage/browser/fileapi/quota/quota_backend_impl_unittest.cc
+++ b/storage/browser/fileapi/quota/quota_backend_impl_unittest.cc
@@ -56,12 +56,12 @@
   void NotifyOriginNoLongerInUse(const GURL& origin) override {}
   void SetUsageCacheEnabled(storage::QuotaClient::ID client_id,
                             const GURL& origin,
-                            blink::StorageType type,
+                            blink::mojom::StorageType type,
                             bool enabled) override {}
 
   void NotifyStorageModified(storage::QuotaClient::ID client_id,
                              const GURL& origin,
-                             blink::StorageType type,
+                             blink::mojom::StorageType type,
                              int64_t delta) override {
     ++storage_modified_count_;
     usage_ += delta;
@@ -70,9 +70,9 @@
 
   void GetUsageAndQuota(base::SequencedTaskRunner* original_task_runner,
                         const GURL& origin,
-                        blink::StorageType type,
+                        blink::mojom::StorageType type,
                         const UsageAndQuotaCallback& callback) override {
-    callback.Run(blink::QuotaStatusCode::kOk, usage_, quota_);
+    callback.Run(blink::mojom::QuotaStatusCode::kOk, usage_, quota_);
   }
 
   int storage_modified_count() { return storage_modified_count_; }
diff --git a/storage/browser/fileapi/sandbox_file_stream_writer.cc b/storage/browser/fileapi/sandbox_file_stream_writer.cc
index 4b09e38..b7639eaf 100644
--- a/storage/browser/fileapi/sandbox_file_stream_writer.cc
+++ b/storage/browser/fileapi/sandbox_file_stream_writer.cc
@@ -169,12 +169,12 @@
 
 void SandboxFileStreamWriter::DidGetUsageAndQuota(
     const net::CompletionCallback& callback,
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     int64_t usage,
     int64_t quota) {
   if (CancelIfRequested())
     return;
-  if (status != blink::QuotaStatusCode::kOk) {
+  if (status != blink::mojom::QuotaStatusCode::kOk) {
     LOG(WARNING) << "Got unexpected quota error : " << static_cast<int>(status);
 
     // crbug.com/349708
diff --git a/storage/browser/fileapi/sandbox_file_stream_writer.h b/storage/browser/fileapi/sandbox_file_stream_writer.h
index 8b20b0b..625b799 100644
--- a/storage/browser/fileapi/sandbox_file_stream_writer.h
+++ b/storage/browser/fileapi/sandbox_file_stream_writer.h
@@ -18,7 +18,7 @@
 #include "storage/browser/fileapi/task_runner_bound_observer_list.h"
 #include "storage/browser/storage_browser_export.h"
 #include "storage/common/fileapi/file_system_types.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 namespace storage {
@@ -58,7 +58,7 @@
       const base::FilePath& platform_path,
       scoped_refptr<storage::ShareableFileReference> file_ref);
   void DidGetUsageAndQuota(const net::CompletionCallback& callback,
-                           blink::QuotaStatusCode status,
+                           blink::mojom::QuotaStatusCode status,
                            int64_t usage,
                            int64_t quota);
   void DidInitializeForWrite(net::IOBuffer* buf, int buf_len,
diff --git a/storage/browser/fileapi/sandbox_file_system_backend_delegate_unittest.cc b/storage/browser/fileapi/sandbox_file_system_backend_delegate_unittest.cc
index 53f769a..2623680 100644
--- a/storage/browser/fileapi/sandbox_file_system_backend_delegate_unittest.cc
+++ b/storage/browser/fileapi/sandbox_file_system_backend_delegate_unittest.cc
@@ -135,7 +135,7 @@
   EXPECT_EQ(quota_manager_proxy()->notify_storage_accessed_count(), 1);
   EXPECT_EQ(quota_manager_proxy()->last_notified_origin(), origin);
   EXPECT_EQ(quota_manager_proxy()->last_notified_type(),
-            blink::StorageType::kTemporary);
+            blink::mojom::StorageType::kTemporary);
 }
 
 }  // namespace content
diff --git a/storage/browser/quota/client_usage_tracker.cc b/storage/browser/quota/client_usage_tracker.cc
index 397927c..4ca8765 100644
--- a/storage/browser/quota/client_usage_tracker.cc
+++ b/storage/browser/quota/client_usage_tracker.cc
@@ -60,7 +60,7 @@
 ClientUsageTracker::ClientUsageTracker(
     UsageTracker* tracker,
     QuotaClient* client,
-    blink::StorageType type,
+    blink::mojom::StorageType type,
     SpecialStoragePolicy* special_storage_policy,
     StorageMonitor* storage_monitor)
     : tracker_(tracker),
@@ -489,7 +489,7 @@
 }
 
 bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const {
-  if (type_ == blink::StorageType::kSyncable)
+  if (type_ == blink::mojom::StorageType::kSyncable)
     return false;
   return special_storage_policy_.get() &&
          special_storage_policy_->IsStorageUnlimited(origin);
diff --git a/storage/browser/quota/client_usage_tracker.h b/storage/browser/quota/client_usage_tracker.h
index 182777d..bced17b 100644
--- a/storage/browser/quota/client_usage_tracker.h
+++ b/storage/browser/quota/client_usage_tracker.h
@@ -21,7 +21,7 @@
 #include "storage/browser/quota/quota_task.h"
 #include "storage/browser/quota/special_storage_policy.h"
 #include "storage/browser/storage_browser_export.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 namespace storage {
@@ -42,7 +42,7 @@
 
   ClientUsageTracker(UsageTracker* tracker,
                      QuotaClient* client,
-                     blink::StorageType type,
+                     blink::mojom::StorageType type,
                      SpecialStoragePolicy* special_storage_policy,
                      StorageMonitor* storage_monitor);
   ~ClientUsageTracker() override;
@@ -117,7 +117,7 @@
 
   UsageTracker* tracker_;
   QuotaClient* client_;
-  const blink::StorageType type_;
+  const blink::mojom::StorageType type_;
   StorageMonitor* storage_monitor_;
 
   int64_t global_limited_usage_;
diff --git a/storage/browser/quota/quota_callbacks.h b/storage/browser/quota/quota_callbacks.h
index 402af55..749ec0d 100644
--- a/storage/browser/quota/quota_callbacks.h
+++ b/storage/browser/quota/quota_callbacks.h
@@ -16,8 +16,7 @@
 #include "base/callback.h"
 #include "base/containers/flat_map.h"
 #include "storage/browser/quota/quota_client.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 class GURL;
 
@@ -29,17 +28,18 @@
 // Common callback types that are used throughout in the quota module.
 typedef base::Callback<void(int64_t usage, int64_t unlimited_usage)>
     GlobalUsageCallback;
-typedef base::Callback<void(blink::QuotaStatusCode status, int64_t quota)>
+typedef base::Callback<void(blink::mojom::QuotaStatusCode status,
+                            int64_t quota)>
     QuotaCallback;
 typedef base::Callback<void(int64_t usage)> UsageCallback;
 typedef base::Callback<void(int64_t usage,
                             base::flat_map<QuotaClient::ID, int64_t>)>
     UsageWithBreakdownCallback;
-typedef base::Callback<void(blink::QuotaStatusCode, int64_t)>
+typedef base::Callback<void(blink::mojom::QuotaStatusCode, int64_t)>
     AvailableSpaceCallback;
-typedef base::Callback<void(blink::QuotaStatusCode)> StatusCallback;
+typedef base::Callback<void(blink::mojom::QuotaStatusCode)> StatusCallback;
 typedef base::Callback<void(const std::set<GURL>& origins,
-                            blink::StorageType type)>
+                            blink::mojom::StorageType type)>
     GetOriginsCallback;
 typedef base::Callback<void(const UsageInfoEntries&)> GetUsageInfoCallback;
 typedef base::Callback<void(const GURL&)> GetOriginCallback;
diff --git a/storage/browser/quota/quota_client.h b/storage/browser/quota/quota_client.h
index 57d274d..9dc00d82 100644
--- a/storage/browser/quota/quota_client.h
+++ b/storage/browser/quota/quota_client.h
@@ -13,8 +13,7 @@
 
 #include "base/callback.h"
 #include "storage/browser/storage_browser_export.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 namespace storage {
@@ -28,7 +27,8 @@
   typedef base::Callback<void(int64_t usage)> GetUsageCallback;
   typedef base::Callback<void(const std::set<GURL>& origins)>
       GetOriginsCallback;
-  typedef base::Callback<void(blink::QuotaStatusCode status)> DeletionCallback;
+  typedef base::Callback<void(blink::mojom::QuotaStatusCode status)>
+      DeletionCallback;
 
   virtual ~QuotaClient() {}
 
@@ -53,29 +53,29 @@
   // |origin_url| and |type|.
   // Note it is safe to fire the callback after the QuotaClient is destructed.
   virtual void GetOriginUsage(const GURL& origin_url,
-                              blink::StorageType type,
+                              blink::mojom::StorageType type,
                               const GetUsageCallback& callback) = 0;
 
   // Called by the QuotaManager.
   // Returns a list of origins that has data in the |type| storage.
   // Note it is safe to fire the callback after the QuotaClient is destructed.
-  virtual void GetOriginsForType(blink::StorageType type,
+  virtual void GetOriginsForType(blink::mojom::StorageType type,
                                  const GetOriginsCallback& callback) = 0;
 
   // Called by the QuotaManager.
   // Returns a list of origins that match the |host|.
   // Note it is safe to fire the callback after the QuotaClient is destructed.
-  virtual void GetOriginsForHost(blink::StorageType type,
+  virtual void GetOriginsForHost(blink::mojom::StorageType type,
                                  const std::string& host,
                                  const GetOriginsCallback& callback) = 0;
 
   // Called by the QuotaManager.
   // Note it is safe to fire the callback after the QuotaClient is destructed.
   virtual void DeleteOriginData(const GURL& origin,
-                                blink::StorageType type,
+                                blink::mojom::StorageType type,
                                 const DeletionCallback& callback) = 0;
 
-  virtual bool DoesSupport(blink::StorageType type) const = 0;
+  virtual bool DoesSupport(blink::mojom::StorageType type) const = 0;
 };
 
 // TODO(dmikurube): Replace it to std::vector for efficiency.
diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc
index c1828782..02ee1493 100644
--- a/storage/browser/quota/quota_database.cc
+++ b/storage/browser/quota/quota_database.cc
@@ -21,7 +21,7 @@
 #include "sql/transaction.h"
 #include "storage/browser/quota/special_storage_policy.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 
 namespace storage {
 namespace {
diff --git a/storage/browser/quota/quota_database.h b/storage/browser/quota/quota_database.h
index 846d5d93..5d215c7 100644
--- a/storage/browser/quota/quota_database.h
+++ b/storage/browser/quota/quota_database.h
@@ -18,7 +18,7 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "storage/browser/storage_browser_export.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 namespace content {
@@ -42,12 +42,12 @@
   struct STORAGE_EXPORT OriginInfoTableEntry {
     OriginInfoTableEntry();
     OriginInfoTableEntry(const GURL& origin,
-                         blink::StorageType type,
+                         blink::mojom::StorageType type,
                          int used_count,
                          const base::Time& last_access_time,
                          const base::Time& last_modified_time);
     GURL origin;
-    blink::StorageType type;
+    blink::mojom::StorageType type;
     int used_count;
     base::Time last_access_time;
     base::Time last_modified_time;
@@ -65,50 +65,50 @@
 
   // Returns whether the record could be found.
   bool GetHostQuota(const std::string& host,
-                    blink::StorageType type,
+                    blink::mojom::StorageType type,
                     int64_t* quota);
 
   // Returns whether the operation succeeded.
   bool SetHostQuota(const std::string& host,
-                    blink::StorageType type,
+                    blink::mojom::StorageType type,
                     int64_t quota);
-  bool DeleteHostQuota(const std::string& host, blink::StorageType type);
+  bool DeleteHostQuota(const std::string& host, blink::mojom::StorageType type);
 
   bool SetOriginLastAccessTime(const GURL& origin,
-                               blink::StorageType type,
+                               blink::mojom::StorageType type,
                                base::Time last_access_time);
 
   bool SetOriginLastModifiedTime(const GURL& origin,
-                                 blink::StorageType type,
+                                 blink::mojom::StorageType type,
                                  base::Time last_modified_time);
 
   // Gets the time |origin| was last evicted. Returns whether the record could
   // be found.
   bool GetOriginLastEvictionTime(const GURL& origin,
-                                 blink::StorageType type,
+                                 blink::mojom::StorageType type,
                                  base::Time* last_eviction_time);
 
   // Sets the time the origin was last evicted. Returns whether the operation
   // succeeded.
   bool SetOriginLastEvictionTime(const GURL& origin,
-                                 blink::StorageType type,
+                                 blink::mojom::StorageType type,
                                  base::Time last_eviction_time);
   bool DeleteOriginLastEvictionTime(const GURL& origin,
-                                    blink::StorageType type);
+                                    blink::mojom::StorageType type);
 
   // Register initial |origins| info |type| to the database.
   // This method is assumed to be called only after the installation or
   // the database schema reset.
   bool RegisterInitialOriginInfo(const std::set<GURL>& origins,
-                                 blink::StorageType type);
+                                 blink::mojom::StorageType type);
 
   // Gets the OriginInfoTableEntry for |origin|. Returns whether the record
   // could be found.
   bool GetOriginInfo(const GURL& origin,
-                     blink::StorageType type,
+                     blink::mojom::StorageType type,
                      OriginInfoTableEntry* entry);
 
-  bool DeleteOriginInfo(const GURL& origin, blink::StorageType type);
+  bool DeleteOriginInfo(const GURL& origin, blink::mojom::StorageType type);
 
   bool GetQuotaConfigValue(const char* key, int64_t* value);
   bool SetQuotaConfigValue(const char* key, int64_t value);
@@ -117,14 +117,14 @@
   // in |exceptions| and not granted the special unlimited storage right.
   // It returns false when it failed in accessing the database.
   // |origin| is set to empty when there is no matching origin.
-  bool GetLRUOrigin(blink::StorageType type,
+  bool GetLRUOrigin(blink::mojom::StorageType type,
                     const std::set<GURL>& exceptions,
                     SpecialStoragePolicy* special_storage_policy,
                     GURL* origin);
 
   // Populates |origins| with the ones that have been modified since
   // the |modified_since|. Returns whether the operation succeeded.
-  bool GetOriginsModifiedSince(blink::StorageType type,
+  bool GetOriginsModifiedSince(blink::mojom::StorageType type,
                                std::set<GURL>* origins,
                                base::Time modified_since);
 
@@ -138,10 +138,10 @@
   struct STORAGE_EXPORT QuotaTableEntry {
     QuotaTableEntry();
     QuotaTableEntry(const std::string& host,
-                    blink::StorageType type,
+                    blink::mojom::StorageType type,
                     int64_t quota);
     std::string host;
-    blink::StorageType type;
+    blink::mojom::StorageType type;
     int64_t quota;
   };
   friend STORAGE_EXPORT bool operator <(
@@ -179,7 +179,7 @@
   bool ResetSchema();
   bool UpgradeSchema(int current_version);
   bool InsertOrReplaceHostQuota(const std::string& host,
-                                blink::StorageType type,
+                                blink::mojom::StorageType type,
                                 int64_t quota);
 
   static bool CreateSchema(
diff --git a/storage/browser/quota/quota_database_unittest.cc b/storage/browser/quota/quota_database_unittest.cc
index 92b35f7..d790276 100644
--- a/storage/browser/quota/quota_database_unittest.cc
+++ b/storage/browser/quota/quota_database_unittest.cc
@@ -37,8 +37,10 @@
 }  // namespace
 
 // Declared to shorten the line lengths.
-static const blink::StorageType kTemporary = blink::StorageType::kTemporary;
-static const blink::StorageType kPersistent = blink::StorageType::kPersistent;
+static const blink::mojom::StorageType kTemporary =
+    blink::mojom::StorageType::kTemporary;
+static const blink::mojom::StorageType kPersistent =
+    blink::mojom::StorageType::kPersistent;
 
 class QuotaDatabaseTest : public testing::Test {
  protected:
diff --git a/storage/browser/quota/quota_manager.cc b/storage/browser/quota/quota_manager.cc
index 9ba9ee41..c7096bb 100644
--- a/storage/browser/quota/quota_manager.cc
+++ b/storage/browser/quota/quota_manager.cc
@@ -38,7 +38,7 @@
 #include "storage/browser/quota/storage_monitor.h"
 #include "storage/browser/quota/usage_tracker.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 
 namespace storage {
 
@@ -210,7 +210,7 @@
 
 void DidGetUsageAndQuotaForWebApps(
     const QuotaManager::UsageAndQuotaCallback& callback,
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     int64_t usage,
     int64_t quota,
     base::flat_map<QuotaClient::ID, int64_t> usage_breakdown) {
@@ -261,9 +261,10 @@
 
     // Determine host_quota differently depending on type.
     if (is_unlimited_) {
-      SetDesiredHostQuota(barrier, blink::QuotaStatusCode::kOk, kNoLimit);
+      SetDesiredHostQuota(barrier, blink::mojom::QuotaStatusCode::kOk,
+                          kNoLimit);
     } else if (type_ == StorageType::kSyncable) {
-      SetDesiredHostQuota(barrier, blink::QuotaStatusCode::kOk,
+      SetDesiredHostQuota(barrier, blink::mojom::QuotaStatusCode::kOk,
                           kSyncableStorageDefaultHostQuota);
     } else if (type_ == StorageType::kPersistent) {
       manager()->GetPersistentHostQuota(
@@ -277,7 +278,7 @@
 
   void Aborted() override {
     weak_factory_.InvalidateWeakPtrs();
-    callback_.Run(blink::QuotaStatusCode::kErrorAbort, 0, 0,
+    callback_.Run(blink::mojom::QuotaStatusCode::kErrorAbort, 0, 0,
                   base::flat_map<QuotaClient::ID, int64_t>());
     DeleteSoon();
   }
@@ -293,7 +294,7 @@
                  host_usage_ +
                      std::max(INT64_C(0), available_space_ -
                                               settings_.must_remain_available));
-    callback_.Run(blink::QuotaStatusCode::kOk, host_usage_, host_quota,
+    callback_.Run(blink::mojom::QuotaStatusCode::kOk, host_usage_, host_quota,
                   std::move(host_usage_breakdown_));
     if (type_ == StorageType::kTemporary && !is_incognito_ && !is_unlimited_) {
       UMA_HISTOGRAM_MBYTES("Quota.QuotaForOrigin", host_quota);
@@ -318,7 +319,7 @@
       int64_t host_quota = is_session_only_
                                ? settings.session_only_per_host_quota
                                : settings.per_host_quota;
-      SetDesiredHostQuota(barrier_closure, blink::QuotaStatusCode::kOk,
+      SetDesiredHostQuota(barrier_closure, blink::mojom::QuotaStatusCode::kOk,
                           host_quota);
     }
   }
@@ -341,7 +342,7 @@
   }
 
   void SetDesiredHostQuota(const base::Closure& barrier_closure,
-                           blink::QuotaStatusCode status,
+                           blink::mojom::QuotaStatusCode status,
                            int64_t quota) {
     desired_host_quota_ = quota;
     barrier_closure.Run();
@@ -391,15 +392,16 @@
 
   void Aborted() override {
     weak_factory_.InvalidateWeakPtrs();
-    callback_.Run(blink::QuotaStatusCode::kErrorAbort, QuotaSettings(), 0, 0, 0,
-                  false);
+    callback_.Run(blink::mojom::QuotaStatusCode::kErrorAbort, QuotaSettings(),
+                  0, 0, 0, false);
     DeleteSoon();
   }
 
   void Completed() override {
     weak_factory_.InvalidateWeakPtrs();
-    callback_.Run(blink::QuotaStatusCode::kOk, settings_, available_space_,
-                  total_space_, global_usage_, global_usage_is_complete_);
+    callback_.Run(blink::mojom::QuotaStatusCode::kOk, settings_,
+                  available_space_, total_space_, global_usage_,
+                  global_usage_is_complete_);
     DeleteSoon();
   }
 
@@ -583,26 +585,26 @@
       // Only remove the entire origin if we didn't skip any client types.
       if (skipped_clients_ == 0)
         manager()->DeleteOriginFromDatabase(origin_, type_, is_eviction_);
-      callback_.Run(blink::QuotaStatusCode::kOk);
+      callback_.Run(blink::mojom::QuotaStatusCode::kOk);
     } else {
       // crbug.com/349708
       TRACE_EVENT0("io", "QuotaManager::OriginDataDeleter::Completed Error");
 
-      callback_.Run(blink::QuotaStatusCode::kErrorInvalidModification);
+      callback_.Run(blink::mojom::QuotaStatusCode::kErrorInvalidModification);
     }
     DeleteSoon();
   }
 
   void Aborted() override {
-    callback_.Run(blink::QuotaStatusCode::kErrorAbort);
+    callback_.Run(blink::mojom::QuotaStatusCode::kErrorAbort);
     DeleteSoon();
   }
 
  private:
-  void DidDeleteOriginData(blink::QuotaStatusCode status) {
+  void DidDeleteOriginData(blink::mojom::QuotaStatusCode status) {
     DCHECK_GT(remaining_clients_, 0);
 
-    if (status != blink::QuotaStatusCode::kOk)
+    if (status != blink::mojom::QuotaStatusCode::kOk)
       ++error_count_;
 
     if (--remaining_clients_ == 0)
@@ -661,18 +663,18 @@
       // crbug.com/349708
       TRACE_EVENT0("io", "QuotaManager::HostDataDeleter::Completed Ok");
 
-      callback_.Run(blink::QuotaStatusCode::kOk);
+      callback_.Run(blink::mojom::QuotaStatusCode::kOk);
     } else {
       // crbug.com/349708
       TRACE_EVENT0("io", "QuotaManager::HostDataDeleter::Completed Error");
 
-      callback_.Run(blink::QuotaStatusCode::kErrorInvalidModification);
+      callback_.Run(blink::mojom::QuotaStatusCode::kErrorInvalidModification);
     }
     DeleteSoon();
   }
 
   void Aborted() override {
-    callback_.Run(blink::QuotaStatusCode::kErrorAbort);
+    callback_.Run(blink::mojom::QuotaStatusCode::kErrorAbort);
     DeleteSoon();
   }
 
@@ -703,10 +705,10 @@
     }
   }
 
-  void DidDeleteOriginData(blink::QuotaStatusCode status) {
+  void DidDeleteOriginData(blink::mojom::QuotaStatusCode status) {
     DCHECK_GT(remaining_deleters_, 0);
 
-    if (status != blink::QuotaStatusCode::kOk)
+    if (status != blink::mojom::QuotaStatusCode::kOk)
       ++error_count_;
 
     if (--remaining_deleters_ == 0)
@@ -873,7 +875,7 @@
   DCHECK(origin == origin.GetOrigin());
   if (!IsSupportedType(type) ||
       (is_incognito_ && !IsSupportedIncognitoType(type))) {
-    callback.Run(blink::QuotaStatusCode::kErrorNotSupported, 0, 0,
+    callback.Run(blink::mojom::QuotaStatusCode::kErrorNotSupported, 0, 0,
                  base::flat_map<QuotaClient::ID, int64_t>());
     return;
   }
@@ -896,7 +898,7 @@
   if (IsStorageUnlimited(origin, type)) {
     // TODO(michaeln): This seems like a non-obvious odd behavior, probably for
     // apps/extensions, but it would be good to eliminate this special case.
-    callback.Run(blink::QuotaStatusCode::kOk, 0, kNoLimit);
+    callback.Run(blink::mojom::QuotaStatusCode::kOk, 0, kNoLimit);
     return;
   }
 
@@ -954,7 +956,7 @@
                                   const StatusCallback& callback) {
   LazyInitialize();
   if (host.empty() || clients_.empty()) {
-    callback.Run(blink::QuotaStatusCode::kOk);
+    callback.Run(blink::mojom::QuotaStatusCode::kOk);
     return;
   }
 
@@ -970,7 +972,7 @@
     // This could happen if we are called on file:///.
     // TODO(kinuko) We may want to respect --allow-file-access-from-files
     // command line switch.
-    callback.Run(blink::QuotaStatusCode::kOk, 0);
+    callback.Run(blink::mojom::QuotaStatusCode::kOk, 0);
     return;
   }
 
@@ -995,12 +997,12 @@
   LazyInitialize();
   if (host.empty()) {
     // This could happen if we are called on file:///.
-    callback.Run(blink::QuotaStatusCode::kErrorNotSupported, 0);
+    callback.Run(blink::mojom::QuotaStatusCode::kErrorNotSupported, 0);
     return;
   }
 
   if (new_quota < 0) {
-    callback.Run(blink::QuotaStatusCode::kErrorInvalidModification, -1);
+    callback.Run(blink::mojom::QuotaStatusCode::kErrorInvalidModification, -1);
     return;
   }
 
@@ -1008,7 +1010,7 @@
   new_quota = std::min(new_quota, kPerHostPersistentQuotaLimit);
 
   if (db_disabled_) {
-    callback.Run(blink::QuotaStatusCode::kErrorInvalidAccess, -1);
+    callback.Run(blink::mojom::QuotaStatusCode::kErrorInvalidAccess, -1);
     return;
   }
 
@@ -1337,14 +1339,14 @@
       base::Bind(&QuotaManager::DidDatabaseWork, weak_factory_.GetWeakPtr()));
 }
 
-void QuotaManager::DidOriginDataEvicted(blink::QuotaStatusCode status) {
+void QuotaManager::DidOriginDataEvicted(blink::mojom::QuotaStatusCode status) {
   DCHECK(io_thread_->BelongsToCurrentThread());
 
   // We only try evict origins that are not in use, so basically
   // deletion attempt for eviction should not fail.  Let's record
   // the origin if we get error and exclude it from future eviction
   // if the error happens consistently (> kThresholdOfErrorsToBeBlacklisted).
-  if (status != blink::QuotaStatusCode::kOk)
+  if (status != blink::mojom::QuotaStatusCode::kOk)
     origins_in_error_[eviction_context_.evicted_origin]++;
 
   eviction_context_.evict_origin_data_callback.Run(status);
@@ -1359,7 +1361,7 @@
   LazyInitialize();
 
   if (origin.is_empty() || clients_.empty()) {
-    callback.Run(blink::QuotaStatusCode::kOk);
+    callback.Run(blink::mojom::QuotaStatusCode::kOk);
     return;
   }
 
@@ -1567,7 +1569,7 @@
                                              bool success) {
   DidDatabaseWork(success);
   persistent_host_quota_callbacks_.Run(
-      host, blink::QuotaStatusCode::kOk,
+      host, blink::mojom::QuotaStatusCode::kOk,
       std::min(*quota, kPerHostPersistentQuotaLimit));
 }
 
@@ -1576,8 +1578,8 @@
                                              const int64_t* new_quota,
                                              bool success) {
   DidDatabaseWork(success);
-  callback.Run(success ? blink::QuotaStatusCode::kOk
-                       : blink::QuotaStatusCode::kErrorInvalidAccess,
+  callback.Run(success ? blink::mojom::QuotaStatusCode::kOk
+                       : blink::mojom::QuotaStatusCode::kErrorInvalidAccess,
                *new_quota);
 }
 
diff --git a/storage/browser/quota/quota_manager.h b/storage/browser/quota/quota_manager.h
index f51b6e0..04fd7c5 100644
--- a/storage/browser/quota/quota_manager.h
+++ b/storage/browser/quota/quota_manager.h
@@ -32,8 +32,7 @@
 #include "storage/browser/quota/special_storage_policy.h"
 #include "storage/browser/quota/storage_observer.h"
 #include "storage/browser/storage_browser_export.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace base {
 class FilePath;
@@ -68,7 +67,7 @@
 class STORAGE_EXPORT QuotaEvictionHandler {
  public:
   using EvictionRoundInfoCallback =
-      base::Callback<void(blink::QuotaStatusCode status,
+      base::Callback<void(blink::mojom::QuotaStatusCode status,
                           const QuotaSettings& settings,
                           int64_t available_space,
                           int64_t total_space,
@@ -82,14 +81,14 @@
 
   // Returns next origin to evict.  It might return an empty GURL when there are
   // no evictable origins.
-  virtual void GetEvictionOrigin(blink::StorageType type,
+  virtual void GetEvictionOrigin(blink::mojom::StorageType type,
                                  const std::set<GURL>& extra_exceptions,
                                  int64_t global_quota,
                                  const GetOriginCallback& callback) = 0;
 
   // Called to evict an origin.
   virtual void EvictOriginData(const GURL& origin,
-                               blink::StorageType type,
+                               blink::mojom::StorageType type,
                                const StatusCallback& callback) = 0;
 
  protected:
@@ -97,10 +96,12 @@
 };
 
 struct UsageInfo {
-  UsageInfo(const std::string& host, blink::StorageType type, int64_t usage)
+  UsageInfo(const std::string& host,
+            blink::mojom::StorageType type,
+            int64_t usage)
       : host(host), type(type), usage(usage) {}
   std::string host;
-  blink::StorageType type;
+  blink::mojom::StorageType type;
   int64_t usage;
 };
 
@@ -113,11 +114,12 @@
       public QuotaEvictionHandler,
       public base::RefCountedThreadSafe<QuotaManager, QuotaManagerDeleter> {
  public:
-  typedef base::Callback<
-      void(blink::QuotaStatusCode, int64_t /* usage */, int64_t /* quota */)>
+  typedef base::Callback<void(blink::mojom::QuotaStatusCode,
+                              int64_t /* usage */,
+                              int64_t /* quota */)>
       UsageAndQuotaCallback;
   typedef base::Callback<void(
-      blink::QuotaStatusCode,
+      blink::mojom::QuotaStatusCode,
       int64_t /* usage */,
       int64_t /* quota */,
       base::flat_map<QuotaClient::ID, int64_t> /* usage breakdown */)>
@@ -145,14 +147,14 @@
   // This method is declared as virtual to allow test code to override it.
   virtual void GetUsageAndQuotaForWebApps(
       const GURL& origin,
-      blink::StorageType type,
+      blink::mojom::StorageType type,
       const UsageAndQuotaCallback& callback);
 
   // Called by DevTools.
   // This method is declared as virtual to allow test code to override it.
   virtual void GetUsageAndQuotaWithBreakdown(
       const GURL& origin,
-      blink::StorageType type,
+      blink::mojom::StorageType type,
       const UsageAndQuotaWithBreakdownCallback& callback);
 
   // Called by StorageClients.
@@ -162,7 +164,7 @@
   // to avoid extra query cost.
   // Do not call this method for apps/user-facing code.
   virtual void GetUsageAndQuota(const GURL& origin,
-                                blink::StorageType type,
+                                blink::mojom::StorageType type,
                                 const UsageAndQuotaCallback& callback);
 
   // Called by clients via proxy.
@@ -170,14 +172,14 @@
   // Used to maintain LRU ordering.
   void NotifyStorageAccessed(QuotaClient::ID client_id,
                              const GURL& origin,
-                             blink::StorageType type);
+                             blink::mojom::StorageType type);
 
   // Called by clients via proxy.
   // Client storage must call this method whenever they have made any
   // modifications that change the amount of data stored in their storage.
   void NotifyStorageModified(QuotaClient::ID client_id,
                              const GURL& origin,
-                             blink::StorageType type,
+                             blink::mojom::StorageType type,
                              int64_t delta);
 
   // Used to avoid evicting origins with open pages.
@@ -191,22 +193,22 @@
 
   void SetUsageCacheEnabled(QuotaClient::ID client_id,
                             const GURL& origin,
-                            blink::StorageType type,
+                            blink::mojom::StorageType type,
                             bool enabled);
 
   // DeleteOriginData and DeleteHostData (surprisingly enough) delete data of a
-  // particular blink::StorageType associated with either a specific origin or
-  // set of origins. Each method additionally requires a |quota_client_mask|
-  // which specifies the types of QuotaClients to delete from the origin. This
-  // is specified by the caller as a bitmask built from QuotaClient::IDs.
-  // Setting the mask to QuotaClient::kAllClientsMask will remove all clients
-  // from the origin, regardless of type.
+  // particular blink::mojom::StorageType associated with either a specific
+  // origin or set of origins. Each method additionally requires a
+  // |quota_client_mask| which specifies the types of QuotaClients to delete
+  // from the origin. This is specified by the caller as a bitmask built from
+  // QuotaClient::IDs. Setting the mask to QuotaClient::kAllClientsMask will
+  // remove all clients from the origin, regardless of type.
   virtual void DeleteOriginData(const GURL& origin,
-                                blink::StorageType type,
+                                blink::mojom::StorageType type,
                                 int quota_client_mask,
                                 const StatusCallback& callback);
   void DeleteHostData(const std::string& host,
-                      blink::StorageType type,
+                      blink::mojom::StorageType type,
                       int quota_client_mask,
                       const StatusCallback& callback);
 
@@ -216,31 +218,32 @@
   void SetPersistentHostQuota(const std::string& host,
                               int64_t new_quota,
                               const QuotaCallback& callback);
-  void GetGlobalUsage(blink::StorageType type,
+  void GetGlobalUsage(blink::mojom::StorageType type,
                       const GlobalUsageCallback& callback);
   void GetHostUsage(const std::string& host,
-                    blink::StorageType type,
+                    blink::mojom::StorageType type,
                     const UsageCallback& callback);
   void GetHostUsage(const std::string& host,
-                    blink::StorageType type,
+                    blink::mojom::StorageType type,
                     QuotaClient::ID client_id,
                     const UsageCallback& callback);
   void GetHostUsageWithBreakdown(const std::string& host,
-                                 blink::StorageType type,
+                                 blink::mojom::StorageType type,
                                  const UsageWithBreakdownCallback& callback);
 
-  bool IsTrackingHostUsage(blink::StorageType type,
+  bool IsTrackingHostUsage(blink::mojom::StorageType type,
                            QuotaClient::ID client_id) const;
 
   void GetStatistics(std::map<std::string, std::string>* statistics);
 
-  bool IsStorageUnlimited(const GURL& origin, blink::StorageType type) const;
+  bool IsStorageUnlimited(const GURL& origin,
+                          blink::mojom::StorageType type) const;
 
-  virtual void GetOriginsModifiedSince(blink::StorageType type,
+  virtual void GetOriginsModifiedSince(blink::mojom::StorageType type,
                                        base::Time modified_since,
                                        const GetOriginsCallback& callback);
 
-  bool ResetUsageTracker(blink::StorageType type);
+  bool ResetUsageTracker(blink::mojom::StorageType type);
 
   // Used to register/deregister observers that wish to monitor storage events.
   void AddStorageObserver(StorageObserver* observer,
@@ -305,7 +308,7 @@
   typedef CallbackQueue<base::Closure> ClosureQueue;
   typedef CallbackQueueMap<QuotaCallback,
                            std::string,
-                           blink::QuotaStatusCode,
+                           blink::mojom::QuotaStatusCode,
                            int64_t>
       HostQuotaCallbackMap;
   using QuotaSettingsCallbackQueue =
@@ -320,7 +323,7 @@
     EvictionContext();
     ~EvictionContext();
     GURL evicted_origin;
-    blink::StorageType evicted_type;
+    blink::mojom::StorageType evicted_type;
     StatusCallback evict_origin_data_callback;
   };
 
@@ -342,20 +345,21 @@
   // The client must remain valid until OnQuotaManagerDestored is called.
   void RegisterClient(QuotaClient* client);
 
-  UsageTracker* GetUsageTracker(blink::StorageType type) const;
+  UsageTracker* GetUsageTracker(blink::mojom::StorageType type) const;
 
   // Extract cached origins list from the usage tracker.
   // (Might return empty list if no origin is tracked by the tracker.)
-  void GetCachedOrigins(blink::StorageType type, std::set<GURL>* origins);
+  void GetCachedOrigins(blink::mojom::StorageType type,
+                        std::set<GURL>* origins);
 
   // These internal methods are separately defined mainly for testing.
   void NotifyStorageAccessedInternal(QuotaClient::ID client_id,
                                      const GURL& origin,
-                                     blink::StorageType type,
+                                     blink::mojom::StorageType type,
                                      base::Time accessed_time);
   void NotifyStorageModifiedInternal(QuotaClient::ID client_id,
                                      const GURL& origin,
-                                     blink::StorageType type,
+                                     blink::mojom::StorageType type,
                                      int64_t delta,
                                      base::Time modified_time);
 
@@ -363,7 +367,7 @@
   void DumpOriginInfoTable(const DumpOriginInfoTableCallback& callback);
 
   void DeleteOriginDataInternal(const GURL& origin,
-                                blink::StorageType type,
+                                blink::mojom::StorageType type,
                                 int quota_client_mask,
                                 bool is_eviction,
                                 const StatusCallback& callback);
@@ -371,10 +375,10 @@
   // Methods for eviction logic.
   void StartEviction();
   void DeleteOriginFromDatabase(const GURL& origin,
-                                blink::StorageType type,
+                                blink::mojom::StorageType type,
                                 bool is_eviction);
 
-  void DidOriginDataEvicted(blink::QuotaStatusCode status);
+  void DidOriginDataEvicted(blink::mojom::QuotaStatusCode status);
 
   void ReportHistogram();
   void DidGetTemporaryGlobalUsageForHistogram(int64_t usage,
@@ -390,16 +394,17 @@
                             const GURL& origin);
 
   // QuotaEvictionHandler.
-  void GetEvictionOrigin(blink::StorageType type,
+  void GetEvictionOrigin(blink::mojom::StorageType type,
                          const std::set<GURL>& extra_exceptions,
                          int64_t global_quota,
                          const GetOriginCallback& callback) override;
   void EvictOriginData(const GURL& origin,
-                       blink::StorageType type,
+                       blink::mojom::StorageType type,
                        const StatusCallback& callback) override;
   void GetEvictionRoundInfo(const EvictionRoundInfoCallback& callback) override;
 
-  void GetLRUOrigin(blink::StorageType type, const GetOriginCallback& callback);
+  void GetLRUOrigin(blink::mojom::StorageType type,
+                    const GetOriginCallback& callback);
 
   void DidGetPersistentHostQuota(const std::string& host,
                                  const int64_t* quota,
diff --git a/storage/browser/quota/quota_manager_proxy.cc b/storage/browser/quota/quota_manager_proxy.cc
index ae2755c..822b12ce1 100644
--- a/storage/browser/quota/quota_manager_proxy.cc
+++ b/storage/browser/quota/quota_manager_proxy.cc
@@ -13,7 +13,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/task_runner_util.h"
 #include "base/trace_event/trace_event.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace storage {
 
@@ -22,7 +22,7 @@
 void DidGetUsageAndQuota(
     base::SequencedTaskRunner* original_task_runner,
     const QuotaManagerProxy::UsageAndQuotaCallback& callback,
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     int64_t usage,
     int64_t quota) {
   if (!original_task_runner->RunsTasksInCurrentSequence()) {
@@ -56,7 +56,7 @@
 
 void QuotaManagerProxy::NotifyStorageAccessed(QuotaClient::ID client_id,
                                               const GURL& origin,
-                                              blink::StorageType type) {
+                                              blink::mojom::StorageType type) {
   if (!io_thread_->BelongsToCurrentThread()) {
     io_thread_->PostTask(
         FROM_HERE,
@@ -71,7 +71,7 @@
 
 void QuotaManagerProxy::NotifyStorageModified(QuotaClient::ID client_id,
                                               const GURL& origin,
-                                              blink::StorageType type,
+                                              blink::mojom::StorageType type,
                                               int64_t delta) {
   if (!io_thread_->BelongsToCurrentThread()) {
     io_thread_->PostTask(
@@ -113,7 +113,7 @@
 
 void QuotaManagerProxy::SetUsageCacheEnabled(QuotaClient::ID client_id,
                                              const GURL& origin,
-                                             blink::StorageType type,
+                                             blink::mojom::StorageType type,
                                              bool enabled) {
   if (!io_thread_->BelongsToCurrentThread()) {
     io_thread_->PostTask(
@@ -129,7 +129,7 @@
 void QuotaManagerProxy::GetUsageAndQuota(
     base::SequencedTaskRunner* original_task_runner,
     const GURL& origin,
-    blink::StorageType type,
+    blink::mojom::StorageType type,
     const UsageAndQuotaCallback& callback) {
   if (!io_thread_->BelongsToCurrentThread()) {
     io_thread_->PostTask(
@@ -140,7 +140,7 @@
   }
   if (!manager_) {
     DidGetUsageAndQuota(original_task_runner, callback,
-                        blink::QuotaStatusCode::kErrorAbort, 0, 0);
+                        blink::mojom::QuotaStatusCode::kErrorAbort, 0, 0);
     return;
   }
 
diff --git a/storage/browser/quota/quota_manager_proxy.h b/storage/browser/quota/quota_manager_proxy.h
index 2d805c31..c1be8b9f 100644
--- a/storage/browser/quota/quota_manager_proxy.h
+++ b/storage/browser/quota/quota_manager_proxy.h
@@ -22,7 +22,7 @@
 #include "storage/browser/quota/quota_task.h"
 #include "storage/browser/quota/special_storage_policy.h"
 #include "storage/browser/storage_browser_export.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace base {
 class SequencedTaskRunner;
@@ -40,21 +40,21 @@
   virtual void RegisterClient(QuotaClient* client);
   virtual void NotifyStorageAccessed(QuotaClient::ID client_id,
                                      const GURL& origin,
-                                     blink::StorageType type);
+                                     blink::mojom::StorageType type);
   virtual void NotifyStorageModified(QuotaClient::ID client_id,
                                      const GURL& origin,
-                                     blink::StorageType type,
+                                     blink::mojom::StorageType type,
                                      int64_t delta);
   virtual void NotifyOriginInUse(const GURL& origin);
   virtual void NotifyOriginNoLongerInUse(const GURL& origin);
 
   virtual void SetUsageCacheEnabled(QuotaClient::ID client_id,
                                     const GURL& origin,
-                                    blink::StorageType type,
+                                    blink::mojom::StorageType type,
                                     bool enabled);
   virtual void GetUsageAndQuota(base::SequencedTaskRunner* original_task_runner,
                                 const GURL& origin,
-                                blink::StorageType type,
+                                blink::mojom::StorageType type,
                                 const UsageAndQuotaCallback& callback);
 
   // This method may only be called on the IO thread.
diff --git a/storage/browser/quota/quota_manager_unittest.cc b/storage/browser/quota/quota_manager_unittest.cc
index 7f0c267..6e6a6a0 100644
--- a/storage/browser/quota/quota_manager_unittest.cc
+++ b/storage/browser/quota/quota_manager_unittest.cc
@@ -33,8 +33,8 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
-using blink::QuotaStatusCode;
-using blink::StorageType;
+using blink::mojom::QuotaStatusCode;
+using blink::mojom::StorageType;
 using storage::QuotaClient;
 using storage::QuotaManager;
 using storage::UsageInfo;
diff --git a/storage/browser/quota/quota_temporary_storage_evictor.cc b/storage/browser/quota/quota_temporary_storage_evictor.cc
index 3c2c4f1..6b0c9f3 100644
--- a/storage/browser/quota/quota_temporary_storage_evictor.cc
+++ b/storage/browser/quota/quota_temporary_storage_evictor.cc
@@ -12,7 +12,7 @@
 #include "base/bind.h"
 #include "base/metrics/histogram_macros.h"
 #include "storage/browser/quota/quota_manager.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 #define UMA_HISTOGRAM_MBYTES(name, sample)          \
@@ -165,7 +165,7 @@
 }
 
 void QuotaTemporaryStorageEvictor::OnGotEvictionRoundInfo(
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     const QuotaSettings& settings,
     int64_t available_space,
     int64_t total_space,
@@ -176,7 +176,7 @@
   // Note: if there is no storage pressure, |current_usage|
   // may not be fully calculated and may be 0.
 
-  if (status != blink::QuotaStatusCode::kOk)
+  if (status != blink::mojom::QuotaStatusCode::kOk)
     ++statistics_.num_errors_on_getting_usage_and_quota;
 
   int64_t usage_overage = std::max(
@@ -204,12 +204,12 @@
   round_statistics_.usage_on_end_of_round = current_usage;
 
   int64_t amount_to_evict = std::max(usage_overage, diskspace_shortage);
-  if (status == blink::QuotaStatusCode::kOk && amount_to_evict > 0) {
+  if (status == blink::mojom::QuotaStatusCode::kOk && amount_to_evict > 0) {
     // Space is getting tight. Get the least recently used origin and continue.
     // TODO(michaeln): if the reason for eviction is low physical disk space,
     // make 'unlimited' origins subject to eviction too.
     quota_eviction_handler_->GetEvictionOrigin(
-        blink::StorageType::kTemporary, in_progress_eviction_origins_,
+        blink::mojom::StorageType::kTemporary, in_progress_eviction_origins_,
         settings.pool_size,
         base::Bind(&QuotaTemporaryStorageEvictor::OnGotEvictionOrigin,
                    weak_factory_.GetWeakPtr()));
@@ -241,13 +241,13 @@
   in_progress_eviction_origins_.insert(origin);
 
   quota_eviction_handler_->EvictOriginData(
-      origin, blink::StorageType::kTemporary,
+      origin, blink::mojom::StorageType::kTemporary,
       base::Bind(&QuotaTemporaryStorageEvictor::OnEvictionComplete,
                  weak_factory_.GetWeakPtr()));
 }
 
 void QuotaTemporaryStorageEvictor::OnEvictionComplete(
-    blink::QuotaStatusCode status) {
+    blink::mojom::QuotaStatusCode status) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   // Just calling ConsiderEviction() or StartEvictionTimerWithDelay() here is
@@ -256,7 +256,7 @@
   // origin permanently.  The evictor skips origins which had deletion errors
   // a few times.
 
-  if (status == blink::QuotaStatusCode::kOk) {
+  if (status == blink::mojom::QuotaStatusCode::kOk) {
     ++statistics_.num_evicted_origins;
     ++round_statistics_.num_evicted_origins_in_round;
     // We many need to get rid of more space so reconsider immediately.
diff --git a/storage/browser/quota/quota_temporary_storage_evictor.h b/storage/browser/quota/quota_temporary_storage_evictor.h
index 45e9c0cf..0932a74 100644
--- a/storage/browser/quota/quota_temporary_storage_evictor.h
+++ b/storage/browser/quota/quota_temporary_storage_evictor.h
@@ -16,7 +16,7 @@
 #include "base/sequence_checker.h"
 #include "base/timer/timer.h"
 #include "storage/browser/storage_browser_export.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 class GURL;
 
@@ -83,14 +83,14 @@
 
   void StartEvictionTimerWithDelay(int delay_ms);
   void ConsiderEviction();
-  void OnGotEvictionRoundInfo(blink::QuotaStatusCode status,
+  void OnGotEvictionRoundInfo(blink::mojom::QuotaStatusCode status,
                               const QuotaSettings& settings,
                               int64_t available_space,
                               int64_t total_space,
                               int64_t current_usage,
                               bool current_usage_is_complete);
   void OnGotEvictionOrigin(const GURL& origin);
-  void OnEvictionComplete(blink::QuotaStatusCode status);
+  void OnEvictionComplete(blink::mojom::QuotaStatusCode status);
 
   void OnEvictionRoundStarted();
   void OnEvictionRoundFinished();
diff --git a/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc b/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc
index 3f04f69e..7ba8782 100644
--- a/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc
+++ b/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc
@@ -21,7 +21,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 using storage::QuotaTemporaryStorageEvictor;
-using blink::StorageType;
+using blink::mojom::StorageType;
 
 namespace content {
 
@@ -40,26 +40,26 @@
                        StorageType type,
                        const storage::StatusCallback& callback) override {
     if (error_on_evict_origin_data_) {
-      callback.Run(blink::QuotaStatusCode::kErrorInvalidModification);
+      callback.Run(blink::mojom::QuotaStatusCode::kErrorInvalidModification);
       return;
     }
     int64_t origin_usage = EnsureOriginRemoved(origin);
     if (origin_usage >= 0)
       available_space_ += origin_usage;
-    callback.Run(blink::QuotaStatusCode::kOk);
+    callback.Run(blink::mojom::QuotaStatusCode::kOk);
   }
 
   void GetEvictionRoundInfo(
       const EvictionRoundInfoCallback& callback) override {
     if (error_on_get_usage_and_quota_) {
-      callback.Run(blink::QuotaStatusCode::kErrorAbort,
+      callback.Run(blink::mojom::QuotaStatusCode::kErrorAbort,
                    storage::QuotaSettings(), 0, 0, 0, false);
       return;
     }
     if (!task_for_get_usage_and_quota_.is_null())
       task_for_get_usage_and_quota_.Run();
-    callback.Run(blink::QuotaStatusCode::kOk, settings_, available_space_,
-                 available_space_ * 2, GetUsage(), true);
+    callback.Run(blink::mojom::QuotaStatusCode::kOk, settings_,
+                 available_space_, available_space_ * 2, GetUsage(), true);
   }
 
   void GetEvictionOrigin(StorageType type,
diff --git a/storage/browser/quota/storage_monitor.cc b/storage/browser/quota/storage_monitor.cc
index 0c18362..90670e71 100644
--- a/storage/browser/quota/storage_monitor.cc
+++ b/storage/browser/quota/storage_monitor.cc
@@ -216,11 +216,11 @@
 
 void HostStorageObservers::GotHostUsageAndQuota(
     const StorageObserver::Filter& filter,
-    blink::QuotaStatusCode status,
+    blink::mojom::QuotaStatusCode status,
     int64_t usage,
     int64_t quota) {
   initializing_ = false;
-  if (status != blink::QuotaStatusCode::kOk)
+  if (status != blink::mojom::QuotaStatusCode::kOk)
     return;
   initialized_ = true;
   cached_quota_ = quota;
@@ -309,8 +309,9 @@
   DCHECK(observer);
 
   // Check preconditions.
-  if (params.filter.storage_type == blink::StorageType::kUnknown ||
-      params.filter.storage_type == blink::StorageType::kQuotaNotManaged ||
+  if (params.filter.storage_type == blink::mojom::StorageType::kUnknown ||
+      params.filter.storage_type ==
+          blink::mojom::StorageType::kQuotaNotManaged ||
       params.filter.origin.is_empty()) {
     NOTREACHED();
     return;
@@ -332,7 +333,7 @@
 }
 
 const StorageTypeObservers* StorageMonitor::GetStorageTypeObservers(
-    blink::StorageType storage_type) const {
+    blink::mojom::StorageType storage_type) const {
   auto it = storage_type_observers_map_.find(storage_type);
   if (it != storage_type_observers_map_.end())
     return it->second.get();
@@ -343,8 +344,8 @@
 void StorageMonitor::NotifyUsageChange(const StorageObserver::Filter& filter,
                                        int64_t delta) {
   // Check preconditions.
-  if (filter.storage_type == blink::StorageType::kUnknown ||
-      filter.storage_type == blink::StorageType::kQuotaNotManaged ||
+  if (filter.storage_type == blink::mojom::StorageType::kUnknown ||
+      filter.storage_type == blink::mojom::StorageType::kQuotaNotManaged ||
       filter.origin.is_empty()) {
     NOTREACHED();
     return;
diff --git a/storage/browser/quota/storage_monitor.h b/storage/browser/quota/storage_monitor.h
index 87a78790..e4f76828 100644
--- a/storage/browser/quota/storage_monitor.h
+++ b/storage/browser/quota/storage_monitor.h
@@ -15,8 +15,7 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "storage/browser/quota/storage_observer.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 namespace content {
 class StorageMonitorTestBase;
@@ -97,7 +96,7 @@
  private:
   void StartInitialization(const StorageObserver::Filter& filter);
   void GotHostUsageAndQuota(const StorageObserver::Filter& filter,
-                            blink::QuotaStatusCode status,
+                            blink::mojom::QuotaStatusCode status,
                             int64_t usage,
                             int64_t quota);
   void DispatchEvent(const StorageObserver::Filter& filter, bool is_update);
@@ -164,14 +163,14 @@
 
   // Returns the observers of a specific storage type.
   const StorageTypeObservers* GetStorageTypeObservers(
-      blink::StorageType storage_type) const;
+      blink::mojom::StorageType storage_type) const;
 
   // Handles a usage change.
   void NotifyUsageChange(const StorageObserver::Filter& filter, int64_t delta);
 
  private:
   QuotaManager* quota_manager_;
-  std::map<blink::StorageType, std::unique_ptr<StorageTypeObservers>>
+  std::map<blink::mojom::StorageType, std::unique_ptr<StorageTypeObservers>>
       storage_type_observers_map_;
 
   DISALLOW_COPY_AND_ASSIGN(StorageMonitor);
diff --git a/storage/browser/quota/storage_monitor_unittest.cc b/storage/browser/quota/storage_monitor_unittest.cc
index b972584..328517d6 100644
--- a/storage/browser/quota/storage_monitor_unittest.cc
+++ b/storage/browser/quota/storage_monitor_unittest.cc
@@ -20,8 +20,8 @@
 #include "storage/browser/test/mock_storage_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using blink::QuotaStatusCode;
-using blink::StorageType;
+using blink::mojom::QuotaStatusCode;
+using blink::mojom::StorageType;
 using storage::HostStorageObservers;
 using storage::QuotaClient;
 using storage::QuotaManager;
diff --git a/storage/browser/quota/storage_observer.cc b/storage/browser/quota/storage_observer.cc
index 4a0ba3d..b582a629 100644
--- a/storage/browser/quota/storage_observer.cc
+++ b/storage/browser/quota/storage_observer.cc
@@ -11,9 +11,9 @@
 // StorageObserver::Filter
 
 StorageObserver::Filter::Filter()
-    : storage_type(blink::StorageType::kUnknown) {}
+    : storage_type(blink::mojom::StorageType::kUnknown) {}
 
-StorageObserver::Filter::Filter(blink::StorageType storage_type,
+StorageObserver::Filter::Filter(blink::mojom::StorageType storage_type,
                                 const GURL& origin)
     : storage_type(storage_type), origin(origin) {}
 
@@ -28,10 +28,11 @@
     : dispatch_initial_state(false) {
 }
 
-StorageObserver::MonitorParams::MonitorParams(blink::StorageType storage_type,
-                                              const GURL& origin,
-                                              const base::TimeDelta& rate,
-                                              bool get_initial_state)
+StorageObserver::MonitorParams::MonitorParams(
+    blink::mojom::StorageType storage_type,
+    const GURL& origin,
+    const base::TimeDelta& rate,
+    bool get_initial_state)
     : filter(storage_type, origin),
       rate(rate),
       dispatch_initial_state(get_initial_state) {}
diff --git a/storage/browser/quota/storage_observer.h b/storage/browser/quota/storage_observer.h
index f1d96275..bdb47c2 100644
--- a/storage/browser/quota/storage_observer.h
+++ b/storage/browser/quota/storage_observer.h
@@ -9,7 +9,7 @@
 
 #include "base/time/time.h"
 #include "storage/browser/quota/quota_client.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 namespace storage {
@@ -21,13 +21,13 @@
   struct STORAGE_EXPORT Filter {
     // The storage type to monitor. This must not be kUnknown or
     // kQuotaNotManaged.
-    blink::StorageType storage_type;
+    blink::mojom::StorageType storage_type;
 
     // The origin to monitor usage for. Must be specified.
     GURL origin;
 
     Filter();
-    Filter(blink::StorageType storage_type, const GURL& origin);
+    Filter(blink::mojom::StorageType storage_type, const GURL& origin);
     bool operator==(const Filter& other) const;
   };
 
@@ -44,7 +44,7 @@
     bool dispatch_initial_state;
 
     MonitorParams();
-    MonitorParams(blink::StorageType storage_type,
+    MonitorParams(blink::mojom::StorageType storage_type,
                   const GURL& origin,
                   const base::TimeDelta& rate,
                   bool get_initial_state);
diff --git a/storage/browser/quota/usage_tracker.cc b/storage/browser/quota/usage_tracker.cc
index ef0d22e6..f830384 100644
--- a/storage/browser/quota/usage_tracker.cc
+++ b/storage/browser/quota/usage_tracker.cc
@@ -34,7 +34,7 @@
 }  // namespace
 
 UsageTracker::UsageTracker(const QuotaClientList& clients,
-                           blink::StorageType type,
+                           blink::mojom::StorageType type,
                            SpecialStoragePolicy* special_storage_policy,
                            StorageMonitor* storage_monitor)
     : type_(type), storage_monitor_(storage_monitor), weak_factory_(this) {
diff --git a/storage/browser/quota/usage_tracker.h b/storage/browser/quota/usage_tracker.h
index 74a56bd..b6325f6 100644
--- a/storage/browser/quota/usage_tracker.h
+++ b/storage/browser/quota/usage_tracker.h
@@ -20,7 +20,7 @@
 #include "storage/browser/quota/quota_task.h"
 #include "storage/browser/quota/special_storage_policy.h"
 #include "storage/browser/storage_browser_export.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 namespace storage {
@@ -34,12 +34,12 @@
 class STORAGE_EXPORT UsageTracker : public QuotaTaskObserver {
  public:
   UsageTracker(const QuotaClientList& clients,
-               blink::StorageType type,
+               blink::mojom::StorageType type,
                SpecialStoragePolicy* special_storage_policy,
                StorageMonitor* storage_monitor);
   ~UsageTracker() override;
 
-  blink::StorageType type() const { return type_; }
+  blink::mojom::StorageType type() const { return type_; }
   ClientUsageTracker* GetClientTracker(QuotaClient::ID client_id);
 
   void GetGlobalLimitedUsage(const UsageCallback& callback);
@@ -96,7 +96,7 @@
   void FinallySendHostUsageWithBreakdown(AccumulateInfo* info,
                                          const std::string& host);
 
-  const blink::StorageType type_;
+  const blink::mojom::StorageType type_;
   std::map<QuotaClient::ID, std::unique_ptr<ClientUsageTracker>>
       client_tracker_map_;
 
diff --git a/storage/browser/quota/usage_tracker_unittest.cc b/storage/browser/quota/usage_tracker_unittest.cc
index fe5559e..7c63c01 100644
--- a/storage/browser/quota/usage_tracker_unittest.cc
+++ b/storage/browser/quota/usage_tracker_unittest.cc
@@ -16,8 +16,8 @@
 #include "storage/browser/test/mock_special_storage_policy.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using blink::QuotaStatusCode;
-using blink::StorageType;
+using blink::mojom::QuotaStatusCode;
+using blink::mojom::StorageType;
 using storage::QuotaClient;
 using storage::QuotaClientList;
 using storage::SpecialStoragePolicy;
diff --git a/storage/browser/test/async_file_test_helper.cc b/storage/browser/test/async_file_test_helper.cc
index ec428f8..b395425e 100644
--- a/storage/browser/test/async_file_test_helper.cc
+++ b/storage/browser/test/async_file_test_helper.cc
@@ -73,11 +73,11 @@
     run_loop->Quit();
 }
 
-void DidGetUsageAndQuota(blink::QuotaStatusCode* status_out,
+void DidGetUsageAndQuota(blink::mojom::QuotaStatusCode* status_out,
                          int64_t* usage_out,
                          int64_t* quota_out,
                          base::OnceClosure done_callback,
-                         blink::QuotaStatusCode status,
+                         blink::mojom::QuotaStatusCode status,
                          int64_t usage,
                          int64_t quota) {
   if (status_out)
@@ -256,13 +256,14 @@
   return (result == base::File::FILE_OK) && file_info.is_directory;
 }
 
-blink::QuotaStatusCode AsyncFileTestHelper::GetUsageAndQuota(
+blink::mojom::QuotaStatusCode AsyncFileTestHelper::GetUsageAndQuota(
     storage::QuotaManager* quota_manager,
     const GURL& origin,
     storage::FileSystemType type,
     int64_t* usage,
     int64_t* quota) {
-  blink::QuotaStatusCode status = blink::QuotaStatusCode::kUnknown;
+  blink::mojom::QuotaStatusCode status =
+      blink::mojom::QuotaStatusCode::kUnknown;
   base::RunLoop run_loop;
   quota_manager->GetUsageAndQuota(
       origin, FileSystemTypeToQuotaStorageType(type),
diff --git a/storage/browser/test/async_file_test_helper.h b/storage/browser/test/async_file_test_helper.h
index 0993079c..746388c 100644
--- a/storage/browser/test/async_file_test_helper.h
+++ b/storage/browser/test/async_file_test_helper.h
@@ -10,7 +10,7 @@
 
 #include "storage/browser/fileapi/file_system_operation.h"
 #include "storage/common/fileapi/file_system_types.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 
 class GURL;
 
@@ -100,7 +100,7 @@
                               const storage::FileSystemURL& url);
 
   // Returns usage and quota. It's valid to pass NULL to |usage| and/or |quota|.
-  static blink::QuotaStatusCode GetUsageAndQuota(
+  static blink::mojom::QuotaStatusCode GetUsageAndQuota(
       storage::QuotaManager* quota_manager,
       const GURL& origin,
       storage::FileSystemType type,
diff --git a/storage/browser/test/mock_quota_manager.cc b/storage/browser/test/mock_quota_manager.cc
index 3c73e1b8..6ac9013 100644
--- a/storage/browser/test/mock_quota_manager.cc
+++ b/storage/browser/test/mock_quota_manager.cc
@@ -48,7 +48,7 @@
                                         StorageType type,
                                         const UsageAndQuotaCallback& callback) {
   StorageInfo& info = usage_and_quota_map_[std::make_pair(origin, type)];
-  callback.Run(blink::QuotaStatusCode::kOk, info.usage, info.quota);
+  callback.Run(blink::mojom::QuotaStatusCode::kOk, info.usage, info.quota);
 }
 
 void MockQuotaManager::SetQuota(const GURL& origin,
@@ -119,7 +119,7 @@
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE, base::Bind(&MockQuotaManager::DidDeleteOriginData,
                             weak_factory_.GetWeakPtr(), callback,
-                            blink::QuotaStatusCode::kOk));
+                            blink::mojom::QuotaStatusCode::kOk));
 }
 
 MockQuotaManager::~MockQuotaManager() = default;
@@ -137,8 +137,9 @@
   callback.Run(*origins, storage_type);
 }
 
-void MockQuotaManager::DidDeleteOriginData(const StatusCallback& callback,
-                                           blink::QuotaStatusCode status) {
+void MockQuotaManager::DidDeleteOriginData(
+    const StatusCallback& callback,
+    blink::mojom::QuotaStatusCode status) {
   callback.Run(status);
 }
 
diff --git a/storage/browser/test/mock_quota_manager.h b/storage/browser/test/mock_quota_manager.h
index db2904c..d5de7aee 100644
--- a/storage/browser/test/mock_quota_manager.h
+++ b/storage/browser/test/mock_quota_manager.h
@@ -17,10 +17,10 @@
 #include "storage/browser/quota/quota_client.h"
 #include "storage/browser/quota/quota_manager.h"
 #include "storage/browser/quota/quota_task.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 using storage::GetOriginsCallback;
 using storage::QuotaClient;
 using storage::QuotaManager;
@@ -137,7 +137,7 @@
                            std::set<GURL>* origins,
                            StorageType storage_type);
   void DidDeleteOriginData(const StatusCallback& callback,
-                           blink::QuotaStatusCode status);
+                           blink::mojom::QuotaStatusCode status);
 
   // The list of stored origins that have been added via AddOrigin.
   std::vector<OriginInfo> origins_;
diff --git a/storage/browser/test/mock_quota_manager_proxy.cc b/storage/browser/test/mock_quota_manager_proxy.cc
index 65f0d94..85d59711 100644
--- a/storage/browser/test/mock_quota_manager_proxy.cc
+++ b/storage/browser/test/mock_quota_manager_proxy.cc
@@ -16,7 +16,7 @@
     : QuotaManagerProxy(quota_manager, task_runner),
       storage_accessed_count_(0),
       storage_modified_count_(0),
-      last_notified_type_(blink::StorageType::kUnknown),
+      last_notified_type_(blink::mojom::StorageType::kUnknown),
       last_notified_delta_(0),
       registered_client_(NULL) {}
 
@@ -37,25 +37,27 @@
 void MockQuotaManagerProxy::GetUsageAndQuota(
     base::SequencedTaskRunner* original_task_runner,
     const GURL& origin,
-    blink::StorageType type,
+    blink::mojom::StorageType type,
     const QuotaManager::UsageAndQuotaCallback& callback) {
   if (mock_manager()) {
     mock_manager()->GetUsageAndQuota(origin, type, callback);
   }
 }
 
-void MockQuotaManagerProxy::NotifyStorageAccessed(QuotaClient::ID client_id,
-                                                  const GURL& origin,
-                                                  blink::StorageType type) {
+void MockQuotaManagerProxy::NotifyStorageAccessed(
+    QuotaClient::ID client_id,
+    const GURL& origin,
+    blink::mojom::StorageType type) {
   ++storage_accessed_count_;
   last_notified_origin_ = origin;
   last_notified_type_ = type;
 }
 
-void MockQuotaManagerProxy::NotifyStorageModified(QuotaClient::ID client_id,
-                                                  const GURL& origin,
-                                                  blink::StorageType type,
-                                                  int64_t delta) {
+void MockQuotaManagerProxy::NotifyStorageModified(
+    QuotaClient::ID client_id,
+    const GURL& origin,
+    blink::mojom::StorageType type,
+    int64_t delta) {
   ++storage_modified_count_;
   last_notified_origin_ = origin;
   last_notified_type_ = type;
diff --git a/storage/browser/test/mock_quota_manager_proxy.h b/storage/browser/test/mock_quota_manager_proxy.h
index cb5acef..fbe5083 100644
--- a/storage/browser/test/mock_quota_manager_proxy.h
+++ b/storage/browser/test/mock_quota_manager_proxy.h
@@ -11,7 +11,7 @@
 #include "storage/browser/quota/quota_client.h"
 #include "storage/browser/quota/quota_manager_proxy.h"
 #include "storage/browser/test/mock_quota_manager.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 using storage::QuotaManagerProxy;
@@ -35,12 +35,12 @@
   void NotifyOriginNoLongerInUse(const GURL& origin) override {}
   void SetUsageCacheEnabled(QuotaClient::ID client_id,
                             const GURL& origin,
-                            blink::StorageType type,
+                            blink::mojom::StorageType type,
                             bool enabled) override {}
   void GetUsageAndQuota(
       base::SequencedTaskRunner* original_task_runner,
       const GURL& origin,
-      blink::StorageType type,
+      blink::mojom::StorageType type,
       const QuotaManager::UsageAndQuotaCallback& callback) override;
 
   // Validates the |client_id| and updates the internal access count
@@ -49,7 +49,7 @@
   // last_notified_type_.
   void NotifyStorageAccessed(QuotaClient::ID client_id,
                              const GURL& origin,
-                             blink::StorageType type) override;
+                             blink::mojom::StorageType type) override;
 
   // Records the |origin|, |type| and |delta| as last_notified_origin_,
   // last_notified_type_ and last_notified_delta_ respecitvely.
@@ -57,13 +57,15 @@
   // updates the manager's internal usage information.
   void NotifyStorageModified(QuotaClient::ID client_id,
                              const GURL& origin,
-                             blink::StorageType type,
+                             blink::mojom::StorageType type,
                              int64_t delta) override;
 
   int notify_storage_accessed_count() const { return storage_accessed_count_; }
   int notify_storage_modified_count() const { return storage_modified_count_; }
   GURL last_notified_origin() const { return last_notified_origin_; }
-  blink::StorageType last_notified_type() const { return last_notified_type_; }
+  blink::mojom::StorageType last_notified_type() const {
+    return last_notified_type_;
+  }
   int64_t last_notified_delta() const { return last_notified_delta_; }
 
  protected:
@@ -77,7 +79,7 @@
   int storage_accessed_count_;
   int storage_modified_count_;
   GURL last_notified_origin_;
-  blink::StorageType last_notified_type_;
+  blink::mojom::StorageType last_notified_type_;
   int64_t last_notified_delta_;
 
   QuotaClient* registered_client_;
diff --git a/storage/browser/test/mock_quota_manager_unittest.cc b/storage/browser/test/mock_quota_manager_unittest.cc
index 8cd429b5..33f7bcf 100644
--- a/storage/browser/test/mock_quota_manager_unittest.cc
+++ b/storage/browser/test/mock_quota_manager_unittest.cc
@@ -18,7 +18,7 @@
 #include "storage/browser/test/mock_storage_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using blink::StorageType;
+using blink::mojom::StorageType;
 
 namespace content {
 
@@ -77,9 +77,9 @@
                    weak_factory_.GetWeakPtr()));
   }
 
-  void DeletedOriginData(blink::QuotaStatusCode status) {
+  void DeletedOriginData(blink::mojom::QuotaStatusCode status) {
     ++deletion_callback_count_;
-    EXPECT_EQ(blink::QuotaStatusCode::kOk, status);
+    EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status);
   }
 
   int deletion_callback_count() const {
diff --git a/storage/browser/test/mock_storage_client.cc b/storage/browser/test/mock_storage_client.cc
index d277560..f97225d 100644
--- a/storage/browser/test/mock_storage_client.cc
+++ b/storage/browser/test/mock_storage_client.cc
@@ -169,7 +169,7 @@
   ErrorOriginSet::iterator itr_error =
       error_origins_.find(make_pair(origin_url, type));
   if (itr_error != error_origins_.end()) {
-    callback.Run(blink::QuotaStatusCode::kErrorInvalidModification);
+    callback.Run(blink::mojom::QuotaStatusCode::kErrorInvalidModification);
     return;
   }
 
@@ -182,7 +182,7 @@
     origin_data_.erase(itr);
   }
 
-  callback.Run(blink::QuotaStatusCode::kOk);
+  callback.Run(blink::mojom::QuotaStatusCode::kOk);
 }
 
 }  // namespace content
diff --git a/storage/browser/test/mock_storage_client.h b/storage/browser/test/mock_storage_client.h
index 0860050..e5443c1 100644
--- a/storage/browser/test/mock_storage_client.h
+++ b/storage/browser/test/mock_storage_client.h
@@ -18,7 +18,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "storage/browser/quota/quota_client.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 namespace storage {
@@ -27,7 +27,7 @@
 
 using storage::QuotaClient;
 using storage::QuotaManagerProxy;
-using blink::StorageType;
+using blink::mojom::StorageType;
 
 namespace content {
 
diff --git a/storage/browser/test/sandbox_file_system_test_helper.h b/storage/browser/test/sandbox_file_system_test_helper.h
index e65b148..80cd27ea 100644
--- a/storage/browser/test/sandbox_file_system_test_helper.h
+++ b/storage/browser/test/sandbox_file_system_test_helper.h
@@ -16,7 +16,7 @@
 #include "storage/browser/fileapi/task_runner_bound_observer_list.h"
 #include "storage/common/fileapi/file_system_types.h"
 #include "storage/common/fileapi/file_system_util.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "url/gurl.h"
 
 namespace base {
@@ -87,7 +87,7 @@
 
   const GURL& origin() const { return origin_; }
   storage::FileSystemType type() const { return type_; }
-  blink::StorageType storage_type() const {
+  blink::mojom::StorageType storage_type() const {
     return storage::FileSystemTypeToQuotaStorageType(type_);
   }
   storage::FileSystemFileUtil* file_util() const { return file_util_; }
diff --git a/storage/common/fileapi/file_system_util.cc b/storage/common/fileapi/file_system_util.cc
index 80f2e10..9a17fca 100644
--- a/storage/common/fileapi/file_system_util.cc
+++ b/storage/common/fileapi/file_system_util.cc
@@ -247,34 +247,35 @@
 }
 
 FileSystemType QuotaStorageTypeToFileSystemType(
-    blink::StorageType storage_type) {
+    blink::mojom::StorageType storage_type) {
   switch (storage_type) {
-    case blink::StorageType::kTemporary:
+    case blink::mojom::StorageType::kTemporary:
       return kFileSystemTypeTemporary;
-    case blink::StorageType::kPersistent:
+    case blink::mojom::StorageType::kPersistent:
       return kFileSystemTypePersistent;
-    case blink::StorageType::kSyncable:
+    case blink::mojom::StorageType::kSyncable:
       return kFileSystemTypeSyncable;
-    case blink::StorageType::kQuotaNotManaged:
-    case blink::StorageType::kUnknown:
+    case blink::mojom::StorageType::kQuotaNotManaged:
+    case blink::mojom::StorageType::kUnknown:
       return kFileSystemTypeUnknown;
   }
   return kFileSystemTypeUnknown;
 }
 
-blink::StorageType FileSystemTypeToQuotaStorageType(FileSystemType type) {
+blink::mojom::StorageType FileSystemTypeToQuotaStorageType(
+    FileSystemType type) {
   switch (type) {
     case kFileSystemTypeTemporary:
-      return blink::StorageType::kTemporary;
+      return blink::mojom::StorageType::kTemporary;
     case kFileSystemTypePersistent:
-      return blink::StorageType::kPersistent;
+      return blink::mojom::StorageType::kPersistent;
     case kFileSystemTypeSyncable:
     case kFileSystemTypeSyncableForInternalSync:
-      return blink::StorageType::kSyncable;
+      return blink::mojom::StorageType::kSyncable;
     case kFileSystemTypePluginPrivate:
-      return blink::StorageType::kQuotaNotManaged;
+      return blink::mojom::StorageType::kQuotaNotManaged;
     default:
-      return blink::StorageType::kUnknown;
+      return blink::mojom::StorageType::kUnknown;
   }
 }
 
diff --git a/storage/common/fileapi/file_system_util.h b/storage/common/fileapi/file_system_util.h
index 0b9060c..540e526d 100644
--- a/storage/common/fileapi/file_system_util.h
+++ b/storage/common/fileapi/file_system_util.h
@@ -13,7 +13,7 @@
 #include "storage/common/fileapi/file_system_info.h"
 #include "storage/common/fileapi/file_system_types.h"
 #include "storage/common/storage_common_export.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom.h"
 #include "third_party/WebKit/public/platform/WebFileError.h"
 #include "third_party/WebKit/public/platform/WebFileSystemType.h"
 
@@ -106,10 +106,10 @@
 // (Basically this naively maps TEMPORARY storage type to TEMPORARY filesystem
 // type, PERSISTENT storage type to PERSISTENT filesystem type and vice versa.)
 STORAGE_COMMON_EXPORT FileSystemType
-QuotaStorageTypeToFileSystemType(blink::StorageType storage_type);
+QuotaStorageTypeToFileSystemType(blink::mojom::StorageType storage_type);
 
-STORAGE_COMMON_EXPORT blink::StorageType FileSystemTypeToQuotaStorageType(
-    FileSystemType type);
+STORAGE_COMMON_EXPORT blink::mojom::StorageType
+FileSystemTypeToQuotaStorageType(FileSystemType type);
 
 // Returns the string representation of the given filesystem |type|.
 // Returns an empty string if the |type| is invalid.
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index dfc4d88..3235883 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -1,6 +1,6 @@
 {
   "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
-  "AAAAA2 See generate_buildbot_json.py to make changes": {},
+  "AAAAA2 See gpu/generate_buildbot_json.py to make changes": {},
   "Android Release (NVIDIA Shield TV)": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/chromium.gpu.json b/testing/buildbot/chromium.gpu.json
index bde8b67..e3dab6ba 100644
--- a/testing/buildbot/chromium.gpu.json
+++ b/testing/buildbot/chromium.gpu.json
@@ -1,6 +1,6 @@
 {
   "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
-  "AAAAA2 See generate_buildbot_json.py to make changes": {},
+  "AAAAA2 See gpu/generate_buildbot_json.py to make changes": {},
   "Android Release (Nexus 5X)": {
     "gtest_tests": [
       {
diff --git a/testing/buildbot/client.v8.fyi.json b/testing/buildbot/client.v8.fyi.json
index 187e83d..03285ed2 100644
--- a/testing/buildbot/client.v8.fyi.json
+++ b/testing/buildbot/client.v8.fyi.json
@@ -1,6 +1,6 @@
 {
   "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
-  "AAAAA2 See generate_buildbot_json.py to make changes": {},
+  "AAAAA2 See gpu/generate_buildbot_json.py to make changes": {},
   "Android Release (Nexus 5X)": {
     "gtest_tests": [],
     "isolated_scripts": [
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
index ae9b5e6e..bd950c0 100644
--- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
+++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -17,7 +17,6 @@
 -BrowsingDataRemoverBrowserTest.Cache
 -BrowsingDataRemoverBrowserTest.CookieDeletion
 -BrowsingDataRemoverTransportSecurityStateBrowserTest.ClearTransportSecurityState
--CaptivePortalBrowserTest.RequestFailsFastTimout
 -CertVerifierBrowserTest.MockCertVerifierSmokeTest
 -ChromeSecurityExploitBrowserTest.CreateFilesystemURLInExtensionOrigin
 -ChromeSitePerProcessTest.LaunchExternalProtocolFromSubframe
@@ -290,29 +289,6 @@
 -BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithOffTheRecordDownloads/1
 -BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithOffTheRecordWindowAndRegularDownload/0
 -BrowserCloseManagerWithDownloadsBrowserTest/BrowserCloseManagerWithDownloadsBrowserTest.TestWithOffTheRecordWindowAndRegularDownload/1
--CaptivePortalBrowserTest.AbortLoad
--CaptivePortalBrowserTest.CloseLoginTab
--CaptivePortalBrowserTest.Disabled
--CaptivePortalBrowserTest.GoBack
--CaptivePortalBrowserTest.GoBackToTimeout
--CaptivePortalBrowserTest.HstsLogin
--CaptivePortalBrowserTest.HttpToHttpsRedirectLogin
--CaptivePortalBrowserTest.InternetConnected
--CaptivePortalBrowserTest.InterstitialTimerCertErrorAfterSlowLoad
--CaptivePortalBrowserTest.Login
--CaptivePortalBrowserTest.LoginExtraNavigations
--CaptivePortalBrowserTest.LoginFastTimeout
--CaptivePortalBrowserTest.LoginIncognito
--CaptivePortalBrowserTest.LoginSlow
--CaptivePortalBrowserTest.NavigateBrokenTab
--CaptivePortalBrowserTest.NavigateLoadingTabToTimeoutSingleSite
--CaptivePortalBrowserTest.NavigateLoadingTabToTimeoutThreeSites
--CaptivePortalBrowserTest.NavigateLoadingTabToTimeoutTwoSites
--CaptivePortalBrowserTest.RedirectSSLCertError
--CaptivePortalBrowserTest.ReloadTimeout
--CaptivePortalBrowserTest.RequestFails
--CaptivePortalBrowserTest.Status511
--CaptivePortalBrowserTest.TwoBrokenTabs
 -ClientHintsBrowserTest.ClientHintsLifetimeNotAttachedCookiesBlocked
 -CommonNameMismatchBrowserTest.CheckWWWSubdomainMismatchInverse/0
 -CommonNameMismatchBrowserTest.CheckWWWSubdomainMismatchInverse/1
@@ -635,7 +611,6 @@
 
 # Switch test from using a custom net::URLRequestFileJob to using a test
 # URLLoaderFactory via SetNetworkFactoryForTesting.
--ErrorPageOfflineTestWithAllowDinosaurFalse.CheckEasterEggIsDisabled
 -ErrorPageSniffTest.SniffSmallHttpErrorResponseAsDownload
 -DNSErrorPageTest.StaleCacheStatus
 
@@ -817,6 +792,40 @@
 -NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.PrefetchCookieCrossDomain/0
 -NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.PrefetchCookieCrossDomain/1
 
+# Depends on captive portal component making requests through URLLoader instead of
+# URLLoaderFetcher, which is blocked on moving content/network to services/network
+# so that it can be used on ios. https://crbug.com/753658
+# TODO(jam): started converting to use interceptor but then blocked on above, see
+# https://chromium-review.googlesource.com/c/chromium/src/+/823222
+-CaptivePortalBrowserTest.AbortLoad
+-CaptivePortalBrowserTest.CloseLoginTab
+-CaptivePortalBrowserTest.Disabled
+-CaptivePortalBrowserTest.GoBack
+-CaptivePortalBrowserTest.GoBackToTimeout
+-CaptivePortalBrowserTest.HstsLogin
+-CaptivePortalBrowserTest.HttpToHttpsRedirectLogin
+-CaptivePortalBrowserTest.InternetConnected
+-CaptivePortalBrowserTest.InterstitialTimerCertErrorAfterSlowLoad
+-CaptivePortalBrowserTest.Login
+-CaptivePortalBrowserTest.LoginExtraNavigations
+-CaptivePortalBrowserTest.LoginFastTimeout
+-CaptivePortalBrowserTest.LoginIncognito
+-CaptivePortalBrowserTest.LoginSlow
+-CaptivePortalBrowserTest.NavigateBrokenTab
+-CaptivePortalBrowserTest.NavigateLoadingTabToTimeoutSingleSite
+-CaptivePortalBrowserTest.NavigateLoadingTabToTimeoutThreeSites
+-CaptivePortalBrowserTest.NavigateLoadingTabToTimeoutTwoSites
+-CaptivePortalBrowserTest.RedirectSSLCertError
+-CaptivePortalBrowserTest.ReloadTimeout
+-CaptivePortalBrowserTest.RequestFails
+-CaptivePortalBrowserTest.Status511
+-CaptivePortalBrowserTest.TwoBrokenTabs
+-CaptivePortalBrowserTest.RequestFailsFastTimout
+-CaptivePortalBrowserTest.SSLCertErrorLogin
+-CaptivePortalBrowserTest.ShowCaptivePortalInterstitialOnCertError
+-CaptivePortalBrowserTest.InterstitialTimerNavigateAwayWhileLoading
+-CaptivePortalBrowserTest.InterstitialTimerNavigateWhileLoading_EndWithCaptivePortalInterstitial
+
 # Add support of download_to_file for URLLoader.
 # http://crbug.com/791702
 -OutOfProcessPPAPITest.FileRef1
@@ -839,6 +848,10 @@
 -ContinueWhereILeftOffTest.SessionCookies
 -RestartTest.SessionCookies
 
+
+# Requires a replacement for ChromeNetworkDelegate.
+-VariationsHttpHeadersBrowserTest.TestStrippingHeadersFromResourceRequest
+
 # Fails because of missing support to navigate to filesystem: URLs.
 # https://crbug.com/797292
 -SBNavigationObserverBrowserTest.DownloadViaHTML5FileApi
@@ -852,18 +865,6 @@
 # Flakes https://logs.chromium.org/v/?s=chromium%2Fbb%2Fchromium.linux%2FLinux_Tests__dbg__1_%2F69105%2F%2B%2Frecipes%2Fsteps%2Fnetwork_service_browser_tests%2F0%2Flogs%2FPopupsOnlyUiDelegateTest.ManyPopupNotifications%2F0
 -PopupsOnlyUiDelegateTest.ManyPopupNotifications
 
-# Flakes https://logs.chromium.org/v/?s=chromium%2Fbb%2Fchromium.linux%2FLinux_Tests__dbg__1_%2F69117%2F%2B%2Frecipes%2Fsteps%2Fnetwork_service_browser_tests%2F0%2Flogs%2FCaptivePortalBrowserTest.SSLCertErrorLogin%2F0
--CaptivePortalBrowserTest.SSLCertErrorLogin
-
-# Flakes https://logs.chromium.org/v/?s=chromium%2Fbb%2Fchromium.linux%2FLinux_Tests__dbg__1_%2F69108%2F%2B%2Frecipes%2Fsteps%2Fnetwork_service_browser_tests%2F0%2Flogs%2FCaptivePortalBrowserTest.ShowCaptivePortalInterstitialOnCertError%2F0
--CaptivePortalBrowserTest.ShowCaptivePortalInterstitialOnCertError
-
-# Flakes https://logs.chromium.org/v/?s=chromium%2Fbb%2Fchromium.linux%2FLinux_Tests__dbg__1_%2F69112%2F%2B%2Frecipes%2Fsteps%2Fnetwork_service_browser_tests%2F0%2Flogs%2FCaptivePortalBrowserTest.InterstitialTimerNavigateAwayWhileLoading%2F0
--CaptivePortalBrowserTest.InterstitialTimerNavigateAwayWhileLoading
-
-# Flakes https://logs.chromium.org/v/?s=chromium%2Fbb%2Fchromium.linux%2FLinux_Tests__dbg__1_%2F69110%2F%2B%2Frecipes%2Fsteps%2Fnetwork_service_browser_tests%2F0%2Flogs%2FCaptivePortalBrowserTest.InterstitialTimerNavigateWhileLoading_EndWithCaptivePortalInterstitial%2F0
--CaptivePortalBrowserTest.InterstitialTimerNavigateWhileLoading_EndWithCaptivePortalInterstitial
-
 # Flakes https://logs.chromium.org/v/?s=chromium%2Fbb%2Fchromium.linux%2FLinux_Tests%2F65814%2F%2B%2Frecipes%2Fsteps%2Fnetwork_service_browser_tests%2F0%2Flogs%2FDeclarativeContentApiTest.NotBookmarkedRulesEvaluatedOnBookmarkEvents%2F0
 -DeclarativeContentApiTest.NotBookmarkedRulesEvaluatedOnBookmarkEvents
 
@@ -884,3 +885,10 @@
 
 # Flakes https://logs.chromium.org/v/?s=chromium%2Fbb%2Fchromium.linux%2FLinux_Tests%2F65816%2F%2B%2Frecipes%2Fsteps%2Fnetwork_service_browser_tests%2F0%2Flogs%2FDeclarativeContentApiTest.IsBookmarkedRulesEvaluatedOnBookmarkEvents%2F0
 -DeclarativeContentApiTest.IsBookmarkedRulesEvaluatedOnBookmarkEvents
+
+# Flakes due to ExtensionBrowserTest::NavigateInRenderer(), crbug.com/798969
+-DeclarativeContentApiTest.DisabledForSpanningIncognito
+-DeclarativeContentApiTest.DisabledForSplitIncognito
+-DeclarativeContentApiTest.EnabledForSpanningIncognito
+-DeclarativeContentApiTest.EnabledForSpanningIncognito
+-SetIconAPITest.Overview
diff --git a/third_party/WebKit/LayoutTests/LeakExpectations b/third_party/WebKit/LayoutTests/LeakExpectations
index 5c291508..da90067 100644
--- a/third_party/WebKit/LayoutTests/LeakExpectations
+++ b/third_party/WebKit/LayoutTests/LeakExpectations
@@ -45,6 +45,7 @@
 crbug.com/796944 [ Linux ] synthetic_gestures/synthetic-pinch-zoom-gesture.html [ Leak Pass ]
 crbug.com/667560 [ Linux ] http/tests/devtools/console/console-search.js [ Leak Pass ]
 crbug.com/798735 [ Linux ] fast/events/drop-handler-should-not-stop-navigate.html [ Leak Pass ]
+crbug.com/798735 [ Linux ] virtual/mouseevent_fractional/fast/events/drop-handler-should-not-stop-navigate.html [ Leak Pass ]
 
 # -----------------------------------------------------------------
 # Not revert suspected CL as jam@ request, expected to be fixed soon.
diff --git a/third_party/WebKit/LayoutTests/MSANExpectations b/third_party/WebKit/LayoutTests/MSANExpectations
index f1cc71a8..47e774b 100644
--- a/third_party/WebKit/LayoutTests/MSANExpectations
+++ b/third_party/WebKit/LayoutTests/MSANExpectations
@@ -79,3 +79,6 @@
 crbug.com/760543 [ Linux ] http/tests/devtools/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.js [ Pass Timeout ]
 crbug.com/760543 [ Linux ] http/tests/devtools/tracing/timeline-time/timeline-usertiming.js [ Pass Timeout ]
 crbug.com/760543 [ Linux ] http/tests/devtools/tracing/timeline-paint/timeline-paint.js [ Pass Timeout ]
+
+# Timing out consistenly on WebKit Linux Trusty MSAN
+crbug.com/798957 [ Linux ] http/tests/devtools/audits2/audits2-limited-run.js [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/NeverFixTests b/third_party/WebKit/LayoutTests/NeverFixTests
index 9d6c1129..d37be5e 100644
--- a/third_party/WebKit/LayoutTests/NeverFixTests
+++ b/third_party/WebKit/LayoutTests/NeverFixTests
@@ -388,6 +388,11 @@
 external/wpt/battery-status/battery-charging-manual.https.html [ WontFix ]
 external/wpt/battery-status/battery-plugging-in-manual.https.html [ WontFix ]
 external/wpt/battery-status/battery-unplugging-manual.https.html [ WontFix ]
+external/wpt/clipboard-apis/async-navigator-clipboard-basics.https.html [ WontFix ]
+external/wpt/clipboard-apis/async-write-dttext-read-dttext-manual.https.html [ WontFix ]
+external/wpt/clipboard-apis/async-write-dttext-read-text-manual.https.html [ WontFix ]
+external/wpt/clipboard-apis/async-write-text-read-dttext-manual.https.html [ WontFix ]
+external/wpt/clipboard-apis/async-write-text-read-text-manual.https.html [ WontFix ]
 external/wpt/console/console-count-logging-manual.html [ WontFix ]
 external/wpt/css/CSS2/linebox/inline-formatting-context-010b.xht [ WontFix ]
 external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-008.xht [ WontFix ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 0f83eee5..3b99651c 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1932,15 +1932,10 @@
 crbug.com/626703 external/wpt/webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html [ Timeout ]
 crbug.com/626703 external/wpt/webaudio/the-audio-api/the-analysernode-interface/test-analyser-output.html [ Timeout ]
 crbug.com/626703 external/wpt/css/css-grid/alignment/grid-gutters-001.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-grid/alignment/grid-gutters-002.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-grid/alignment/grid-gutters-003.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-grid/alignment/grid-gutters-004.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-grid/alignment/grid-gutters-005.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-grid/alignment/grid-gutters-006.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-grid/alignment/grid-gutters-007.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-grid/alignment/grid-gutters-008.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-grid/alignment/grid-gutters-009.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-grid/alignment/grid-gutters-010.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-writing-modes/table-cell-001.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-writing-modes/table-cell-002.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-fonts/font-synthesis-01.html [ Failure ]
@@ -2782,7 +2777,6 @@
 # ====== Begin of display: contents tests ======
 
 crbug.com/795217 external/wpt/css/css-display/display-contents-details.html [ Failure ]
-crbug.com/181374 external/wpt/css/css-display/display-contents-dynamic-table-001-inline.html [ Failure ]
 
 # ====== End of display: contents tests ======
 
@@ -3541,6 +3535,8 @@
 crbug.com/779087 external/wpt/feature-policy/autoplay-default-feature-policy.https.sub.html [ Skip ]
 crbug.com/779087 external/wpt/feature-policy/autoplay-disabled-by-feature-policy.https.sub.html [ Skip ]
 
+crbug.com/798572 virtual/enable_wasm/external/wpt/wasm/wasm_service_worker_test.https.html [ Failure ]
+
 # Sheriff failures 2017-12-15
 crbug.com/795250 [ Win7 Linux ] virtual/scroll_customization/fast/events/touch/gesture/gesture-tap-hover-state-iframe.html [ Pass Failure ]
 crbug.com/795250 [ Win7 ] virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-tap-hover-state-iframe.html [ Pass Failure ]
@@ -3555,3 +3551,6 @@
 # Sheriff failures 2018-01-02
 crbug.com/798527 [ Linux ] virtual/spv175/compositing/gestures/gesture-tapHighlight-with-box-shadow.html [ Pass Failure ]
 crbug.com/798592 [ Win7 ] virtual/threaded/http/tests/devtools/tracing/timeline-style/timeline-recalculate-styles.js [ Pass Failure ]
+
+# Sheriff failures 2018-01-03
+crbug.com/798680 external/wpt/pointerevents/pointerlock/pointerevent_pointerlock_supercedes_capture-manual.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/clipboard/readtext-denied.https-expected.txt b/third_party/WebKit/LayoutTests/clipboard/readtext-denied.https-expected.txt
new file mode 100644
index 0000000..d5d1bfb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/clipboard/readtext-denied.https-expected.txt
@@ -0,0 +1,12 @@
+Tests navigator.clipboard.readText() permission failure.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS PermissionsHelper.setPermission is defined.
+PASS navigator.clipboard is non-null.
+PASS clipboard.readText() fail (as expected).
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/clipboard/readtext-denied.https.html b/third_party/WebKit/LayoutTests/clipboard/readtext-denied.https.html
new file mode 100644
index 0000000..c089a3a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/clipboard/readtext-denied.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/js-test.js"></script>
+<script src="../http/tests/resources/permissions-helper.js"></script>
+</head>
+<body>
+<script>
+description("Tests navigator.clipboard.readText() permission failure.");
+
+shouldBeDefined("PermissionsHelper.setPermission");
+
+function successCallback(access) {
+  testFailed(
+    "clipboard.readText() does not fail (even though it really should have).");
+  finishJSTest();
+}
+
+function errorCallback(error) {
+  testPassed("clipboard.readText() fail (as expected).");
+  finishJSTest();
+}
+
+window.jsTestIsAsync = true;
+
+PermissionsHelper.setPermission('clipboard-read', 'denied').then(function() {
+  shouldBeNonNull("navigator.clipboard");
+  navigator.clipboard.readText().then(successCallback, errorCallback);
+});
+
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/clipboard/readtext-granted.https-expected.txt b/third_party/WebKit/LayoutTests/clipboard/readtext-granted.https-expected.txt
new file mode 100644
index 0000000..7751372
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/clipboard/readtext-granted.https-expected.txt
@@ -0,0 +1,12 @@
+Tests navigator.clipboard.readText() permission success.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS PermissionsHelper.setPermission is defined.
+PASS navigator.clipboard is non-null.
+PASS clipboard.readText() success (as expected).
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/clipboard/readtext-granted.https.html b/third_party/WebKit/LayoutTests/clipboard/readtext-granted.https.html
new file mode 100644
index 0000000..6f2ada9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/clipboard/readtext-granted.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/js-test.js"></script>
+<script src="../http/tests/resources/permissions-helper.js"></script>
+</head>
+<body>
+<script>
+description("Tests navigator.clipboard.readText() permission success.");
+
+shouldBeDefined("PermissionsHelper.setPermission");
+
+function successCallback(access) {
+  testPassed("clipboard.readText() success (as expected).");
+  finishJSTest();
+}
+
+function errorCallback(error) {
+  testFailed(
+    "clipboard.readText() does not fail (even though we hoped it would).");
+  finishJSTest();
+}
+
+window.jsTestIsAsync = true;
+
+PermissionsHelper.setPermission('clipboard-read', 'granted').then(function() {
+  shouldBeNonNull("navigator.clipboard");
+  navigator.clipboard.readText().then(successCallback, errorCallback);
+});
+
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/clipboard/writetext-denied.https-expected.txt b/third_party/WebKit/LayoutTests/clipboard/writetext-denied.https-expected.txt
new file mode 100644
index 0000000..15877da5e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/clipboard/writetext-denied.https-expected.txt
@@ -0,0 +1,12 @@
+Tests navigator.clipboard.writeText() permission failure.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS PermissionsHelper.setPermission is defined.
+PASS navigator.clipboard is non-null.
+PASS clipboard.writeText() fail (as expected).
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/clipboard/writetext-denied.https.html b/third_party/WebKit/LayoutTests/clipboard/writetext-denied.https.html
new file mode 100644
index 0000000..3abd9b74
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/clipboard/writetext-denied.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/js-test.js"></script>
+<script src="../http/tests/resources/permissions-helper.js"></script>
+</head>
+<body>
+<script>
+description("Tests navigator.clipboard.writeText() permission failure.");
+
+shouldBeDefined("PermissionsHelper.setPermission");
+
+function successCallback(access) {
+  testFailed(
+    "clipboard.writeText() does not fail (even though it really should have).");
+  finishJSTest();
+}
+
+function errorCallback(error) {
+  testPassed("clipboard.writeText() fail (as expected).");
+  finishJSTest();
+}
+
+window.jsTestIsAsync = true;
+
+PermissionsHelper.setPermission('clipboard-write', 'denied').then(function() {
+  shouldBeNonNull("navigator.clipboard");
+  navigator.clipboard.writeText("xyz").then(successCallback, errorCallback);
+});
+
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/clipboard/writetext-granted.https-expected.txt b/third_party/WebKit/LayoutTests/clipboard/writetext-granted.https-expected.txt
new file mode 100644
index 0000000..fbeb5e0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/clipboard/writetext-granted.https-expected.txt
@@ -0,0 +1,12 @@
+Tests navigator.clipboard.writeText() permission success.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS PermissionsHelper.setPermission is defined.
+PASS navigator.clipboard is non-null.
+PASS clipboard.writeText() success (as expected).
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/third_party/WebKit/LayoutTests/clipboard/writetext-granted.https.html b/third_party/WebKit/LayoutTests/clipboard/writetext-granted.https.html
new file mode 100644
index 0000000..b0716bc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/clipboard/writetext-granted.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/js-test.js"></script>
+<script src="../http/tests/resources/permissions-helper.js"></script>
+</head>
+<body>
+<script>
+description("Tests navigator.clipboard.writeText() permission success.");
+
+shouldBeDefined("PermissionsHelper.setPermission");
+
+function successCallback(access) {
+  testPassed("clipboard.writeText() success (as expected).");
+  finishJSTest();
+}
+
+function errorCallback(error) {
+  testFailed(
+    "clipboard.writeText() does not fail (even though we hoped it would).");
+  finishJSTest();
+}
+
+window.jsTestIsAsync = true;
+
+PermissionsHelper.setPermission('clipboard-write', 'granted').then(function() {
+  shouldBeNonNull("navigator.clipboard");
+  navigator.clipboard.writeText("xyz").then(successCallback, errorCallback);
+});
+
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/fixup-dynamic-anonymous-inline-table-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/fixup-dynamic-anonymous-inline-table-001.html
new file mode 100644
index 0000000..9bf7b4c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/fixup-dynamic-anonymous-inline-table-001.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<title>CSS Test: CSS Tables fixup merge anonymous inline table siblings (row-group + row-group)</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<link rel="help" href="https://drafts.csswg.org/css-tables/#fixup-algorithm">
+<style>
+  .group {
+    display: table-row-group;
+  }
+  .cell {
+    display: table-cell;
+  }
+  .filler {
+    width: 100px;
+    height: 50px;
+    background-color: green;
+  }
+</style>
+<p>Test passes if there is a filled green square.</p>
+<span>
+  <span class="group">
+    <span class="cell">
+      <div class="filler"></div>
+    </span>
+  </span>
+  <span id="rm">Remove me</span>
+  <span class="group">
+    <span class="cell">
+      <div class="filler"></div>
+    </span>
+  </span>
+</span>
+<script>
+  rm.offsetTop;
+  rm.remove();
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/fixup-dynamic-anonymous-inline-table-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/fixup-dynamic-anonymous-inline-table-002.html
new file mode 100644
index 0000000..9f3a2ff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/fixup-dynamic-anonymous-inline-table-002.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>CSS Test: CSS Tables fixup merge anonymous inline table siblings (cell + row)</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<link rel="help" href="https://drafts.csswg.org/css-tables/#fixup-algorithm">
+<style>
+  .row {
+    display: table-row;
+  }
+  .cell {
+    display: table-cell;
+  }
+  .filler {
+    width: 100px;
+    height: 50px;
+    background-color: green;
+  }
+</style>
+<p>Test passes if there is a filled green square.</p>
+<span>
+  <span class="cell">
+    <div class="filler"></div>
+  </span>
+  <span id="rm">Remove me</span>
+  <span class="row">
+    <span class="cell">
+      <div class="filler"></div>
+    </span>
+  </span>
+</span>
+<script>
+  rm.offsetTop;
+  rm.remove();
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/fixup-dynamic-anonymous-inline-table-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/fixup-dynamic-anonymous-inline-table-003.html
new file mode 100644
index 0000000..42b7f9a0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/fixup-dynamic-anonymous-inline-table-003.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<title>CSS Test: CSS Tables fixup merge anonymous inline table siblings (cell + cell)</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<link rel="help" href="https://drafts.csswg.org/css-tables/#fixup-algorithm">
+<style>
+  .cell {
+    display: table-cell;
+  }
+  .filler {
+    width: 50px;
+    height: 100px;
+    background-color: green;
+  }
+</style>
+<p>Test passes if there is a filled green square.</p>
+<div style="width:100px">
+  <span>
+    <span class="cell">
+      <div class="filler"></div>
+    </span>
+    <span id="rm">Remove me</span>
+    <span class="cell">
+      <div class="filler"></div>
+    </span>
+  </span>
+</div>
+<script>
+  rm.offsetTop;
+  rm.remove();
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/fixup-dynamic-anonymous-table-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/fixup-dynamic-anonymous-table-001.html
new file mode 100644
index 0000000..d9dbc51
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/fixup-dynamic-anonymous-table-001.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>CSS Test: CSS Tables fixup merge anonymous table siblings (cell + cell)</title>
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<link rel="help" href="https://drafts.csswg.org/css-tables/#fixup-algorithm">
+<style>
+  .cell {
+    display: table-cell;
+    width: 50px;
+    height: 100px;
+    background-color: green;
+  }
+</style>
+<p>Test passes if there is a filled green square.</p>
+<div>
+  <span class="cell"></span>
+  <span id="rm">Remove me</span>
+  <span class="cell"></span>
+</div>
+<script>
+  rm.offsetTop;
+  rm.remove();
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-objects/interface.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-objects/interface.html
new file mode 100644
index 0000000..8d346b1ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-objects/interface.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>CSSStyleValue IDL</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#stylevalue-objects">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/WebIDLParser.js"></script>
+<script src="/resources/idlharness.js"></script>
+<script type="text/plain" id="idl">
+interface CSSStyleValue {
+    stringifier;
+    static CSSStyleValue? parse(DOMString property, DOMString cssText);
+    static sequence<CSSStyleValue>? parseAll(DOMString property, DOMString cssText);
+};
+</script>
+<script>
+'use strict';
+const idlArray = new IdlArray();
+idlArray.add_idls(document.getElementById('idl').textContent);
+idlArray.test();
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssKeywordValue-interface.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssKeywordValue-interface.html
new file mode 100644
index 0000000..444e080
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssKeywordValue-interface.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>CSSKeywordValue IDL</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#keywordvalue-objects">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/WebIDLParser.js"></script>
+<script src="/resources/idlharness.js"></script>
+<script type="text/plain" id="idl">
+[Constructor(DOMString value)]
+interface CSSKeywordValue : CSSStyleValue {
+    attribute DOMString value;
+};
+</script>
+<script>
+'use strict';
+const idlArray = new IdlArray();
+idlArray.add_untested_idls('interface CSSStyleValue { stringifier; };');
+idlArray.add_idls(document.getElementById('idl').textContent);
+idlArray.add_objects({
+    CSSKeywordValue: ['new CSSKeywordValue("auto")']
+});
+idlArray.test();
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/policies/referrer-origin-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/policies/referrer-origin-expected.txt
deleted file mode 100644
index afa1d39..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/policies/referrer-origin-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS Request's referrer is origin
-FAIL Cross-origin referrer is overridden by client origin promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'fetch' on 'Window': The origin of 'https://www.web-platform.test:8444/' should be same as 'http://web-platform.test:8001'"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/policies/referrer-origin-service-worker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/policies/referrer-origin-service-worker.https-expected.txt
deleted file mode 100644
index 666689b..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/policies/referrer-origin-service-worker.https-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-PASS Fetch in service worker: referrer with no-referrer policy
-PASS Request's referrer is origin
-FAIL Cross-origin referrer is overridden by client origin promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'fetch' on 'ServiceWorkerGlobalScope': The origin of 'https://www.web-platform.test:8444/' should be same as 'https://web-platform.test:8444'"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/policies/referrer-origin-worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/policies/referrer-origin-worker-expected.txt
deleted file mode 100644
index 4337f2c6..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/policies/referrer-origin-worker-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS Request's referrer is origin
-FAIL Cross-origin referrer is overridden by client origin promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'fetch' on 'WorkerGlobalScope': The origin of 'https://www.web-platform.test:8444/' should be same as 'http://web-platform.test:8001'"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/request/request-init-001.sub-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/request/request-init-001.sub-expected.txt
deleted file mode 100644
index fc13f288..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/request/request-init-001.sub-expected.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-This is a testharness.js-based test.
-PASS Check method init value of GET and associated getter
-PASS Check method init value of HEAD and associated getter
-PASS Check method init value of POST and associated getter
-PASS Check method init value of PUT and associated getter
-PASS Check method init value of DELETE and associated getter
-PASS Check method init value of OPTIONS and associated getter
-PASS Check method init value of head and associated getter
-PASS Check referrer init value of /relative/ressource and associated getter
-PASS Check referrer init value of http://web-platform.test:8001/relative/ressource?query=true#fragment and associated getter
-PASS Check referrer init value of http://web-platform.test:8001/ and associated getter
-FAIL Check referrer init value of http://test.url and associated getter Failed to construct 'Request': The origin of 'http://test.url' should be same as 'http://web-platform.test:8001'
-PASS Check referrer init value of about:client and associated getter
-PASS Check referrer init value of  and associated getter
-PASS Check referrerPolicy init value of  and associated getter
-PASS Check referrerPolicy init value of no-referrer and associated getter
-PASS Check referrerPolicy init value of no-referrer-when-downgrade and associated getter
-PASS Check referrerPolicy init value of origin and associated getter
-PASS Check referrerPolicy init value of origin-when-cross-origin and associated getter
-PASS Check referrerPolicy init value of unsafe-url and associated getter
-PASS Check referrerPolicy init value of same-origin and associated getter
-PASS Check referrerPolicy init value of strict-origin and associated getter
-PASS Check referrerPolicy init value of strict-origin-when-cross-origin and associated getter
-PASS Check mode init value of same-origin and associated getter
-PASS Check mode init value of no-cors and associated getter
-PASS Check mode init value of cors and associated getter
-PASS Check credentials init value of omit and associated getter
-PASS Check credentials init value of same-origin and associated getter
-PASS Check credentials init value of include and associated getter
-PASS Check cache init value of default and associated getter
-PASS Check cache init value of no-store and associated getter
-PASS Check cache init value of reload and associated getter
-PASS Check cache init value of no-cache and associated getter
-PASS Check cache init value of force-cache and associated getter
-PASS Check redirect init value of follow and associated getter
-PASS Check redirect init value of error and associated getter
-PASS Check redirect init value of manual and associated getter
-PASS Check integrity init value of  and associated getter
-PASS Check integrity init value of AZERTYUIOP1234567890 and associated getter
-PASS Check window init value of null and associated getter
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/media/track/captions-webvtt/large-timestamp.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/large-timestamp.vtt
similarity index 100%
rename from third_party/WebKit/LayoutTests/media/track/captions-webvtt/large-timestamp.vtt
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/large-timestamp.vtt
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/metadata.vtt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/metadata.vtt
new file mode 100644
index 0000000..03d8cf4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/resources/metadata.vtt
@@ -0,0 +1,38 @@
+WEBVTT
+
+00:00:00.000 --> 00:00:01.000
+Lorem ipsum dolor sit amet,
+
+00:00:02.000 --> 00:00:03.000
+consectetuer adipiscing elit,
+
+00:00:04.000 --> 00:00:05.000
+sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
+
+00:00:06.000 --> 00:00:07.000
+Ut wisi enim ad minim veniam,
+
+00:00:08.000 --> 00:00:09.000
+quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
+
+00:00:10.000 --> 00:00:11.000
+Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat,
+
+00:00:12.000 --> 00:00:13.000
+vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
+
+00:00:14.000 --> 00:00:15.000
+dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
+
+00:00:16.000 --> 00:00:17.000
+Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id
+
+00:00:18.000 --> 00:00:19.000
+quod mazim placerat facer possim assum.
+
+00:00:20.000 --> 00:00:21.000
+Typi non habent claritatem insitam;
+
+00:00:22.000 --> 00:00:23.000
+est usus legentis in iis qui facit eorum claritatem.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-large-timestamp.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-large-timestamp.html
new file mode 100644
index 0000000..bae1852c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-large-timestamp.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Very large timestamp is parsed correctly</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<video>
+    <track src="resources/large-timestamp.vtt" default>
+    <script>
+    async_test(function(t) {
+        var testTrack = document.querySelector("track");
+        testTrack.onload = t.step_func_done(function() {
+            assert_equals(testTrack.track.cues.length, 1);
+            var cue = testTrack.track.cues[0];
+            assert_equals(parseInt(cue.id), 1);
+            assert_equals(cue.startTime / 3600, 1234567);
+            assert_equals(cue.endTime / 3600, 1234567890);
+        });
+    });
+    </script>
+</video>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-load-error-readyState.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-load-error-readyState.html
new file mode 100644
index 0000000..8e232bf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-load-error-readyState.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>Error event on HTMLTrackElement and ERROR readyState on TextTrack</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<video>
+  <track src="junk" default>
+  <script>
+  async_test(function(t) {
+    var track = document.querySelector("track");
+    track.onerror = t.step_func_done(function() {
+      assert_equals(track.readyState, HTMLTrackElement.ERROR);
+    });
+  });
+  </script>
+</video>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-load-from-element-readyState.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-load-from-element-readyState.html
new file mode 100644
index 0000000..62a68f6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-load-from-element-readyState.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>Load event on HTMLTrackElement and LOADED readyState on TextTrack when src is set on the element</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<video>
+  <track src="resources/webvtt-file.vtt" default>
+  <script>
+  async_test(function(t) {
+    var track = document.querySelector("track");
+    track.onload = t.step_func_done(function() {
+      assert_equals(track.readyState, HTMLTrackElement.LOADED);
+    });
+  });
+  </script>
+</video>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-load-from-src-readyState.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-load-from-src-readyState.html
new file mode 100644
index 0000000..e569eeb9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-load-from-src-readyState.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>Load event on HTMLTrackElement and LOADED readyState on TextTrack when src is set from JavaScript</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<video>
+    <track>
+</video>
+<script>
+async_test(function(t) {
+    var track = document.querySelector("track");
+    assert_equals(track.readyState, HTMLTrackElement.NONE);
+
+    track.onload = t.step_func_done(function() {
+        assert_equals(track.readyState, HTMLTrackElement.LOADED);
+    });
+
+    track.src = "resources/webvtt-file.vtt";
+    track.track.mode = "hidden";
+});
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-mode-disabled.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-mode-disabled.html
new file mode 100644
index 0000000..6b46bf4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-mode-disabled.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>Cues are properly removed from the active cue list when their track changes mode to disabled</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<video>
+    <track src="resources/captions-gaps.vtt" kind="captions" default >
+    <script>
+    async_test(function(t) {
+        var video = document.querySelector("video");
+        var testTrack = document.querySelector("track");
+
+        video.src = getVideoURI("/media/counting");
+        video.oncanplaythrough = t.step_func(startTest);
+        video.onseeked = t.step_func_done(seeked);
+
+        function startTest() {
+            // Set the mode of the text track to "showing".
+            testTrack.track.mode = "showing";
+            // Seek to a time with a caption.
+            video.currentTime = 1.5;
+        }
+
+        function seeked() {
+            // Set the mode of the text track to "hidden", then to "showing" again.
+            testTrack.track.mode = "hidden";
+            testTrack.track.mode = "showing";
+
+            // Set the mode of the text track to "disabled".
+            testTrack.track.mode = "disabled";
+        }
+    });
+    </script>
+</video>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-mode-not-changed-by-new-track.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-mode-not-changed-by-new-track.html
similarity index 84%
rename from third_party/WebKit/LayoutTests/media/track/track-mode-not-changed-by-new-track.html
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-mode-not-changed-by-new-track.html
index 5a455b1..2902ba9 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-mode-not-changed-by-new-track.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-mode-not-changed-by-new-track.html
@@ -1,10 +1,10 @@
 <!DOCTYPE html>
-<title>Tests that a track appended after the initial track configuration does not change other tracks.</title>
-<script src="../media-file.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<title>A track appended after the initial track configuration does not change other tracks</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 <video>
-    <track kind="metadata" src="captions-webvtt/metadata.vtt">
+    <track kind="metadata" src="resources/metadata.vtt">
 </video>
 <script>
 async_test(function(t) {
@@ -14,7 +14,7 @@
     assert_equals(track1.readyState, HTMLTrackElement.NONE);
     assert_equals(track1.track.mode, 'disabled');
 
-    video.src = findMediaFile('video', '../content/test');
+    video.src = getVideoURI('/media/test');
     video.oncanplaythrough = t.step_func(canplaythrough);
     track1.onload = t.step_func(metadataTrackLoaded);
 
@@ -37,7 +37,7 @@
         track2 = document.createElement('track');
         track2.setAttribute('kind', 'captions');
         track2.setAttribute('default', 'default');
-        track2.setAttribute('src', 'captions-webvtt/tc004-webvtt-file.vtt');
+        track2.setAttribute('src', 'resources/webvtt-file.vtt');
         track2.onload = t.step_func(captionsTrackLoaded);
         video.appendChild(track2);
     }
diff --git a/third_party/WebKit/LayoutTests/media/track/track-mode-triggers-loading.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-mode-triggers-loading.html
similarity index 72%
rename from third_party/WebKit/LayoutTests/media/track/track-mode-triggers-loading.html
rename to third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-mode-triggers-loading.html
index dc10a5aa..2e29d70 100644
--- a/third_party/WebKit/LayoutTests/media/track/track-mode-triggers-loading.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-mode-triggers-loading.html
@@ -1,10 +1,10 @@
 <!DOCTYPE html>
-<title>Tests that a "metadata" track does not load automatically, but does load when the mode is changed.</title>
-<script src="../media-file.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
+<title>A "metadata" track does not load automatically, but it does load when the mode is changed</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 <video>
-    <track kind="metadata" src="captions-webvtt/metadata.vtt">
+    <track kind="metadata" src="resources/metadata.vtt">
 </video>
 <script>
 async_test(function(t) {
@@ -15,7 +15,7 @@
     assert_equals(track.readyState, HTMLTrackElement.NONE);
     assert_equals(video.textTracks[0].mode, "disabled");
 
-    video.src = findMediaFile("video", "../content/test");
+    video.src = getVideoURI("/media/test");
     video.oncanplaythrough = t.step_func(canplaythrough);
     track.onload = t.step_func_done(trackLoaded);
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-mode.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-mode.html
new file mode 100644
index 0000000..29208a3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-mode.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<title>TextTrack mode attribute</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<video>
+    <track src="resources/captions-fast.vtt" default>
+    <script>
+    async_test(function(t) {
+        var video = document.querySelector("video");
+        var track = document.querySelector("track");
+        track.onload = t.step_func(trackLoaded);
+
+        var cueCount = 0;
+        var textTrack;
+        function trackLoaded() {
+            textTrack = track.track;
+            // Test default attribute value.
+            assert_equals(textTrack.mode, "showing");
+            assert_equals(video.textTracks[0].mode, "showing");
+            // Set to bogus value, should return default.
+            var value = "bogus";
+            textTrack.mode = value;
+            assert_equals(textTrack.mode, "showing");
+            assert_equals(video.textTracks[0].mode, "showing");
+
+            // Set to numeric value (no longer supported), should return default.
+            textTrack.mode = 2;
+            assert_equals(textTrack.mode, "showing");
+            assert_equals(video.textTracks[0].mode, "showing");
+
+            // Set to known values.
+            setModeAndCheck("disabled");
+
+            video.src = getVideoURI("/media/test");
+            video.play();
+            // Wait for end of first cue (no events should fire while track is disabled).
+            t.step_timeout(testHiddenAndShowing, 400);
+        }
+
+        track.oncuechange = t.step_func(function(event) {
+            cueCount++;
+            if (cueCount == textTrack.cues.length)
+                t.done();
+        });
+
+        function setModeAndCheck(value) {
+            textTrack.mode =  value;
+            assert_equals(textTrack.mode, value);
+            assert_equals(video.textTracks[0].mode, value);
+            if (value == "disabled")
+                assert_equals(textTrack.cues, null);
+        }
+
+        function testHiddenAndShowing() {
+            setModeAndCheck("hidden");
+            setModeAndCheck("showing");
+        }
+    });
+    </script>
+</video>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/opera/interfaces/VTTCue/constructor.html b/third_party/WebKit/LayoutTests/external/wpt/webvtt/api/VTTCue/constructor-exceptions.html
similarity index 85%
rename from third_party/WebKit/LayoutTests/media/track/opera/interfaces/VTTCue/constructor.html
rename to third_party/WebKit/LayoutTests/external/wpt/webvtt/api/VTTCue/constructor-exceptions.html
index 5e98f65..4d051fb3 100644
--- a/third_party/WebKit/LayoutTests/media/track/opera/interfaces/VTTCue/constructor.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webvtt/api/VTTCue/constructor-exceptions.html
@@ -1,7 +1,7 @@
 <!doctype html>
-<title>VTTCue constructor</title>
-<script src=../../../../../resources/testharness.js></script>
-<script src=../../../../../resources/testharnessreport.js></script>
+<title>VTTCue constructor exceptions</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
 <div id=log></div>
 <script>
 test(function() {
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-atomics-wait.html b/third_party/WebKit/LayoutTests/fast/workers/worker-atomics-wait.html
index 6c58939..bd47036 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/worker-atomics-wait.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/worker-atomics-wait.html
@@ -14,24 +14,30 @@
     testRunner.waitUntilDone();
 }
 
-var view = new Int32Array(new SharedArrayBuffer(4));
-try {
-  Atomics.wait(view, 0, 0, 0);
-  log("FAIL: Calling Atomics.wait on the main thread did not throw.");
-} catch (e) {
-  log("PASS: Calling Atomics.wait on the main thread throws.");
-}
-
-var worker = new Worker('resources/worker-atomics-wait.js');
-worker.postMessage(view);
-
-worker.onmessage = function(e) {
-    log(e.data);
-    if (e.data == 'DONE') {
-        if (window.testRunner)
-            testRunner.notifyDone();
+if (window.internals && internals.runtimeFlags.sharedArrayBufferEnabled && window.SharedArrayBuffer) {
+    var view = new Int32Array(new SharedArrayBuffer(4));
+    try {
+      Atomics.wait(view, 0, 0, 0);
+      log("FAIL: Calling Atomics.wait on the main thread did not throw.");
+    } catch (e) {
+      log("PASS: Calling Atomics.wait on the main thread throws.");
     }
-};
+
+    var worker = new Worker('resources/worker-atomics-wait.js');
+    worker.postMessage(view);
+
+    worker.onmessage = function(e) {
+        log(e.data);
+        if (e.data == 'DONE') {
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+    };
+} else {
+    log("SharedArrayBuffers are not enabled -- skipping test.");
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
 
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/fast/workers/worker-sharedarraybuffer-transfer.html b/third_party/WebKit/LayoutTests/fast/workers/worker-sharedarraybuffer-transfer.html
index e2fd79dc..3f03c94 100644
--- a/third_party/WebKit/LayoutTests/fast/workers/worker-sharedarraybuffer-transfer.html
+++ b/third_party/WebKit/LayoutTests/fast/workers/worker-sharedarraybuffer-transfer.html
@@ -238,18 +238,23 @@
     testRunner.waitUntilDone();
 }
 
-var worker = new Worker('resources/worker-sharedarraybuffer-transfer.js');
+if (window.internals && internals.runtimeFlags.sharedArrayBufferEnabled && window.SharedArrayBuffer) {
+    var worker = new Worker('resources/worker-sharedarraybuffer-transfer.js');
 
-runNextTest();
+    runNextTest();
 
-worker.onmessage = function(e) {
-    if (e.data != 'DONE') {
-        // The worker sent a pass/fail message.
-        log(e.data);
-    } else {
-        runNextTest();
-    }
-};
+    worker.onmessage = function(e) {
+        if (e.data != 'DONE') {
+            // The worker sent a pass/fail message.
+            log(e.data);
+        } else {
+            runNextTest();
+        }
+    };
+} else {
+    log("SharedArrayBuffers are not enabled -- skipping test.");
+    testRunner.notifyDone();
+}
 
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console-xhr-logging-async-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console-xhr-logging-async-expected.txt
index 919c8eb..ddc8d00 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/console-xhr-logging-async-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console-xhr-logging-async-expected.txt
@@ -1,9 +1,11 @@
 Tests that XMLHttpRequest Logging works when Enabled and doesn't show logs when Disabled for asynchronous XHRs.
 
-VM:5 XHR loaded: 1
+XHR with logging enabled: 
 VM:37 XHR finished loading: GET "http://127.0.0.1:8000/devtools/resources/xhr-exists.html".
 makeXHR @ VM:37
 makeXHRForJSONArguments @ VM:43
 (anonymous) @ VM:1
+VM:5 XHR loaded: 1
+XHR with logging disabled: 
 VM:5 XHR loaded: 2
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console-xhr-logging-async.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console-xhr-logging-async.js
index a76cb58c..90f19e1 100644
--- a/third_party/WebKit/LayoutTests/http/tests/devtools/console-xhr-logging-async.js
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console-xhr-logging-async.js
@@ -16,19 +16,25 @@
 
   function step1() {
     Common.settingForTest('monitoringXHREnabled').set(true);
-    makeRequest(step2);
+    makeRequest(() => {
+      TestRunner.deprecatedRunAfterPendingDispatches(() => {
+        TestRunner.addResult('XHR with logging enabled: ');
+        // Sorting console messages to prevent flakiness.
+        TestRunner.addResults(ConsoleTestRunner.dumpConsoleMessagesIntoArray().sort());
+        Console.ConsoleView.clearConsole();
+        step2();
+      });
+    });
   }
 
   function step2() {
     Common.settingForTest('monitoringXHREnabled').set(false);
-    makeRequest(step3);
-  }
-
-  function step3() {
-    function finish() {
-      ConsoleTestRunner.dumpConsoleMessages();
-      TestRunner.completeTest();
-    }
-    TestRunner.deprecatedRunAfterPendingDispatches(finish);
+    makeRequest(() => {
+      TestRunner.deprecatedRunAfterPendingDispatches(() => {
+        TestRunner.addResult('XHR with logging disabled: ');
+        ConsoleTestRunner.dumpConsoleMessages();
+        TestRunner.completeTest();
+      });
+    });
   }
 })();
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/request.js b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/request.js
index f35b99f..30e5d9c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/request.js
+++ b/third_party/WebKit/LayoutTests/http/tests/fetch/script-tests/request.js
@@ -486,8 +486,9 @@
 
 test(function() {
     var referrer = OTHER_ORIGIN + '/path?query';
-    assert_throws({name: 'TypeError'},
-        () => new Request(URL, {referrer: referrer}));
+
+    assert_equals(new Request(URL, {referrer: referrer}).referrer, 'about:client',
+                      'constructed with cross-origin referrer');
   }, 'Request with a url with another origin');
 
 test(function() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/resources/permissions-helper.js b/third_party/WebKit/LayoutTests/http/tests/resources/permissions-helper.js
index 286ff12..1e18f50e 100644
--- a/third_party/WebKit/LayoutTests/http/tests/resources/permissions-helper.js
+++ b/third_party/WebKit/LayoutTests/http/tests/resources/permissions-helper.js
@@ -27,6 +27,10 @@
         return {name: "background-sync"};
       case "accessibility-events":
         return {name: "accessibility-events"};
+      case "clipboard-read":
+        return {name: "clipboard-read"};
+      case "clipboard-write":
+        return {name: "clipboard-write"};
       default:
         throw "Invalid permission name provided";
     }
diff --git a/third_party/WebKit/LayoutTests/media/track/opera/interfaces/VTTCue/getCueAsHTMLCrash-expected.txt b/third_party/WebKit/LayoutTests/media/track/opera/interfaces/VTTCue/getCueAsHTMLCrash-expected.txt
deleted file mode 100644
index f035308..0000000
--- a/third_party/WebKit/LayoutTests/media/track/opera/interfaces/VTTCue/getCueAsHTMLCrash-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-PASS , creating the cue
-FAIL , > assert_false: hasChildNodes() expected false got true
-PASS , 
-PASS , x\0
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/media/track/opera/interfaces/VTTCue/getCueAsHTMLCrash.html b/third_party/WebKit/LayoutTests/media/track/opera/interfaces/VTTCue/getCueAsHTMLCrash.html
deleted file mode 100644
index 8cb9cd7..0000000
--- a/third_party/WebKit/LayoutTests/media/track/opera/interfaces/VTTCue/getCueAsHTMLCrash.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!DOCTYPE html>
-<html>
-<div>Test passes if it does not induce a crash.</div>
-<script src=../../../../../resources/testharness.js></script>
-<script src=../../../../../resources/testharnessreport.js></script>
-<script>
-if (window.testRunner)
-    testRunner.dumpAsText();
-
-test(function(){
-    var c1 = new VTTCue(0, 1, '<c>x\0');
-    window.frag = c1.getCueAsHTML();
-}, document.title+', creating the cue');
-
-test(function(){
-    assert_false(frag.childNodes[0].hasChildNodes(), 'hasChildNodes()');
-}, document.title+', >');
-
-test(function(){}, document.title+', ');
-test(function(){}, document.title+', x\\0');
-</script>
-</html>
diff --git a/third_party/WebKit/LayoutTests/media/track/track-large-timestamp.html b/third_party/WebKit/LayoutTests/media/track/track-large-timestamp.html
deleted file mode 100644
index 81f8be9..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-large-timestamp.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<title>Tests that a very large timestamp is parsed correctly.</title>
-<script src="../media-file.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<video>
-    <track src="captions-webvtt/large-timestamp.vtt" default>
-</video>
-<script>
-async_test(function(t) {
-    var testTrack = document.querySelector("track");
-    testTrack.onload = t.step_func_done(function() {
-        assert_equals(testTrack.track.cues.length, 1);
-        var cue = testTrack.track.cues[0];
-        assert_equals(parseInt(cue.id), 1);
-        assert_equals(cue.startTime / 3600, 1234567);
-        assert_equals(cue.endTime / 3600, 1234567890);
-    });
-});
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-load-error-readyState.html b/third_party/WebKit/LayoutTests/media/track/track-load-error-readyState.html
deleted file mode 100644
index 2846be9..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-load-error-readyState.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<title>Tests the error event on HTMLTrackElement and ERROR readyState on TextTrack.</title>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<video>
-  <track src="junk" default>
-  <script>
-  async_test(function(t) {
-    var track = document.querySelector("track");
-    track.onerror = t.step_func_done(function() {
-      assert_equals(track.readyState, HTMLTrackElement.ERROR);
-    });
-  });
-  </script>
-</video>
diff --git a/third_party/WebKit/LayoutTests/media/track/track-load-from-element-readyState.html b/third_party/WebKit/LayoutTests/media/track/track-load-from-element-readyState.html
deleted file mode 100644
index 088b7a2..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-load-from-element-readyState.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<title>Tests the load event on HTMLTrackElement and LOADED readyState on TextTrack when src is set on the element.</title>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<video>
-  <track src="captions-webvtt/tc004-webvtt-file.vtt" default>
-  <script>
-  async_test(function(t) {
-    var track = document.querySelector("track");
-    track.onload = t.step_func_done(function() {
-      assert_equals(track.readyState, HTMLTrackElement.LOADED);
-    });
-  });
-  </script>
-</video>
diff --git a/third_party/WebKit/LayoutTests/media/track/track-load-from-src-readyState.html b/third_party/WebKit/LayoutTests/media/track/track-load-from-src-readyState.html
deleted file mode 100644
index 97c50c4..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-load-from-src-readyState.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<title>Tests the load event on HTMLTrackElement and LOADED readyState on TextTrack when src is set from JavaScript.</title>
-<video>
-    <track>
-</video>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script>
-async_test(function(t) {
-    var track = document.querySelector("track");
-    assert_equals(track.readyState, HTMLTrackElement.NONE);
-
-    track.onload = t.step_func_done(function () {
-        assert_equals(track.readyState, HTMLTrackElement.LOADED);
-    });
-
-    track.src = "captions-webvtt/tc004-webvtt-file.vtt";
-    track.track.mode = "hidden";
-});
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-mode-disabled-crash.html b/third_party/WebKit/LayoutTests/media/track/track-mode-disabled-crash.html
deleted file mode 100644
index 4ed7a1e..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-mode-disabled-crash.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<title>Tests that cues are properly removed from the active cue list when their track changes mode to disabled.</title>
-<script src="../media-file.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<video>
-    <track src="captions-webvtt/captions-gaps.vtt" kind="captions" default >
-</video>
-<script>
-async_test(function(t) {
-    var video = document.querySelector("video");
-    var testTrack = document.querySelector("track");
-
-    video.src = findMediaFile("video", "../content/counting");
-    video.oncanplaythrough = t.step_func(startTest);
-    video.onseeked = t.step_func_done(seeked);
-
-    function startTest() {
-        // Set the mode of the text track to showing.
-        testTrack.track.mode = "showing";
-        // Seek to a time with a caption.
-        video.currentTime = 1.5;
-    }
-
-    function seeked() {
-        // Set the mode of the text track to hidden, then showing again.
-        testTrack.track.mode = "hidden";
-        testTrack.track.mode = "showing";
-
-        // Set the mode of the text track to disabled.
-        testTrack.track.mode = "disabled";
-        // No crash, PASS.
-    }
-});
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/media/track/track-mode.html b/third_party/WebKit/LayoutTests/media/track/track-mode.html
deleted file mode 100644
index bb4562f..0000000
--- a/third_party/WebKit/LayoutTests/media/track/track-mode.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE html>
-<title>Tests that the TextTrack mode attribute is appropriately set.</title>
-<script src="../media-file.js"></script>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<video>
-    <track src="captions-webvtt/captions-fast.vtt" default>
-</video>
-<script>
-async_test(function(t) {
-    var video = document.querySelector("video");
-    var track = document.querySelector("track");
-    track.onload = t.step_func(trackLoaded);
-
-    var cueCount = 0;
-    var textTrack;
-    function trackLoaded() {
-        textTrack = track.track;
-        // Test default attribute value.
-        assert_equals(textTrack.mode, "showing");
-        assert_equals(video.textTracks[0].mode, "showing");
-        // Set to bogus value, should return default.
-        var value = "bogus";
-        textTrack.mode = value;
-        assert_equals(textTrack.mode, "showing");
-        assert_equals(video.textTracks[0].mode, "showing");
-
-        // Set to numeric value (no longer supported), should return default.
-        textTrack.mode = 2;
-        assert_equals(textTrack.mode, "showing");
-        assert_equals(video.textTracks[0].mode, "showing");
-
-        // Set to known values.
-        setModeAndCheck("disabled");
-
-        video.src = findMediaFile("video", "../content/test");
-        video.play();
-        // Wait for end of first cue (no events should fire while track is disabled).
-        setTimeout(testHiddenAndShowing, 400);
-    }
-
-    track.oncuechange = t.step_func(function(event) {
-        cueCount++;
-        if (cueCount == textTrack.cues.length)
-            t.done();
-    });
-
-    function setModeAndCheck(value) {
-        textTrack.mode =  value;
-        assert_equals(textTrack.mode, value);
-        assert_equals(video.textTracks[0].mode, value);
-        if (value == "disabled")
-            assert_equals(textTrack.cues, null);
-    }
-
-    function testHiddenAndShowing() {
-        setModeAndCheck("hidden");
-        setModeAndCheck("showing");
-    }
-});
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/typedcssom/resources/testhelper.js b/third_party/WebKit/LayoutTests/typedcssom/resources/testhelper.js
index 4ea0ee43..00403029 100644
--- a/third_party/WebKit/LayoutTests/typedcssom/resources/testhelper.js
+++ b/third_party/WebKit/LayoutTests/typedcssom/resources/testhelper.js
@@ -114,6 +114,18 @@
   return createDivWithStyle(test, cssText).computedStyleMap();
 }
 
+// Creates a new style element with a rule |cssText| and returns
+// its declared style property map.
+function createDeclaredStyleMap(test, cssText) {
+  const style = document.createElement('style');
+  document.head.appendChild(style);
+  const rule = style.sheet.cssRules[style.sheet.insertRule('#test { ' + cssText + '}')];
+  test.add_cleanup(() => {
+    style.remove();
+  });
+  return rule.attributeStyleMap;
+}
+
 // Creates a new element with background image set to |imageValue|
 // and returns a new Image element that can be used to attach
 // event listeners regarding the image.
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/append.html b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/append.html
new file mode 100644
index 0000000..50c7d26
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/append.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>StylePropertyMap.append tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#append-to-a-stylepropertymap">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<body>
+<script>
+'use strict';
+
+const gInvalidTestCases = [
+  { property: 'lemon', values: ['ade'], desc: 'an unsupported property name' },
+  { property: null, values: ['foo'], desc: 'an null property name' },
+  { property: 'width', values: ['10px'], desc: 'a property that is not list valued' },
+  { property: 'transition-duration', values: [CSS.px(10)], desc: 'an invalid CSSStyleValue' },
+  { property: 'transition-duration', values: ['10px'], desc: 'an invalid String value' },
+  { property: 'transition-duration', values: [CSS.s(1), '10px', CSS.px(10)], desc: 'a mix of valid and invalid values' },
+];
+
+for (const {property, values, desc} of gInvalidTestCases) {
+  test(t => {
+    let styleMap = createDeclaredStyleMap(t, '');
+    assert_throws(new TypeError(), () => styleMap.append(property, ...values));
+  }, 'Calling StylePropertyMap.append with ' + desc + ' throws TypeError');
+}
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, '');
+
+  styleMap.append('transition-duration', CSS.s(1), '2s');
+  assert_style_value_array_equals(styleMap.getAll('transition-duration'),
+      [CSS.s(1), CSS.s(2)]);
+
+  styleMap.append('transition-duration', '3s', CSS.s(4));
+  assert_style_value_array_equals(styleMap.getAll('transition-duration'),
+      [CSS.s(1), CSS.s(2), CSS.s(3), CSS.s(4)]);
+}, 'Appending a list-valued property with CSSStyleValue or String updates its values');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, '');
+
+  styleMap.append('transition-duration', '1s, 2s');
+  assert_style_value_array_equals(styleMap.getAll('transition-duration'),
+      [CSS.s(1), CSS.s(2)]);
+
+  styleMap.append('transition-duration', '3s, 4s');
+  assert_style_value_array_equals(styleMap.getAll('transition-duration'),
+      [CSS.s(1), CSS.s(2), CSS.s(3), CSS.s(4)]);
+}, 'Appending a list-valued property with list-valued string updates its values');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, 'transition-duration: 5s, 10s');
+
+  styleMap.append('tRaNsItIoN-dUrAtIoN', '1s', CSS.s(2));
+  const result = styleMap.getAll('transition-duration');
+  assert_style_value_array_equals(result,
+      [CSS.s(5), CSS.s(10), CSS.s(1), CSS.s(2)]);
+}, 'StylePropertyMap.append is case-insensitive');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/declared.html b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/declared.html
new file mode 100644
index 0000000..d0b2ef2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/declared.html
@@ -0,0 +1,76 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Declared StylePropertyMap tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#declared-stylepropertymap-objects">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<style>
+div {
+  height: 10px;
+  width: 50%;
+  width: 'lemon';
+  --foo: auto;
+  transition-duration: 1s, 2s;
+  color: 10;
+}
+
+#target {
+  height: 20px;
+  --foo: 1s;
+  width: 10%;
+}
+</style>
+<div style="width: 50px">
+  <div id="target" style="top: 5px; --bar: auto;"></div>
+</div>
+<script>
+'use strict';
+
+const target = document.getElementById('target');
+const styleMap = document.styleSheets[0].rules[0].attributeStyleMap;
+
+test(() => {
+  const properties = styleMap.getProperties();
+  assert_array_equals(properties, ['height', 'transition-duration', 'width', '--foo']);
+}, 'Declared StylePropertyMap only contains properties in the style rule');
+
+test(() => {
+  assert_style_value_equals(styleMap.get('height'), CSS.px(10));
+}, 'Declared StylePropertyMap contains CSS property declarations in style rules');
+
+test(() => {
+  assert_equals(styleMap.get('top'), null);
+  assert_equals(styleMap.get('--bar'), null);
+}, 'Declared StylePropertyMap does not contain inline styles');
+
+test(() => {
+  assert_style_value_equals(styleMap.get('--foo'), new CSSUnparsedValue(' auto'));
+}, 'Declared StylePropertyMap contains custom property declarations');
+
+test(() => {
+  assert_equals(styleMap.get('color'), null);
+}, 'Declared StylePropertyMap does not contain properties with invalid values');
+
+test(() => {
+  assert_style_value_equals(styleMap.get('width'), CSS.percent(50));
+}, 'Declared StylePropertyMap contains properties with their last valid value');
+
+test(() => {
+  const style = document.createElement('style');
+  document.head.appendChild(style);
+
+  style.sheet.insertRule('.test { width: 10px; }');
+  let rule = style.sheet.rules[0];
+
+  let styleMap = rule.attributeStyleMap;
+  assert_style_value_equals(styleMap.get('width'), CSS.px(10));
+
+  rule.style.width = '20px';
+  assert_style_value_equals(styleMap.get('width'), CSS.px(20));
+
+  styleMap.set('width', CSS.px(30));
+  assert_equals(rule.cssText, '.test { width: 30px; }');
+}, 'Declared StylePropertyMap is live');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/delete-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/delete-expected.txt
new file mode 100644
index 0000000..7a389ce59
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/delete-expected.txt
@@ -0,0 +1,9 @@
+This is a testharness.js-based test.
+PASS Calling StylePropertyMap.delete with an unsupported property name throws a TypeError
+PASS Deleting a property not in a StylePropertyMap is a no-op
+PASS Deleting a property in the property model removes it from the property model
+FAIL Deleting a custom property in the property model removes it from the property model Failed to execute 'delete' on 'StylePropertyMap': Invalid propertyName: --foo
+PASS Deleting a list-valued property in the property model removes it from the property model
+PASS Deleting a mixed-case property in the property model removes it from the property model
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/get.html b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/get.html
new file mode 100644
index 0000000..ec5bf3e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/get.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>StylePropertyMap.get tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#get-a-value-from-a-stylepropertymap">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<body>
+<script>
+'use strict';
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t);
+  assert_throws(new TypeError(), () => styleMap.get('lemon'));
+}, 'Calling StylePropertyMap.get with an unsupported property throws a TypeError');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t);
+  assert_equals(styleMap.get('height'), null);
+}, 'Calling StylePropertyMap.get with a property not in the property model returns null');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, '--foo: auto');
+  assert_equals(styleMap.get('--Foo'), null);
+}, 'Calling StylePropertyMap.get with a custom property not in the property model returns null');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, 'width: 10px; height: 20px');
+  assert_style_value_equals(styleMap.get('width'), CSS.px(10));
+}, 'Calling StylePropertyMap.get with a valid property returns the correct entry');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, 'height: 20px; width: 10px;');
+  assert_style_value_equals(styleMap.get('wIdTh'), CSS.px(10));
+}, 'StylePropertyMap.get with a valid property in mixed case returns the correct entry');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, '--foo: auto; --bar: 10px');
+  assert_style_value_equals(styleMap.get('--foo'), new CSSUnparsedValue(' auto'));
+}, 'Calling StylePropertyMap.get with a valid custom property returns the correct entry');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, 'width: 10px; transition-duration: 1s, 2s; height: 10px;');
+  assert_style_value_equals(styleMap.get('transition-duration'), CSS.s(1));
+}, 'Calling StylePropertyMap.get with a list-valued property returns only the first value');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/getAll.html b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/getAll.html
new file mode 100644
index 0000000..d3d26c81
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/getAll.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>StylePropertyMap.getAll tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#stylepropertymap">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<body>
+<script>
+'use strict';
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t);
+  assert_throws(new TypeError(), () => styleMap.getAll('lemon'));
+}, 'Calling StylePropertyMap.getAll with an unsupported property throws a TypeError');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t);
+  assert_style_value_array_equals(styleMap.getAll('height'), []);
+}, 'Calling StylePropertyMap.getAll with a property not in the property model returns an empty list');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, '--foo: auto');
+  assert_style_value_array_equals(styleMap.getAll('--Foo'), []);
+}, 'Calling StylePropertyMap.getAll with a custom property not in the property model returns an empty list');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, 'width: 10px; height: 20px');
+  assert_style_value_array_equals(styleMap.getAll('width'), [CSS.px(10)]);
+}, 'Calling StylePropertyMap.getAll with a valid property returns a single element list with the correct entry');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, 'height: 20px; width: 10px');
+  assert_style_value_array_equals(styleMap.getAll('wIdTh'), [CSS.px(10)]);
+}, 'StylePropertyMap.getAll is case-insensitive');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, '--foo: auto; --bar: 10px');
+  assert_style_value_array_equals(styleMap.getAll('--foo'), [new CSSUnparsedValue(' auto')]);
+}, 'Calling StylePropertyMap.getAll with a valid custom property returns a single element list with the correct entry');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, 'width: 10px; transition-duration: 1s, 2s; height: 20px');
+  assert_style_value_array_equals(styleMap.getAll('transition-duration'), [CSS.s(1), CSS.s(2)]);
+}, 'Calling StylePropertyMap.getAll with a list-valued property returns all the values');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/getProperties.html b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/getProperties.html
new file mode 100644
index 0000000..801c58b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/getProperties.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>StylePropertyMap.getProperties tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-getproperties">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<body>
+<script>
+'use strict';
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, '');
+  assert_array_equals(styleMap.getProperties(), []);
+}, 'Calling StylePropertyMap.getProperties on an empty property model returns a zero-length array');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, '--A: A; width: 0px; --C: C; transition-duration: 1s, 2s; color: red; --B: B;');
+  assert_array_equals(styleMap.getProperties(),
+    ['color', 'transition-duration', 'width', '--A', '--B', '--C']);
+}, 'StylePropertyMap.getProperties returns CSS properties in alphabetical order then custom properties by codepoint');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/has.html b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/has.html
new file mode 100644
index 0000000..fbf83af
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/has.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>StylePropertyMap.has tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#check-if-stylepropertymap-has-a-property">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<body>
+<script>
+'use strict';
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t);
+  assert_throws(new TypeError(), () => styleMap.has('lemon'));
+}, 'Calling StylePropertyMap.has with an unsupported property throws a TypeError');
+
+const gTestCases = [
+  { property: 'height', expected: false, desc: 'a property not in the property model' },
+  { property: '--Foo', expected: false, desc: 'a custom property not in the property model' },
+  { property: 'width', expected: true, desc: 'a valid property' },
+  { property: 'wIdTh', expected: true, desc: 'a valid property in mixed case' },
+  { property: '--foo', expected: true, desc: 'a valid custom property' },
+  { property: 'transition-duration', expected: true, desc: 'a valid list-valued property' },
+];
+
+for (const {property, expected, desc} of gTestCases) {
+  test(t => {
+    const styleMap = createDeclaredStyleMap(t, 'width: 10px; --foo: auto; transition-duration: 1s, 2s');
+    assert_equals(styleMap.has(property), expected);
+  }, 'Calling StylePropertyMap.has with ' + desc + ' returns ' + expected);
+}
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/iterable.html b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/iterable.html
new file mode 100644
index 0000000..af48cb37
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/iterable.html
@@ -0,0 +1,51 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>StylePropertyMap iterable tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#the-stylepropertymap">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<body>
+<script>
+'use strict';
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, '');
+  assert_array_equals([...styleMap.entries()], []);
+}, 'Iterating over an empty StylePropertyMap gives a zero-length array');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, '--A: A; width: 10px; --C: C; transition-duration: 1s, 2s; color: red; --B: B;');
+  assert_array_equals([...styleMap.keys()],
+    ['color', 'transition-duration', 'width', '--A', '--B', '--C']);
+}, 'StylePropertyMap iterates properties in correct order');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, 'height: 5px; width: 10px;');
+  const keys = [...styleMap.keys()], values = [...styleMap.values()];
+
+  assert_array_equals(keys, ['height', 'width']);
+  assert_style_value_array_equals(values, [CSS.px(5), CSS.px(10)]);
+}, 'StylePropertyMap iterator returns CSS properties with the correct CSSStyleValue');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, 'transition-duration: 1s, 2s');
+  const keys = [...styleMap.keys()], values = [...styleMap.values()];
+
+  assert_array_equals(keys, ['transition-duration']);
+  assert_style_value_array_equals(values[0], [CSS.s(1), CSS.s(2)]);
+}, 'StylePropertyMap iterator returns list-valued properties with the correct CSSStyleValue');
+
+test(t => {
+  const styleMap = createDeclaredStyleMap(t, '--A: A; --B: B; --C: C');
+  const keys = [...styleMap.keys()], values = [...styleMap.values()];
+
+  assert_array_equals(keys, ['--A', '--B', '--C']);
+  assert_style_value_array_equals(values, [
+    new CSSUnparsedValue(' A'),
+    new CSSUnparsedValue(' B'),
+    new CSSUnparsedValue(' C'),
+  ])
+}, 'StylePropertyMap iterator returns custom properties with the correct CSSStyleValue');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/set-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/set-expected.txt
new file mode 100644
index 0000000..048f392
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/set-expected.txt
@@ -0,0 +1,14 @@
+This is a testharness.js-based test.
+PASS Setting a StylePropertyMap with an unsupported property name throws TypeError
+PASS Setting a StylePropertyMap with an null property name throws TypeError
+PASS Setting a StylePropertyMap with an invalid CSSStyleValue throws TypeError
+PASS Setting a StylePropertyMap with an invalid String throws TypeError
+PASS Setting a non list-valued property with multiple arguments throws TypeError
+PASS Setting a non list-valued property with list-valued string throws TypeError
+PASS Setting a property with CSSStyleValue or String updates its value
+PASS Setting a list-valued property with CSSStyleValue or String updates its values
+PASS Setting a list-valued property with a list-valued string updates its value
+FAIL Setting a custom property with CSSStyleValue or String updates its value Failed to execute 'set' on 'StylePropertyMap': Invalid propertyName: --foo
+PASS StylePropertyMap.set is case-insensitive
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/set.html b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/set.html
new file mode 100644
index 0000000..42c8f3db
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/set.html
@@ -0,0 +1,81 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>StylePropertyMap.set</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#set-a-value-on-a-stylepropertymap">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<body>
+<script>
+'use strict';
+
+const gInvalidTestCases = [
+  { property: 'lemon', values: ['ade'], desc: 'an unsupported property name' },
+  { property: null, values: ['foo'], desc: 'an null property name' },
+  { property: 'width', values: [CSS.deg(0)], desc: 'an invalid CSSStyleValue' },
+  { property: 'width', values: ['10s'], desc: 'an invalid String' },
+];
+
+for (const {property, values, desc} of gInvalidTestCases) {
+  test(t => {
+    let styleMap = createDeclaredStyleMap(t, '');
+    assert_throws(new TypeError(), () => styleMap.set(property, ...values));
+  }, 'Setting a StylePropertyMap with ' + desc + ' throws TypeError');
+}
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, '');
+  assert_throws(new TypeError(), () => styleMap.set('width', CSS.px(10), CSS.px(10)));
+}, 'Setting a non list-valued property with multiple arguments throws TypeError');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, '');
+  assert_throws(new TypeError(), () => styleMap.set('width', '1s, 2s'));
+}, 'Setting a non list-valued property with list-valued string throws TypeError');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, '');
+
+  styleMap.set('width', CSS.px(10));
+  assert_style_value_array_equals(styleMap.get('width'), CSS.px(10));
+
+  styleMap.set('width', '20px');
+  assert_style_value_array_equals(styleMap.get('width'), CSS.px(20));
+}, 'Setting a property with CSSStyleValue or String updates its value');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, '');
+
+  styleMap.set('transition-duration', CSS.s(1), '2s');
+  assert_style_value_array_equals(styleMap.getAll('transition-duration'), [CSS.s(1), CSS.s(2)]);
+
+  styleMap.set('transition-duration', '3s', CSS.s(4));
+  assert_style_value_array_equals(styleMap.getAll('transition-duration'), [CSS.s(3), CSS.s(4)]);
+}, 'Setting a list-valued property with CSSStyleValue or String updates its values');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, '');
+
+  styleMap.set('transition-duration', '1s, 2s');
+  assert_style_value_array_equals(styleMap.getAll('transition-duration'), [CSS.s(1), CSS.s(2)]);
+}, 'Setting a list-valued property with a list-valued string updates its value');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, '');
+
+  styleMap.set('--foo', CSS.px(10));
+  assert_style_value_array_equals(styleMap.get('--foo'), CSS.px(10));
+
+  styleMap.set('--foo', '20px');
+  assert_style_value_array_equals(styleMap.get('--foo'), new CSSUnparsedValue('20px'));
+}, 'Setting a custom property with CSSStyleValue or String updates its value');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, 'transition-duration: 5s, 10s');
+
+  styleMap.set('tRaNsItIoN-dUrAtIoN', '1s', CSS.s(2));
+  const result = styleMap.getAll('transition-duration');
+  assert_style_value_array_equals(result, [CSS.s(1), CSS.s(2)]);
+}, 'StylePropertyMap.set is case-insensitive');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/test.html b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/test.html
new file mode 100644
index 0000000..d9078f2e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/test.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Declared StylePropertyMap tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#declared-stylepropertymap-objects">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<style>
+#target { width: 100px; height: 100px; background: red; }
+</style>
+<body>
+<div id="target">
+<script>
+'use strict';
+
+test(() => {
+  let rule = document.styleSheets[0].rules[0];
+  rule.attributeStyleMap.set('width', CSS.px(200));
+  assert_equals(getComputedStyle(target).width, '200px')
+  rule.attributeStyleMap.set('width', CSS.px(150));
+  assert_equals(getComputedStyle(target).width, '150px')
+});
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/update-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/update-expected.txt
new file mode 100644
index 0000000..dea45763
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/update-expected.txt
@@ -0,0 +1,14 @@
+This is a testharness.js-based test.
+PASS Updating a StylePropertyMap with an unsupported property name throws TypeError
+PASS Updating a StylePropertyMap with an null property name throws TypeError
+PASS Updating a StylePropertyMap with an invalid CSSStyleValue throws TypeError
+PASS Updating a StylePropertyMap with an invalid String throws TypeError
+PASS Updating a property with CSSStyleValue updates its value
+PASS Updating a list-valued property with CSSStyleValue updates its value
+FAIL Updating a custom property with CSSStyleValue updates its value Failed to execute 'update' on 'StylePropertyMap': Invalid propertyName: --foo
+PASS Calling StylePropertyMap.update on an empty property model calls update function with null
+PASS Calling StylePropertyMap.update on an existing property calls update function with old value
+PASS Calling StylePropertyMap.update on an existing list-valued property calls update function with first value
+PASS StylePropertyMap.update is case-insensitive
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/update.html b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/update.html
new file mode 100644
index 0000000..15cc3fab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/typedcssom/the-stylepropertymap/declared/update.html
@@ -0,0 +1,88 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>StylePropertyMap.update tests</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#update-a-value-in-a-stylepropertymap">
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../resources/testhelper.js"></script>
+<body>
+<script>
+'use strict';
+
+const gInvalidTestCases = [
+  { property: 'lemon', value: 'ade', desc: 'an unsupported property name' },
+  { property: null, value: 'foo', desc: 'an null property name' },
+  { property: 'width', value: CSS.deg(0), desc: 'an invalid CSSStyleValue' },
+  { property: 'width', value: '10s', desc: 'an invalid String' },
+];
+
+for (const {property, value, desc} of gInvalidTestCases) {
+  test(t => {
+    let styleMap = createDeclaredStyleMap(t, '');
+    assert_throws(new TypeError(), () => styleMap.update(property, () => value));
+  }, 'Updating a StylePropertyMap with ' + desc + ' throws TypeError');
+}
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, '');
+
+  styleMap.update('width', () => CSS.px(10));
+  assert_style_value_array_equals(styleMap.get('width'), CSS.px(10));
+
+  styleMap.update('width', () => CSS.px(20));
+  assert_style_value_array_equals(styleMap.get('width'), CSS.px(20));
+}, 'Updating a property with CSSStyleValue updates its value');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, '');
+
+  styleMap.update('transition-duration', () => CSS.s(1));
+  assert_style_value_array_equals(styleMap.getAll('transition-duration'), [CSS.s(1)]);
+
+  styleMap.update('transition-duration', () => CSS.s(2));
+  assert_style_value_array_equals(styleMap.getAll('transition-duration'), [CSS.s(2)]);
+}, 'Updating a list-valued property with CSSStyleValue updates its value');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, '');
+
+  styleMap.update('--foo', () => CSS.px(10));
+  assert_style_value_array_equals(styleMap.get('--foo'), CSS.px(10));
+
+  styleMap.update('--foo', () => CSS.px(20));
+  assert_style_value_array_equals(styleMap.get('--foo'), CSS.px(20));
+}, 'Updating a custom property with CSSStyleValue updates its value');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, '');
+  styleMap.update('width', oldValue => {
+    assert_equals(oldValue, null);
+    return CSS.px(10);
+  });
+}, 'Calling StylePropertyMap.update on an empty property model calls update function with null');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, 'width: 10px');
+  styleMap.update('width', oldValue => {
+    assert_style_value_equals(oldValue, CSS.px(10));
+    return CSS.px(20);
+  });
+}, 'Calling StylePropertyMap.update on an existing property calls update function with old value');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, 'transition-duration: 1s, 2s');
+  styleMap.update('transition-duration', oldValue => {
+    assert_style_value_equals(oldValue, CSS.s(1));
+    return CSS.s(2);
+  });
+}, 'Calling StylePropertyMap.update on an existing list-valued property calls update function with first value');
+
+test(t => {
+  let styleMap = createDeclaredStyleMap(t, 'width: 10px');
+
+  styleMap.update('wIdTh', () => CSS.px(20));
+  const result = styleMap.get('width');
+  assert_style_value_equals(result, CSS.px(20));
+}, 'StylePropertyMap.update is case-insensitive');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 84915b76..1145ec6 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -798,6 +798,7 @@
     setter cssText
 interface CSSStyleRule : CSSRule
     attribute @@toStringTag
+    getter attributeStyleMap
     getter selectorText
     getter style
     method constructor
diff --git a/third_party/WebKit/Source/build/scripts/core/css/properties/templates/CSSProperty.h.tmpl b/third_party/WebKit/Source/build/scripts/core/css/properties/templates/CSSProperty.h.tmpl
index f3dffea..772021e 100644
--- a/third_party/WebKit/Source/build/scripts/core/css/properties/templates/CSSProperty.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/core/css/properties/templates/CSSProperty.h.tmpl
@@ -35,8 +35,19 @@
  public:
   CORE_EXPORT static const CSSProperty& Get(CSSPropertyID);
 
+  // For backwards compatibility when passing around CSSUnresolvedProperty
+  // references. In case we need to call a function that hasn't been converted
+  // to using property classes yet.
+  virtual CSSPropertyID PropertyID() const {
+    NOTREACHED();
+    return CSSPropertyInvalid;
+  }
+  bool IDEquals(CSSPropertyID id) const { return PropertyID() == id; }
   bool IsResolvedProperty() const override { return true; }
-  WTF::String GetJSPropertyName() const;
+  virtual const WTF::String GetJSPropertyName() const {
+    NOTREACHED();
+    return g_empty_string;
+  }
   virtual bool IsInterpolable() const { return false; }
   virtual bool IsInherited() const { return false; }
   virtual bool IsCompositableProperty() const { return false; }
diff --git a/third_party/WebKit/Source/build/scripts/core/css/properties/templates/CSSPropertySubclass.h.tmpl b/third_party/WebKit/Source/build/scripts/core/css/properties/templates/CSSPropertySubclass.h.tmpl
index b429027..02d82fa 100644
--- a/third_party/WebKit/Source/build/scripts/core/css/properties/templates/CSSPropertySubclass.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/core/css/properties/templates/CSSPropertySubclass.h.tmpl
@@ -31,13 +31,16 @@
  public:
   constexpr {{property_classname}}() : {{property.namespace_group}}() {}
   {% endif %}
-  CSSPropertyID PropertyID() const override { return {{property.property_id}}; }
   const char* GetPropertyName() const override { return "{{property.name}}\0"; }
   const WTF::AtomicString& GetPropertyNameAtomicString() const override {
     static const WTF::AtomicString& name = WTF::AtomicString("{{property.name}}\0");
     return name;
   }
   {% if property.alias_for == None %}
+  const WTF::String GetJSPropertyName() const override {
+    return WTF::String("{{property_classname[0].lower() + property_classname[1:]}}\0");
+  }
+  CSSPropertyID PropertyID() const override { return {{property.property_id}}; }
   {% for property_method in property.property_methods %}
   {{property_method.return_type}} {{property_method.name}}{{property_method.parameters}} const override;
   {% endfor %}
diff --git a/third_party/WebKit/Source/build/scripts/core/css/properties/templates/CSSUnresolvedProperty.h.tmpl b/third_party/WebKit/Source/build/scripts/core/css/properties/templates/CSSUnresolvedProperty.h.tmpl
index f9f0a0cf..1d46a42 100644
--- a/third_party/WebKit/Source/build/scripts/core/css/properties/templates/CSSUnresolvedProperty.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/core/css/properties/templates/CSSUnresolvedProperty.h.tmpl
@@ -21,14 +21,6 @@
  public:
   CORE_EXPORT static const CSSUnresolvedProperty& Get(CSSPropertyID);
 
-  // For backwards compatibility when passing around CSSUnresolvedProperty
-  // references. In case we need to call a function that hasn't been converted
-  // to using property classes yet.
-  virtual CSSPropertyID PropertyID() const {
-    NOTREACHED();
-    return CSSPropertyInvalid;
-  }
-  bool IDEquals(CSSPropertyID id) const { return PropertyID() == id; }
   virtual bool IsResolvedProperty() const { return false; }
   virtual const char* GetPropertyName() const {
     NOTREACHED();
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp b/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp
index 97951303..a78dbf3f 100644
--- a/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp
+++ b/third_party/WebKit/Source/core/clipboard/DataTransfer.cpp
@@ -103,6 +103,8 @@
       layer = layer->StackingNode()->AncestorStackingContextNode()->Layer();
     IntRect absolute_bounding_box =
         dragged_layout_object->AbsoluteBoundingBoxRectIncludingDescendants();
+    absolute_bounding_box.Intersect(
+        layer->GetLayoutObject().GetFrameView()->VisibleContentRect());
     FloatRect bounding_box =
         layer->GetLayoutObject()
             .AbsoluteToLocalQuad(FloatQuad(absolute_bounding_box),
@@ -127,10 +129,12 @@
       border_box_properties =
           *layer->GetLayoutObject().FirstFragment().LocalBorderBoxProperties();
     }
+    FloatPoint paint_offset = dragged_layout_object->LocalToAncestorPoint(
+        FloatPoint(), &layer->GetLayoutObject(), kUseTransforms);
     return DataTransfer::CreateDragImageForFrame(
         *local_frame_, 1.0f,
         LayoutObject::ShouldRespectImageOrientation(dragged_layout_object),
-        bounding_box, builder, border_box_properties);
+        bounding_box.Size(), paint_offset, builder, border_box_properties);
   }
 
  private:
@@ -360,14 +364,14 @@
 }
 
 // static
-// Converts from bounds in CSS space to device space based on the given frame.
-FloatRect DataTransfer::DeviceSpaceRect(const FloatRect css_rect,
+// Converts from size in CSS space to device space based on the given frame.
+FloatSize DataTransfer::DeviceSpaceSize(const FloatSize& css_size,
                                         const LocalFrame& frame) {
   float device_scale_factor = frame.GetPage()->DeviceScaleFactorDeprecated();
   float page_scale_factor = frame.GetPage()->GetVisualViewport().Scale();
-  FloatRect device_rect(css_rect);
-  device_rect.Scale(device_scale_factor * page_scale_factor);
-  return device_rect;
+  FloatSize device_size(css_size);
+  device_size.Scale(device_scale_factor * page_scale_factor);
+  return device_size;
 }
 
 // static
@@ -377,24 +381,25 @@
     const LocalFrame& frame,
     float opacity,
     RespectImageOrientationEnum image_orientation,
-    const FloatRect& css_rect,
+    const FloatSize& css_size,
+    const FloatPoint& paint_offset,
     PaintRecordBuilder& builder,
     const PropertyTreeState& property_tree_state) {
   float device_scale_factor = frame.GetPage()->DeviceScaleFactorDeprecated();
   float page_scale_factor = frame.GetPage()->GetVisualViewport().Scale();
 
-  FloatRect rect_in_visual_viewport = ClipByVisualViewport(css_rect, frame);
-  FloatRect device_rect = DeviceSpaceRect(rect_in_visual_viewport, frame);
-
+  FloatSize device_size = DeviceSpaceSize(css_size, frame);
   AffineTransform transform;
-  transform.Translate(-device_rect.X(), -device_rect.Y());
+  FloatSize paint_offset_size =
+      DeviceSpaceSize(FloatSize(paint_offset.X(), paint_offset.Y()), frame);
+  transform.Translate(-paint_offset_size.Width(), -paint_offset_size.Height());
   transform.Scale(device_scale_factor * page_scale_factor);
 
   // Rasterize upfront, since DragImage::create() is going to do it anyway
   // (SkImage::asLegacyBitmap).
   SkSurfaceProps surface_props(0, kUnknown_SkPixelGeometry);
   sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(
-      device_rect.Width(), device_rect.Height(), &surface_props);
+      device_size.Width(), device_size.Height(), &surface_props);
   if (!surface)
     return nullptr;
 
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransfer.h b/third_party/WebKit/Source/core/clipboard/DataTransfer.h
index 5741cd6..e520d273 100644
--- a/third_party/WebKit/Source/core/clipboard/DataTransfer.h
+++ b/third_party/WebKit/Source/core/clipboard/DataTransfer.h
@@ -136,13 +136,19 @@
   static FloatRect ClipByVisualViewport(const FloatRect& rect_in_document,
                                         const LocalFrame&);
 
-  // Returns the rect with device scale factor and page scale factor applied.
-  static FloatRect DeviceSpaceRect(const FloatRect css_rect, const LocalFrame&);
+  // Returns the size with device scale factor and page scale factor applied.
+  static FloatSize DeviceSpaceSize(const FloatSize& css_size,
+                                   const LocalFrame&);
+
+  // |css_size| is the size of the image in CSS pixels.
+  // |paint_offset| is the offset from the origin of the dragged
+  // object of the PaintRecordBuilder.
   static std::unique_ptr<DragImage> CreateDragImageForFrame(
       const LocalFrame&,
       float,
       RespectImageOrientationEnum,
-      const FloatRect&,
+      const FloatSize& css_size,
+      const FloatPoint& paint_offset,
       PaintRecordBuilder&,
       const PropertyTreeState&);
   static std::unique_ptr<DragImage> NodeImage(const LocalFrame&, Node&);
diff --git a/third_party/WebKit/Source/core/clipboard/DataTransferTest.cpp b/third_party/WebKit/Source/core/clipboard/DataTransferTest.cpp
index c2a1220..7682f68 100644
--- a/third_party/WebKit/Source/core/clipboard/DataTransferTest.cpp
+++ b/third_party/WebKit/Source/core/clipboard/DataTransferTest.cpp
@@ -235,4 +235,32 @@
       EXPECT_EQ(expected_bitmap.getColor(x, y), bitmap.getColor(x, y));
 }
 
+TEST_P(DataTransferTest, NodeImageWithScrolling) {
+  SetBodyInnerHTML(R"HTML(
+    <style>
+    #inner {
+      position: absolute;
+      top: 800px;
+      left: 0;
+      height: 100px;
+      width: 200px;
+      background: lightblue;
+      isolation: isolate;
+    }
+    </style>
+    <div id="inner" draggable="true" ondragstart="drag(event)"></div>
+  )HTML");
+
+  const int scroll_amount = 800;
+  LocalFrameView* frame_view = GetDocument().View();
+  frame_view->LayoutViewportScrollableArea()->SetScrollOffset(
+      ScrollOffset(0, scroll_amount), kProgrammaticScroll);
+
+  Element& inner = *GetDocument().getElementById("inner");
+  const auto image = DataTransfer::NodeImage(GetFrame(), inner);
+  const int inner_width = 200;
+  const int inner_height = 100;
+  EXPECT_EQ(IntSize(inner_width, inner_height), image->Size());
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn
index 17566c2..858ff2b3 100644
--- a/third_party/WebKit/Source/core/css/BUILD.gn
+++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -361,6 +361,8 @@
     "cssom/CSSUnsupportedStyleValue.h",
     "cssom/ComputedStylePropertyMap.cpp",
     "cssom/ComputedStylePropertyMap.h",
+    "cssom/DeclaredStylePropertyMap.cpp",
+    "cssom/DeclaredStylePropertyMap.h",
     "cssom/ElementComputedStyleMap.h",
     "cssom/FilteredComputedStylePropertyMap.cpp",
     "cssom/FilteredComputedStylePropertyMap.h",
diff --git a/third_party/WebKit/Source/core/css/CSSStyleRule.cpp b/third_party/WebKit/Source/core/css/CSSStyleRule.cpp
index 3ec9484..beea086 100644
--- a/third_party/WebKit/Source/core/css/CSSStyleRule.cpp
+++ b/third_party/WebKit/Source/core/css/CSSStyleRule.cpp
@@ -26,6 +26,7 @@
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/StyleRule.h"
 #include "core/css/StyleRuleCSSStyleDeclaration.h"
+#include "core/css/cssom/DeclaredStylePropertyMap.h"
 #include "core/css/parser/CSSParser.h"
 #include "core/dom/ExecutionContext.h"
 #include "platform/wtf/text/StringBuilder.h"
@@ -41,7 +42,9 @@
 }
 
 CSSStyleRule::CSSStyleRule(StyleRule* style_rule, CSSStyleSheet* parent)
-    : CSSRule(parent), style_rule_(style_rule) {}
+    : CSSRule(parent),
+      style_rule_(style_rule),
+      attribute_style_map_(new DeclaredStylePropertyMap(this)) {}
 
 CSSStyleRule::~CSSStyleRule() = default;
 
@@ -108,6 +111,7 @@
 void CSSStyleRule::Trace(blink::Visitor* visitor) {
   visitor->Trace(style_rule_);
   visitor->Trace(properties_cssom_wrapper_);
+  visitor->Trace(attribute_style_map_);
   CSSRule::Trace(visitor);
 }
 
diff --git a/third_party/WebKit/Source/core/css/CSSStyleRule.h b/third_party/WebKit/Source/core/css/CSSStyleRule.h
index 3f74a48..99cc937 100644
--- a/third_party/WebKit/Source/core/css/CSSStyleRule.h
+++ b/third_party/WebKit/Source/core/css/CSSStyleRule.h
@@ -23,6 +23,7 @@
 #define CSSStyleRule_h
 
 #include "core/css/CSSRule.h"
+#include "core/css/cssom/StylePropertyMap.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
@@ -50,6 +51,10 @@
 
   CSSStyleDeclaration* style() const;
 
+  StylePropertyMap* attributeStyleMap() const {
+    return attribute_style_map_.Get();
+  }
+
   // FIXME: Not CSSOM. Remove.
   StyleRule* GetStyleRule() const { return style_rule_.Get(); }
 
@@ -62,6 +67,7 @@
 
   Member<StyleRule> style_rule_;
   mutable Member<StyleRuleCSSStyleDeclaration> properties_cssom_wrapper_;
+  Member<StylePropertyMap> attribute_style_map_;
 };
 
 DEFINE_CSS_RULE_TYPE_CASTS(CSSStyleRule, kStyleRule);
diff --git a/third_party/WebKit/Source/core/css/CSSStyleRule.idl b/third_party/WebKit/Source/core/css/CSSStyleRule.idl
index c34647e4..d2373f9 100644
--- a/third_party/WebKit/Source/core/css/CSSStyleRule.idl
+++ b/third_party/WebKit/Source/core/css/CSSStyleRule.idl
@@ -23,4 +23,5 @@
 interface CSSStyleRule : CSSRule {
     [SetterCallWith=ExecutionContext] attribute DOMString selectorText;
     [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
+    [SameObject, RuntimeEnabled=CSSTypedOM] readonly attribute StylePropertyMap attributeStyleMap;
 };
diff --git a/third_party/WebKit/Source/core/css/cssom/DeclaredStylePropertyMap.cpp b/third_party/WebKit/Source/core/css/cssom/DeclaredStylePropertyMap.cpp
new file mode 100644
index 0000000..ca8f417
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/cssom/DeclaredStylePropertyMap.cpp
@@ -0,0 +1,79 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/css/cssom/DeclaredStylePropertyMap.h"
+
+#include "core/css/CSSCustomPropertyDeclaration.h"
+#include "core/css/CSSPropertyValueSet.h"
+
+#include "core/css/CSSStyleRule.h"
+#include "core/css/CSSStyleSheet.h"
+#include "core/css/StyleRule.h"
+
+namespace blink {
+
+DeclaredStylePropertyMap::DeclaredStylePropertyMap(CSSStyleRule* owner_rule)
+    : StylePropertyMap(), owner_rule_(owner_rule) {}
+
+const CSSValue* DeclaredStylePropertyMap::GetProperty(
+    CSSPropertyID property_id) {
+  if (!GetStyleRule())
+    return nullptr;
+  return GetStyleRule()->Properties().GetPropertyCSSValue(property_id);
+}
+
+const CSSValue* DeclaredStylePropertyMap::GetCustomProperty(
+    AtomicString property_name) {
+  if (!GetStyleRule())
+    return nullptr;
+  return GetStyleRule()->Properties().GetPropertyCSSValue(property_name);
+}
+
+void DeclaredStylePropertyMap::SetProperty(CSSPropertyID property_id,
+                                           const CSSValue& value) {
+  if (!GetStyleRule())
+    return;
+  CSSStyleSheet::RuleMutationScope mutation_scope(owner_rule_);
+  GetStyleRule()->MutableProperties().SetProperty(property_id, value);
+}
+
+void DeclaredStylePropertyMap::RemoveProperty(CSSPropertyID property_id) {
+  if (!GetStyleRule())
+    return;
+  CSSStyleSheet::RuleMutationScope mutation_scope(owner_rule_);
+  GetStyleRule()->MutableProperties().RemoveProperty(property_id);
+}
+
+void DeclaredStylePropertyMap::RemoveCustomProperty(
+    const AtomicString& property_name) {
+  if (!GetStyleRule())
+    return;
+  CSSStyleSheet::RuleMutationScope mutation_scope(owner_rule_);
+  GetStyleRule()->MutableProperties().RemoveProperty(property_name);
+}
+
+void DeclaredStylePropertyMap::ForEachProperty(
+    const IterationCallback& callback) {
+  const CSSPropertyValueSet& declared_style_set = GetStyleRule()->Properties();
+  for (unsigned i = 0; i < declared_style_set.PropertyCount(); i++) {
+    const auto& property_reference = declared_style_set.PropertyAt(i);
+    if (property_reference.Id() == CSSPropertyVariable) {
+      const auto& decl =
+          ToCSSCustomPropertyDeclaration(property_reference.Value());
+      callback(decl.GetName(), property_reference.Value());
+    } else {
+      const CSSProperty& property = CSSProperty::Get(property_reference.Id());
+      callback(property.GetPropertyNameAtomicString(),
+               property_reference.Value());
+    }
+  }
+}
+
+StyleRule* DeclaredStylePropertyMap::GetStyleRule() const {
+  if (!owner_rule_)
+    return nullptr;
+  return owner_rule_->GetStyleRule();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/cssom/DeclaredStylePropertyMap.h b/third_party/WebKit/Source/core/css/cssom/DeclaredStylePropertyMap.h
new file mode 100644
index 0000000..4bcf0dcd
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/cssom/DeclaredStylePropertyMap.h
@@ -0,0 +1,50 @@
+// Copyright 2017 the Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DeclaredStylePropertyMap_h
+#define DeclaredStylePropertyMap_h
+
+#include "core/css/cssom/StylePropertyMap.h"
+
+namespace blink {
+
+class CSSStyleRule;
+class StyleRule;
+
+// This class implements declared StylePropertMap in the Typed CSSOM
+// API. The specification is here:
+// https://drafts.css-houdini.org/css-typed-om-1/#declared-stylepropertymap-objects
+//
+// The declared StylePropertyMap retrieves styles specified by a CSS style rule
+// and returns them as CSSStyleValues. The IDL for this class is in
+// StylePropertyMap.idl. The declared StylePropertyMap for an element is
+// accessed via CSSStyleRule.attributeStyleMap (see CSSStyleRule.idl)
+class CORE_EXPORT DeclaredStylePropertyMap final : public StylePropertyMap {
+  WTF_MAKE_NONCOPYABLE(DeclaredStylePropertyMap);
+
+ public:
+  explicit DeclaredStylePropertyMap(CSSStyleRule* owner_rule);
+
+  virtual void Trace(blink::Visitor* visitor) {
+    visitor->Trace(owner_rule_);
+    StylePropertyMap::Trace(visitor);
+  }
+
+ protected:
+  const CSSValue* GetProperty(CSSPropertyID) override;
+  const CSSValue* GetCustomProperty(AtomicString) override;
+  void ForEachProperty(const IterationCallback&) override;
+  void SetProperty(CSSPropertyID, const CSSValue&) override;
+  void RemoveProperty(CSSPropertyID) override;
+  void RemoveCustomProperty(const AtomicString&) override;
+
+ private:
+  StyleRule* GetStyleRule() const;
+
+  WeakMember<CSSStyleRule> owner_rule_;
+};
+
+}  // namespace blink
+
+#endif
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyBaseCustom.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyBaseCustom.cpp
index 1cb663d3..1075e032 100644
--- a/third_party/WebKit/Source/core/css/properties/CSSPropertyBaseCustom.cpp
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyBaseCustom.cpp
@@ -76,29 +76,6 @@
   return *shorthand_properties[kBottomSide];
 }
 
-WTF::String CSSProperty::GetJSPropertyName() const {
-  char result[maxCSSPropertyNameLength + 1];
-  const char* cssPropertyName = GetPropertyName();
-  const char* propertyNamePointer = cssPropertyName;
-  if (!propertyNamePointer)
-    return g_empty_string;
-
-  char* resultPointer = result;
-  while (char character = *propertyNamePointer++) {
-    if (character == '-') {
-      char nextCharacter = *propertyNamePointer++;
-      if (!nextCharacter)
-        break;
-      character = (propertyNamePointer - 2 != cssPropertyName)
-                      ? ToASCIIUpper(nextCharacter)
-                      : nextCharacter;
-    }
-    *resultPointer++ = character;
-  }
-  *resultPointer = '\0';
-  return String(result);
-}
-
 const CSSValue* CSSProperty::CSSValueFromComputedStyle(
     const ComputedStyle& style,
     const LayoutObject* layout_object,
diff --git a/third_party/WebKit/Source/core/exported/WebElement.cpp b/third_party/WebKit/Source/core/exported/WebElement.cpp
index 465c458..e3e0f6b6 100644
--- a/third_party/WebKit/Source/core/exported/WebElement.cpp
+++ b/third_party/WebKit/Source/core/exported/WebElement.cpp
@@ -137,7 +137,7 @@
   if (IsNull())
     return WebImage();
 
-  return WebImage(Unwrap<Element>()->ImageContents());
+  return WebImage(Unwrap<Element>()->ImageContents(), kRespectImageOrientation);
 }
 
 WebElement::WebElement(Element* elem) : WebNode(elem) {}
diff --git a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
index 568d1cc..10b8f14 100644
--- a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
@@ -7740,6 +7740,62 @@
   EXPECT_EQ(bitmap.getColor(0, 0), SK_ColorBLUE);
 }
 
+TEST_P(ParameterizedWebFrameTest, WebNodeImageContentsWithOrientation) {
+  FrameTestHelpers::WebViewHelper web_view_helper;
+  web_view_helper.InitializeAndLoad("about:blank");
+  WebLocalFrame* frame = web_view_helper.LocalMainFrame();
+
+  // 4x8 jpg with orientation = 6 ( 90 degree CW rotation ).
+  // w - white, b - blue.
+  //   raw      =>       oriented
+  // w w w w          b b b b w w w w
+  // w w w w          b b b b w w w w
+  // w w w w          b b b b w w w w
+  // w w w w          b b b b w w w w
+  // b b b b
+  // b b b b
+  // b b b b
+  // b b b b
+  static const char kBlueJPGWithOrientation[] =
+      "<img "
+      "src=\"data:image/"
+      "jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QBiRXhpZgAATU0AKgAAAAgABQESAAM"
+      "AAAABAAYAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAAITAAMAAAABAA"
+      "EAAAAAAAAAAABgAAAAAQAAAGAAAAAB/9sAQwACAQECAQECAgICAgICAgMFAwMDAwMGBAQDB"
+      "QcGBwcHBgcHCAkLCQgICggHBwoNCgoLDAwMDAcJDg8NDA4LDAwM/9sAQwECAgIDAwMGAwMG"
+      "DAgHCAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw"
+      "M/8AAEQgACAAEAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC/"
+      "/EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJ"
+      "DNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3"
+      "eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tf"
+      "Y2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCA"
+      "kKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM"
+      "1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpz"
+      "dHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytL"
+      "T1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A7j/iMz/6tv8A/Mgf/e"
+    "2iiiv9ff8AiVzwx/6Fn/lbEf8Ay0+A/tvG/wA/4L/I/9k=\">";
+
+  // Load up the image and test that we can extract the contents.
+  KURL test_url = ToKURL("about:blank");
+  FrameTestHelpers::LoadHTMLString(frame, kBlueJPGWithOrientation, test_url);
+
+  WebNode node = frame->GetDocument().Body().FirstChild();
+  EXPECT_TRUE(node.IsElementNode());
+  WebElement element = node.To<WebElement>();
+
+  WebImage image_with_orientation = element.ImageContents();
+  ASSERT_FALSE(image_with_orientation.IsNull());
+  EXPECT_EQ(image_with_orientation.Size().width, 8);
+  EXPECT_EQ(image_with_orientation.Size().height, 4);
+  SkBitmap oriented_bitmap = image_with_orientation.GetSkBitmap();
+  // Should be almost blue.
+  SkColor oriented_color = oriented_bitmap.getColor(0, 0);
+  EXPECT_NEAR(SkColorGetR(oriented_color), SkColorGetR(SK_ColorBLUE), 5);
+  EXPECT_NEAR(SkColorGetG(oriented_color), SkColorGetG(SK_ColorBLUE), 5);
+  EXPECT_NEAR(SkColorGetB(oriented_color), SkColorGetB(SK_ColorBLUE), 5);
+  EXPECT_NEAR(SkColorGetA(oriented_color), SkColorGetA(SK_ColorBLUE), 5);
+}
+
 class TestStartStopCallbackWebFrameClient
     : public FrameTestHelpers::TestWebFrameClient {
  public:
diff --git a/third_party/WebKit/Source/core/fetch/Request.cpp b/third_party/WebKit/Source/core/fetch/Request.cpp
index 5bfdf49..1756073 100644
--- a/third_party/WebKit/Source/core/fetch/Request.cpp
+++ b/third_party/WebKit/Source/core/fetch/Request.cpp
@@ -186,22 +186,23 @@
                                        "' is not a valid URL.");
         return nullptr;
       }
-      if (parsed_referrer.ProtocolIsAbout() &&
-          parsed_referrer.Host().IsEmpty() &&
-          parsed_referrer.GetPath() == "client") {
-        // "If |parsedReferrer|'s non-relative flag is set, scheme is
-        // "about", and path contains a single string "client", set
-        // request's referrer to "client" and terminate these
-        // substeps."
+      if ((parsed_referrer.ProtocolIsAbout() &&
+           parsed_referrer.Host().IsEmpty() &&
+           parsed_referrer.GetPath() == "client") ||
+          !origin->IsSameSchemeHostPortAndSuborigin(
+              SecurityOrigin::Create(parsed_referrer).get())) {
+        // If |parsedReferrer|'s host is empty
+        // it's cannot-be-a-base-URL flag must be set
+
+        // "If one of the following conditions is true, then set
+        // request’s referrer to "client":
+        //
+        //     |parsedReferrer|’s cannot-be-a-base-URL flag is set,
+        //     scheme is "about", and path contains a single string "client".
+        //
+        //     parsedReferrer’s origin is not same origin with origin"
+        //
         request->SetReferrerString(FetchRequestData::ClientReferrerString());
-      } else if (!origin->IsSameSchemeHostPortAndSuborigin(
-                     SecurityOrigin::Create(parsed_referrer).get())) {
-        // "If |parsedReferrer|'s origin is not same origin with
-        // |origin|, throw a TypeError."
-        exception_state.ThrowTypeError(
-            "The origin of '" + init.GetReferrer().referrer +
-            "' should be same as '" + origin->ToString() + "'");
-        return nullptr;
       } else {
         // "Set |request|'s referrer to |parsedReferrer|."
         request->SetReferrerString(AtomicString(parsed_referrer.GetString()));
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
index 406b1f6..940405d0 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
@@ -1409,10 +1409,7 @@
   if (full_remove_insert && IsLayoutBlock() && child->IsBox())
     ToLayoutBox(child)->RemoveFromPercentHeightContainer();
 
-  if (full_remove_insert && (to_box_model_object->IsLayoutBlock() ||
-                             to_box_model_object->IsLayoutInline())) {
-    // Takes care of adding the new child correctly if toBlock and fromBlock
-    // have different kind of children (block vs inline).
+  if (full_remove_insert) {
     to_box_model_object->AddChild(
         VirtualChildren()->RemoveChildNode(this, child), before_child);
   } else {
@@ -1473,4 +1470,57 @@
   return true;
 }
 
+void LayoutBoxModelObject::MoveNonAnonymousTableDescendantsTo(
+    LayoutBoxModelObject* to_box_model_object) {
+  LayoutObject* child = SlowFirstChild();
+  DCHECK(IsAnonymous());
+  // Append non-anonymous descendants' sub-trees of one anonymous table part to
+  // another. We walk down past anonymous descendants to make sure existing
+  // anonymous table part chains in to_box_model_object are used.
+  while (child) {
+    LayoutObject* next_child = child->NextSibling();
+    if (child->IsAnonymous() && child->IsTablePart()) {
+      ToLayoutBoxModelObject(child)->MoveNonAnonymousTableDescendantsTo(
+          to_box_model_object);
+      child->Destroy();
+    } else {
+      MoveChildTo(to_box_model_object, child, true);
+      // If we move a subtree rooted at a table section or row, we need to mark
+      // the section for cell recalc in case there is a cell descendant.
+      // Normally, boxes in a subtree will be added one by one, and AddChild in
+      // LayoutTableRow will make sure cells are added with AddCell or the table
+      // section marked for cell recalc. Since the cell is just moved along with
+      // its subtree here, we need to mark the section for recalc.
+      if (child->IsTableSection())
+        ToLayoutTableSection(child)->SetNeedsCellRecalc();
+      else if (child->IsTableRow())
+        ToLayoutTableRow(child)->Section()->SetNeedsCellRecalc();
+    }
+    child = next_child;
+  }
+}
+
+void LayoutBoxModelObject::MergeAnonymousTablePartsIfNeeded(
+    LayoutBoxModelObject* prev,
+    LayoutBoxModelObject* next) {
+  if (!prev || !next || !prev->IsAnonymous() || !next->IsAnonymous())
+    return;
+  DCHECK(prev->IsInline() == next->IsInline());
+  next->MoveNonAnonymousTableDescendantsTo(prev);
+  next->Destroy();
+}
+
+void LayoutBoxModelObject::RemoveChild(LayoutObject* old_child) {
+  LayoutObject* prev = old_child->PreviousSibling();
+  LayoutObject* next = old_child->NextSibling();
+
+  LayoutObject::RemoveChild(old_child);
+
+  if (DocumentBeingDestroyed())
+    return;
+
+  if (prev && next && prev->IsTable() && next->IsTable())
+    MergeAnonymousTablePartsIfNeeded(ToLayoutTable(prev), ToLayoutTable(next));
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
index f439e1e5..a7992f80 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.h
@@ -435,6 +435,8 @@
   void AbsoluteQuads(Vector<FloatQuad>& quads,
                      MapCoordinatesFlags mode = 0) const override;
 
+  void RemoveChild(LayoutObject*) override;
+
  protected:
   // Compute absolute quads for |this|, but not any continuations. May only be
   // called for objects which can be or have continuations, i.e. LayoutInline or
@@ -494,6 +496,9 @@
 
   void InvalidateStickyConstraints();
 
+  void MergeAnonymousTablePartsIfNeeded(LayoutBoxModelObject* prev,
+                                        LayoutBoxModelObject* next);
+
  public:
   // These functions are only used internally to manipulate the layout tree
   // structure via remove/insert/appendChildNode.
@@ -566,6 +571,8 @@
         &LayoutBoxModelObject::BorderTop, &LayoutBoxModelObject::BorderRight,
         &LayoutBoxModelObject::BorderBottom, &LayoutBoxModelObject::BorderLeft);
   }
+
+  void MoveNonAnonymousTableDescendantsTo(LayoutBoxModelObject*);
 };
 
 DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutBoxModelObject, IsBoxModelObject());
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index 4e9364fa..0564885 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -233,6 +233,18 @@
   section->AddChild(child);
 }
 
+void LayoutTable::RemoveChild(LayoutObject* old_child) {
+  if (!DocumentBeingDestroyed()) {
+    LayoutObject* prev = old_child->PreviousSibling();
+    LayoutObject* next = old_child->NextSibling();
+    if (prev && next && prev->IsTableSection() && next->IsTableSection()) {
+      MergeAnonymousTablePartsIfNeeded(ToLayoutTableSection(prev),
+                                       ToLayoutTableSection(next));
+    }
+  }
+  LayoutBlock::RemoveChild(old_child);
+}
+
 void LayoutTable::AddCaption(const LayoutTableCaption* caption) {
   DCHECK_EQ(captions_.Find(caption), kNotFound);
   captions_.push_back(const_cast<LayoutTableCaption*>(caption));
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.h b/third_party/WebKit/Source/core/layout/LayoutTable.h
index e58b798..3825db6 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.h
@@ -500,6 +500,8 @@
 
   void SetIsAnyColumnEverCollapsed() { is_any_column_ever_collapsed_ = true; }
 
+  void RemoveChild(LayoutObject*) final;
+
   // TODO(layout-dev): All mutables in this class are lazily updated by
   // recalcSections() which is called by various getter methods (e.g.
   // borderBefore(), borderAfter()).
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp b/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
index a9abe265..bba091c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableRow.cpp
@@ -184,6 +184,16 @@
     Section()->SetNeedsCellRecalc();
 }
 
+void LayoutTableRow::RemoveChild(LayoutObject* old_child) {
+  if (!DocumentBeingDestroyed()) {
+    LayoutTableCell* prev_cell =
+        ToLayoutTableCell(old_child->PreviousSibling());
+    LayoutTableCell* next_cell = ToLayoutTableCell(old_child->NextSibling());
+    MergeAnonymousTablePartsIfNeeded(prev_cell, next_cell);
+  }
+  LayoutTableBoxComponent::RemoveChild(old_child);
+}
+
 void LayoutTableRow::UpdateLayout() {
   DCHECK(NeedsLayout());
   LayoutAnalyzer::Scope analyzer(*this);
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableRow.h b/third_party/WebKit/Source/core/layout/LayoutTableRow.h
index 201e457a..254781b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableRow.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTableRow.h
@@ -154,6 +154,7 @@
 
   void NextSibling() const = delete;
   void PreviousSibling() const = delete;
+  void RemoveChild(LayoutObject*) final;
 
   // This field should never be read directly. It should be read through
   // rowIndex() above instead. This is to ensure that we never read this
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
index 2bab6b5..0749d1e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
@@ -202,6 +202,15 @@
   LayoutTableBoxComponent::AddChild(child, before_child);
 }
 
+void LayoutTableSection::RemoveChild(LayoutObject* old_child) {
+  if (!DocumentBeingDestroyed()) {
+    MergeAnonymousTablePartsIfNeeded(
+        ToLayoutTableRow(old_child->PreviousSibling()),
+        ToLayoutTableRow(old_child->NextSibling()));
+  }
+  LayoutTableBoxComponent::RemoveChild(old_child);
+}
+
 static inline void CheckThatVectorIsDOMOrdered(
     const Vector<LayoutTableCell*, 1>& cells) {
 #ifndef NDEBUG
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.h b/third_party/WebKit/Source/core/layout/LayoutTableSection.h
index 02e68d1e..c02e90bc 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTableSection.h
+++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.h
@@ -303,7 +303,8 @@
     return type == kLayoutObjectTableSection || LayoutBox::IsOfType(type);
   }
 
-  void WillBeRemovedFromTree() override;
+  void WillBeRemovedFromTree() final;
+  void RemoveChild(LayoutObject*) final;
 
   int BorderSpacingForRow(unsigned row) const {
     return grid_[row].row ? Table()->VBorderSpacing() : 0;
diff --git a/third_party/WebKit/Source/core/messaging/MessagePort.cpp b/third_party/WebKit/Source/core/messaging/MessagePort.cpp
index d941449..22b848a 100644
--- a/third_party/WebKit/Source/core/messaging/MessagePort.cpp
+++ b/third_party/WebKit/Source/core/messaging/MessagePort.cpp
@@ -89,7 +89,7 @@
     return;
 
   channel_.PostMojoMessage(
-      mojom::blink::TransferableMessage::SerializeAsMessage(&msg));
+      mojom::blink::TransferableMessage::WrapAsMessage(std::move(msg)));
 }
 
 MessagePortChannel MessagePort::Disentangle() {
diff --git a/third_party/WebKit/Source/core/page/DragController.cpp b/third_party/WebKit/Source/core/page/DragController.cpp
index d3f3a309..2d81e5c6 100644
--- a/third_party/WebKit/Source/core/page/DragController.cpp
+++ b/third_party/WebKit/Source/core/page/DragController.cpp
@@ -1146,8 +1146,8 @@
   frame.View()->PaintContents(builder.Context(), paint_flags,
                               EnclosingIntRect(painting_rect));
   return DataTransfer::CreateDragImageForFrame(
-      frame, opacity, kDoNotRespectImageOrientation, painting_rect, builder,
-      PropertyTreeState::Root());
+      frame, opacity, kDoNotRespectImageOrientation, painting_rect.Size(),
+      painting_rect.Location(), builder, PropertyTreeState::Root());
 }
 
 bool DragController::StartDrag(LocalFrame* src,
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
index 8d8c030..08fd81a 100644
--- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -1008,9 +1008,9 @@
       IntRect corner =
           scrollable_area->ResizerCornerRect(bounds, kResizerForTouch);
       // Map corner to top-frame coords.
-      corner = scrollable_area->Box()
-                   .LocalToAbsoluteQuad(FloatRect(corner),
-                                        kTraverseDocumentBoundaries)
+      corner = scrollable_area->GetLayoutBox()
+                   ->LocalToAbsoluteQuad(FloatRect(corner),
+                                         kTraverseDocumentBoundaries)
                    .EnclosingBoundingBox();
       should_handle_scroll_gesture_on_main_thread_region.Unite(corner);
     }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index efe57e8e..94d0502 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -131,7 +131,7 @@
       scroll_anchor_(this),
       non_composited_main_thread_scrolling_reasons_(0),
       has_been_disposed_(false) {
-  Node* node = Box().GetNode();
+  Node* node = GetLayoutBox()->GetNode();
   if (node && node->IsElementNode()) {
     // We save and restore only the scrollOffset as the other scroll values are
     // recalculated.
@@ -155,12 +155,12 @@
 }
 
 void PaintLayerScrollableArea::Dispose() {
-  if (InResizeMode() && !Box().DocumentBeingDestroyed()) {
-    if (LocalFrame* frame = Box().GetFrame())
+  if (InResizeMode() && !GetLayoutBox()->DocumentBeingDestroyed()) {
+    if (LocalFrame* frame = GetLayoutBox()->GetFrame())
       frame->GetEventHandler().ResizeScrollableAreaDestroyed();
   }
 
-  if (LocalFrame* frame = Box().GetFrame()) {
+  if (LocalFrame* frame = GetLayoutBox()->GetFrame()) {
     if (LocalFrameView* frame_view = frame->View()) {
       frame_view->RemoveScrollableArea(this);
       frame_view->RemoveAnimatingScrollableArea(this);
@@ -172,20 +172,20 @@
   if (ScrollingCoordinator* scrolling_coordinator = GetScrollingCoordinator())
     scrolling_coordinator->WillDestroyScrollableArea(this);
 
-  if (!Box().DocumentBeingDestroyed()) {
-    Node* node = Box().GetNode();
+  if (!GetLayoutBox()->DocumentBeingDestroyed()) {
+    Node* node = GetLayoutBox()->GetNode();
     // FIXME: Make setSavedLayerScrollOffset take DoubleSize. crbug.com/414283.
     if (node && node->IsElementNode())
       ToElement(node)->SetSavedLayerScrollOffset(scroll_offset_);
   }
 
-  if (LocalFrame* frame = Box().GetFrame()) {
+  if (LocalFrame* frame = GetLayoutBox()->GetFrame()) {
     if (LocalFrameView* frame_view = frame->View())
-      frame_view->RemoveResizerArea(Box());
+      frame_view->RemoveResizerArea(*GetLayoutBox());
   }
 
-  Box()
-      .GetDocument()
+  GetLayoutBox()
+      ->GetDocument()
       .GetPage()
       ->GlobalRootScrollerController()
       .DidDisposeScrollableArea(*this);
@@ -204,7 +204,7 @@
   // willBeRemovedFromTree,
   // leaving the ScrollAnchor with a stale LayoutObject pointer.
   if (RuntimeEnabledFeatures::ScrollAnchoringEnabled() &&
-      !Box().DocumentBeingDestroyed())
+      !GetLayoutBox()->DocumentBeingDestroyed())
     scroll_anchor_.ClearSelf();
 
   if (SmoothScrollSequencer* sequencer = GetSmoothScrollSequencer())
@@ -220,14 +220,14 @@
 }
 
 PlatformChromeClient* PaintLayerScrollableArea::GetChromeClient() const {
-  if (Page* page = Box().GetFrame()->GetPage())
+  if (Page* page = GetLayoutBox()->GetFrame()->GetPage())
     return &page->GetChromeClient();
   return nullptr;
 }
 
 SmoothScrollSequencer* PaintLayerScrollableArea::GetSmoothScrollSequencer()
     const {
-  if (Page* page = Box().GetFrame()->GetPage())
+  if (Page* page = GetLayoutBox()->GetFrame()->GetPage())
     return page->GetSmoothScrollSequencer();
   return nullptr;
 }
@@ -268,7 +268,7 @@
 }
 
 bool PaintLayerScrollableArea::ShouldUseIntegerScrollOffset() const {
-  Frame* frame = Box().GetFrame();
+  Frame* frame = GetLayoutBox()->GetFrame();
   if (frame->GetSettings() &&
       !frame->GetSettings()->GetPreferCompositingToLCDTextEnabled())
     return true;
@@ -277,7 +277,7 @@
 }
 
 bool PaintLayerScrollableArea::IsActive() const {
-  Page* page = Box().GetFrame()->GetPage();
+  Page* page = GetLayoutBox()->GetFrame()->GetPage();
   return page && page->GetFocusController().IsActive();
 }
 
@@ -314,10 +314,11 @@
     horizontal_thickness = VerticalScrollbar()->ScrollbarThickness();
     vertical_thickness = HorizontalScrollbar()->ScrollbarThickness();
   }
-  return IntRect(
-      CornerStart(Box(), bounds.X(), bounds.MaxX(), horizontal_thickness),
-      bounds.MaxY() - vertical_thickness - Box().StyleRef().BorderBottomWidth(),
-      horizontal_thickness, vertical_thickness);
+  return IntRect(CornerStart(*GetLayoutBox(), bounds.X(), bounds.MaxX(),
+                             horizontal_thickness),
+                 bounds.MaxY() - vertical_thickness -
+                     GetLayoutBox()->StyleRef().BorderBottomWidth(),
+                 horizontal_thickness, vertical_thickness);
 }
 
 IntRect PaintLayerScrollableArea::ScrollCornerRect() const {
@@ -328,11 +329,11 @@
   // (b) Both scrollbars are present.
   bool has_horizontal_bar = HorizontalScrollbar();
   bool has_vertical_bar = VerticalScrollbar();
-  bool has_resizer = Box().Style()->Resize() != EResize::kNone;
+  bool has_resizer = GetLayoutBox()->Style()->Resize() != EResize::kNone;
   if ((has_horizontal_bar && has_vertical_bar) ||
       (has_resizer && (has_horizontal_bar || has_vertical_bar))) {
-    return CornerRect(
-        Box().PixelSnappedBorderBoxRect(Layer()->SubpixelAccumulation()));
+    return CornerRect(GetLayoutBox()->PixelSnappedBorderBoxRect(
+        Layer()->SubpixelAccumulation()));
   }
   return IntRect();
 }
@@ -341,39 +342,39 @@
 PaintLayerScrollableArea::ConvertFromScrollbarToContainingEmbeddedContentView(
     const Scrollbar& scrollbar,
     const IntRect& scrollbar_rect) const {
-  LayoutView* view = Box().View();
+  LayoutView* view = GetLayoutBox()->View();
   if (!view)
     return scrollbar_rect;
 
   IntRect rect = scrollbar_rect;
   rect.Move(ScrollbarOffset(scrollbar));
 
-  return view->GetFrameView()->ConvertFromLayoutObject(Box(), rect);
+  return view->GetFrameView()->ConvertFromLayoutObject(*GetLayoutBox(), rect);
 }
 
 IntPoint
 PaintLayerScrollableArea::ConvertFromScrollbarToContainingEmbeddedContentView(
     const Scrollbar& scrollbar,
     const IntPoint& scrollbar_point) const {
-  LayoutView* view = Box().View();
+  LayoutView* view = GetLayoutBox()->View();
   if (!view)
     return scrollbar_point;
 
   IntPoint point = scrollbar_point;
   point.Move(ScrollbarOffset(scrollbar));
-  return view->GetFrameView()->ConvertFromLayoutObject(Box(), point);
+  return view->GetFrameView()->ConvertFromLayoutObject(*GetLayoutBox(), point);
 }
 
 IntPoint
 PaintLayerScrollableArea::ConvertFromContainingEmbeddedContentViewToScrollbar(
     const Scrollbar& scrollbar,
     const IntPoint& parent_point) const {
-  LayoutView* view = Box().View();
+  LayoutView* view = GetLayoutBox()->View();
   if (!view)
     return parent_point;
 
-  IntPoint point =
-      view->GetFrameView()->ConvertToLayoutObject(Box(), parent_point);
+  IntPoint point = view->GetFrameView()->ConvertToLayoutObject(*GetLayoutBox(),
+                                                               parent_point);
 
   point.Move(-ScrollbarOffset(scrollbar));
   return point;
@@ -381,7 +382,7 @@
 
 IntPoint PaintLayerScrollableArea::ConvertFromRootFrame(
     const IntPoint& point_in_root_frame) const {
-  LayoutView* view = Box().View();
+  LayoutView* view = GetLayoutBox()->View();
   if (!view)
     return point_in_root_frame;
 
@@ -405,14 +406,14 @@
   bool offset_was_zero = scroll_offset_.IsZero();
   scroll_offset_ = new_offset;
 
-  LocalFrame* frame = Box().GetFrame();
+  LocalFrame* frame = GetLayoutBox()->GetFrame();
   DCHECK(frame);
 
-  LocalFrameView* frame_view = Box().GetFrameView();
+  LocalFrameView* frame_view = GetLayoutBox()->GetFrameView();
   bool is_root_layer = Layer()->IsRootLayer();
 
   TRACE_EVENT1("devtools.timeline", "ScrollLayer", "data",
-               InspectorScrollLayerEvent::Data(&Box()));
+               InspectorScrollLayerEvent::Data(GetLayoutBox()));
 
   // FIXME(420741): Resolve circular dependency between scroll offset and
   // compositing state, and remove this disabler.
@@ -431,7 +432,7 @@
     UpdateCompositingLayersAfterScroll();
   }
 
-  Box().DispatchFakeMouseMoveEventSoon(frame->GetEventHandler());
+  GetLayoutBox()->DispatchFakeMouseMoveEventSoon(frame->GetEventHandler());
 
   if (scroll_type == kUserScroll || scroll_type == kCompositorScroll) {
     Page* page = frame->GetPage();
@@ -447,16 +448,19 @@
   if (!RuntimeEnabledFeatures::RootLayerScrollingEnabled() && is_root_layer) {
     frame_view->SetNeedsPaintPropertyUpdate();
   } else {
-    Box().SetNeedsPaintPropertyUpdate();
+    GetLayoutBox()->SetNeedsPaintPropertyUpdate();
   }
 
   // Schedule the scroll DOM event.
-  if (Box().GetNode())
-    Box().GetNode()->GetDocument().EnqueueScrollEventForNode(Box().GetNode());
+  if (GetLayoutBox()->GetNode()) {
+    GetLayoutBox()->GetNode()->GetDocument().EnqueueScrollEventForNode(
+        GetLayoutBox()->GetNode());
+  }
 
-  if (AXObjectCache* cache = Box().GetDocument().ExistingAXObjectCache())
-    cache->HandleScrollPositionChanged(&Box());
-  Box().View()->ClearHitTestCache();
+  if (AXObjectCache* cache =
+          GetLayoutBox()->GetDocument().ExistingAXObjectCache())
+    cache->HandleScrollPositionChanged(GetLayoutBox());
+  GetLayoutBox()->View()->ClearHitTestCache();
 
   // Inform the FrameLoader of the new scroll position, so it can be restored
   // when navigating back.
@@ -485,9 +489,10 @@
     // change position due to scroll so a paint invalidation is needed.
     // TODO(pdr): This invalidation can be removed if the local background
     // attachment is painted into the scrolling contents.
-    if (ScrollsOverflow() && Box().Style()->BackgroundLayers().Attachment() ==
-                                 EFillAttachment::kLocal) {
-      Box().SetShouldDoFullPaintInvalidation();
+    if (ScrollsOverflow() &&
+        GetLayoutBox()->Style()->BackgroundLayers().Attachment() ==
+            EFillAttachment::kLocal) {
+      GetLayoutBox()->SetShouldDoFullPaintInvalidation();
       return;
     }
 
@@ -517,12 +522,12 @@
 
   bool requires_paint_invalidation = true;
 
-  LocalFrameView* frame_view = Box().GetFrameView();
+  LocalFrameView* frame_view = GetLayoutBox()->GetFrameView();
   bool is_root_layer = Layer()->IsRootLayer();
-  if (Box().View()->Compositor()->InCompositingMode()) {
+  if (GetLayoutBox()->View()->Compositor()->InCompositingMode()) {
     bool only_scrolled_composited_layers =
         ScrollsOverflow() && Layer()->IsAllScrollingContentComposited() &&
-        Box().Style()->BackgroundLayers().Attachment() !=
+        GetLayoutBox()->Style()->BackgroundLayers().Attachment() !=
             EFillAttachment::kLocal;
 
     if (UsesCompositedScrolling() || only_scrolled_composited_layers)
@@ -539,8 +544,10 @@
     InvalidatePaintForStickyDescendants();
   }
 
-  if (requires_paint_invalidation)
-    Box().SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
+  if (requires_paint_invalidation) {
+    GetLayoutBox()
+        ->SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
+  }
 }
 
 IntSize PaintLayerScrollableArea::ScrollOffsetInt() const {
@@ -556,7 +563,7 @@
 }
 
 IntSize PaintLayerScrollableArea::MaximumScrollOffsetInt() const {
-  if (!Box().HasOverflowClip())
+  if (!GetLayoutBox()->HasOverflowClip())
     return ToIntSize(-ScrollOrigin());
 
   IntSize content_size = ContentsSize();
@@ -574,9 +581,9 @@
     visible_size = controller.RootScrollerVisibleArea();
   } else {
     visible_size =
-        PixelSnappedIntRect(
-            Box().OverflowClipRect(Box().Location(),
-                                   kIgnorePlatformAndCSSOverlayScrollbarSize))
+        PixelSnappedIntRect(GetLayoutBox()->OverflowClipRect(
+                                GetLayoutBox()->Location(),
+                                kIgnorePlatformAndCSSOverlayScrollbarSize))
             .Size();
   }
 
@@ -596,8 +603,8 @@
     IncludeScrollbarsInRect scrollbar_inclusion) const {
   // LayoutContentRect is conceptually the same as the box's client rect.
   LayoutSize layer_size(Layer()->Size());
-  LayoutUnit border_width = Box().BorderWidth();
-  LayoutUnit border_height = Box().BorderHeight();
+  LayoutUnit border_width = GetLayoutBox()->BorderWidth();
+  LayoutUnit border_height = GetLayoutBox()->BorderHeight();
   LayoutUnit horizontal_scrollbar_height, vertical_scrollbar_width;
   if (scrollbar_inclusion == kExcludeScrollbars) {
     horizontal_scrollbar_height = LayoutUnit(
@@ -623,9 +630,9 @@
   LayoutRect layout_content_rect(LayoutContentRect(scrollbar_inclusion));
   // TODO(szager): It's not clear that Floor() is the right thing to do here;
   // what is the correct behavior for fractional scroll offsets?
-  return IntRect(
-      FlooredIntPoint(layout_content_rect.Location()),
-      PixelSnappedIntSize(layout_content_rect.Size(), Box().Location()));
+  return IntRect(FlooredIntPoint(layout_content_rect.Location()),
+                 PixelSnappedIntSize(layout_content_rect.Size(),
+                                     GetLayoutBox()->Location()));
 }
 
 IntSize PaintLayerScrollableArea::ContentsSize() const {
@@ -635,7 +642,7 @@
 void PaintLayerScrollableArea::ContentsResized() {
   ScrollableArea::ContentsResized();
   // Need to update the bounds of the scroll property.
-  Box().SetNeedsPaintPropertyUpdate();
+  GetLayoutBox()->SetNeedsPaintPropertyUpdate();
 }
 
 bool PaintLayerScrollableArea::IsScrollable() const {
@@ -643,19 +650,21 @@
 }
 
 IntPoint PaintLayerScrollableArea::LastKnownMousePosition() const {
-  return Box().GetFrame()
-             ? Box().GetFrame()->GetEventHandler().LastKnownMousePosition()
-             : IntPoint();
+  return GetLayoutBox()->GetFrame() ? GetLayoutBox()
+                                          ->GetFrame()
+                                          ->GetEventHandler()
+                                          .LastKnownMousePosition()
+                                    : IntPoint();
 }
 
 bool PaintLayerScrollableArea::ScrollAnimatorEnabled() const {
-  if (Settings* settings = Box().GetFrame()->GetSettings())
+  if (Settings* settings = GetLayoutBox()->GetFrame()->GetSettings())
     return settings->GetScrollAnimatorEnabled();
   return false;
 }
 
 bool PaintLayerScrollableArea::ShouldSuspendScrollAnimations() const {
-  LayoutView* view = Box().View();
+  LayoutView* view = GetLayoutBox()->View();
   if (!view)
     return true;
   return view->GetFrameView()->ShouldSuspendScrollAnimations();
@@ -666,36 +675,36 @@
 
   layer_.ClearClipRects();
 
-  if (LayoutView* view = Box().View())
+  if (LayoutView* view = GetLayoutBox()->View())
     view->ClearHitTestCache();
 }
 
 void PaintLayerScrollableArea::ScrollbarFrameRectChanged() {
   // Size of non-overlay scrollbar affects overflow clip rect.
   if (!HasOverlayScrollbars())
-    Box().SetNeedsPaintPropertyUpdate();
+    GetLayoutBox()->SetNeedsPaintPropertyUpdate();
 }
 
 bool PaintLayerScrollableArea::ScrollbarsCanBeActive() const {
-  LayoutView* view = Box().View();
+  LayoutView* view = GetLayoutBox()->View();
   if (!view)
     return false;
   return view->GetFrameView()->ScrollbarsCanBeActive();
 }
 
 IntRect PaintLayerScrollableArea::ScrollableAreaBoundingBox() const {
-  return Box().AbsoluteBoundingBoxRect(kTraverseDocumentBoundaries);
+  return GetLayoutBox()->AbsoluteBoundingBoxRect(kTraverseDocumentBoundaries);
 }
 
 void PaintLayerScrollableArea::RegisterForAnimation() {
-  if (LocalFrame* frame = Box().GetFrame()) {
+  if (LocalFrame* frame = GetLayoutBox()->GetFrame()) {
     if (LocalFrameView* frame_view = frame->View())
       frame_view->AddAnimatingScrollableArea(this);
   }
 }
 
 void PaintLayerScrollableArea::DeregisterForAnimation() {
-  if (LocalFrame* frame = Box().GetFrame()) {
+  if (LocalFrame* frame = GetLayoutBox()->GetFrame()) {
     if (LocalFrameView* frame_view = frame->View())
       frame_view->RemoveAnimatingScrollableArea(this);
   }
@@ -703,33 +712,33 @@
 
 bool PaintLayerScrollableArea::UserInputScrollable(
     ScrollbarOrientation orientation) const {
-  if (Box().IsIntrinsicallyScrollable(orientation))
+  if (GetLayoutBox()->IsIntrinsicallyScrollable(orientation))
     return true;
 
-  if (Box().IsLayoutView()) {
-    Document& document = Box().GetDocument();
+  if (GetLayoutBox()->IsLayoutView()) {
+    Document& document = GetLayoutBox()->GetDocument();
     Element* fullscreen_element = Fullscreen::FullscreenElementFrom(document);
     if (fullscreen_element && fullscreen_element != document.documentElement())
       return false;
 
     ScrollbarMode h_mode;
     ScrollbarMode v_mode;
-    ToLayoutView(Box()).CalculateScrollbarModes(h_mode, v_mode);
+    ToLayoutView(GetLayoutBox())->CalculateScrollbarModes(h_mode, v_mode);
     ScrollbarMode mode =
         (orientation == kHorizontalScrollbar) ? h_mode : v_mode;
     return mode == kScrollbarAuto || mode == kScrollbarAlwaysOn;
   }
 
   EOverflow overflow_style = (orientation == kHorizontalScrollbar)
-                                 ? Box().Style()->OverflowX()
-                                 : Box().Style()->OverflowY();
+                                 ? GetLayoutBox()->Style()->OverflowX()
+                                 : GetLayoutBox()->Style()->OverflowY();
   return (overflow_style == EOverflow::kScroll ||
           overflow_style == EOverflow::kAuto ||
           overflow_style == EOverflow::kOverlay);
 }
 
 bool PaintLayerScrollableArea::ShouldPlaceVerticalScrollbarOnLeft() const {
-  return Box().ShouldPlaceBlockDirectionScrollbarOnLogicalLeft();
+  return GetLayoutBox()->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft();
 }
 
 int PaintLayerScrollableArea::PageStep(ScrollbarOrientation orientation) const {
@@ -742,8 +751,8 @@
   return max(page_step, 1);
 }
 
-LayoutBox& PaintLayerScrollableArea::Box() const {
-  return *layer_.GetLayoutBox();
+LayoutBox* PaintLayerScrollableArea::GetLayoutBox() const {
+  return layer_.GetLayoutBox();
 }
 
 PaintLayer* PaintLayerScrollableArea::Layer() const {
@@ -759,13 +768,13 @@
 }
 
 int PaintLayerScrollableArea::PixelSnappedScrollWidth() const {
-  return SnapSizeToPixel(ScrollWidth(),
-                         Box().ClientLeft() + Box().Location().X());
+  return SnapSizeToPixel(ScrollWidth(), GetLayoutBox()->ClientLeft() +
+                                            GetLayoutBox()->Location().X());
 }
 
 int PaintLayerScrollableArea::PixelSnappedScrollHeight() const {
-  return SnapSizeToPixel(ScrollHeight(),
-                         Box().ClientTop() + Box().Location().Y());
+  return SnapSizeToPixel(ScrollHeight(), GetLayoutBox()->ClientTop() +
+                                             GetLayoutBox()->Location().Y());
 }
 
 void PaintLayerScrollableArea::UpdateScrollOrigin() {
@@ -774,16 +783,17 @@
   if (OverflowRect().IsEmpty())
     return;
   LayoutRect scrollable_overflow(overflow_rect_);
-  scrollable_overflow.Move(-Box().BorderLeft(), -Box().BorderTop());
+  scrollable_overflow.Move(-GetLayoutBox()->BorderLeft(),
+                           -GetLayoutBox()->BorderTop());
   SetScrollOrigin(-scrollable_overflow.PixelSnappedLocation() +
-                  Box().OriginAdjustmentForScrollbars());
+                  GetLayoutBox()->OriginAdjustmentForScrollbars());
 }
 
 void PaintLayerScrollableArea::UpdateScrollDimensions() {
-  if (overflow_rect_.Size() != Box().LayoutOverflowRect().Size())
+  if (overflow_rect_.Size() != GetLayoutBox()->LayoutOverflowRect().Size())
     ContentsResized();
-  overflow_rect_ = Box().LayoutOverflowRect();
-  Box().FlipForWritingMode(overflow_rect_);
+  overflow_rect_ = GetLayoutBox()->LayoutOverflowRect();
+  GetLayoutBox()->FlipForWritingMode(overflow_rect_);
   UpdateScrollOrigin();
 }
 
@@ -863,49 +873,51 @@
     Layer()->UpdateSelfPaintingLayer();
 
     // Force an update since we know the scrollbars have changed things.
-    if (Box().GetDocument().HasAnnotatedRegions())
-      Box().GetDocument().SetAnnotatedRegionsDirty(true);
+    if (GetLayoutBox()->GetDocument().HasAnnotatedRegions())
+      GetLayoutBox()->GetDocument().SetAnnotatedRegionsDirty(true);
 
     // Our proprietary overflow: overlay value doesn't trigger a layout.
     // If the box is managed by LayoutNG, don't go here. We don't want to
     // re-enter the NG layout algorithm for this box from here.
     if (((horizontal_scrollbar_should_change &&
-          Box().Style()->OverflowX() != EOverflow::kOverlay) ||
+          GetLayoutBox()->Style()->OverflowX() != EOverflow::kOverlay) ||
          (vertical_scrollbar_should_change &&
-          Box().Style()->OverflowY() != EOverflow::kOverlay)) &&
-        !IsManagedByLayoutNG(Box())) {
+          GetLayoutBox()->Style()->OverflowY() != EOverflow::kOverlay)) &&
+        !IsManagedByLayoutNG(*GetLayoutBox())) {
       if ((vertical_scrollbar_should_change &&
-           Box().IsHorizontalWritingMode()) ||
+           GetLayoutBox()->IsHorizontalWritingMode()) ||
           (horizontal_scrollbar_should_change &&
-           !Box().IsHorizontalWritingMode())) {
-        Box().SetPreferredLogicalWidthsDirty();
+           !GetLayoutBox()->IsHorizontalWritingMode())) {
+        GetLayoutBox()->SetPreferredLogicalWidthsDirty();
       }
       if (PreventRelayoutScope::RelayoutIsPrevented()) {
         // We're not doing re-layout right now, but we still want to
         // add the scrollbar to the logical width now, to facilitate parent
         // layout.
-        Box().UpdateLogicalWidth();
+        GetLayoutBox()->UpdateLogicalWidth();
         PreventRelayoutScope::SetBoxNeedsLayout(*this, had_horizontal_scrollbar,
                                                 had_vertical_scrollbar);
       } else {
         in_overflow_relayout_ = true;
-        SubtreeLayoutScope layout_scope(Box());
+        SubtreeLayoutScope layout_scope(*GetLayoutBox());
         layout_scope.SetNeedsLayout(
-            &Box(), LayoutInvalidationReason::kScrollbarChanged);
-        if (Box().IsLayoutBlock()) {
-          LayoutBlock& block = ToLayoutBlock(Box());
-          block.ScrollbarsChanged(horizontal_scrollbar_should_change,
-                                  vertical_scrollbar_should_change);
-          block.UpdateBlockLayout(true);
+            GetLayoutBox(), LayoutInvalidationReason::kScrollbarChanged);
+        if (GetLayoutBox()->IsLayoutBlock()) {
+          LayoutBlock* block = ToLayoutBlock(GetLayoutBox());
+          block->ScrollbarsChanged(horizontal_scrollbar_should_change,
+                                   vertical_scrollbar_should_change);
+          block->UpdateBlockLayout(true);
         } else {
-          Box().UpdateLayout();
+          GetLayoutBox()->UpdateLayout();
         }
         in_overflow_relayout_ = false;
         scrollbar_manager_.DestroyDetachedScrollbars();
       }
-      LayoutObject* parent = Box().Parent();
-      if (parent && parent->IsFlexibleBox())
-        ToLayoutFlexibleBox(parent)->ClearCachedMainSizeForChild(Box());
+      LayoutObject* parent = GetLayoutBox()->Parent();
+      if (parent && parent->IsFlexibleBox()) {
+        ToLayoutFlexibleBox(parent)->ClearCachedMainSizeForChild(
+            *GetLayoutBox());
+      }
     }
   }
 
@@ -962,17 +974,17 @@
   // Being the global root scroller will affect clipping size due to browser
   // controls behavior so we need to update compositing based on updated clip
   // geometry.
-  if (Box().GetNode()->IsElementNode()) {
-    ToElement(Box().GetNode())->SetNeedsCompositingUpdate();
-    Box().SetNeedsPaintPropertyUpdate();
+  if (GetLayoutBox()->GetNode()->IsElementNode()) {
+    ToElement(GetLayoutBox()->GetNode())->SetNeedsCompositingUpdate();
+    GetLayoutBox()->SetNeedsPaintPropertyUpdate();
   }
 
   // On Android, where the VisualViewport supplies scrollbars, we need to
   // remove the PLSA's scrollbars if we become the global root scroller.
   // In general, this would be problematic as that can cause layout but this
   // should only ever apply with overlay scrollbars.
-  if (Box().GetFrame()->GetSettings() &&
-      Box().GetFrame()->GetSettings()->GetViewportEnabled()) {
+  if (GetLayoutBox()->GetFrame()->GetSettings() &&
+      GetLayoutBox()->GetFrame()->GetSettings()->GetViewportEnabled()) {
     bool needs_horizontal_scrollbar;
     bool needs_vertical_scrollbar;
     ComputeScrollbarExistence(needs_horizontal_scrollbar,
@@ -986,7 +998,7 @@
   return RuntimeEnabledFeatures::ScrollAnchoringEnabled() &&
          scroll_anchor_.HasScroller() &&
          GetLayoutBox()->Style()->OverflowAnchor() != EOverflowAnchor::kNone &&
-         !Box().GetDocument().FinishingOrIsPrinting();
+         !GetLayoutBox()->GetDocument().FinishingOrIsPrinting();
 }
 
 FloatQuad PaintLayerScrollableArea::LocalToVisibleContentQuad(
@@ -1002,11 +1014,11 @@
 
 scoped_refptr<WebTaskRunner> PaintLayerScrollableArea::GetTimerTaskRunner()
     const {
-  return Box().GetFrame()->GetTaskRunner(TaskType::kUnspecedTimer);
+  return GetLayoutBox()->GetFrame()->GetTaskRunner(TaskType::kUnspecedTimer);
 }
 
 ScrollBehavior PaintLayerScrollableArea::ScrollBehaviorStyle() const {
-  return Box().Style()->GetScrollBehavior();
+  return GetLayoutBox()->Style()->GetScrollBehavior();
 }
 
 bool PaintLayerScrollableArea::HasHorizontalOverflow() const {
@@ -1024,7 +1036,7 @@
   if (NeedsRelayout() && !HadVerticalScrollbarBeforeRelayout())
     client_width += VerticalScrollbarWidth();
   LayoutUnit scroll_width(ScrollWidth());
-  LayoutUnit box_x = Box().Location().X();
+  LayoutUnit box_x = GetLayoutBox()->Location().X();
   return SnapSizeToPixel(scroll_width, box_x) >
          SnapSizeToPixel(client_width, box_x);
 }
@@ -1034,7 +1046,7 @@
       LayoutContentRect(kIncludeScrollbars).Height() -
       HorizontalScrollbarHeight(kIgnorePlatformAndCSSOverlayScrollbarSize);
   LayoutUnit scroll_height(ScrollHeight());
-  LayoutUnit box_y = Box().Location().Y();
+  LayoutUnit box_y = GetLayoutBox()->Location().Y();
   return SnapSizeToPixel(scroll_height, box_y) >
          SnapSizeToPixel(client_height, box_y);
 }
@@ -1067,8 +1079,8 @@
     old_background =
         old_style->VisitedDependentColor(GetCSSPropertyBackgroundColor());
   }
-  Color new_background =
-      Box().Style()->VisitedDependentColor(GetCSSPropertyBackgroundColor());
+  Color new_background = GetLayoutBox()->Style()->VisitedDependentColor(
+      GetCSSPropertyBackgroundColor());
 
   if (new_background != old_background) {
     RecalculateScrollbarOverlayColorTheme(new_background);
@@ -1090,24 +1102,25 @@
   bool vertical_scrollbar_changed =
       SetHasVerticalScrollbar(needs_vertical_scrollbar);
 
-  if (Box().IsLayoutBlock() &&
+  if (GetLayoutBox()->IsLayoutBlock() &&
       (horizontal_scrollbar_changed || vertical_scrollbar_changed)) {
-    ToLayoutBlock(Box()).ScrollbarsChanged(
-        horizontal_scrollbar_changed, vertical_scrollbar_changed,
-        LayoutBlock::ScrollbarChangeContext::kStyleChange);
+    ToLayoutBlock(GetLayoutBox())
+        ->ScrollbarsChanged(horizontal_scrollbar_changed,
+                            vertical_scrollbar_changed,
+                            LayoutBlock::ScrollbarChangeContext::kStyleChange);
   }
 
   // With overflow: scroll, scrollbars are always visible but may be disabled.
   // When switching to another value, we need to re-enable them (see bug 11985).
   if (HasHorizontalScrollbar() && old_style &&
       old_style->OverflowX() == EOverflow::kScroll &&
-      Box().Style()->OverflowX() != EOverflow::kScroll) {
+      GetLayoutBox()->Style()->OverflowX() != EOverflow::kScroll) {
     HorizontalScrollbar()->SetEnabled(true);
   }
 
   if (HasVerticalScrollbar() && old_style &&
       old_style->OverflowY() == EOverflow::kScroll &&
-      Box().Style()->OverflowY() != EOverflow::kScroll) {
+      GetLayoutBox()->Style()->OverflowY() != EOverflow::kScroll) {
     VerticalScrollbar()->SetEnabled(true);
   }
 
@@ -1146,10 +1159,11 @@
   bool vertical_scrollbar_should_change =
       needs_vertical_scrollbar != HasVerticalScrollbar();
 
-  if ((Box().HasAutoHorizontalScrollbar() &&
+  if ((GetLayoutBox()->HasAutoHorizontalScrollbar() &&
        horizontal_scrollbar_should_change) ||
-      (Box().HasAutoVerticalScrollbar() && vertical_scrollbar_should_change)) {
-    Box().SetNeedsLayoutAndFullPaintInvalidation(
+      (GetLayoutBox()->HasAutoVerticalScrollbar() &&
+       vertical_scrollbar_should_change)) {
+    GetLayoutBox()->SetNeedsLayoutAndFullPaintInvalidation(
         LayoutInvalidationReason::kUnknown);
   }
 
@@ -1163,13 +1177,15 @@
 
   const IntRect& scroll_corner = ScrollCornerRect();
 
-  return IntRect(HorizontalScrollbarStart(border_box_rect.X()),
-                 border_box_rect.MaxY() - Box().BorderBottom().ToInt() -
-                     HorizontalScrollbar()->ScrollbarThickness(),
-                 border_box_rect.Width() -
-                     (Box().BorderLeft() + Box().BorderRight()).ToInt() -
-                     scroll_corner.Width(),
-                 HorizontalScrollbar()->ScrollbarThickness());
+  return IntRect(
+      HorizontalScrollbarStart(border_box_rect.X()),
+      border_box_rect.MaxY() - GetLayoutBox()->BorderBottom().ToInt() -
+          HorizontalScrollbar()->ScrollbarThickness(),
+      border_box_rect.Width() -
+          (GetLayoutBox()->BorderLeft() + GetLayoutBox()->BorderRight())
+              .ToInt() -
+          scroll_corner.Width(),
+      HorizontalScrollbar()->ScrollbarThickness());
 }
 
 IntRect PaintLayerScrollableArea::RectForVerticalScrollbar(
@@ -1181,27 +1197,28 @@
 
   return IntRect(
       VerticalScrollbarStart(border_box_rect.X(), border_box_rect.MaxX()),
-      border_box_rect.Y() + Box().BorderTop().ToInt(),
+      border_box_rect.Y() + GetLayoutBox()->BorderTop().ToInt(),
       VerticalScrollbar()->ScrollbarThickness(),
       border_box_rect.Height() -
-          (Box().BorderTop() + Box().BorderBottom()).ToInt() -
+          (GetLayoutBox()->BorderTop() + GetLayoutBox()->BorderBottom())
+              .ToInt() -
           scroll_corner.Height());
 }
 
 int PaintLayerScrollableArea::VerticalScrollbarStart(int min_x,
                                                      int max_x) const {
-  if (Box().ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
-    return min_x + Box().BorderLeft().ToInt();
-  return max_x - Box().BorderRight().ToInt() -
+  if (GetLayoutBox()->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+    return min_x + GetLayoutBox()->BorderLeft().ToInt();
+  return max_x - GetLayoutBox()->BorderRight().ToInt() -
          VerticalScrollbar()->ScrollbarThickness();
 }
 
 int PaintLayerScrollableArea::HorizontalScrollbarStart(int min_x) const {
-  int x = min_x + Box().BorderLeft().ToInt();
-  if (Box().ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+  int x = min_x + GetLayoutBox()->BorderLeft().ToInt();
+  if (GetLayoutBox()->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
     x += HasVerticalScrollbar()
              ? VerticalScrollbar()->ScrollbarThickness()
-             : ResizerCornerRect(Box().PixelSnappedBorderBoxRect(
+             : ResizerCornerRect(GetLayoutBox()->PixelSnappedBorderBoxRect(
                                      Layer()->SubpixelAccumulation()),
                                  kResizerForPointer)
                    .Width();
@@ -1213,12 +1230,12 @@
   if (&scrollbar == VerticalScrollbar()) {
     return IntSize(
         VerticalScrollbarStart(0, Layer()->PixelSnappedSize().Width()),
-        Box().BorderTop().ToInt());
+        GetLayoutBox()->BorderTop().ToInt());
   }
 
   if (&scrollbar == HorizontalScrollbar()) {
     return IntSize(HorizontalScrollbarStart(0),
-                   Box().BorderTop().ToInt() + VisibleHeight());
+                   GetLayoutBox()->BorderTop().ToInt() + VisibleHeight());
   }
 
   NOTREACHED();
@@ -1269,7 +1286,7 @@
   if (!HasScrollbar())
     return false;
 
-  const LayoutObject& style_source = ScrollbarStyleSource(Box());
+  const LayoutObject& style_source = ScrollbarStyleSource(*GetLayoutBox());
   bool needs_custom =
       style_source.IsBox() &&
       style_source.StyleRef().HasPseudoStyle(kPseudoIdScrollbar);
@@ -1295,7 +1312,7 @@
     }
 
     // Check if native scrollbar should change.
-    Page* page = Box().GetFrame()->LocalFrameRoot().GetPage();
+    Page* page = GetLayoutBox()->GetFrame()->LocalFrameRoot().GetPage();
     DCHECK(page);
     ScrollbarTheme* current_theme = &page->GetScrollbarTheme();
 
@@ -1310,37 +1327,39 @@
     bool& needs_vertical_scrollbar,
     ComputeScrollbarExistenceOption option) const {
   // Scrollbars may be hidden or provided by visual viewport or frame instead.
-  DCHECK(Box().GetFrame()->GetSettings());
-  if (VisualViewportSuppliesScrollbars() || !CanHaveOverflowScrollbars(Box()) ||
-      Box().GetFrame()->GetSettings()->GetHideScrollbars()) {
+  DCHECK(GetLayoutBox()->GetFrame()->GetSettings());
+  if (VisualViewportSuppliesScrollbars() ||
+      !CanHaveOverflowScrollbars(*GetLayoutBox()) ||
+      GetLayoutBox()->GetFrame()->GetSettings()->GetHideScrollbars()) {
     needs_horizontal_scrollbar = false;
     needs_vertical_scrollbar = false;
     return;
   }
 
-  needs_horizontal_scrollbar = Box().ScrollsOverflowX();
-  needs_vertical_scrollbar = Box().ScrollsOverflowY();
+  needs_horizontal_scrollbar = GetLayoutBox()->ScrollsOverflowX();
+  needs_vertical_scrollbar = GetLayoutBox()->ScrollsOverflowY();
 
   // Don't add auto scrollbars if the box contents aren't visible.
-  if (Box().HasAutoHorizontalScrollbar()) {
+  if (GetLayoutBox()->HasAutoHorizontalScrollbar()) {
     if (option == kForbidAddingAutoBars)
       needs_horizontal_scrollbar &= HasHorizontalScrollbar();
     needs_horizontal_scrollbar &=
-        Box().IsRooted() && HasHorizontalOverflow() &&
+        GetLayoutBox()->IsRooted() && HasHorizontalOverflow() &&
         VisibleContentRect(kIncludeScrollbars).Height();
   }
 
-  if (Box().HasAutoVerticalScrollbar()) {
+  if (GetLayoutBox()->HasAutoVerticalScrollbar()) {
     if (option == kForbidAddingAutoBars)
       needs_vertical_scrollbar &= HasVerticalScrollbar();
-    needs_vertical_scrollbar &= Box().IsRooted() && HasVerticalOverflow() &&
+    needs_vertical_scrollbar &= GetLayoutBox()->IsRooted() &&
+                                HasVerticalOverflow() &&
                                 VisibleContentRect(kIncludeScrollbars).Width();
   }
 
-  if (Box().IsLayoutView()) {
+  if (GetLayoutBox()->IsLayoutView()) {
     ScrollbarMode h_mode;
     ScrollbarMode v_mode;
-    ToLayoutView(Box()).CalculateScrollbarModes(h_mode, v_mode);
+    ToLayoutView(GetLayoutBox())->CalculateScrollbarModes(h_mode, v_mode);
 
     // Look for the scrollbarModes and reset the needs Horizontal & vertical
     // Scrollbar values based on scrollbarModes, as during force style change
@@ -1369,10 +1388,10 @@
   if (!needs_horizontal_scrollbar && !needs_vertical_scrollbar)
     return false;
 
-  if (Box().IsLayoutView()) {
+  if (GetLayoutBox()->IsLayoutView()) {
     ScrollbarMode h_mode;
     ScrollbarMode v_mode;
-    ToLayoutView(Box()).CalculateScrollbarModes(h_mode, v_mode);
+    ToLayoutView(GetLayoutBox())->CalculateScrollbarModes(h_mode, v_mode);
     if (h_mode != kScrollbarAuto || v_mode != kScrollbarAuto)
       return false;
 
@@ -1383,8 +1402,8 @@
       return true;
     }
   } else {
-    if (!Box().HasAutoVerticalScrollbar() ||
-        !Box().HasAutoHorizontalScrollbar())
+    if (!GetLayoutBox()->HasAutoVerticalScrollbar() ||
+        !GetLayoutBox()->HasAutoHorizontalScrollbar())
       return false;
 
     LayoutSize client_size_with_scrollbars =
@@ -1421,8 +1440,8 @@
   SetScrollCornerNeedsPaintInvalidation();
 
   // Force an update since we know the scrollbars have changed things.
-  if (Box().GetDocument().HasAnnotatedRegions())
-    Box().GetDocument().SetAnnotatedRegionsDirty(true);
+  if (GetLayoutBox()->GetDocument().HasAnnotatedRegions())
+    GetLayoutBox()->GetDocument().SetAnnotatedRegionsDirty(true);
   return true;
 }
 
@@ -1449,8 +1468,8 @@
   SetScrollCornerNeedsPaintInvalidation();
 
   // Force an update since we know the scrollbars have changed things.
-  if (Box().GetDocument().HasAnnotatedRegions())
-    Box().GetDocument().SetAnnotatedRegionsDirty(true);
+  if (GetLayoutBox()->GetDocument().HasAnnotatedRegions())
+    GetLayoutBox()->GetDocument().SetAnnotatedRegionsDirty(true);
   return true;
 }
 
@@ -1460,7 +1479,7 @@
     return 0;
   if (overlay_scrollbar_clip_behavior ==
           kIgnorePlatformAndCSSOverlayScrollbarSize &&
-      Box().Style()->OverflowY() == EOverflow::kOverlay) {
+      GetLayoutBox()->Style()->OverflowY() == EOverflow::kOverlay) {
     return 0;
   }
   if ((overlay_scrollbar_clip_behavior == kIgnorePlatformOverlayScrollbarSize ||
@@ -1479,7 +1498,7 @@
     return 0;
   if (overlay_scrollbar_clip_behavior ==
           kIgnorePlatformAndCSSOverlayScrollbarSize &&
-      Box().Style()->OverflowX() == EOverflow::kOverlay) {
+      GetLayoutBox()->Style()->OverflowX() == EOverflow::kOverlay) {
     return 0;
   }
   if ((overlay_scrollbar_clip_behavior == kIgnorePlatformOverlayScrollbarSize ||
@@ -1493,11 +1512,11 @@
 }
 
 void PaintLayerScrollableArea::PositionOverflowControls() {
-  if (!HasScrollbar() && !Box().CanResize())
+  if (!HasScrollbar() && !GetLayoutBox()->CanResize())
     return;
 
   const IntRect border_box =
-      Box().PixelSnappedBorderBoxRect(layer_.SubpixelAccumulation());
+      GetLayoutBox()->PixelSnappedBorderBoxRect(layer_.SubpixelAccumulation());
 
   if (Scrollbar* vertical_scrollbar = VerticalScrollbar())
     vertical_scrollbar->SetFrameRect(RectForVerticalScrollbar(border_box));
@@ -1526,18 +1545,18 @@
   if (!scroll_corner_ && HasOverlayScrollbars())
     return;
 
-  const LayoutObject& style_source = ScrollbarStyleSource(Box());
+  const LayoutObject& style_source = ScrollbarStyleSource(*GetLayoutBox());
   scoped_refptr<ComputedStyle> corner =
-      Box().HasOverflowClip()
+      GetLayoutBox()->HasOverflowClip()
           ? style_source.GetUncachedPseudoStyle(
                 PseudoStyleRequest(kPseudoIdScrollbarCorner),
                 style_source.Style())
           : scoped_refptr<ComputedStyle>(nullptr);
   if (corner) {
     if (!scroll_corner_) {
-      scroll_corner_ =
-          LayoutScrollbarPart::CreateAnonymous(&Box().GetDocument(), this);
-      scroll_corner_->SetDangerousOneWayParent(&Box());
+      scroll_corner_ = LayoutScrollbarPart::CreateAnonymous(
+          &GetLayoutBox()->GetDocument(), this);
+      scroll_corner_->SetDangerousOneWayParent(GetLayoutBox());
     }
     scroll_corner_->SetStyleWithWritingModeOfParent(std::move(corner));
   } else if (scroll_corner_) {
@@ -1549,14 +1568,15 @@
 bool PaintLayerScrollableArea::HitTestOverflowControls(
     HitTestResult& result,
     const IntPoint& local_point) {
-  if (!HasScrollbar() && !Box().CanResize())
+  if (!HasScrollbar() && !GetLayoutBox()->CanResize())
     return false;
 
   IntRect resize_control_rect;
-  if (Box().Style()->Resize() != EResize::kNone) {
-    resize_control_rect = ResizerCornerRect(
-        Box().PixelSnappedBorderBoxRect(Layer()->SubpixelAccumulation()),
-        kResizerForPointer);
+  if (GetLayoutBox()->Style()->Resize() != EResize::kNone) {
+    resize_control_rect =
+        ResizerCornerRect(GetLayoutBox()->PixelSnappedBorderBoxRect(
+                              Layer()->SubpixelAccumulation()),
+                          kResizerForPointer);
     if (resize_control_rect.Contains(local_point))
       return true;
   }
@@ -1566,7 +1586,8 @@
       VerticalScrollbar()->ShouldParticipateInHitTesting()) {
     LayoutRect v_bar_rect(
         VerticalScrollbarStart(0, Layer()->PixelSnappedSize().Width()),
-        Box().BorderTop().ToInt(), VerticalScrollbar()->ScrollbarThickness(),
+        GetLayoutBox()->BorderTop().ToInt(),
+        VerticalScrollbar()->ScrollbarThickness(),
         VisibleContentRect(kIncludeScrollbars).Height() -
             (HasHorizontalScrollbar()
                  ? HorizontalScrollbar()->ScrollbarThickness()
@@ -1583,7 +1604,7 @@
     // TODO(crbug.com/638981): Are the conversions to int intentional?
     LayoutRect h_bar_rect(
         HorizontalScrollbarStart(0),
-        Box().BorderTop().ToInt() + VisibleHeight(),
+        GetLayoutBox()->BorderTop().ToInt() + VisibleHeight(),
         VisibleContentRect(kIncludeScrollbars).Width() -
             (HasVerticalScrollbar() ? VerticalScrollbar()->ScrollbarThickness()
                                     : resize_control_size),
@@ -1603,7 +1624,7 @@
 IntRect PaintLayerScrollableArea::ResizerCornerRect(
     const IntRect& bounds,
     ResizerHitTestType resizer_hit_test_type) const {
-  if (Box().Style()->Resize() == EResize::kNone)
+  if (GetLayoutBox()->Style()->Resize() == EResize::kNone)
     return IntRect();
   IntRect corner = CornerRect(bounds);
 
@@ -1625,9 +1646,10 @@
 IntRect PaintLayerScrollableArea::ScrollCornerAndResizerRect() const {
   IntRect scroll_corner_and_resizer = ScrollCornerRect();
   if (scroll_corner_and_resizer.IsEmpty()) {
-    scroll_corner_and_resizer = ResizerCornerRect(
-        Box().PixelSnappedBorderBoxRect(Layer()->SubpixelAccumulation()),
-        kResizerForPointer);
+    scroll_corner_and_resizer =
+        ResizerCornerRect(GetLayoutBox()->PixelSnappedBorderBoxRect(
+                              Layer()->SubpixelAccumulation()),
+                          kResizerForPointer);
   }
   return scroll_corner_and_resizer;
 }
@@ -1635,11 +1657,11 @@
 bool PaintLayerScrollableArea::IsPointInResizeControl(
     const IntPoint& absolute_point,
     ResizerHitTestType resizer_hit_test_type) const {
-  if (!Box().CanResize())
+  if (!GetLayoutBox()->CanResize())
     return false;
 
-  IntPoint local_point =
-      RoundedIntPoint(Box().AbsoluteToLocal(absolute_point, kUseTransforms));
+  IntPoint local_point = RoundedIntPoint(
+      GetLayoutBox()->AbsoluteToLocal(absolute_point, kUseTransforms));
   IntRect local_bounds(IntPoint(), Layer()->PixelSnappedSize());
   return ResizerCornerRect(local_bounds, resizer_hit_test_type)
       .Contains(local_point);
@@ -1648,7 +1670,7 @@
 bool PaintLayerScrollableArea::HitTestResizerInFragments(
     const PaintLayerFragments& layer_fragments,
     const HitTestLocation& hit_test_location) const {
-  if (!Box().CanResize())
+  if (!GetLayoutBox()->CanResize())
     return false;
 
   if (layer_fragments.IsEmpty())
@@ -1667,41 +1689,41 @@
 }
 
 void PaintLayerScrollableArea::UpdateResizerAreaSet() {
-  LocalFrame* frame = Box().GetFrame();
+  LocalFrame* frame = GetLayoutBox()->GetFrame();
   if (!frame)
     return;
   LocalFrameView* frame_view = frame->View();
   if (!frame_view)
     return;
-  if (Box().CanResize())
-    frame_view->AddResizerArea(Box());
+  if (GetLayoutBox()->CanResize())
+    frame_view->AddResizerArea(*GetLayoutBox());
   else
-    frame_view->RemoveResizerArea(Box());
+    frame_view->RemoveResizerArea(*GetLayoutBox());
 }
 
 void PaintLayerScrollableArea::UpdateResizerStyle(
     const ComputedStyle* old_style) {
   if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() && old_style &&
-      old_style->Resize() != Box().StyleRef().Resize()) {
+      old_style->Resize() != GetLayoutBox()->StyleRef().Resize()) {
     // Invalidate the composited scroll corner layer on resize style change.
     if (auto* graphics_layer = LayerForScrollCorner())
       graphics_layer->SetNeedsDisplay();
   }
 
-  if (!resizer_ && !Box().CanResize())
+  if (!resizer_ && !GetLayoutBox()->CanResize())
     return;
 
-  const LayoutObject& style_source = ScrollbarStyleSource(Box());
+  const LayoutObject& style_source = ScrollbarStyleSource(*GetLayoutBox());
   scoped_refptr<ComputedStyle> resizer =
-      Box().HasOverflowClip()
+      GetLayoutBox()->HasOverflowClip()
           ? style_source.GetUncachedPseudoStyle(
                 PseudoStyleRequest(kPseudoIdResizer), style_source.Style())
           : scoped_refptr<ComputedStyle>(nullptr);
   if (resizer) {
     if (!resizer_) {
-      resizer_ =
-          LayoutScrollbarPart::CreateAnonymous(&Box().GetDocument(), this);
-      resizer_->SetDangerousOneWayParent(&Box());
+      resizer_ = LayoutScrollbarPart::CreateAnonymous(
+          &GetLayoutBox()->GetDocument(), this);
+      resizer_->SetDangerousOneWayParent(GetLayoutBox());
     }
     resizer_->SetStyleWithWritingModeOfParent(std::move(resizer));
   } else if (resizer_) {
@@ -1758,19 +1780,21 @@
   // FIXME: This assumes the location is 0, 0. Is this guaranteed to always be
   // the case?
   IntSize element_size = Layer()->PixelSnappedSize();
-  if (Box().ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+  if (GetLayoutBox()->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
     element_size.SetWidth(0);
   IntPoint resizer_point = IntPoint(element_size);
-  IntPoint local_point =
-      RoundedIntPoint(Box().AbsoluteToLocal(absolute_point, kUseTransforms));
+  IntPoint local_point = RoundedIntPoint(
+      GetLayoutBox()->AbsoluteToLocal(absolute_point, kUseTransforms));
   return local_point - resizer_point;
 }
 
 LayoutSize PaintLayerScrollableArea::MinimumSizeForResizing(float zoom_factor) {
-  LayoutUnit min_width = MinimumValueForLength(
-      Box().StyleRef().MinWidth(), Box().ContainingBlock()->Size().Width());
-  LayoutUnit min_height = MinimumValueForLength(
-      Box().StyleRef().MinHeight(), Box().ContainingBlock()->Size().Height());
+  LayoutUnit min_width =
+      MinimumValueForLength(GetLayoutBox()->StyleRef().MinWidth(),
+                            GetLayoutBox()->ContainingBlock()->Size().Width());
+  LayoutUnit min_height =
+      MinimumValueForLength(GetLayoutBox()->StyleRef().MinHeight(),
+                            GetLayoutBox()->ContainingBlock()->Size().Height());
   min_width = std::max(LayoutUnit(min_width / zoom_factor),
                        LayoutUnit(kDefaultMinimumWidthForResizing));
   min_height = std::max(LayoutUnit(min_height / zoom_factor),
@@ -1781,27 +1805,28 @@
 void PaintLayerScrollableArea::Resize(const IntPoint& pos,
                                       const LayoutSize& old_offset) {
   // FIXME: This should be possible on generated content but is not right now.
-  if (!InResizeMode() || !Box().CanResize() || !Box().GetNode())
+  if (!InResizeMode() || !GetLayoutBox()->CanResize() ||
+      !GetLayoutBox()->GetNode())
     return;
 
-  DCHECK(Box().GetNode()->IsElementNode());
-  Element* element = ToElement(Box().GetNode());
+  DCHECK(GetLayoutBox()->GetNode()->IsElementNode());
+  Element* element = ToElement(GetLayoutBox()->GetNode());
 
   Document& document = element->GetDocument();
 
-  float zoom_factor = Box().Style()->EffectiveZoom();
+  float zoom_factor = GetLayoutBox()->Style()->EffectiveZoom();
 
   IntSize new_offset =
       OffsetFromResizeCorner(document.View()->RootFrameToContents(pos));
   new_offset.SetWidth(new_offset.Width() / zoom_factor);
   new_offset.SetHeight(new_offset.Height() / zoom_factor);
 
-  LayoutSize current_size = Box().Size();
+  LayoutSize current_size = GetLayoutBox()->Size();
   current_size.Scale(1 / zoom_factor);
 
   LayoutSize adjusted_old_offset = LayoutSize(
       old_offset.Width() / zoom_factor, old_offset.Height() / zoom_factor);
-  if (Box().ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
+  if (GetLayoutBox()->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
     new_offset.SetWidth(-new_offset.Width());
     adjusted_old_offset.SetWidth(-adjusted_old_offset.Width());
   }
@@ -1811,23 +1836,24 @@
                         current_size);
 
   bool is_box_sizing_border =
-      Box().Style()->BoxSizing() == EBoxSizing::kBorderBox;
+      GetLayoutBox()->Style()->BoxSizing() == EBoxSizing::kBorderBox;
 
-  EResize resize = Box().Style()->Resize();
+  EResize resize = GetLayoutBox()->Style()->Resize();
   if (resize != EResize::kVertical && difference.Width()) {
     if (element->IsFormControlElement()) {
       // Make implicit margins from the theme explicit (see
       // <http://bugs.webkit.org/show_bug.cgi?id=9547>).
-      element->SetInlineStyleProperty(CSSPropertyMarginLeft,
-                                      Box().MarginLeft() / zoom_factor,
-                                      CSSPrimitiveValue::UnitType::kPixels);
-      element->SetInlineStyleProperty(CSSPropertyMarginRight,
-                                      Box().MarginRight() / zoom_factor,
-                                      CSSPrimitiveValue::UnitType::kPixels);
+      element->SetInlineStyleProperty(
+          CSSPropertyMarginLeft, GetLayoutBox()->MarginLeft() / zoom_factor,
+          CSSPrimitiveValue::UnitType::kPixels);
+      element->SetInlineStyleProperty(
+          CSSPropertyMarginRight, GetLayoutBox()->MarginRight() / zoom_factor,
+          CSSPrimitiveValue::UnitType::kPixels);
     }
     LayoutUnit base_width =
-        Box().Size().Width() -
-        (is_box_sizing_border ? LayoutUnit() : Box().BorderAndPaddingWidth());
+        GetLayoutBox()->Size().Width() -
+        (is_box_sizing_border ? LayoutUnit()
+                              : GetLayoutBox()->BorderAndPaddingWidth());
     base_width = LayoutUnit(base_width / zoom_factor);
     element->SetInlineStyleProperty(CSSPropertyWidth,
                                     RoundToInt(base_width + difference.Width()),
@@ -1839,15 +1865,16 @@
       // Make implicit margins from the theme explicit (see
       // <http://bugs.webkit.org/show_bug.cgi?id=9547>).
       element->SetInlineStyleProperty(CSSPropertyMarginTop,
-                                      Box().MarginTop() / zoom_factor,
+                                      GetLayoutBox()->MarginTop() / zoom_factor,
                                       CSSPrimitiveValue::UnitType::kPixels);
-      element->SetInlineStyleProperty(CSSPropertyMarginBottom,
-                                      Box().MarginBottom() / zoom_factor,
-                                      CSSPrimitiveValue::UnitType::kPixels);
+      element->SetInlineStyleProperty(
+          CSSPropertyMarginBottom, GetLayoutBox()->MarginBottom() / zoom_factor,
+          CSSPrimitiveValue::UnitType::kPixels);
     }
     LayoutUnit base_height =
-        Box().Size().Height() -
-        (is_box_sizing_border ? LayoutUnit() : Box().BorderAndPaddingHeight());
+        GetLayoutBox()->Size().Height() -
+        (is_box_sizing_border ? LayoutUnit()
+                              : GetLayoutBox()->BorderAndPaddingHeight());
     base_height = LayoutUnit(base_height / zoom_factor);
     element->SetInlineStyleProperty(
         CSSPropertyHeight, RoundToInt(base_height + difference.Height()),
@@ -1868,10 +1895,11 @@
     ScrollType scroll_type,
     bool is_for_scroll_sequence) {
   LayoutRect local_expose_rect(
-      Box()
-          .AbsoluteToLocalQuad(FloatQuad(FloatRect(rect)), kUseTransforms)
+      GetLayoutBox()
+          ->AbsoluteToLocalQuad(FloatQuad(FloatRect(rect)), kUseTransforms)
           .BoundingBox());
-  local_expose_rect.Move(-Box().BorderLeft(), -Box().BorderTop());
+  local_expose_rect.Move(-GetLayoutBox()->BorderLeft(),
+                         -GetLayoutBox()->BorderTop());
   LayoutRect visible_rect(IntPoint(), VisibleContentRect().Size());
   LayoutRect r = ScrollAlignment::GetRectToExpose(
       visible_rect, local_expose_rect, align_x, align_y);
@@ -1892,17 +1920,17 @@
       ClampScrollOffset(new_scroll_offset) - old_scroll_offset;
   local_expose_rect.Move(-LayoutSize(scroll_offset_difference));
 
-  LayoutRect intersect =
-      LocalToAbsolute(Box(), Intersection(visible_rect, local_expose_rect));
+  LayoutRect intersect = LocalToAbsolute(
+      *GetLayoutBox(), Intersection(visible_rect, local_expose_rect));
   if (intersect.IsEmpty() && !visible_rect.IsEmpty() &&
       !local_expose_rect.IsEmpty()) {
-    return LocalToAbsolute(Box(), local_expose_rect);
+    return LocalToAbsolute(*GetLayoutBox(), local_expose_rect);
   }
   return intersect;
 }
 
 void PaintLayerScrollableArea::UpdateScrollableAreaSet() {
-  LocalFrame* frame = Box().GetFrame();
+  LocalFrame* frame = GetLayoutBox()->GetFrame();
   if (!frame)
     return;
 
@@ -1910,16 +1938,17 @@
   if (!frame_view)
     return;
 
-  bool has_overflow = !Box().Size().IsZero() &&
-                      ((HasHorizontalOverflow() && Box().ScrollsOverflowX()) ||
-                       (HasVerticalOverflow() && Box().ScrollsOverflowY()));
+  bool has_overflow =
+      !GetLayoutBox()->Size().IsZero() &&
+      ((HasHorizontalOverflow() && GetLayoutBox()->ScrollsOverflowX()) ||
+       (HasVerticalOverflow() && GetLayoutBox()->ScrollsOverflowY()));
 
-  bool is_visible_to_hit_test = Box().Style()->VisibleToHitTesting();
+  bool is_visible_to_hit_test = GetLayoutBox()->Style()->VisibleToHitTesting();
   bool did_scroll_overflow = scrolls_overflow_;
-  if (Box().IsLayoutView()) {
+  if (GetLayoutBox()->IsLayoutView()) {
     ScrollbarMode h_mode;
     ScrollbarMode v_mode;
-    ToLayoutView(Box()).CalculateScrollbarModes(h_mode, v_mode);
+    ToLayoutView(GetLayoutBox())->CalculateScrollbarModes(h_mode, v_mode);
     if (h_mode == kScrollbarAlwaysOff && v_mode == kScrollbarAlwaysOff)
       has_overflow = false;
   }
@@ -1929,10 +1958,10 @@
 
   // The scroll and scroll offset properties depend on |scrollsOverflow| (see:
   // PaintPropertyTreeBuilder::updateScrollAndScrollTranslation).
-  Box().SetNeedsPaintPropertyUpdate();
+  GetLayoutBox()->SetNeedsPaintPropertyUpdate();
 
   if (scrolls_overflow_) {
-    DCHECK(CanHaveOverflowScrollbars(Box()));
+    DCHECK(CanHaveOverflowScrollbars(*GetLayoutBox()));
     frame_view->AddScrollableArea(this);
   } else {
     frame_view->RemoveScrollableArea(this);
@@ -1942,7 +1971,7 @@
 }
 
 void PaintLayerScrollableArea::UpdateCompositingLayersAfterScroll() {
-  PaintLayerCompositor* compositor = Box().View()->Compositor();
+  PaintLayerCompositor* compositor = GetLayoutBox()->View()->Compositor();
   if (!compositor->InCompositingMode())
     return;
 
@@ -1958,7 +1987,7 @@
     // composited layer.
     if (Layer()->IsRootLayer() &&
         RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
-      LocalFrame* frame = Box().GetFrame();
+      LocalFrame* frame = GetLayoutBox()->GetFrame();
       if (frame && frame->View() &&
           frame->View()->HasViewportConstrainedObjects()) {
         Layer()->SetNeedsCompositingInputsUpdate();
@@ -1971,7 +2000,7 @@
 
 ScrollingCoordinator* PaintLayerScrollableArea::GetScrollingCoordinator()
     const {
-  LocalFrame* frame = Box().GetFrame();
+  LocalFrame* frame = GetLayoutBox()->GetFrame();
   if (!frame)
     return nullptr;
 
@@ -1991,7 +2020,7 @@
 }
 
 bool PaintLayerScrollableArea::ShouldScrollOnMainThread() const {
-  if (LocalFrame* frame = Box().GetFrame()) {
+  if (LocalFrame* frame = GetLayoutBox()->GetFrame()) {
     if (frame->View()->GetMainThreadScrollingReasons())
       return true;
   }
@@ -2108,7 +2137,7 @@
 }
 
 bool PaintLayerScrollableArea::VisualViewportSuppliesScrollbars() const {
-  LocalFrame* frame = Box().GetFrame();
+  LocalFrame* frame = GetLayoutBox()->GetFrame();
   if (!frame || !frame->GetSettings())
     return false;
 
@@ -2125,7 +2154,7 @@
 
 bool PaintLayerScrollableArea::ScheduleAnimation() {
   if (PlatformChromeClient* client = GetChromeClient()) {
-    client->ScheduleAnimation(Box().GetFrame()->View());
+    client->ScheduleAnimation(GetLayoutBox()->GetFrame()->View());
     return true;
   }
   return false;
@@ -2149,8 +2178,12 @@
 }
 
 void PaintLayerScrollableArea::GetTickmarks(Vector<IntRect>& tickmarks) const {
-  if (layer_.IsRootLayer())
-    tickmarks = Box().GetDocument().Markers().LayoutRectsForTextMatchMarkers();
+  if (layer_.IsRootLayer()) {
+    tickmarks = GetLayoutBox()
+                    ->GetDocument()
+                    .Markers()
+                    .LayoutRectsForTextMatchMarkers();
+  }
 }
 
 PaintLayerScrollableArea*
@@ -2213,7 +2246,7 @@
                                              : !v_bar_is_attached_);
   Scrollbar* scrollbar = nullptr;
   const LayoutObject& style_source =
-      ScrollbarStyleSource(ScrollableArea()->Box());
+      ScrollbarStyleSource(*ScrollableArea()->GetLayoutBox());
   bool has_custom_scrollbar_style =
       style_source.IsBox() &&
       style_source.StyleRef().HasPseudoStyle(kPseudoIdScrollbar);
@@ -2227,11 +2260,15 @@
       scrollbar_size = LayoutTheme::GetTheme().ScrollbarControlSizeForPart(
           style_source.StyleRef().Appearance());
     }
-    scrollbar = Scrollbar::Create(
-        ScrollableArea(), orientation, scrollbar_size,
-        &ScrollableArea()->Box().GetFrame()->GetPage()->GetChromeClient());
+    scrollbar = Scrollbar::Create(ScrollableArea(), orientation, scrollbar_size,
+                                  &ScrollableArea()
+                                       ->GetLayoutBox()
+                                       ->GetFrame()
+                                       ->GetPage()
+                                       ->GetChromeClient());
   }
-  ScrollableArea()->Box().GetDocument().View()->AddScrollbar(scrollbar);
+  ScrollableArea()->GetLayoutBox()->GetDocument().View()->AddScrollbar(
+      scrollbar);
   return scrollbar;
 }
 
@@ -2253,13 +2290,14 @@
   if (!scrollbar->IsCustomScrollbar())
     ScrollableArea()->WillRemoveScrollbar(*scrollbar, orientation);
 
-  ScrollableArea()->Box().GetDocument().View()->RemoveScrollbar(scrollbar);
+  ScrollableArea()->GetLayoutBox()->GetDocument().View()->RemoveScrollbar(
+      scrollbar);
   scrollbar->DisconnectFromScrollableArea();
   scrollbar = nullptr;
 }
 
 uint64_t PaintLayerScrollableArea::Id() const {
-  return DOMNodeIds::IdForNode(Box().GetNode());
+  return DOMNodeIds::IdForNode(GetLayoutBox()->GetNode());
 }
 
 int PaintLayerScrollableArea::PreventRelayoutScope::count_ = 0;
@@ -2284,19 +2322,20 @@
     if (relayout_needed_) {
       for (auto scrollable_area : *needs_relayout_) {
         DCHECK(scrollable_area->NeedsRelayout());
-        LayoutBox& box = scrollable_area->Box();
+        LayoutBox* box = scrollable_area->GetLayoutBox();
         layout_scope_->SetNeedsLayout(
-            &box, LayoutInvalidationReason::kScrollbarChanged);
-        if (box.IsLayoutBlock()) {
+            box, LayoutInvalidationReason::kScrollbarChanged);
+        if (box->IsLayoutBlock()) {
           bool horizontal_scrollbar_changed =
               scrollable_area->HasHorizontalScrollbar() !=
               scrollable_area->HadHorizontalScrollbarBeforeRelayout();
           bool vertical_scrollbar_changed =
               scrollable_area->HasVerticalScrollbar() !=
               scrollable_area->HadVerticalScrollbarBeforeRelayout();
-          if (horizontal_scrollbar_changed || vertical_scrollbar_changed)
-            ToLayoutBlock(box).ScrollbarsChanged(horizontal_scrollbar_changed,
-                                                 vertical_scrollbar_changed);
+          if (horizontal_scrollbar_changed || vertical_scrollbar_changed) {
+            ToLayoutBlock(box)->ScrollbarsChanged(horizontal_scrollbar_changed,
+                                                  vertical_scrollbar_changed);
+          }
         }
         scrollable_area->SetNeedsRelayout(false);
       }
@@ -2371,7 +2410,7 @@
 }
 
 ScrollbarTheme& PaintLayerScrollableArea::GetPageScrollbarTheme() const {
-  Page* page = Box().GetFrame()->GetPage();
+  Page* page = GetLayoutBox()->GetFrame()->GetPage();
   DCHECK(page);
 
   return page->GetScrollbarTheme();
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
index c44ea67..877ac9e 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
@@ -411,8 +411,6 @@
 
   IntRect ResizerCornerRect(const IntRect&, ResizerHitTestType) const;
 
-  // TODO(ymalik): Remove box() and update callers to use layoutBox() instead.
-  LayoutBox& Box() const;
   PaintLayer* Layer() const override;
 
   LayoutScrollbarPart* Resizer() const override { return resizer_; }
@@ -432,7 +430,7 @@
   ScrollAnchor* GetScrollAnchor() override { return &scroll_anchor_; }
   bool IsPaintLayerScrollableArea() const override { return true; }
 
-  LayoutBox* GetLayoutBox() const override { return &Box(); }
+  LayoutBox* GetLayoutBox() const override;
 
   FloatQuad LocalToVisibleContentQuad(const FloatQuad&,
                                       const LayoutObject*,
diff --git a/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp b/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
index 4fb3b8fa..c03b265 100644
--- a/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
@@ -24,11 +24,11 @@
 void ScrollableAreaPainter::PaintResizer(GraphicsContext& context,
                                          const IntPoint& paint_offset,
                                          const CullRect& cull_rect) {
-  if (GetScrollableArea().Box().Style()->Resize() == EResize::kNone)
+  if (GetScrollableArea().GetLayoutBox()->Style()->Resize() == EResize::kNone)
     return;
 
   IntRect abs_rect = GetScrollableArea().ResizerCornerRect(
-      GetScrollableArea().Box().PixelSnappedBorderBoxRect(
+      GetScrollableArea().GetLayoutBox()->PixelSnappedBorderBoxRect(
           GetScrollableArea().Layer()->SubpixelAccumulation()),
       kResizerForPointer);
   if (abs_rect.IsEmpty())
@@ -74,8 +74,8 @@
   IntPoint points[4];
   bool on_left = false;
   if (GetScrollableArea()
-          .Box()
-          .ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
+          .GetLayoutBox()
+          ->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
     on_left = true;
     points[0].SetX(resizer_corner_rect.X() + 1);
     points[1].SetX(resizer_corner_rect.X() + resizer_corner_rect.Width() -
@@ -127,7 +127,7 @@
     const CullRect& cull_rect,
     bool painting_overlay_controls) {
   // Don't do anything if we have no overflow.
-  if (!GetScrollableArea().Box().HasOverflowClip())
+  if (!GetScrollableArea().GetLayoutBox()->HasOverflowClip())
     return;
 
   IntPoint adjusted_paint_offset = paint_offset;
@@ -155,7 +155,7 @@
     if (!OverflowControlsIntersectRect(adjusted_cull_rect))
       return;
 
-    LayoutView* layout_view = GetScrollableArea().Box().View();
+    LayoutView* layout_view = GetScrollableArea().GetLayoutBox()->View();
 
     PaintLayer* painting_root =
         GetScrollableArea().Layer()->EnclosingLayerWithCompositedLayerMapping(
@@ -173,7 +173,7 @@
 
   IntRect clip_rect(adjusted_paint_offset,
                     GetScrollableArea().Layer()->PixelSnappedSize());
-  ClipRecorder clip_recorder(context, GetScrollableArea().Box(),
+  ClipRecorder clip_recorder(context, *GetScrollableArea().GetLayoutBox(),
                              DisplayItem::kClipLayerOverflowControls,
                              clip_rect);
 
@@ -207,7 +207,7 @@
 bool ScrollableAreaPainter::OverflowControlsIntersectRect(
     const CullRect& cull_rect) const {
   const IntRect border_box =
-      GetScrollableArea().Box().PixelSnappedBorderBoxRect(
+      GetScrollableArea().GetLayoutBox()->PixelSnappedBorderBoxRect(
           GetScrollableArea().Layer()->SubpixelAccumulation());
 
   if (cull_rect.IntersectsCullRect(
@@ -267,7 +267,7 @@
     const {
   if (const auto* graphics_layer = GetScrollableArea().LayerForScrollCorner())
     return *graphics_layer;
-  return GetScrollableArea().Box();
+  return *GetScrollableArea().GetLayoutBox();
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
index c744ad7..af22e1e 100644
--- a/third_party/WebKit/Source/devtools/BUILD.gn
+++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -415,7 +415,6 @@
   "front_end/object_ui/RemoteObjectPreviewFormatter.js",
   "front_end/perf_ui/chartViewport.css",
   "front_end/perf_ui/ChartViewport.js",
-  "front_end/perf_ui/filmStripDialog.css",
   "front_end/perf_ui/filmStripView.css",
   "front_end/perf_ui/FilmStripView.js",
   "front_end/perf_ui/flameChart.css",
@@ -807,6 +806,7 @@
   "front_end/ui/Widget.js",
   "front_end/ui/XElement.js",
   "front_end/ui/XLink.js",
+  "front_end/ui/XWidget.js",
   "front_end/ui/ZoomManager.js",
   "front_end/worker_service/ServiceDispatcher.js",
   "front_end/workspace/FileManager.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
index f852ae4..faf0393 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
+++ b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
@@ -220,7 +220,8 @@
       row.createChild('span', 'audits2-launcher-description dimmed').textContent = preset.description;
     }
 
-    this._statusView = this._createStatusView(uiElement);
+    this._statusView = new Audits2.Audits2Panel.StatusView();
+    this._statusView.render(uiElement);
     this._dialogHelpText = uiElement.createChild('div', 'audits2-dialog-help-text');
 
     var buttonsRow = uiElement.createChild('div', 'audits2-dialog-buttons hbox');
@@ -240,18 +241,6 @@
   }
 
   /**
-   * @param {!Element} launcherUIElement
-   * @return {!Element}
-   */
-  _createStatusView(launcherUIElement) {
-    var statusView = launcherUIElement.createChild('div', 'audits2-status vbox hidden');
-    this._statusIcon = statusView.createChild('div', 'icon');
-    this._statusElement = statusView.createChild('div');
-    this._updateStatus(Common.UIString('Loading...'));
-    return statusView;
-  }
-
-  /**
    * @return {!Promise<undefined>}
    */
   _updateInspectedURL() {
@@ -324,7 +313,7 @@
         })
         .catch(err => {
           if (err instanceof Error)
-            this._renderBugReport(err);
+            this._statusView.renderBugReport(err, this._inspectedURL);
         });
   }
 
@@ -335,8 +324,6 @@
 
     delete this._dialog;
     delete this._statusView;
-    delete this._statusIcon;
-    delete this._statusElement;
     delete this._startButton;
     delete this._cancelButton;
     delete this._auditSelectorForm;
@@ -350,10 +337,13 @@
     this._hideDialog();
   }
 
-  _cancel() {
+  async _cancel() {
     if (this._auditRunning) {
       this._updateStatus(Common.UIString('Cancelling\u2026'));
-      this._stopAndReattach();
+      await this._stopAndReattach();
+
+      if (this._statusView)
+        this._statusView.reset();
     } else {
       this._hideDialog();
     }
@@ -364,21 +354,25 @@
       return;
     this._startButton.classList.toggle('hidden', this._auditRunning);
     this._startButton.disabled = this._auditRunning;
-    this._statusView.classList.toggle('hidden', !this._auditRunning);
+    this._statusView.setVisible(this._auditRunning);
     this._auditSelectorForm.classList.toggle('hidden', this._auditRunning);
-    if (this._auditRunning)
-      this._headerTitleElement.textContent = Common.UIString('Auditing your web page \u2026');
-    else
+    if (this._auditRunning) {
+      var parsedURL = (this._inspectedURL || '').asParsedURL();
+      var pageHost = parsedURL && parsedURL.host;
+      this._headerTitleElement.textContent =
+          pageHost ? ls`Auditing ${pageHost}\u2026` : ls`Auditing your web page\u2026`;
+    } else {
       this._headerTitleElement.textContent = Common.UIString('Audits to perform');
+    }
   }
 
   /**
    * @param {string} statusMessage
    */
   _updateStatus(statusMessage) {
-    if (!this._dialog)
+    if (!this._dialog || !this._statusView)
       return;
-    this._statusElement.textContent = statusMessage;
+    this._statusView.updateStatus(statusMessage);
   }
 
   /**
@@ -416,49 +410,6 @@
   }
 
   /**
-   * @param {!Error} err
-   */
-  _renderBugReport(err) {
-    console.error(err);
-    this._statusElement.textContent = '';
-    this._statusIcon.classList.add('error');
-    this._statusElement.createTextChild(Common.UIString('Ah, sorry! We ran into an error: '));
-    this._statusElement.createChild('em').createTextChild(err.message);
-    if (Audits2.Audits2Panel.KnownBugPatterns.some(pattern => pattern.test(err.message))) {
-      var message = Common.UIString(
-          'Try to navigate to the URL in a fresh Chrome profile without any other tabs or ' +
-          'extensions open and try again.');
-      this._statusElement.createChild('p').createTextChild(message);
-    } else {
-      this._createBugReportLink(err, this._statusElement);
-    }
-  }
-
-  /**
-   * @param {!Error} err
-   * @param {!Element} parentElem
-   */
-  _createBugReportLink(err, parentElem) {
-    var baseURI = 'https://github.com/GoogleChrome/lighthouse/issues/new?';
-    var title = encodeURI('title=DevTools Error: ' + err.message.substring(0, 60));
-
-    var issueBody = `
-**Initial URL**: ${this._inspectedURL}
-**Chrome Version**: ${navigator.userAgent.match(/Chrome\/(\S+)/)[1]}
-**Error Message**: ${err.message}
-**Stack Trace**:
-\`\`\`
-${err.stack}
-\`\`\`
-    `;
-    var body = '&body=' + encodeURIComponent(issueBody.trim());
-    var reportErrorEl = parentElem.createChild('a', 'audits2-link audits2-report-error');
-    reportErrorEl.href = baseURI + title + body;
-    reportErrorEl.textContent = Common.UIString('Report this bug');
-    reportErrorEl.target = '_blank';
-  }
-
-  /**
    * @param {!DataTransfer} dataTransfer
    */
   _handleDrop(dataTransfer) {
@@ -489,6 +440,234 @@
   }
 };
 
+Audits2.Audits2Panel.StatusView = class {
+  constructor() {
+    this._statusView = null;
+    this._progressWrapper = null;
+    this._progressBar = null;
+    this._statusText = null;
+
+    this._textChangedAt = 0;
+    this._fastFactsQueued = Audits2.Audits2Panel.StatusView.FastFacts.slice();
+    this._currentPhase = null;
+    this._scheduledTextChangeTimeout = null;
+    this._scheduledFastFactTimeout = null;
+  }
+
+  /**
+   * @param {!Element} parentElement
+   */
+  render(parentElement) {
+    this.reset();
+
+    this._statusView = parentElement.createChild('div', 'audits2-status vbox hidden');
+    this._progressWrapper = this._statusView.createChild('div', 'audits2-progress-wrapper');
+    this._progressBar = this._progressWrapper.createChild('div', 'audits2-progress-bar');
+    this._statusText = this._statusView.createChild('div', 'audits2-status-text');
+
+    this.updateStatus(Common.UIString('Loading...'));
+  }
+
+  reset() {
+    this._resetProgressBarClasses();
+    clearTimeout(this._scheduledFastFactTimeout);
+
+    this._textChangedAt = 0;
+    this._fastFactsQueued = Audits2.Audits2Panel.StatusView.FastFacts.slice();
+    this._currentPhase = null;
+    this._scheduledTextChangeTimeout = null;
+    this._scheduledFastFactTimeout = null;
+  }
+
+  /**
+   * @param {boolean} isVisible
+   */
+  setVisible(isVisible) {
+    this._statusView.classList.toggle('hidden', !isVisible);
+
+    if (!isVisible)
+      clearTimeout(this._scheduledFastFactTimeout);
+  }
+
+  /**
+   * @param {?string} message
+   */
+  updateStatus(message) {
+    if (!message || !this._statusText)
+      return;
+
+    if (message.startsWith('Cancel')) {
+      this._commitTextChange(Common.UIString('Cancelling\u2026'));
+      clearTimeout(this._scheduledFastFactTimeout);
+      return;
+    }
+
+    var nextPhase = this._getPhaseForMessage(message);
+    if (!nextPhase && !this._currentPhase) {
+      this._commitTextChange(Common.UIString('Lighthouse is warming up\u2026'));
+      clearTimeout(this._scheduledFastFactTimeout);
+    } else if (nextPhase && (!this._currentPhase || this._currentPhase.order < nextPhase.order)) {
+      this._currentPhase = nextPhase;
+      this._scheduleTextChange(Common.UIString(nextPhase.message));
+      this._scheduleFastFactCheck();
+      this._resetProgressBarClasses();
+      this._progressBar.classList.add(nextPhase.progressBarClass);
+    }
+  }
+
+  /**
+   * @param {string} message
+   * @return {?Audits2.Audits2Panel.StatusView.StatusPhases}
+   */
+  _getPhaseForMessage(message) {
+    return Audits2.Audits2Panel.StatusView.StatusPhases.find(phase => message.startsWith(phase.statusMessagePrefix));
+  }
+
+  _resetProgressBarClasses() {
+    if (!this._progressBar)
+      return;
+
+    this._progressBar.className = 'audits2-progress-bar';
+  }
+
+  _scheduleFastFactCheck() {
+    if (!this._currentPhase || this._scheduledFastFactTimeout)
+      return;
+
+    this._scheduledFastFactTimeout = setTimeout(() => {
+      this._updateFastFactIfNecessary();
+      this._scheduledFastFactTimeout = null;
+
+      this._scheduleFastFactCheck();
+    }, 100);
+  }
+
+  _updateFastFactIfNecessary() {
+    var now = performance.now();
+    if (now - this._textChangedAt < Audits2.Audits2Panel.StatusView.fastFactRotationInterval)
+      return;
+    if (!this._fastFactsQueued.length)
+      return;
+
+    var fastFactIndex = Math.floor(Math.random() * this._fastFactsQueued.length);
+    this._scheduleTextChange(ls`\ud83d\udca1 ${this._fastFactsQueued[fastFactIndex]}`);
+    this._fastFactsQueued.splice(fastFactIndex, 1);
+  }
+
+  /**
+   * @param {string} text
+   */
+  _commitTextChange(text) {
+    if (!this._statusText)
+      return;
+    this._textChangedAt = performance.now();
+    this._statusText.textContent = text;
+  }
+
+  /**
+   * @param {string} text
+   */
+  _scheduleTextChange(text) {
+    if (this._scheduledTextChangeTimeout)
+      clearTimeout(this._scheduledTextChangeTimeout);
+
+    var msSinceLastChange = performance.now() - this._textChangedAt;
+    var msToTextChange = Audits2.Audits2Panel.StatusView.minimumTextVisibilityDuration - msSinceLastChange;
+
+    this._scheduledTextChangeTimeout = setTimeout(() => {
+      this._commitTextChange(text);
+    }, Math.max(msToTextChange, 0));
+  }
+
+  /**
+   * @param {!Error} err
+   * @param {string} inspectedURL
+   */
+  renderBugReport(err, inspectedURL) {
+    console.error(err);
+    this._commitTextChange('');
+    this._statusText.createTextChild(Common.UIString('Ah, sorry! We ran into an error: '));
+    this._statusText.createChild('em').createTextChild(err.message);
+    if (Audits2.Audits2Panel.KnownBugPatterns.some(pattern => pattern.test(err.message))) {
+      var message = Common.UIString(
+          'Try to navigate to the URL in a fresh Chrome profile without any other tabs or ' +
+          'extensions open and try again.');
+      this._statusText.createChild('p').createTextChild(message);
+    } else {
+      this._renderBugReportLink(err, inspectedURL);
+    }
+  }
+
+  /**
+   * @param {!Error} err
+   * @param {string} inspectedURL
+   */
+  _renderBugReportLink(err, inspectedURL) {
+    var baseURI = 'https://github.com/GoogleChrome/lighthouse/issues/new?';
+    var title = encodeURI('title=DevTools Error: ' + err.message.substring(0, 60));
+
+    var issueBody = `
+**Initial URL**: ${inspectedURL}
+**Chrome Version**: ${navigator.userAgent.match(/Chrome\/(\S+)/)[1]}
+**Error Message**: ${err.message}
+**Stack Trace**:
+\`\`\`
+${err.stack}
+\`\`\`
+    `;
+    var body = '&body=' + encodeURIComponent(issueBody.trim());
+    var reportErrorEl = UI.XLink.create(
+        baseURI + title + body, Common.UIString('Report this bug'), 'audits2-link audits2-report-error');
+    this._statusText.appendChild(reportErrorEl);
+  }
+};
+
+/** @typedef {{message: string, progressBarClass: string, order: number}} */
+Audits2.Audits2Panel.StatusView.StatusPhases = [
+  {
+    progressBarClass: 'loading',
+    message: 'Lighthouse is loading your page with throttling to measure performance on a mobile device on 3G.',
+    statusMessagePrefix: 'Loading page',
+    order: 10,
+  },
+  {
+    progressBarClass: 'gathering',
+    message: 'Lighthouse is gathering information about the page to compute your score.',
+    statusMessagePrefix: 'Retrieving',
+    order: 20,
+  },
+  {
+    progressBarClass: 'auditing',
+    message: 'Almost there! Lighthouse is now generating your own special pretty report!',
+    statusMessagePrefix: 'Evaluating',
+    order: 30,
+  }
+];
+
+Audits2.Audits2Panel.StatusView.FastFacts = [
+  '1MB takes a minimum of 5 seconds to download on a typical 3G connection [Source: WebPageTest and DevTools 3G definition].',
+  'Rebuilding Pinterest pages for performance increased conversion rates by 15% [Source: WPO Stats]',
+  'BBC has seen a loss of 10% of their users for every extra second of page load [Source: WPO Stats]',
+  'By reducing the response size of JSON needed for displaying comments, Instagram saw increased impressions [Source: WPO Stats]',
+  'Walmart saw a 1% increase in revenue for every 100ms improvement in page load [Source: WPO Stats]',
+  'If a site takes >1 second to become interactive, users lose attention, and their perception of completing the page task is broken [Source: Google Developers Blog]',
+  '75% of global mobile users in 2016 were on 2G or 3G [Source: GSMA Mobile]',
+  'The average user device costs less than 200 USD. [Source: International Data Corporation]',
+  '53% of all site visits are abandoned if page load takes more than 3 seconds [Source: Google DoubleClick blog]',
+  '19 seconds is the average time a mobile web page takes to load on a 3G connection [Source: Google DoubleClick blog]',
+  '14 seconds is the average time a mobile web page takes to load on a 4G connection [Source: Google DoubleClick blog]',
+  '70% of mobile pages take nearly 7 seconds for the visual content above the fold to display on the screen. [Source: Think with Google]',
+  'As page load time increases from one second to seven seconds, the probability of a mobile site visitor bouncing increases 113%. [Source: Think with Google]',
+  'As the number of elements on a page increases from 400 to 6,000, the probability of conversion drops 95%. [Source: Think with Google]',
+  '70% of mobile pages weigh over 1MB, 36% over 2MB, and 12% over 4MB. [Source: Think with Google]',
+  'Lighthouse only simulates mobile performance; to measure performance on a real device, try WebPageTest.org [Source: Lighthouse team]',
+];
+
+/** @const */
+Audits2.Audits2Panel.StatusView.fastFactRotationInterval = 6000;
+/** @const */
+Audits2.Audits2Panel.StatusView.minimumTextVisibilityDuration = 3000;
+
 /**
  * @override
  */
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/audits2Dialog.css b/third_party/WebKit/Source/devtools/front_end/audits2/audits2Dialog.css
index 3d098c74..a27e1ed 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits2/audits2Dialog.css
+++ b/third_party/WebKit/Source/devtools/front_end/audits2/audits2Dialog.css
@@ -5,7 +5,8 @@
  */
 
 .audits2-view {
-    margin: 7px 20px;
+    --view-horizontal-margin: 20px;
+    margin: 7px var(--view-horizontal-margin);
     flex: auto;
     align-items: center;
 }
@@ -36,33 +37,65 @@
     color: #666;
 }
 
-.audits2-status .icon {
-    width: 64px;
-    height: 64px;
-    margin: 20px;
-    animation: spinner-animation 1200ms linear infinite;
-    transform-origin: 50% 50%;
-    padding: 4px;
+.audits2-status-text {
+    text-align: center;
+    height: 60px;
+    display: flex;
+    justify-content: center;
+    flex-direction: column;
 }
 
-.audits2-status .icon::before {
-    display: inline-block;
-    border: 4px solid #1565C0;
-    border-radius: 28px;
-    width: 56px;
-    height: 56px;
-    content: "";
-    position: absolute;
-    box-sizing: border-box;
+.audits2-progress-wrapper {
+    width: calc(100% + 2 * var(--view-horizontal-margin));
+    height: 2px;
+    background-color: #E1F5FE;
+    position: relative;
+    margin: 10px;
 }
 
-.audits2-status .icon::after {
-    display: inline-block;
-    width: 24px;
-    height: 28px;
-    background: white;
+.audits2-progress-bar {
+    width: 0%;
+    height: 100%;
+    background: #039BE5;
     position: absolute;
-    content: "";
+    transform-origin: left;
+    animation-fill-mode: forwards;
+    animation-timing-function: ease-out;
+    --progress-bar-loading-duration: 45s;
+    --progress-bar-gathering-duration: 12s;
+    --progress-bar-gathering-percent: 70%;
+    --progress-bar-auditing-duration: 5s;
+    --progress-bar-auditing-percent: 95%;
+}
+
+.audits2-progress-bar.loading {
+    animation-duration: var(--progress-bar-loading-duration);
+    animation-name: progressBarLoading;
+}
+
+@keyframes progressBarLoading {
+  0% { width: 0%; }
+  100% { width: var(--progress-bar-gathering-percent); }
+}
+
+.audits2-progress-bar.gathering {
+    animation-duration: var(--progress-bar-gathering-duration);
+    animation-name: progressBarGathering;
+}
+
+@keyframes progressBarGathering {
+  0% { width: var(--progress-bar-gathering-percent); }
+  100% { width: var(--progress-bar-auditing-percent); }
+}
+
+.audits2-progress-bar.auditing {
+    animation-duration: var(--progress-bar-auditing-duration);
+    animation-name: progressBarAuditing;
+}
+
+@keyframes progressBarAuditing {
+  0% { width: var(--progress-bar-auditing-percent); }
+  100% { width: 99%; }
 }
 
 .audits2-report-error {
@@ -74,12 +107,6 @@
     margin: 15px 10px;
 }
 
-.audits2-status .icon.error,
-.audits2-status .icon.error::before,
-.audits2-status .icon.error::after {
-    display: none;
-}
-
 .audits2-launcher-row {
     padding: 6px;
 }
@@ -95,8 +122,4 @@
 
 .audits2-dialog-buttons {
     justify-content: center;
-}
-
-@keyframes spinner-animation {
-    from { transform: rotate(0); }
-    to { transform: rotate(360deg); }
+}
\ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/externs.js b/third_party/WebKit/Source/devtools/front_end/externs.js
index 579f68d..e6ef2d12 100644
--- a/third_party/WebKit/Source/devtools/front_end/externs.js
+++ b/third_party/WebKit/Source/devtools/front_end/externs.js
@@ -638,6 +638,15 @@
  */
 Element.prototype.addEventListener = function(type, listener, options) {};
 
+/**
+ * @override
+ * @param {string} type
+ * @param {(!EventListener|!function (!Event): (boolean|undefined)|null)} listener
+ * @param {(boolean|!{capture: (boolean|undefined), once: (boolean|undefined), passive: (boolean|undefined)})=} options
+ * @this {EventTarget}
+ */
+Element.prototype.removeEventListener = function(type, listener, options) {};
+
 var acorn = {
   /**
    * @param {string} text
@@ -802,3 +811,9 @@
  * @return {string}
  */
 var ls = function(strings, vararg) {};
+
+/**
+ * @constructor
+ * @param {function(!Array<*>)} callback
+ */
+var ResizeObserver = function(callback) {};
diff --git a/third_party/WebKit/Source/devtools/front_end/network_log/HAREntry.js b/third_party/WebKit/Source/devtools/front_end/network_log/HAREntry.js
index 0eeb532f..198992d 100644
--- a/third_party/WebKit/Source/devtools/front_end/network_log/HAREntry.js
+++ b/third_party/WebKit/Source/devtools/front_end/network_log/HAREntry.js
@@ -62,8 +62,10 @@
       ipAddress = ipAddress.substr(0, portPositionInString);
 
     var timings = this._buildTimings();
+    var time = 0;
     // "ssl" is included in the connect field, so do not double count it.
-    var time = timings.blocked + timings.dns + timings.connect + timings.send + timings.wait + timings.receive;
+    for (var t of [timings.blocked, timings.dns, timings.connect, timings.send, timings.wait, timings.receive])
+      time += Math.max(t, 0);
 
     var entry = {
       startedDateTime: NetworkLog.HARLog.pseudoWallTime(this._request, this._request.issueTime()),
@@ -153,7 +155,7 @@
     var issueTime = this._request.issueTime();
     var startTime = this._request.startTime;
 
-    var result = {blocked: -1, dns: -1, ssl: -1, connect: -1, send: 0, wait: 0, receive: -1, _blocked_queueing: -1};
+    var result = {blocked: -1, dns: -1, ssl: -1, connect: -1, send: 0, wait: 0, receive: 0, _blocked_queueing: -1};
 
     var queuedTime = (issueTime < startTime) ? startTime - issueTime : -1;
     result.blocked = queuedTime;
diff --git a/third_party/WebKit/Source/devtools/front_end/perf_ui/FilmStripView.js b/third_party/WebKit/Source/devtools/front_end/perf_ui/FilmStripView.js
index e5ba112..3872f5b 100644
--- a/third_party/WebKit/Source/devtools/front_end/perf_ui/FilmStripView.js
+++ b/third_party/WebKit/Source/devtools/front_end/perf_ui/FilmStripView.js
@@ -201,47 +201,47 @@
   FrameBased: 'FrameBased'
 };
 
-
-/**
- * @unrestricted
- */
-PerfUI.FilmStripView.Dialog = class extends UI.VBox {
+PerfUI.FilmStripView.Dialog = class {
   /**
    * @param {!SDK.FilmStripModel.Frame} filmStripFrame
    * @param {number=} zeroTime
    */
   constructor(filmStripFrame, zeroTime) {
-    super(true);
-    this.registerRequiredCSS('perf_ui/filmStripDialog.css');
-    this.contentElement.classList.add('filmstrip-dialog');
-    this.contentElement.tabIndex = 0;
+    var prevButton = UI.createTextButton('\u25C0', this._onPrevFrame.bind(this));
+    prevButton.title = Common.UIString('Previous frame');
+    var nextButton = UI.createTextButton('\u25B6', this._onNextFrame.bind(this));
+    nextButton.title = Common.UIString('Next frame');
+
+    this._fragment = UI.Fragment.build`
+      <x-widget flex=none margin=12px>
+        <x-hbox overflow=auto border='1px solid #ddd' max-height=80vh max-width=80vw>
+          <img $=image></img>
+        </x-hbox>
+        <x-hbox x-center justify-content=center margin-top=10px>
+          ${prevButton}
+          <x-hbox $=time margin=8px></x-hbox>
+          ${nextButton}
+        </x-hbox>
+      </x-widget>
+    `;
+
+    this._widget = /** @type {!UI.XWidget} */ (this._fragment.element());
+    this._widget.tabIndex = 0;
+    this._widget.addEventListener('keydown', this._keyDown.bind(this), false);
 
     this._frames = filmStripFrame.model().frames();
     this._index = filmStripFrame.index;
     this._zeroTime = zeroTime || filmStripFrame.model().zeroTime();
-
-    var imageScrollElement = this.contentElement.createChild('div', 'filmstrip-dialog-image-scroll');
-    this._imageElement = imageScrollElement.createChild('img');
-    var footerElement = this.contentElement.createChild('div', 'filmstrip-dialog-footer');
-    footerElement.createChild('div', 'flex-auto');
-    var prevButton = UI.createTextButton('\u25C0', this._onPrevFrame.bind(this));
-    prevButton.title = Common.UIString('Previous frame');
-    footerElement.appendChild(prevButton);
-    this._timeLabel = footerElement.createChild('div', 'filmstrip-dialog-label');
-    var nextButton = UI.createTextButton('\u25B6', this._onNextFrame.bind(this));
-    nextButton.title = Common.UIString('Next frame');
-    footerElement.appendChild(nextButton);
-    footerElement.createChild('div', 'flex-auto');
-
-    this.contentElement.addEventListener('keydown', this._keyDown.bind(this), false);
-    this.setDefaultFocusedElement(this.contentElement);
+    /** @type {?UI.Dialog} */
+    this._dialog = null;
     this._render();
   }
 
   _resize() {
     if (!this._dialog) {
       this._dialog = new UI.Dialog();
-      this.show(this._dialog.contentElement);
+      this._dialog.contentElement.appendChild(this._widget);
+      this._dialog.setDefaultFocusedElement(this._widget);
       this._dialog.show();
     }
     this._dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
@@ -303,9 +303,9 @@
    */
   _render() {
     var frame = this._frames[this._index];
-    this._timeLabel.textContent = Number.millisToString(frame.timestamp - this._zeroTime);
+    this._fragment.$('time').textContent = Number.millisToString(frame.timestamp - this._zeroTime);
     return frame.imageDataPromise()
-        .then(PerfUI.FilmStripView._setImageData.bind(null, this._imageElement))
+        .then(PerfUI.FilmStripView._setImageData.bind(null, this._fragment.$('image')))
         .then(this._resize.bind(this));
   }
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/perf_ui/filmStripDialog.css b/third_party/WebKit/Source/devtools/front_end/perf_ui/filmStripDialog.css
deleted file mode 100644
index ec36734..0000000
--- a/third_party/WebKit/Source/devtools/front_end/perf_ui/filmStripDialog.css
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-
-:host {
-    flex: none !important;
-}
-
-.filmstrip-dialog {
-    margin: 12px;
-}
-
-.filmstrip-dialog-image-scroll {
-    overflow: auto;
-    border: 1px solid #ddd;
-    max-height: 80vh;
-    max-width: 80vw;
-}
-
-.filmstrip-dialog-footer {
-    display: flex;
-    align-items: center;
-    margin-top: 10px;
-}
-
-.filmstrip-dialog-label {
-    margin: 8px 8px;
-}
diff --git a/third_party/WebKit/Source/devtools/front_end/perf_ui/module.json b/third_party/WebKit/Source/devtools/front_end/perf_ui/module.json
index ac787fc..eb0d8998 100644
--- a/third_party/WebKit/Source/devtools/front_end/perf_ui/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/perf_ui/module.json
@@ -46,7 +46,6 @@
     "resources": [
         "chartViewport.css",
         "filmStripView.css",
-        "filmStripDialog.css",
         "flameChart.css",
         "overviewGrid.css",
         "pieChart.css",
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/GlassPane.js b/third_party/WebKit/Source/devtools/front_end/ui/GlassPane.js
index dd6f964f..b9a2faa 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/GlassPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/GlassPane.js
@@ -45,6 +45,13 @@
   }
 
   /**
+   * @param {?Element} element
+   */
+  setDefaultFocusedElement(element) {
+    this._widget.setDefaultFocusedElement(element);
+  }
+
+  /**
    * @param {boolean} dimmed
    */
   setDimmed(dimmed) {
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
index e2ac6bf..35b704c 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
@@ -744,6 +744,7 @@
   var document = event.target && event.target.ownerDocument;
   var element = document ? document.deepActiveElement() : null;
   UI.Widget.focusWidgetForNode(element);
+  UI.XWidget.focusWidgetForNode(element);
   if (!UI._keyboardFocus)
     return;
   element.setAttribute('data-keyboard-focus', 'true');
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/Widget.js b/third_party/WebKit/Source/devtools/front_end/ui/Widget.js
index fef1eb8..76b0524a4 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/Widget.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/Widget.js
@@ -492,9 +492,17 @@
       for (var child of this._children) {
         if (child._visible) {
           child.focus();
-          break;
+          return;
         }
       }
+      var child = this.contentElement.traverseNextNode(this.contentElement);
+      while (child) {
+        if (child instanceof UI.XWidget) {
+          child.focus();
+          return;
+        }
+        child = child.traverseNextNode(this.contentElement);
+      }
     }
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/XElement.js b/third_party/WebKit/Source/devtools/front_end/ui/XElement.js
index 7c9ead9..b5a9db1d 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/XElement.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/XElement.js
@@ -8,10 +8,11 @@
 UI.XElement = class extends HTMLElement {
   static get observedAttributes() {
     return [
-      'flex',       'padding',    'padding-top',   'padding-bottom', 'padding-left', 'padding-right',
-      'margin',     'margin-top', 'margin-bottom', 'margin-left',    'margin-right', 'overflow',
-      'overflow-x', 'overflow-y', 'font-size',     'color',          'background',   'background-color',
-      'border',     'border-top', 'border-bottom', 'border-left',    'border-right'
+      'flex',          'padding',     'padding-top',      'padding-bottom', 'padding-left',
+      'padding-right', 'margin',      'margin-top',       'margin-bottom',  'margin-left',
+      'margin-right',  'overflow',    'overflow-x',       'overflow-y',     'font-size',
+      'color',         'background',  'background-color', 'border',         'border-top',
+      'border-bottom', 'border-left', 'border-right',     'max-width',      'max-height'
     ];
   }
 
@@ -62,7 +63,7 @@
 
   static get observedAttributes() {
     // TODO(dgozman): should be super.observedAttributes, but does not compile.
-    return UI.XElement.observedAttributes.concat(['x-start', 'x-center', 'x-stretch', 'x-baseline']);
+    return UI.XElement.observedAttributes.concat(['x-start', 'x-center', 'x-stretch', 'x-baseline', 'justify-content']);
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/XWidget.js b/third_party/WebKit/Source/devtools/front_end/ui/XWidget.js
new file mode 100644
index 0000000..c47335b
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/ui/XWidget.js
@@ -0,0 +1,184 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @extends {UI.XElement}
+ */
+UI.XWidget = class extends UI.XElement {
+  constructor() {
+    super();
+    this.style.setProperty('display', 'flex');
+    this.style.setProperty('flex-direction', 'column');
+    this.style.setProperty('align-items', 'stretch');
+    this.style.setProperty('justify-content', 'flex-start');
+    this.style.setProperty('contain', 'layout style');
+
+    this._visible = false;
+    /** @type {?DocumentFragment} */
+    this._shadowRoot;
+    /** @type {?Element} */
+    this._defaultFocusedElement = null;
+    /** @type {!Array<!Element>} */
+    this._elementsToRestoreScrollPositionsFor = [];
+    /** @type {?function()} */
+    this._onShownCallback;
+    /** @type {?function()} */
+    this._onHiddenCallback;
+    /** @type {?function()} */
+    this._onResizedCallback;
+
+    if (!UI.XWidget._observer) {
+      UI.XWidget._observer = new ResizeObserver(entries => {
+        for (var entry of entries) {
+          if (entry.target._visible && entry.target._onResizedCallback)
+            entry.target._onResizedCallback.call(null);
+        }
+      });
+    }
+    UI.XWidget._observer.observe(this);
+
+    this.setElementsToRestoreScrollPositionsFor([this]);
+  }
+
+  /**
+   * @param {?Node} node
+   */
+  static focusWidgetForNode(node) {
+    node = node && node.parentNodeOrShadowHost();
+    var widget = null;
+    while (node) {
+      if (node instanceof UI.XWidget) {
+        if (widget)
+          node._defaultFocusedElement = widget;
+        widget = node;
+      }
+      node = node.parentNodeOrShadowHost();
+    }
+  }
+
+  /**
+   * @return {boolean}
+   */
+  isShowing() {
+    return this._visible;
+  }
+
+  /**
+   * @param {string} cssFile
+   */
+  registerRequiredCSS(cssFile) {
+    UI.appendStyle(this._shadowRoot || this, cssFile);
+  }
+
+  /**
+   * @param {?function()} callback
+   */
+  setOnShown(callback) {
+    this._onShownCallback = callback;
+  }
+
+  /**
+   * @param {?function()} callback
+   */
+  setOnHidden(callback) {
+    this._onHiddenCallback = callback;
+  }
+
+  /**
+   * @param {?function()} callback
+   */
+  setOnResized(callback) {
+    this._onResizedCallback = callback;
+  }
+
+  /**
+   * @param {!Array<!Element>} elements
+   */
+  setElementsToRestoreScrollPositionsFor(elements) {
+    for (var element of this._elementsToRestoreScrollPositionsFor)
+      element.removeEventListener('scroll', UI.XWidget._storeScrollPosition, {passive: true, capture: false});
+    this._elementsToRestoreScrollPositionsFor = elements;
+    for (var element of this._elementsToRestoreScrollPositionsFor)
+      element.addEventListener('scroll', UI.XWidget._storeScrollPosition, {passive: true, capture: false});
+  }
+
+  restoreScrollPositions() {
+    for (var element of this._elementsToRestoreScrollPositionsFor) {
+      if (element._scrollTop)
+        element.scrollTop = element._scrollTop;
+      if (element._scrollLeft)
+        element.scrollLeft = element._scrollLeft;
+    }
+  }
+
+  /**
+   * @param {!Event} event
+   */
+  static _storeScrollPosition(event) {
+    var element = event.currentTarget;
+    element._scrollTop = element.scrollTop;
+    element._scrollLeft = element.scrollLeft;
+  }
+
+  /**
+   * @param {?Element} element
+   */
+  setDefaultFocusedElement(element) {
+    if (element && !this.isSelfOrAncestor(element))
+      throw new Error('Default focus must be descendant');
+    this._defaultFocusedElement = element;
+  }
+
+  /**
+   * @override
+   */
+  focus() {
+    if (!this._visible)
+      return;
+
+    var element;
+    if (this._defaultFocusedElement && this.isSelfOrAncestor(this._defaultFocusedElement)) {
+      element = this._defaultFocusedElement;
+    } else if (this.tabIndex !== -1) {
+      element = this;
+    } else {
+      var child = this.traverseNextNode(this);
+      while (child) {
+        if ((child instanceof UI.XWidget) && child._visible) {
+          element = child;
+          break;
+        }
+        child = child.traverseNextNode(this);
+      }
+    }
+
+    if (!element || element.hasFocus())
+      return;
+    if (element === this)
+      HTMLElement.prototype.focus.call(this);
+    else
+      element.focus();
+  }
+
+  /**
+   * @override
+   */
+  connectedCallback() {
+    this._visible = true;
+    this.restoreScrollPositions();
+    if (this._onShownCallback)
+      this._onShownCallback.call(null);
+  }
+
+  /**
+   * @override
+   */
+  disconnectedCallback() {
+    this._visible = false;
+    if (this._onHiddenCallback)
+      this._onHiddenCallback.call(null);
+  }
+};
+
+self.customElements.define('x-widget', UI.XWidget);
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/module.json b/third_party/WebKit/Source/devtools/front_end/ui/module.json
index d2721e4..ec0c9740 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/ui/module.json
@@ -55,7 +55,8 @@
         "ZoomManager.js",
         "ShortcutsScreen.js",
         "Geometry.js",
-        "XLink.js"
+        "XLink.js",
+        "XWidget.js"
     ],
     "resources": [
         "checkboxTextLabel.css",
diff --git a/third_party/WebKit/Source/modules/clipboard/ClipboardPromise.cpp b/third_party/WebKit/Source/modules/clipboard/ClipboardPromise.cpp
index 95c2412..f1ea1d9 100644
--- a/third_party/WebKit/Source/modules/clipboard/ClipboardPromise.cpp
+++ b/third_party/WebKit/Source/modules/clipboard/ClipboardPromise.cpp
@@ -9,14 +9,33 @@
 #include "core/clipboard/DataTransfer.h"
 #include "core/clipboard/DataTransferItem.h"
 #include "core/clipboard/DataTransferItemList.h"
-#include "platform/CrossThreadFunctional.h"
+#include "core/dom/ExecutionContext.h"
+#include "core/frame/LocalFrame.h"
+#include "modules/permissions/PermissionUtils.h"
 #include "platform/clipboard/ClipboardMimeTypes.h"
 #include "public/platform/Platform.h"
 #include "public/platform/TaskType.h"
+#include "public/platform/modules/permissions/permission.mojom-blink.h"
 #include "third_party/WebKit/public/platform/WebClipboard.h"
 
+// And now, a brief note about clipboard permissions.
+//
+// There are 2 clipboard permissions defined in the spec:
+// * clipboard-read
+// * clipboard-write
+// See https://w3c.github.io/clipboard-apis/#clipboard-permissions
+//
+// In Chromium we automatically grant clipboard-write access and clipboard-read
+// access is gated behind a permission prompt. Both clipboard read and write
+// require the tab to be focused (and Chromium must be the foreground app) for
+// the operation to be allowed.
+
 namespace blink {
 
+using mojom::blink::PermissionStatus;
+using mojom::blink::PermissionService;
+using mojom::PageVisibilityState;
+
 ScriptPromise ClipboardPromise::CreateForRead(ScriptState* script_state) {
   ClipboardPromise* clipboard_promise = new ClipboardPromise(script_state);
   clipboard_promise->GetTaskRunner()->PostTask(
@@ -54,17 +73,84 @@
 
 ClipboardPromise::ClipboardPromise(ScriptState* script_state)
     : ContextLifecycleObserver(blink::ExecutionContext::From(script_state)),
+      script_state_(script_state),
       script_promise_resolver_(ScriptPromiseResolver::Create(script_state)),
-      buffer_(mojom::ClipboardBuffer::kStandard) {}
+      buffer_(mojom::ClipboardBuffer::kStandard),
+      write_data_() {}
 
 scoped_refptr<WebTaskRunner> ClipboardPromise::GetTaskRunner() {
   // TODO(garykac): Replace MiscPlatformAPI with TaskType specific to clipboard.
   return GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI);
 }
 
-// TODO(garykac): This currently only handles plain text.
-void ClipboardPromise::HandleRead() {
+PermissionService* ClipboardPromise::GetPermissionService() {
+  if (!permission_service_) {
+    ConnectToPermissionService(ExecutionContext::From(script_state_),
+                               mojo::MakeRequest(&permission_service_));
+  }
+  return permission_service_.get();
+}
+
+bool ClipboardPromise::IsFocusedDocument(ExecutionContext* context) {
+  DCHECK(context->IsDocument());
+  Document* doc = ToDocumentOrNull(context);
+  return doc && doc->hasFocus();
+}
+
+void ClipboardPromise::RequestReadPermission(
+    PermissionService::RequestPermissionCallback callback) {
   DCHECK(script_promise_resolver_);
+
+  ExecutionContext* context = ExecutionContext::From(script_state_);
+  DCHECK(context->IsSecureContext());  // [SecureContext] in IDL
+
+  // Document must be focused.
+  if (!IsFocusedDocument(context) || !GetPermissionService()) {
+    script_promise_resolver_->Reject();
+    return;
+  }
+
+  // Query for permission if necessary.
+  // See crbug.com/795929 for moving this check into the Browser process.
+  permission_service_->RequestPermission(
+      CreateClipboardPermissionDescriptor(
+          mojom::blink::PermissionName::CLIPBOARD_READ, false),
+      false, std::move(callback));
+}
+
+void ClipboardPromise::CheckWritePermission(
+    PermissionService::HasPermissionCallback callback) {
+  DCHECK(script_promise_resolver_);
+
+  ExecutionContext* context = ExecutionContext::From(script_state_);
+  DCHECK(context->IsSecureContext());  // [SecureContext] in IDL
+
+  // Document must be focused.
+  if (!IsFocusedDocument(context) || !GetPermissionService()) {
+    script_promise_resolver_->Reject();
+    return;
+  }
+
+  // Check current permission (but do not query the user).
+  // See crbug.com/795929 for moving this check into the Browser process.
+  permission_service_->HasPermission(
+      CreateClipboardPermissionDescriptor(
+          mojom::blink::PermissionName::CLIPBOARD_WRITE, false),
+      std::move(callback));
+}
+
+void ClipboardPromise::HandleRead() {
+  RequestReadPermission(WTF::Bind(&ClipboardPromise::HandleReadWithPermission,
+                                  WrapPersistent(this)));
+}
+
+// TODO(garykac): This currently only handles plain text.
+void ClipboardPromise::HandleReadWithPermission(PermissionStatus status) {
+  if (status != PermissionStatus::GRANTED) {
+    script_promise_resolver_->Reject();
+    return;
+  }
+
   String plain_text = Platform::Current()->Clipboard()->ReadPlainText(buffer_);
 
   const DataTransfer::DataTransferType type =
@@ -77,32 +163,61 @@
 }
 
 void ClipboardPromise::HandleReadText() {
-  DCHECK(script_promise_resolver_);
+  RequestReadPermission(WTF::Bind(
+      &ClipboardPromise::HandleReadTextWithPermission, WrapPersistent(this)));
+}
+
+void ClipboardPromise::HandleReadTextWithPermission(PermissionStatus status) {
+  if (status != PermissionStatus::GRANTED) {
+    script_promise_resolver_->Reject();
+    return;
+  }
+
   String text = Platform::Current()->Clipboard()->ReadPlainText(buffer_);
   script_promise_resolver_->Resolve(text);
 }
 
 // TODO(garykac): This currently only handles plain text.
 void ClipboardPromise::HandleWrite(DataTransfer* data) {
-  DCHECK(script_promise_resolver_);
+  // Scan DataTransfer and extract data types that we support.
   size_t num_items = data->items()->length();
   for (unsigned long i = 0; i < num_items; i++) {
     DataTransferItem* item = data->items()->item(i);
     DataObjectItem* objectItem = item->GetDataObjectItem();
     if (objectItem->Kind() == DataObjectItem::kStringKind &&
         objectItem->GetType() == kMimeTypeTextPlain) {
-      String text = objectItem->GetAsString();
-      Platform::Current()->Clipboard()->WritePlainText(text);
-      script_promise_resolver_->Resolve();
-      return;
+      write_data_ = objectItem->GetAsString();
+      break;
     }
   }
-  script_promise_resolver_->Reject();
+  CheckWritePermission(WTF::Bind(&ClipboardPromise::HandleWriteWithPermission,
+                                 WrapPersistent(this)));
+}
+
+void ClipboardPromise::HandleWriteWithPermission(PermissionStatus status) {
+  if (status != PermissionStatus::GRANTED) {
+    script_promise_resolver_->Reject();
+    return;
+  }
+
+  Platform::Current()->Clipboard()->WritePlainText(write_data_);
+  script_promise_resolver_->Resolve();
 }
 
 void ClipboardPromise::HandleWriteText(const String& data) {
+  write_data_ = data;
+  CheckWritePermission(WTF::Bind(
+      &ClipboardPromise::HandleWriteTextWithPermission, WrapPersistent(this)));
+}
+
+void ClipboardPromise::HandleWriteTextWithPermission(PermissionStatus status) {
+  if (status != PermissionStatus::GRANTED) {
+    script_promise_resolver_->Reject();
+    return;
+  }
+
   DCHECK(script_promise_resolver_);
-  Platform::Current()->Clipboard()->WritePlainText(data);
+  Platform::Current()->Clipboard()->WritePlainText(write_data_);
   script_promise_resolver_->Resolve();
 }
 
diff --git a/third_party/WebKit/Source/modules/clipboard/ClipboardPromise.h b/third_party/WebKit/Source/modules/clipboard/ClipboardPromise.h
index 8b0c254..b4aa20e 100644
--- a/third_party/WebKit/Source/modules/clipboard/ClipboardPromise.h
+++ b/third_party/WebKit/Source/modules/clipboard/ClipboardPromise.h
@@ -8,6 +8,7 @@
 #include "bindings/core/v8/ScriptPromise.h"
 #include "core/CoreExport.h"
 #include "core/dom/ContextLifecycleObserver.h"
+#include "public/platform/modules/permissions/permission.mojom-blink.h"
 #include "third_party/WebKit/common/clipboard/clipboard.mojom-blink.h"
 
 namespace blink {
@@ -35,16 +36,36 @@
   ClipboardPromise(ScriptState*);
 
   scoped_refptr<WebTaskRunner> GetTaskRunner();
+  mojom::blink::PermissionService* GetPermissionService();
+
+  bool IsFocusedDocument(ExecutionContext*);
+
+  void RequestReadPermission(
+      mojom::blink::PermissionService::RequestPermissionCallback);
+  void CheckWritePermission(
+      mojom::blink::PermissionService::HasPermissionCallback);
 
   void HandleRead();
+  void HandleReadWithPermission(mojom::blink::PermissionStatus);
+
   void HandleReadText();
+  void HandleReadTextWithPermission(mojom::blink::PermissionStatus);
 
   void HandleWrite(DataTransfer*);
+  void HandleWriteWithPermission(mojom::blink::PermissionStatus);
+
   void HandleWriteText(const String&);
+  void HandleWriteTextWithPermission(mojom::blink::PermissionStatus);
+
+  ScriptState* script_state_;
 
   Member<ScriptPromiseResolver> script_promise_resolver_;
 
+  mojom::blink::PermissionServicePtr permission_service_;
+
   mojom::ClipboardBuffer buffer_;
+
+  WebString write_data_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp
index 98c2317..510b1b7 100644
--- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuota.cpp
@@ -45,10 +45,12 @@
 #include "public/platform/Platform.h"
 #include "public/platform/TaskType.h"
 #include "public/platform/WebStorageQuotaCallbacks.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom-blink.h"
 
 namespace blink {
 
+using mojom::StorageType;
+
 namespace {
 
 StorageType GetStorageType(DeprecatedStorageQuota::Type type) {
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.cpp b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.cpp
index e86707b..96031f9 100644
--- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.cpp
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.cpp
@@ -70,7 +70,8 @@
     quota_callback_->InvokeAndReportException(nullptr, granted_quota_in_bytes);
 }
 
-void DeprecatedStorageQuotaCallbacksImpl::DidFail(QuotaStatusCode error) {
+void DeprecatedStorageQuotaCallbacksImpl::DidFail(
+    mojom::QuotaStatusCode error) {
   if (error_callback_) {
     error_callback_->InvokeAndReportException(
         nullptr, DOMError::Create(static_cast<ExceptionCode>(error)));
diff --git a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.h b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.h
index 241b8ac..05370b0 100644
--- a/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.h
+++ b/third_party/WebKit/Source/modules/quota/DeprecatedStorageQuotaCallbacksImpl.h
@@ -62,7 +62,7 @@
                                     unsigned long long quota_in_bytes) override;
   void DidGrantStorageQuota(unsigned long long usage_in_bytes,
                             unsigned long long granted_quota_in_bytes) override;
-  void DidFail(QuotaStatusCode) override;
+  void DidFail(mojom::QuotaStatusCode) override;
 
  private:
   DeprecatedStorageQuotaCallbacksImpl(V8StorageUsageCallback*,
diff --git a/third_party/WebKit/Source/modules/quota/StorageManager.cpp b/third_party/WebKit/Source/modules/quota/StorageManager.cpp
index bd07f4d..710f357 100644
--- a/third_party/WebKit/Source/modules/quota/StorageManager.cpp
+++ b/third_party/WebKit/Source/modules/quota/StorageManager.cpp
@@ -18,8 +18,7 @@
 #include "platform/wtf/Assertions.h"
 #include "platform/wtf/Functional.h"
 #include "public/platform/Platform.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom-blink.h"
 
 namespace blink {
 
@@ -50,7 +49,7 @@
     resolver_->Resolve(estimate);
   }
 
-  void DidFail(QuotaStatusCode error) override {
+  void DidFail(mojom::QuotaStatusCode error) override {
     // TODO(sashab): Replace this with a switch statement, and remove the enum
     // values from QuotaStatusCode.
     resolver_->Reject(DOMException::Create(static_cast<ExceptionCode>(error)));
@@ -127,7 +126,7 @@
   }
 
   Platform::Current()->QueryStorageUsageAndQuota(
-      WrapRefCounted(security_origin), StorageType::kTemporary,
+      WrapRefCounted(security_origin), mojom::StorageType::kTemporary,
       new EstimateCallbacks(resolver));
   return promise;
 }
@@ -156,10 +155,12 @@
   resolver->Resolve(status == PermissionStatus::GRANTED);
 }
 
-STATIC_ASSERT_ENUM(QuotaStatusCode::kErrorNotSupported, kNotSupportedError);
-STATIC_ASSERT_ENUM(QuotaStatusCode::kErrorInvalidModification,
+STATIC_ASSERT_ENUM(mojom::QuotaStatusCode::kErrorNotSupported,
+                   kNotSupportedError);
+STATIC_ASSERT_ENUM(mojom::QuotaStatusCode::kErrorInvalidModification,
                    kInvalidModificationError);
-STATIC_ASSERT_ENUM(QuotaStatusCode::kErrorInvalidAccess, kInvalidAccessError);
-STATIC_ASSERT_ENUM(QuotaStatusCode::kErrorAbort, kAbortError);
+STATIC_ASSERT_ENUM(mojom::QuotaStatusCode::kErrorInvalidAccess,
+                   kInvalidAccessError);
+STATIC_ASSERT_ENUM(mojom::QuotaStatusCode::kErrorAbort, kAbortError);
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/quota/StorageQuotaClient.cpp b/third_party/WebKit/Source/modules/quota/StorageQuotaClient.cpp
index 2b0502b7..f23f99a 100644
--- a/third_party/WebKit/Source/modules/quota/StorageQuotaClient.cpp
+++ b/third_party/WebKit/Source/modules/quota/StorageQuotaClient.cpp
@@ -46,7 +46,7 @@
 StorageQuotaClient::~StorageQuotaClient() {}
 
 void StorageQuotaClient::RequestQuota(ScriptState* script_state,
-                                      StorageType storage_type,
+                                      mojom::StorageType storage_type,
                                       unsigned long long new_quota_in_bytes,
                                       V8StorageQuotaCallback* success_callback,
                                       V8StorageErrorCallback* error_callback) {
diff --git a/third_party/WebKit/Source/modules/quota/StorageQuotaClient.h b/third_party/WebKit/Source/modules/quota/StorageQuotaClient.h
index 3375e63..981bd218 100644
--- a/third_party/WebKit/Source/modules/quota/StorageQuotaClient.h
+++ b/third_party/WebKit/Source/modules/quota/StorageQuotaClient.h
@@ -37,7 +37,7 @@
 #include "platform/Supplementable.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Forward.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom-blink.h"
 
 namespace blink {
 
@@ -58,7 +58,7 @@
   virtual ~StorageQuotaClient();
 
   void RequestQuota(ScriptState*,
-                    StorageType,
+                    mojom::StorageType,
                     unsigned long long new_quota_in_bytes,
                     V8StorageQuotaCallback*,
                     V8StorageErrorCallback*);
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
index c8d1813..1d65feae 100644
--- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
+++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
@@ -68,6 +68,8 @@
       : vr_display_(vr_display) {}
   ~VRDisplayFrameRequestCallback() override {}
   void Invoke(double high_res_time_ms) override {
+    if (Id() != vr_display_->PendingMagicWindowVSyncId())
+      return;
     double monotonic_time;
     if (!vr_display_->GetDocument() || !vr_display_->GetDocument()->Loader()) {
       monotonic_time = WTF::CurrentTimeTicksInSeconds();
@@ -221,6 +223,7 @@
     if (pending_magic_window_vsync_)
       return;
     magic_window_vsync_waiting_for_pose_.Reset();
+    magic_window_pose_request_time_ = WTF::CurrentTimeTicks();
     magic_window_provider_->GetPose(
         WTF::Bind(&VRDisplay::OnMagicWindowPose, WrapWeakPersistent(this)));
     pending_magic_window_vsync_ = true;
@@ -256,6 +259,7 @@
   // before rAF (b), after rAF (c), or not at all (d). If rAF isn't called at
   // all, there won't be future frames.
 
+  pending_magic_window_vsync_ = false;
   pending_presenting_vsync_ = true;
   vr_presentation_provider_->GetVSync(
       WTF::Bind(&VRDisplay::OnPresentingVSync, WrapWeakPersistent(this)));
@@ -919,6 +923,7 @@
   did_submit_this_frame_ = false;
   frame_transport_method_ = FrameTransport::kUninitialized;
   wait_for_previous_render_ = WaitPrevStrategy::kUninitialized;
+  RequestVSync();
 }
 
 void VRDisplay::OnActivate(device::mojom::blink::VRDisplayEventReason reason,
@@ -1049,21 +1054,26 @@
   if (is_presenting_)
     return;
   vr_frame_id_ = -1;
-  WTF::TimeDelta pose_age = WTF::CurrentTimeTicks() - magic_window_pose_time_;
-  if (pose_age < kMagicWindowPoseAgeThreshold) {
-    ProcessScheduledAnimations(timestamp);
-  } else {
-    // The VSync got triggered before ever getting a pose, or the pose is
+  WTF::TimeDelta pose_age =
+      WTF::CurrentTimeTicks() - magic_window_pose_received_time_;
+  if (pose_age >= kMagicWindowPoseAgeThreshold &&
+      magic_window_pose_request_time_ > magic_window_pose_received_time_) {
+    // The VSync got triggered before ever receiving a pose, or the pose is
     // stale. Defer the animation until a pose arrives to avoid passing null
-    // poses to the application.
+    // poses to the application, but only do this if we have an outstanding
+    // unresolved GetPose request. For example, the pose might be stale after
+    // exiting VR Browser magic window mode due to a longish transition, but we
+    // need to use it anyway if it's from the current frame's GetPose.
     magic_window_vsync_waiting_for_pose_ =
         WTF::Bind(&VRDisplay::ProcessScheduledAnimations,
                   WrapWeakPersistent(this), timestamp);
+  } else {
+    ProcessScheduledAnimations(timestamp);
   }
 }
 
 void VRDisplay::OnMagicWindowPose(device::mojom::blink::VRPosePtr pose) {
-  magic_window_pose_time_ = WTF::CurrentTimeTicks();
+  magic_window_pose_received_time_ = WTF::CurrentTimeTicks();
   if (!in_animation_frame_) {
     frame_pose_ = std::move(pose);
   } else {
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplay.h b/third_party/WebKit/Source/modules/vr/VRDisplay.h
index 28d0d67..9cfc03d7 100644
--- a/third_party/WebKit/Source/modules/vr/VRDisplay.h
+++ b/third_party/WebKit/Source/modules/vr/VRDisplay.h
@@ -100,6 +100,7 @@
   void FocusChanged();
 
   void OnMagicWindowVSync(double timestamp);
+  int PendingMagicWindowVSyncId() { return pending_magic_window_vsync_id_; }
 
   void Trace(blink::Visitor*) override;
   void TraceWrappers(const ScriptWrappableVisitor*) const override;
@@ -248,7 +249,8 @@
   bool pending_magic_window_vsync_ = false;
   int pending_magic_window_vsync_id_ = -1;
   base::OnceClosure magic_window_vsync_waiting_for_pose_;
-  WTF::TimeTicks magic_window_pose_time_;
+  WTF::TimeTicks magic_window_pose_request_time_;
+  WTF::TimeTicks magic_window_pose_received_time_;
   bool in_animation_frame_ = false;
   bool did_submit_this_frame_ = false;
   bool display_blurred_ = false;
diff --git a/third_party/WebKit/Source/platform/StorageQuotaCallbacks.h b/third_party/WebKit/Source/platform/StorageQuotaCallbacks.h
index 55eff8a..ecbf1ec 100644
--- a/third_party/WebKit/Source/platform/StorageQuotaCallbacks.h
+++ b/third_party/WebKit/Source/platform/StorageQuotaCallbacks.h
@@ -35,7 +35,7 @@
 #include "platform/heap/Handle.h"
 #include "platform/wtf/Assertions.h"
 #include "platform/wtf/Noncopyable.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom-blink.h"
 
 namespace blink {
 
@@ -56,7 +56,7 @@
                                     unsigned long long granted_quota_in_bytes) {
     NOTREACHED();
   }
-  virtual void DidFail(QuotaStatusCode) { NOTREACHED(); }
+  virtual void DidFail(mojom::QuotaStatusCode) { NOTREACHED(); }
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/WebVectorTest.cpp b/third_party/WebKit/Source/platform/WebVectorTest.cpp
index a6d1a48e..b66c16a 100644
--- a/third_party/WebKit/Source/platform/WebVectorTest.cpp
+++ b/third_party/WebKit/Source/platform/WebVectorTest.cpp
@@ -6,6 +6,7 @@
 
 #include "platform/wtf/StdLibExtras.h"
 #include "platform/wtf/Vector.h"
+#include "public/platform/WebString.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
@@ -124,4 +125,30 @@
     EXPECT_EQ(input[i], assigned[i]);
 }
 
+TEST(WebVectorTest, Reserve) {
+  WebVector<int> vector;
+  vector.reserve(10);
+
+  EXPECT_EQ(10U, vector.capacity());
+}
+
+TEST(WebVectorTest, EmplaceBackArgumentForwarding) {
+  WebVector<WebString> vector;
+  vector.reserve(1);
+  WebUChar buffer[] = {'H', 'e', 'l', 'l', 'o', ' ', 'b', 'l', 'i', 'n', 'k'};
+  vector.emplace_back(buffer, WTF_ARRAY_LENGTH(buffer));
+  ASSERT_EQ(1U, vector.size());
+  EXPECT_EQ(WebString(buffer, WTF_ARRAY_LENGTH(buffer)), vector[0]);
+}
+
+TEST(WebVectorTest, EmplaceBackElementPlacement) {
+  WebVector<int> vector;
+  vector.reserve(10);
+  for (int i = 0; i < 10; ++i)
+    vector.emplace_back(i);
+  ASSERT_EQ(10U, vector.size());
+  for (int i = 0; i < 10; ++i)
+    EXPECT_EQ(i, vector[i]);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/exported/WebImage.cpp b/third_party/WebKit/Source/platform/exported/WebImage.cpp
index 5bb788ec..1af970a 100644
--- a/third_party/WebKit/Source/platform/exported/WebImage.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebImage.cpp
@@ -33,7 +33,9 @@
 #include <algorithm>
 #include <memory>
 #include "base/memory/scoped_refptr.h"
+#include "platform/DragImage.h"
 #include "platform/SharedBuffer.h"
+#include "platform/graphics/BitmapImage.h"
 #include "platform/graphics/Image.h"
 #include "platform/image-decoders/ImageDecoder.h"
 #include "platform/wtf/Vector.h"
@@ -169,11 +171,24 @@
   return WebSize(bitmap_.width(), bitmap_.height());
 }
 
-WebImage::WebImage(scoped_refptr<Image> image) {
+WebImage::WebImage(scoped_refptr<Image> image,
+                   RespectImageOrientationEnum should_respect_image_orientation) {
   if (!image)
     return;
 
-  if (sk_sp<SkImage> sk_image = image->PaintImageForCurrentFrame().GetSkImage())
+  PaintImage paint_image = image->PaintImageForCurrentFrame();
+  if (!paint_image)
+    return;
+
+  if (should_respect_image_orientation == kRespectImageOrientation &&
+      image->IsBitmapImage()) {
+    ImageOrientation orientation = ToBitmapImage(image.get())->CurrentFrameOrientation();
+    paint_image = DragImage::ResizeAndOrientImage(paint_image, orientation);
+    if (!paint_image)
+      return;
+  }
+
+  if (sk_sp<SkImage> sk_image = paint_image.GetSkImage())
     sk_image->asLegacyBitmap(&bitmap_, SkImage::kRO_LegacyBitmapMode);
 }
 
diff --git a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
index 90fa9c2..540926f 100644
--- a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
@@ -322,6 +322,10 @@
   RuntimeEnabledFeatures::SetForceOverlayFullscreenVideoEnabled(enable);
 }
 
+void WebRuntimeFeatures::EnableSharedArrayBuffer(bool enable) {
+  RuntimeEnabledFeatures::SetSharedArrayBufferEnabled(enable);
+}
+
 void WebRuntimeFeatures::EnableSharedWorker(bool enable) {
   RuntimeEnabledFeatures::SetSharedWorkerEnabled(enable);
 }
diff --git a/third_party/WebKit/Source/platform/exported/WebStorageQuotaCallbacks.cpp b/third_party/WebKit/Source/platform/exported/WebStorageQuotaCallbacks.cpp
index 688e7ab..04f4f6e 100644
--- a/third_party/WebKit/Source/platform/exported/WebStorageQuotaCallbacks.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebStorageQuotaCallbacks.cpp
@@ -36,7 +36,7 @@
   private_.Reset();
 }
 
-void WebStorageQuotaCallbacks::DidFail(QuotaStatusCode error) {
+void WebStorageQuotaCallbacks::DidFail(mojom::QuotaStatusCode error) {
   DCHECK(!private_.IsNull());
   private_->DidFail(error);
   private_.Reset();
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
index ebd3833..69b4048 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
@@ -295,7 +295,7 @@
 
   TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox");
 
-  // Resolve the multisampled buffer into m_backColorBuffer texture.
+  // Resolve the multisampled buffer into the texture attached to fbo_.
   ResolveIfNeeded();
 
   if (!using_gpu_compositing_ && !force_gpu_result) {
@@ -357,6 +357,16 @@
     gl_->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
   }
 
+  if (premultiplied_alpha_false_texture_) {
+    // The rendering results are in this texture rather than the
+    // back_color_buffer_'s texture. Copy them in, multiplying the alpha channel
+    // into the color channels.
+    gl_->CopySubTextureCHROMIUM(premultiplied_alpha_false_texture_, 0,
+                                texture_target_, back_color_buffer_->texture_id,
+                                0, 0, 0, 0, 0, size_.Width(), size_.Height(),
+                                GL_FALSE, GL_TRUE, GL_FALSE);
+  }
+
   // Specify the buffer that we will put in the mailbox.
   scoped_refptr<ColorBuffer> color_buffer_for_mailbox;
   if (preserve_drawing_buffer_ == kDiscard) {
@@ -774,8 +784,17 @@
     produce_sync_token = front_color_buffer_->produce_sync_token;
   } else {
     src_gl->GenMailboxCHROMIUM(mailbox.name);
-    src_gl->ProduceTextureDirectCHROMIUM(back_color_buffer_->texture_id,
-                                         mailbox.name);
+    if (premultiplied_alpha_false_texture_) {
+      // If this texture exists, then it holds the rendering results at this
+      // point, rather than back_color_buffer_. back_color_buffer_ receives the
+      // contents of this texture later, premultiplying alpha into the color
+      // channels.
+      src_gl->ProduceTextureDirectCHROMIUM(premultiplied_alpha_false_texture_,
+                                           mailbox.name);
+    } else {
+      src_gl->ProduceTextureDirectCHROMIUM(back_color_buffer_->texture_id,
+                                           mailbox.name);
+    }
     src_gl->GenUnverifiedSyncTokenCHROMIUM(produce_sync_token.GetData());
   }
 
@@ -818,7 +837,11 @@
 
     layer_->SetOpaque(!want_alpha_channel_);
     layer_->SetBlendBackgroundColor(want_alpha_channel_);
-    layer_->SetPremultipliedAlpha(premultiplied_alpha_);
+    // If ShouldUseChromiumImage(), premultiplied_alpha_ has already been
+    // handled via CopySubTextureCHROMIUM, and does not need to be handled by
+    // the compositor.
+    layer_->SetPremultipliedAlpha(premultiplied_alpha_ &&
+                                  !ShouldUseChromiumImage());
     layer_->SetNearestNeighbor(filter_quality_ == kNone_SkFilterQuality);
     GraphicsLayer::RegisterContentsLayer(layer_->Layer());
   }
@@ -852,12 +875,16 @@
   if (depth_stencil_buffer_)
     gl_->DeleteRenderbuffers(1, &depth_stencil_buffer_);
 
+  if (premultiplied_alpha_false_texture_)
+    gl_->DeleteTextures(1, &premultiplied_alpha_false_texture_);
+
   size_ = IntSize();
 
   back_color_buffer_ = nullptr;
   front_color_buffer_ = nullptr;
   multisample_renderbuffer_ = 0;
   depth_stencil_buffer_ = 0;
+  premultiplied_alpha_false_texture_ = 0;
   multisample_fbo_ = 0;
   fbo_ = 0;
 
@@ -872,6 +899,50 @@
   // Recreate m_backColorBuffer.
   back_color_buffer_ = CreateColorBuffer(size);
 
+  // Most OS compositors assume GpuMemoryBuffers contain premultiplied-alpha
+  // content. If the user created the context with premultipliedAlpha:false and
+  // GpuMemoryBuffers are being used, allocate a non-GMB texture which will hold
+  // the non-premultiplied rendering results. These will be copied into the GMB
+  // via CopySubTextureCHROMIUM, performing the premultiplication step then.
+  if (ShouldUseChromiumImage() && allocate_alpha_channel_ &&
+      !premultiplied_alpha_) {
+    state_restorer_->SetTextureBindingDirty();
+    // TODO(kbr): unify with code in CreateColorBuffer.
+    if (premultiplied_alpha_false_texture_) {
+      gl_->DeleteTextures(1, &premultiplied_alpha_false_texture_);
+      premultiplied_alpha_false_texture_ = 0;
+    }
+    gl_->GenTextures(1, &premultiplied_alpha_false_texture_);
+    // The command decoder forbids allocating "real" OpenGL textures with the
+    // GL_TEXTURE_RECTANGLE_ARB target. Allocate this temporary texture with
+    // type GL_TEXTURE_2D all the time. CopySubTextureCHROMIUM can handle
+    // copying between 2D and rectangular textures.
+    gl_->BindTexture(GL_TEXTURE_2D, premultiplied_alpha_false_texture_);
+    if (storage_texture_supported_) {
+      GLenum internal_storage_format = GL_RGBA8;
+      if (use_half_float_storage_) {
+        internal_storage_format = GL_RGBA16F_EXT;
+      }
+      gl_->TexStorage2DEXT(GL_TEXTURE_2D, 1, internal_storage_format,
+                           size.Width(), size.Height());
+    } else {
+      GLenum internal_format = GL_RGBA;
+      GLenum format = internal_format;
+      GLenum data_type = GL_UNSIGNED_BYTE;
+      if (use_half_float_storage_) {
+        if (webgl_version_ > kWebGL1) {
+          internal_format = GL_RGBA16F;
+          data_type = GL_HALF_FLOAT;
+        } else {
+          internal_format = GL_RGBA;
+          data_type = GL_HALF_FLOAT_OES;
+        }
+      }
+      gl_->TexImage2D(GL_TEXTURE_2D, 0, internal_format, size.Width(),
+                      size.Height(), 0, format, data_type, nullptr);
+    }
+  }
+
   AttachColorBufferToReadFramebuffer();
 
   if (WantExplicitResolve()) {
@@ -1317,17 +1388,26 @@
 
   gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
 
-  GLenum id = back_color_buffer_->texture_id;
+  GLenum id = 0;
+  GLenum texture_target = 0;
 
-  gl_->BindTexture(texture_target_, id);
+  if (premultiplied_alpha_false_texture_) {
+    id = premultiplied_alpha_false_texture_;
+    texture_target = GL_TEXTURE_2D;
+  } else {
+    id = back_color_buffer_->texture_id;
+    texture_target = texture_target_;
+  }
+
+  gl_->BindTexture(texture_target, id);
 
   if (anti_aliasing_mode_ == kMSAAImplicitResolve) {
     gl_->FramebufferTexture2DMultisampleEXT(
-        GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target_, id, 0,
+        GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, id, 0,
         sample_count_);
   } else {
     gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                              texture_target_, id, 0);
+                              texture_target, id, 0);
   }
 }
 
@@ -1449,13 +1529,6 @@
 bool DrawingBuffer::ShouldUseChromiumImage() {
   return RuntimeEnabledFeatures::WebGLImageChromiumEnabled() &&
          chromium_image_usage_ == kAllowChromiumImage &&
-#if defined(OS_MACOSX)
-         // Core Animation assumes that the incoming alpha channel is
-         // premultiplied into the color channels. Fall back to
-         // regular compositing if the user wants the alpha channel
-         // interpreted as separate.
-         premultiplied_alpha_ &&
-#endif
          Platform::Current()->GetGpuMemoryBufferManager();
 }
 
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
index ff92729..9e2840f4 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
+++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h
@@ -479,6 +479,14 @@
   // The id of the renderbuffer storage for |m_multisampleFBO|.
   GLuint multisample_renderbuffer_ = 0;
 
+  // If premultipliedAlpha:false is set during context creation, and a
+  // GpuMemoryBuffer is used for the DrawingBuffer's storage, then a separate,
+  // regular, OpenGL texture is allocated to hold either the rendering results
+  // (if antialias:false) or resolve results (if antialias:true). Then
+  // CopyTextureCHROMIUM is used to multiply the alpha channel into the color
+  // channels when copying into the GMB.
+  GLuint premultiplied_alpha_false_texture_ = 0;
+
   // When wantExplicitResolve() returns false, the target of all draw and
   // read operations. When wantExplicitResolve() returns true, the target of
   // all read operations.
diff --git a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
index 68e6f5e..ec61d3e0 100644
--- a/third_party/WebKit/Source/platform/runtime_enabled_features.json5
+++ b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
@@ -219,7 +219,7 @@
     },
     {
       name: "CSSDisplayContents",
-      status: "experimental",
+      status: "stable",
     },
     {
       name: "CSSFontSizeAdjust",
@@ -968,6 +968,10 @@
       status: "experimental",
     },
     {
+      name: "SharedArrayBuffer",
+      status: "stable",
+    },
+    {
       name: "SharedWorker",
       status: "stable",
     },
diff --git a/third_party/WebKit/Source/platform/scheduler/util/thread_cpu_throttler.cc b/third_party/WebKit/Source/platform/scheduler/util/thread_cpu_throttler.cc
index accbf40..f68158d 100644
--- a/third_party/WebKit/Source/platform/scheduler/util/thread_cpu_throttler.cc
+++ b/third_party/WebKit/Source/platform/scheduler/util/thread_cpu_throttler.cc
@@ -14,6 +14,8 @@
 #if defined(OS_POSIX)
 #include <signal.h>
 #define USE_SIGNALS 1
+#elif defined(OS_WIN)
+#include <windows.h>
 #endif
 
 using base::subtle::Atomic32;
diff --git a/third_party/WebKit/common/BUILD.gn b/third_party/WebKit/common/BUILD.gn
index 7305f79..53f7209 100644
--- a/third_party/WebKit/common/BUILD.gn
+++ b/third_party/WebKit/common/BUILD.gn
@@ -53,8 +53,6 @@
     "origin_trials/trial_token.h",
     "origin_trials/trial_token_validator.cc",
     "origin_trials/trial_token_validator.h",
-    "quota/quota_status_code.h",
-    "quota/storage_type.h",
     "sandbox_flags.h",
   ]
 
diff --git a/third_party/WebKit/common/quota/OWNERS b/third_party/WebKit/common/quota/OWNERS
index 2c44a46..08850f4 100644
--- a/third_party/WebKit/common/quota/OWNERS
+++ b/third_party/WebKit/common/quota/OWNERS
@@ -1,6 +1,2 @@
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
-per-file *_struct_traits*.*=set noparent
-per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
-per-file *.typemap=set noparent
-per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/third_party/WebKit/common/quota/quota_status_code.h b/third_party/WebKit/common/quota/quota_status_code.h
deleted file mode 100644
index 76a1aef..0000000
--- a/third_party/WebKit/common/quota/quota_status_code.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_WEBKIT_COMMON_QUOTA_QUOTA_STATUS_CODE_H_
-#define THIRD_PARTY_WEBKIT_COMMON_QUOTA_QUOTA_STATUS_CODE_H_
-
-namespace blink {
-
-// These values need to match dom/ExceptionState.h.
-// TODO(sashab): Remove this and use mojom::storage::QuotaStatusCode instead.
-enum class QuotaStatusCode {
-  kOk = 0,
-  kErrorNotSupported = 7,
-  kErrorInvalidModification = 11,
-  kErrorInvalidAccess = 13,
-  kErrorAbort = 17,
-  kUnknown = -1,
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_WEBKIT_COMMON_QUOTA_QUOTA_STATUS_CODE_H_
diff --git a/third_party/WebKit/common/quota/quota_types.mojom b/third_party/WebKit/common/quota/quota_types.mojom
index 2ef5b27f..4ee2452 100644
--- a/third_party/WebKit/common/quota/quota_types.mojom
+++ b/third_party/WebKit/common/quota/quota_types.mojom
@@ -4,7 +4,6 @@
 
 module blink.mojom;
 
-// TODO(sashab): Remove duplicate definition blink::StorageType.
 enum StorageType {
   kTemporary,
   kPersistent,
@@ -13,12 +12,12 @@
   kUnknown,
 };
 
-// TODO(sashab): Remove duplicate definition blink::QuotaStatusCode.
+// These values need to match dom/ExceptionState.h.
 enum QuotaStatusCode {
   kOk = 0,
-  kErrorNotSupported,
-  kErrorInvalidModification,
-  kErrorInvalidAccess,
-  kErrorAbort,
-  kUnknown,
+  kErrorNotSupported = 7,
+  kErrorInvalidModification = 11,
+  kErrorInvalidAccess = 13,
+  kErrorAbort = 17,
+  kUnknown = -1,
 };
diff --git a/third_party/WebKit/common/quota/quota_types.typemap b/third_party/WebKit/common/quota/quota_types.typemap
deleted file mode 100644
index 230d8fe..0000000
--- a/third_party/WebKit/common/quota/quota_types.typemap
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//third_party/WebKit/common/quota/quota_types.mojom"
-public_headers = [
-  "//third_party/WebKit/common/quota/quota_status_code.h",
-  "//third_party/WebKit/common/quota/storage_type.h",
-]
-traits_headers =
-    [ "//third_party/WebKit/common/quota/quota_types_struct_traits.h" ]
-type_mappings = [
-  "blink.mojom.QuotaStatusCode=blink::QuotaStatusCode",
-  "blink.mojom.StorageType=blink::StorageType",
-]
diff --git a/third_party/WebKit/common/quota/quota_types_struct_traits.h b/third_party/WebKit/common/quota/quota_types_struct_traits.h
deleted file mode 100644
index 5cf3413..0000000
--- a/third_party/WebKit/common/quota/quota_types_struct_traits.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_WEBKIT_COMMON_QUOTA_QUOTA_TYPES_STRUCT_TRAITS_H_
-#define THIRD_PARTY_WEBKIT_COMMON_QUOTA_QUOTA_TYPES_STRUCT_TRAITS_H_
-
-#include "mojo/public/cpp/bindings/enum_traits.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
-#include "third_party/WebKit/common/quota/quota_types.mojom.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
-
-namespace mojo {
-
-template <>
-struct EnumTraits<blink::mojom::StorageType, blink::StorageType> {
-  static blink::mojom::StorageType ToMojom(blink::StorageType storage_type) {
-    switch (storage_type) {
-      case blink::StorageType::kTemporary:
-        return blink::mojom::StorageType::kTemporary;
-      case blink::StorageType::kPersistent:
-        return blink::mojom::StorageType::kPersistent;
-      case blink::StorageType::kSyncable:
-        return blink::mojom::StorageType::kSyncable;
-      case blink::StorageType::kQuotaNotManaged:
-        return blink::mojom::StorageType::kQuotaNotManaged;
-      case blink::StorageType::kUnknown:
-        return blink::mojom::StorageType::kUnknown;
-    }
-    NOTREACHED();
-    return blink::mojom::StorageType::kUnknown;
-  }
-
-  static bool FromMojom(blink::mojom::StorageType storage_type,
-                        blink::StorageType* out) {
-    switch (storage_type) {
-      case blink::mojom::StorageType::kTemporary:
-        *out = blink::StorageType::kTemporary;
-        return true;
-      case blink::mojom::StorageType::kPersistent:
-        *out = blink::StorageType::kPersistent;
-        return true;
-      case blink::mojom::StorageType::kSyncable:
-        *out = blink::StorageType::kSyncable;
-        return true;
-      case blink::mojom::StorageType::kQuotaNotManaged:
-        *out = blink::StorageType::kQuotaNotManaged;
-        return true;
-      case blink::mojom::StorageType::kUnknown:
-        *out = blink::StorageType::kUnknown;
-        return true;
-    }
-    NOTREACHED();
-    *out = blink::StorageType::kUnknown;
-    return false;
-  }
-};
-
-template <>
-struct EnumTraits<blink::mojom::QuotaStatusCode, blink::QuotaStatusCode> {
-  static blink::mojom::QuotaStatusCode ToMojom(
-      blink::QuotaStatusCode status_code) {
-    switch (status_code) {
-      case blink::QuotaStatusCode::kOk:
-        return blink::mojom::QuotaStatusCode::kOk;
-      case blink::QuotaStatusCode::kErrorNotSupported:
-        return blink::mojom::QuotaStatusCode::kErrorNotSupported;
-      case blink::QuotaStatusCode::kErrorInvalidModification:
-        return blink::mojom::QuotaStatusCode::kErrorInvalidModification;
-      case blink::QuotaStatusCode::kErrorInvalidAccess:
-        return blink::mojom::QuotaStatusCode::kErrorInvalidAccess;
-      case blink::QuotaStatusCode::kErrorAbort:
-        return blink::mojom::QuotaStatusCode::kErrorAbort;
-      case blink::QuotaStatusCode::kUnknown:
-        return blink::mojom::QuotaStatusCode::kUnknown;
-    }
-    NOTREACHED();
-    return blink::mojom::QuotaStatusCode::kUnknown;
-  }
-
-  static bool FromMojom(blink::mojom::QuotaStatusCode status_code,
-                        blink::QuotaStatusCode* out) {
-    switch (status_code) {
-      case blink::mojom::QuotaStatusCode::kOk:
-        *out = blink::QuotaStatusCode::kOk;
-        return true;
-      case blink::mojom::QuotaStatusCode::kErrorNotSupported:
-        *out = blink::QuotaStatusCode::kErrorNotSupported;
-        return true;
-      case blink::mojom::QuotaStatusCode::kErrorInvalidModification:
-        *out = blink::QuotaStatusCode::kErrorInvalidModification;
-        return true;
-      case blink::mojom::QuotaStatusCode::kErrorInvalidAccess:
-        *out = blink::QuotaStatusCode::kErrorInvalidAccess;
-        return true;
-      case blink::mojom::QuotaStatusCode::kErrorAbort:
-        *out = blink::QuotaStatusCode::kErrorAbort;
-        return true;
-      case blink::mojom::QuotaStatusCode::kUnknown:
-        *out = blink::QuotaStatusCode::kUnknown;
-        return true;
-    }
-    NOTREACHED();
-    return false;
-  }
-};
-
-}  // namespace mojo
-
-#endif  // THIRD_PARTY_WEBKIT_COMMON_QUOTA_QUOTA_TYPES_STRUCT_TRAITS_H_
diff --git a/third_party/WebKit/common/quota/storage_type.h b/third_party/WebKit/common/quota/storage_type.h
deleted file mode 100644
index d5c0288..0000000
--- a/third_party/WebKit/common/quota/storage_type.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_WEBKIT_COMMON_QUOTA_STORAGE_TYPE_H_
-#define THIRD_PARTY_WEBKIT_COMMON_QUOTA_STORAGE_TYPE_H_
-
-namespace blink {
-
-// TODO(sashab): Remove this and use mojom::storage::StorageType instead.
-enum class StorageType {
-  kTemporary,
-  kPersistent,
-  kSyncable,
-  kQuotaNotManaged,
-  kUnknown,
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_WEBKIT_COMMON_QUOTA_STORAGE_TYPE_H_
diff --git a/third_party/WebKit/common/typemaps.gni b/third_party/WebKit/common/typemaps.gni
index da421d0..873a123b 100644
--- a/third_party/WebKit/common/typemaps.gni
+++ b/third_party/WebKit/common/typemaps.gni
@@ -6,5 +6,4 @@
   "//third_party/WebKit/common/feature_policy/feature_policy.typemap",
   "//third_party/WebKit/common/message_port/cloneable_message.typemap",
   "//third_party/WebKit/common/message_port/transferable_message.typemap",
-  "//third_party/WebKit/common/quota/quota_types.typemap",
 ]
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h
index c128766..f063ac5 100644
--- a/third_party/WebKit/public/platform/Platform.h
+++ b/third_party/WebKit/public/platform/Platform.h
@@ -62,7 +62,7 @@
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "third_party/WebKit/common/feature_policy/feature_policy.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom-shared.h"
 
 namespace base {
 class SingleThreadTaskRunner;
@@ -702,7 +702,7 @@
   // error code.
   virtual void QueryStorageUsageAndQuota(
       const WebSecurityOrigin& storage_partition,
-      StorageType,
+      mojom::StorageType,
       WebStorageQuotaCallbacks) {}
 
   // WebDatabase --------------------------------------------------------
diff --git a/third_party/WebKit/public/platform/WebImage.h b/third_party/WebKit/public/platform/WebImage.h
index 90e7601c..ef1fb2c 100644
--- a/third_party/WebKit/public/platform/WebImage.h
+++ b/third_party/WebKit/public/platform/WebImage.h
@@ -38,6 +38,7 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 
 #if INSIDE_BLINK
+#include "platform/graphics/ImageOrientation.h"
 #include "base/memory/scoped_refptr.h"
 #endif
 
@@ -92,7 +93,8 @@
   BLINK_PLATFORM_EXPORT WebSize Size() const;
 
 #if INSIDE_BLINK
-  BLINK_PLATFORM_EXPORT WebImage(scoped_refptr<Image>);
+  BLINK_PLATFORM_EXPORT WebImage(scoped_refptr<Image>,
+                                 RespectImageOrientationEnum = kDoNotRespectImageOrientation);
 #endif
 
   WebImage(const SkBitmap& bitmap) : bitmap_(bitmap) {}
diff --git a/third_party/WebKit/public/platform/WebRuntimeFeatures.h b/third_party/WebKit/public/platform/WebRuntimeFeatures.h
index 9b5a573..305bd164 100644
--- a/third_party/WebKit/public/platform/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/platform/WebRuntimeFeatures.h
@@ -134,6 +134,7 @@
   BLINK_PLATFORM_EXPORT static void EnableServiceWorkerScriptStreaming(bool);
   BLINK_PLATFORM_EXPORT static void EnableServiceWorkerScriptFullCodeCache(
       bool);
+  BLINK_PLATFORM_EXPORT static void EnableSharedArrayBuffer(bool);
   BLINK_PLATFORM_EXPORT static void EnableSharedWorker(bool);
   BLINK_PLATFORM_EXPORT static void EnableSlimmingPaintV2(bool);
   BLINK_PLATFORM_EXPORT static void EnableTouchEventFeatureDetection(bool);
diff --git a/third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h b/third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h
index 69a26c23..c2c623ac 100644
--- a/third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h
+++ b/third_party/WebKit/public/platform/WebStorageQuotaCallbacks.h
@@ -33,7 +33,7 @@
 
 #include "WebCommon.h"
 #include "WebPrivatePtr.h"
-#include "third_party/WebKit/common/quota/quota_status_code.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom-shared.h"
 
 namespace blink {
 
@@ -67,7 +67,7 @@
       unsigned long long usage_in_bytes,
       unsigned long long granted_quota_in_bytes);
 
-  BLINK_PLATFORM_EXPORT void DidFail(QuotaStatusCode);
+  BLINK_PLATFORM_EXPORT void DidFail(mojom::QuotaStatusCode);
 
  private:
   WebPrivatePtr<StorageQuotaCallbacks> private_;
diff --git a/third_party/WebKit/public/platform/WebVector.h b/third_party/WebKit/public/platform/WebVector.h
index 6cc2882c..beb7b49 100644
--- a/third_party/WebKit/public/platform/WebVector.h
+++ b/third_party/WebKit/public/platform/WebVector.h
@@ -42,23 +42,30 @@
 //
 // Sample usage:
 //
-//   void Foo(WebVector<int>& result)
-//   {
-//       WebVector<int> data(10);
-//       for (size_t i = 0; i < data.size(); ++i)
-//           data[i] = ...
-//       result.swap(data);
+//   void Foo(WebVector<int>& result) {
+//     WebVector<int> data(10);
+//     for (size_t i = 0; i < data.size(); ++i)
+//         data[i] = ...
+//     result.Swap(data);
+//   }
+//
+// In-place element construction:
+//
+//   WebVector<WebString> Foo() {
+//     WebVector<WebString> data;
+//     data.reserve(10);
+//     WebUChar* buffer = ....;
+//     data.emplace_back(buffer, buffer_size);
+//     return data;
 //   }
 //
 // It is also possible to assign from any container that implements begin()
 // and end().
 //
-//   void Foo(const std::vector<WTF::String>& input)
-//   {
-//       WebVector<WebString> strings = input;
-//       ...
+//   void Foo(const std::vector<WTF::String>& input) {
+//     WebVector<WebString> strings = input;
+//     ...
 //   }
-//
 template <typename T>
 class WebVector {
  public:
@@ -68,6 +75,7 @@
 
   ~WebVector() = default;
 
+  // Create a vector with |size| default-constructed elements.
   explicit WebVector(size_t size = 0) : data_(size) {}
 
   template <typename U>
@@ -123,6 +131,9 @@
   // TODO(slangley): Remove all uses of IsEmpty.
   bool IsEmpty() const { return empty(); }
 
+  size_t capacity() const { return data_.capacity(); }
+  void reserve(size_t new_capacity) { data_.reserve(new_capacity); }
+
   T& operator[](size_t i) {
     DCHECK_LT(i, data_.size());
     return data_[i];
@@ -141,6 +152,12 @@
   const_iterator begin() const { return data_.begin(); }
   const_iterator end() const { return data_.end(); }
 
+  template <typename... Args>
+  void emplace_back(Args&&... args) {
+    DCHECK_LT(data_.size(), data_.capacity());
+    data_.emplace_back(std::forward<Args>(args)...);
+  }
+
   void Swap(WebVector<T>& other) { data_.swap(other.data_); }
 
  private:
diff --git a/third_party/WebKit/public/web/WebFrameClient.h b/third_party/WebKit/public/web/WebFrameClient.h
index 2a8cab2..81075c1 100644
--- a/third_party/WebKit/public/web/WebFrameClient.h
+++ b/third_party/WebKit/public/web/WebFrameClient.h
@@ -72,7 +72,7 @@
 #include "public/platform/modules/serviceworker/WebServiceWorkerProvider.h"
 #include "third_party/WebKit/common/feature_policy/feature_policy.h"
 #include "third_party/WebKit/common/page/page_visibility_state.mojom-shared.h"
-#include "third_party/WebKit/common/quota/storage_type.h"
+#include "third_party/WebKit/common/quota/quota_types.mojom-shared.h"
 #include "third_party/WebKit/common/sandbox_flags.h"
 #include "v8/include/v8.h"
 
@@ -719,7 +719,7 @@
   // is called with an error code otherwise.
   // Note that the requesting quota size may not always be granted and
   // a smaller amount of quota than requested might be returned.
-  virtual void RequestStorageQuota(StorageType,
+  virtual void RequestStorageQuota(mojom::StorageType,
                                    unsigned long long new_quota_in_bytes,
                                    WebStorageQuotaCallbacks) {}
 
diff --git a/third_party/zlib/BUILD.gn b/third_party/zlib/BUILD.gn
index c3cc8b5..e87d129 100644
--- a/third_party/zlib/BUILD.gn
+++ b/third_party/zlib/BUILD.gn
@@ -107,12 +107,41 @@
   public_configs = [ ":zlib_inflate_chunk_simd_config" ]
 }
 
+config("zlib_crc32_simd_config") {
+  if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
+    defines = [ "CRC32_SIMD_SSE42_PCLMUL" ]
+  }
+}
+
+source_set("zlib_crc32_simd") {
+  visibility = [ ":*" ]
+
+  if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
+    sources = [
+      "crc32_simd.c",
+      "crc32_simd.h",
+    ]
+
+    if (!is_win || is_clang) {
+      cflags = [
+        "-msse4.2",
+        "-mpclmul",
+      ]
+    }
+  }
+
+  public_configs = [ ":zlib_crc32_simd_config" ]
+}
+
 static_library("zlib_x86_simd") {
+  visibility = [ ":*" ]
+
   if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
     sources = [
       "crc_folding.c",
       "fill_window_sse.c",
     ]
+
     if (!is_win || is_clang) {
       cflags = [
         "-msse4.2",
@@ -176,6 +205,8 @@
   deps = []
 
   if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
+    deps += [ ":zlib_crc32_simd" ]
+
     deps += [ ":zlib_adler32_simd" ]
     sources += [ "x86.c" ]
 
diff --git a/third_party/zlib/crc32.c b/third_party/zlib/crc32.c
index 9162429..b4ad1e10 100644
--- a/third_party/zlib/crc32.c
+++ b/third_party/zlib/crc32.c
@@ -30,6 +30,7 @@
 
 #include "deflate.h"
 #include "x86.h"
+#include "crc32_simd.h"
 #include "zutil.h"      /* for STDC and FAR definitions */
 
 /* Definitions for doing the crc four data bytes at a time. */
@@ -241,6 +242,32 @@
     const unsigned char FAR *buf;
     uInt len;
 {
+#if defined(CRC32_SIMD_SSE42_PCLMUL)
+    /*
+     * Use x86 sse4.2+pclmul SIMD to compute the crc32. Since this
+     * routine can be freely used, check the CPU features here, to
+     * stop TSAN complaining about thread data races accessing the
+     * x86_cpu_enable_simd feature variable below.
+     */
+    if (buf == Z_NULL) {
+        if (!len) /* Assume user is calling crc32(0, NULL, 0); */
+            x86_check_features();
+        return 0UL;
+    }
+
+    if (x86_cpu_enable_simd && len >= Z_CRC32_SSE42_MINIMUM_LENGTH) {
+        /* crc32 16-byte chunks */
+        uInt chunk_size = len & ~Z_CRC32_SSE42_CHUNKSIZE_MASK;
+        crc = ~crc32_sse42_simd_(buf, chunk_size, ~(uint32_t)crc);
+        /* check remaining data */
+        len -= chunk_size;
+        if (!len)
+            return crc;
+        /* Fall into the default crc32 for the remaining data. */
+        buf += chunk_size;
+    }
+#endif /* CRC32_SIMD_SSE42_PCLMUL */
+
     return crc32_z(crc, buf, len);
 }
 
diff --git a/third_party/zlib/crc32_simd.c b/third_party/zlib/crc32_simd.c
new file mode 100644
index 0000000..c2d42556
--- /dev/null
+++ b/third_party/zlib/crc32_simd.c
@@ -0,0 +1,157 @@
+/* crc32_simd.c
+ *
+ * Copyright 2017 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the Chromium source repository LICENSE file.
+ */
+
+#include "crc32_simd.h"
+
+#if defined(CRC32_SIMD_SSE42_PCLMUL)
+
+/*
+ * crc32_sse42_simd_(): compute the crc32 of the buffer, where the buffer
+ * length must be at least 64, and a multiple of 16. Based on:
+ *
+ * "Fast CRC Computation for Generic Polynomials Using PCLMULQDQ Instruction"
+ *  V. Gopal, E. Ozturk, et al., 2009, http://intel.ly/2ySEwL0
+ */
+
+#include <emmintrin.h>
+#include <smmintrin.h>
+#include <wmmintrin.h>
+
+uint32_t ZLIB_INTERNAL crc32_sse42_simd_(  /* SSE4.2+PCLMUL */
+    const unsigned char *buf,
+    z_size_t len,
+    uint32_t crc)
+{
+    /*
+     * Definitions of the bit-reflected domain constants k1,k2,k3, etc and
+     * the CRC32+Barrett polynomials given at the end of the paper.
+     */
+    static const uint64_t zalign(16) k1k2[] = { 0x0154442bd4, 0x01c6e41596 };
+    static const uint64_t zalign(16) k3k4[] = { 0x01751997d0, 0x00ccaa009e };
+    static const uint64_t zalign(16) k5k0[] = { 0x0163cd6124, 0x0000000000 };
+    static const uint64_t zalign(16) poly[] = { 0x01db710641, 0x01f7011641 };
+
+    __m128i x0, x1, x2, x3, x4, x5, x6, x7, x8, y5, y6, y7, y8;
+
+    /*
+     * There's at least one block of 64.
+     */
+    x1 = _mm_loadu_si128((__m128i *)(buf + 0x00));
+    x2 = _mm_loadu_si128((__m128i *)(buf + 0x10));
+    x3 = _mm_loadu_si128((__m128i *)(buf + 0x20));
+    x4 = _mm_loadu_si128((__m128i *)(buf + 0x30));
+
+    x1 = _mm_xor_si128(x1, _mm_cvtsi32_si128(crc));
+
+    x0 = _mm_load_si128((__m128i *)k1k2);
+
+    buf += 64;
+    len -= 64;
+
+    /*
+     * Parallel fold blocks of 64, if any.
+     */
+    while (len >= 64)
+    {
+        x5 = _mm_clmulepi64_si128(x1, x0, 0x00);
+        x6 = _mm_clmulepi64_si128(x2, x0, 0x00);
+        x7 = _mm_clmulepi64_si128(x3, x0, 0x00);
+        x8 = _mm_clmulepi64_si128(x4, x0, 0x00);
+
+        x1 = _mm_clmulepi64_si128(x1, x0, 0x11);
+        x2 = _mm_clmulepi64_si128(x2, x0, 0x11);
+        x3 = _mm_clmulepi64_si128(x3, x0, 0x11);
+        x4 = _mm_clmulepi64_si128(x4, x0, 0x11);
+
+        y5 = _mm_loadu_si128((__m128i *)(buf + 0x00));
+        y6 = _mm_loadu_si128((__m128i *)(buf + 0x10));
+        y7 = _mm_loadu_si128((__m128i *)(buf + 0x20));
+        y8 = _mm_loadu_si128((__m128i *)(buf + 0x30));
+
+        x1 = _mm_xor_si128(x1, x5);
+        x2 = _mm_xor_si128(x2, x6);
+        x3 = _mm_xor_si128(x3, x7);
+        x4 = _mm_xor_si128(x4, x8);
+
+        x1 = _mm_xor_si128(x1, y5);
+        x2 = _mm_xor_si128(x2, y6);
+        x3 = _mm_xor_si128(x3, y7);
+        x4 = _mm_xor_si128(x4, y8);
+
+        buf += 64;
+        len -= 64;
+    }
+
+    /*
+     * Fold into 128-bits.
+     */
+    x0 = _mm_load_si128((__m128i *)k3k4);
+
+    x5 = _mm_clmulepi64_si128(x1, x0, 0x00);
+    x1 = _mm_clmulepi64_si128(x1, x0, 0x11);
+    x1 = _mm_xor_si128(x1, x2);
+    x1 = _mm_xor_si128(x1, x5);
+
+    x5 = _mm_clmulepi64_si128(x1, x0, 0x00);
+    x1 = _mm_clmulepi64_si128(x1, x0, 0x11);
+    x1 = _mm_xor_si128(x1, x3);
+    x1 = _mm_xor_si128(x1, x5);
+
+    x5 = _mm_clmulepi64_si128(x1, x0, 0x00);
+    x1 = _mm_clmulepi64_si128(x1, x0, 0x11);
+    x1 = _mm_xor_si128(x1, x4);
+    x1 = _mm_xor_si128(x1, x5);
+
+    /*
+     * Single fold blocks of 16, if any.
+     */
+    while (len >= 16)
+    {
+        x2 = _mm_loadu_si128((__m128i *)buf);
+
+        x5 = _mm_clmulepi64_si128(x1, x0, 0x00);
+        x1 = _mm_clmulepi64_si128(x1, x0, 0x11);
+        x1 = _mm_xor_si128(x1, x2);
+        x1 = _mm_xor_si128(x1, x5);
+
+        buf += 16;
+        len -= 16;
+    }
+
+    /*
+     * Fold 128-bits to 64-bits.
+     */
+    x2 = _mm_clmulepi64_si128(x1, x0, 0x10);
+    x3 = _mm_set_epi32(0, ~0, 0, ~0);
+    x1 = _mm_srli_si128(x1, 8);
+    x1 = _mm_xor_si128(x1, x2);
+
+    x0 = _mm_loadl_epi64((__m128i*)k5k0);
+
+    x2 = _mm_srli_si128(x1, 4);
+    x1 = _mm_and_si128(x1, x3);
+    x1 = _mm_clmulepi64_si128(x1, x0, 0x00);
+    x1 = _mm_xor_si128(x1, x2);
+
+    /*
+     * Barret reduce to 32-bits.
+     */
+    x0 = _mm_load_si128((__m128i*)poly);
+
+    x2 = _mm_and_si128(x1, x3);
+    x2 = _mm_clmulepi64_si128(x2, x0, 0x10);
+    x2 = _mm_and_si128(x2, x3);
+    x2 = _mm_clmulepi64_si128(x2, x0, 0x00);
+    x1 = _mm_xor_si128(x1, x2);
+
+    /*
+     * Return the crc32.
+     */
+    return _mm_extract_epi32(x1, 1);
+}
+
+#endif  /* CRC32_SIMD_SSE42_PCLMUL */
diff --git a/third_party/zlib/crc32_simd.h b/third_party/zlib/crc32_simd.h
new file mode 100644
index 0000000..4e6f326
--- /dev/null
+++ b/third_party/zlib/crc32_simd.h
@@ -0,0 +1,27 @@
+/* crc32_simd.h
+ *
+ * Copyright 2017 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the Chromium source repository LICENSE file.
+ */
+
+#include <stdint.h>
+
+#include "zconf.h"
+#include "zutil.h"
+
+/*
+ * crc32_sse42_simd_(): compute the crc32 of the buffer, where the buffer
+ * length must be at least 64, and a multiple of 16.
+ */
+uint32_t ZLIB_INTERNAL crc32_sse42_simd_(
+    const unsigned char *buf,
+    z_size_t len,
+    uint32_t crc);
+
+/*
+ * crc32_sse42_simd_ buffer size constraints: see the use in zlib/crc32.c
+ * for computing the crc32 of an arbitrary length buffer.
+ */
+#define Z_CRC32_SSE42_MINIMUM_LENGTH 64
+#define Z_CRC32_SSE42_CHUNKSIZE_MASK 15
diff --git a/third_party/zlib/names.h b/third_party/zlib/names.h
index c18b90f..55a8a3f 100644
--- a/third_party/zlib/names.h
+++ b/third_party/zlib/names.h
@@ -176,4 +176,9 @@
 #define inflate_fast_chunk_ Cr_z_inflate_fast_chunk_
 #endif
 
+#if defined(CRC32_SIMD_SSE42_PCLMUL)
+/* Symbols added by crc32_simd.c */
+#define crc32_sse42_simd_ Cr_z_crc32_sse42_simd_
+#endif
+
 #endif  /* THIRD_PARTY_ZLIB_NAMES_H_ */
diff --git a/tools/gn/filesystem_utils.cc b/tools/gn/filesystem_utils.cc
index f97edf6..b1370e8 100644
--- a/tools/gn/filesystem_utils.cc
+++ b/tools/gn/filesystem_utils.cc
@@ -15,6 +15,10 @@
 #include "tools/gn/settings.h"
 #include "tools/gn/source_dir.h"
 
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
 namespace {
 
 enum DotDisposition {
diff --git a/tools/gn/xcode_writer.cc b/tools/gn/xcode_writer.cc
index ea61744..bdfdce04 100644
--- a/tools/gn/xcode_writer.cc
+++ b/tools/gn/xcode_writer.cc
@@ -36,7 +36,8 @@
 using TargetToPBXTarget = std::unordered_map<const Target*, PBXTarget*>;
 
 const char kEarlGreyFileNameIdentifier[] = "egtest.mm";
-const char kXCTestFileNameIdentifier[] = "xctest.mm";
+const char kXCTestObjCFileNameIdentifier[] = "xctest.m";
+const char kXCTestObjCppFileNameIdentifier[] = "xctest.mm";
 const char kXCTestModuleTargetNamePostfix[] = "_module";
 const char kXCUITestRunnerTargetNamePostfix[] = "_runner";
 
@@ -127,7 +128,9 @@
 bool IsXCTestFile(const SourceFile& file) {
   return base::EndsWith(file.GetName(), kEarlGreyFileNameIdentifier,
                         base::CompareCase::SENSITIVE) ||
-         base::EndsWith(file.GetName(), kXCTestFileNameIdentifier,
+         base::EndsWith(file.GetName(), kXCTestObjCFileNameIdentifier,
+                        base::CompareCase::SENSITIVE) ||
+         base::EndsWith(file.GetName(), kXCTestObjCppFileNameIdentifier,
                         base::CompareCase::SENSITIVE);
 }
 
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 748c729..049b765 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -25548,6 +25548,7 @@
   <int value="7533886" label="disable-offer-store-unmasked-wallet-cards"/>
   <int value="10458238" label="disable-print-preview-simplify"/>
   <int value="11698808" label="enable-dom-distiller-button-animation"/>
+  <int value="23556595" label="MarkHttpAs:enabled"/>
   <int value="27507364" label="apps-keep-chrome-alive"/>
   <int value="28272521" label="ash-enable-display-move-window-accels"/>
   <int value="31848187" label="ViewsTaskManager:disabled"/>
@@ -25603,6 +25604,7 @@
   <int value="180074362" label="memory-pressure-thresholds"/>
   <int value="185991204" label="enable-webrtc-srtp-encrypted-headers"/>
   <int value="189728101" label="FasterLocationReload:disabled"/>
+  <int value="191737931" label="enable-mark-http-as"/>
   <int value="194573877" label="MacViewsNativeDialogs:disabled"/>
   <int value="194895489" label="passive-listeners-default"/>
   <int value="200347243" label="WebVRExperimentalRendering:disabled"/>
@@ -25758,6 +25760,7 @@
   <int value="630244477" label="ServiceWorkerPaymentApps:enabled"/>
   <int value="630947363" label="touch-events"/>
   <int value="632340413" label="network-settings-config"/>
+  <int value="635076832" label="MarkHttpAs:disabled"/>
   <int value="635971109" label="PrintPdfAsImage:disabled"/>
   <int value="636425179" label="mhtml-generator-option"/>
   <int value="637396292" label="AllBookmarks:enabled"/>
@@ -27382,8 +27385,11 @@
 </enum>
 
 <enum name="MarkHttpAsStatus">
+  <obsolete>
+    Deprecated 12/2017.
+  </obsolete>
   <int value="0" label="Neutral (deprecated February 2017)"/>
-  <int value="1" label="Non-Secure"/>
+  <int value="1" label="Dangerous"/>
   <int value="2"
       label="Neutral with a verbose warning on sensitive fields (deprecated
              October 2017)"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 36e7a5e..a2bb213 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -53536,6 +53536,18 @@
   </summary>
 </histogram>
 
+<histogram name="NQE.ContentObserver.NetworkQualityMeaningfullyChanged"
+    enum="BooleanChanged">
+  <owner>tbansal@chromium.org</owner>
+  <summary>
+    This metric is recorded when the network quality change notification is
+    received by content and before the network quality change is notified to the
+    renderers. Records true if the notified network quality change is
+    meaningfully different from the last network quality notified to the
+    renderers.
+  </summary>
+</histogram>
+
 <histogram name="NQE.Correlation.ResourceLoadTime.0Kb_128Kb">
   <obsolete>
     Obsoleted in December 2017.
@@ -83765,6 +83777,12 @@
 </histogram>
 
 <histogram name="SSL.MarkHttpAsStatus" enum="MarkHttpAsStatus">
+  <obsolete>
+    Deprecated December 2017 (M65). This information in this histogram can be
+    found in LoginCustomFlags (for users who have set a flag) or by filtering to
+    users with the MarkHttpAs feature enabled (for seeing the field trial
+    breakdown).
+  </obsolete>
   <owner>estark@chromium.org</owner>
   <owner>felt@chromium.org</owner>
   <summary>
diff --git a/ui/app_list/app_list_view_delegate.h b/ui/app_list/app_list_view_delegate.h
index 944d707..1a90a78 100644
--- a/ui/app_list/app_list_view_delegate.h
+++ b/ui/app_list/app_list_view_delegate.h
@@ -7,6 +7,7 @@
 
 #include <vector>
 
+#include "base/strings/string16.h"
 #include "base/time/time.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/app_list/app_list_export.h"
@@ -43,10 +44,10 @@
   // Gets the SpeechUIModel for the app list. Owned by the AppListViewDelegate.
   virtual SpeechUIModel* GetSpeechUI() = 0;
 
-  // Invoked to start a new search. Delegate collects query input from
-  // SearchBoxModel and populates SearchResults. Both models are sub models
-  // of AppListModel.
-  virtual void StartSearch() = 0;
+  // Invoked to start a new search. This collects a list of search results
+  // matching the raw query, which is an unhandled string typed into the search
+  // box by the user.
+  virtual void StartSearch(const base::string16& raw_query) = 0;
 
   // Invoked to open the search result.
   virtual void OpenSearchResult(SearchResult* result,
diff --git a/ui/app_list/search_controller.cc b/ui/app_list/search_controller.cc
index fd2f6c7..95492e3 100644
--- a/ui/app_list/search_controller.cc
+++ b/ui/app_list/search_controller.cc
@@ -9,7 +9,6 @@
 #include <utility>
 #include <vector>
 
-#include "ash/app_list/model/search/search_box_model.h"
 #include "ash/app_list/model/search/search_result.h"
 #include "base/bind.h"
 #include "base/metrics/histogram_macros.h"
@@ -22,17 +21,18 @@
 
 namespace app_list {
 
-SearchController::SearchController(SearchBoxModel* search_box,
-                                   SearchModel::SearchResults* results,
+SearchController::SearchController(SearchModel::SearchResults* results,
                                    History* history)
-    : search_box_(search_box), mixer_(new Mixer(results)), history_(history) {}
+    : mixer_(new Mixer(results)), history_(history) {}
 
 SearchController::~SearchController() {
 }
 
-void SearchController::Start() {
+void SearchController::Start(const base::string16& raw_query) {
+  last_raw_query_ = raw_query;
+
   base::string16 query;
-  base::TrimWhitespace(search_box_->text(), base::TRIM_ALL, &query);
+  base::TrimWhitespace(raw_query, base::TRIM_ALL, &query);
 
   dispatching_query_ = true;
   for (const auto& provider : providers_)
@@ -59,7 +59,7 @@
     // Count AppList.Search here because it is composed of search + action.
     base::RecordAction(base::UserMetricsAction("AppList_OpenSearchResult"));
 
-    UMA_HISTOGRAM_COUNTS_100(kSearchQueryLength, search_box_->text().size());
+    UMA_HISTOGRAM_COUNTS_100(kSearchQueryLength, last_raw_query_.size());
 
     if (result->distance_from_origin() >= 0) {
       UMA_HISTOGRAM_COUNTS_100(kSearchResultDistanceFromOrigin,
@@ -70,8 +70,7 @@
   result->Open(event_flags);
 
   if (history_ && history_->IsReady()) {
-    history_->AddLaunchEvent(base::UTF16ToUTF8(search_box_->text()),
-                             result->id());
+    history_->AddLaunchEvent(base::UTF16ToUTF8(last_raw_query_), result->id());
   }
 }
 
@@ -102,7 +101,7 @@
 
   KnownResults known_results;
   if (history_ && history_->IsReady()) {
-    history_->GetKnownResults(base::UTF16ToUTF8(search_box_->text()))
+    history_->GetKnownResults(base::UTF16ToUTF8(last_raw_query_))
         ->swap(known_results);
   }
 
diff --git a/ui/app_list/search_controller.h b/ui/app_list/search_controller.h
index f308fc23..4212e8b 100644
--- a/ui/app_list/search_controller.h
+++ b/ui/app_list/search_controller.h
@@ -19,7 +19,6 @@
 namespace app_list {
 
 class History;
-class SearchBoxModel;
 class SearchProvider;
 class SearchResult;
 
@@ -28,12 +27,11 @@
 // results to the given SearchResults UI model.
 class APP_LIST_EXPORT SearchController {
  public:
-  SearchController(SearchBoxModel* search_box,
-                   SearchModel::SearchResults* results,
-                   History* history);
+  SearchController(SearchModel::SearchResults* results, History* history);
   virtual ~SearchController();
 
-  void Start();
+  // TODO(hejq): can we accept a trimmed query here?
+  void Start(const base::string16& raw_query);
 
   void OpenResult(SearchResult* result, int event_flags);
   void InvokeResultAction(SearchResult* result,
@@ -50,7 +48,7 @@
   // Invoked when the search results are changed.
   void OnResultsChanged();
 
-  SearchBoxModel* search_box_;
+  base::string16 last_raw_query_;
 
   bool dispatching_query_ = false;
 
diff --git a/ui/app_list/test/app_list_test_view_delegate.h b/ui/app_list/test/app_list_test_view_delegate.h
index 91ba720..296daaf 100644
--- a/ui/app_list/test/app_list_test_view_delegate.h
+++ b/ui/app_list/test/app_list_test_view_delegate.h
@@ -52,7 +52,7 @@
   AppListModel* GetModel() override;
   SearchModel* GetSearchModel() override;
   SpeechUIModel* GetSpeechUI() override;
-  void StartSearch() override {}
+  void StartSearch(const base::string16& raw_query) override {}
   void OpenSearchResult(SearchResult* result,
                         int event_flags) override;
   void InvokeSearchResultAction(SearchResult* result,
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc
index 3d966b3..fd86c0d9 100644
--- a/ui/app_list/views/app_list_main_view.cc
+++ b/ui/app_list/views/app_list_main_view.cc
@@ -5,11 +5,11 @@
 #include "ui/app_list/views/app_list_main_view.h"
 
 #include <algorithm>
+#include <memory>
 
 #include "ash/app_list/model/app_list_folder_item.h"
 #include "ash/app_list/model/app_list_item.h"
 #include "ash/app_list/model/app_list_model.h"
-#include "ash/app_list/model/search/search_box_model.h"
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/files/file_path.h"
@@ -167,13 +167,13 @@
 }
 
 void AppListMainView::QueryChanged(SearchBoxView* sender) {
+  base::string16 raw_query = search_model_->search_box()->text();
   base::string16 query;
-  base::TrimWhitespace(search_model_->search_box()->text(), base::TRIM_ALL,
-                       &query);
+  base::TrimWhitespace(raw_query, base::TRIM_ALL, &query);
   bool should_show_search = !query.empty();
   contents_view_->ShowSearchResults(should_show_search);
 
-  delegate_->StartSearch();
+  delegate_->StartSearch(raw_query);
 }
 
 void AppListMainView::BackButtonPressed() {
diff --git a/ui/app_list/views/apps_grid_view_unittest.cc b/ui/app_list/views/apps_grid_view_unittest.cc
index 9486cd1..c4880332 100644
--- a/ui/app_list/views/apps_grid_view_unittest.cc
+++ b/ui/app_list/views/apps_grid_view_unittest.cc
@@ -652,7 +652,11 @@
   EXPECT_EQ("1,2", page_flip_waiter.selected_pages());
   EXPECT_EQ(2, GetPaginationModel()->selected_page());
 
+  // Cancel drag and put the dragged view back to its ideal position so that
+  // the next drag would pick it up.
   apps_grid_view_->EndDrag(true);
+  test_api_->LayoutToIdealBounds();
+
   // Now drag to the top edge, and test the other direction.
   to.set_y(apps_grid_bounds.y());
 
diff --git a/ui/base/cursor/cursor_loader_win.cc b/ui/base/cursor/cursor_loader_win.cc
index 2c20a19..6967a29a 100644
--- a/ui/base/cursor/cursor_loader_win.cc
+++ b/ui/base/cursor/cursor_loader_win.cc
@@ -9,6 +9,8 @@
 #include "ui/base/cursor/cursor.h"
 #include "ui/resources/grit/ui_unscaled_resources.h"
 
+#include <windows.h>
+
 namespace ui {
 
 namespace {
diff --git a/ui/base/win/foreground_helper.h b/ui/base/win/foreground_helper.h
index b5ca5f0..4d6ac26 100644
--- a/ui/base/win/foreground_helper.h
+++ b/ui/base/win/foreground_helper.h
@@ -10,6 +10,8 @@
 #include "ui/base/ui_base_export.h"
 #include "ui/gfx/win/window_impl.h"
 
+#include <windows.h>
+
 namespace ui {
 
 // Helper class for moving a window to the foreground.
diff --git a/ui/compositor/test/test_compositor_host_win.cc b/ui/compositor/test/test_compositor_host_win.cc
index c2e90b0..2572fcf28 100644
--- a/ui/compositor/test/test_compositor_host_win.cc
+++ b/ui/compositor/test/test_compositor_host_win.cc
@@ -12,6 +12,8 @@
 #include "ui/compositor/compositor.h"
 #include "ui/gfx/win/window_impl.h"
 
+#include <windows.h>
+
 namespace ui {
 
 class TestCompositorHostWin : public TestCompositorHost,
diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc
index 74f8a70..e9b705e 100644
--- a/ui/events/blink/input_handler_proxy.cc
+++ b/ui/events/blink/input_handler_proxy.cc
@@ -135,7 +135,8 @@
 InputHandlerProxy::InputHandlerProxy(
     cc::InputHandler* input_handler,
     InputHandlerProxyClient* client,
-    bool touchpad_and_wheel_scroll_latching_enabled)
+    bool touchpad_and_wheel_scroll_latching_enabled,
+    bool async_wheel_events_enabled)
     : client_(client),
       input_handler_(input_handler),
       synchronous_input_handler_(nullptr),
@@ -153,10 +154,13 @@
       smooth_scroll_enabled_(false),
       touchpad_and_wheel_scroll_latching_enabled_(
           touchpad_and_wheel_scroll_latching_enabled),
+      async_wheel_events_enabled_(touchpad_and_wheel_scroll_latching_enabled &&
+                                  async_wheel_events_enabled),
       touch_result_(kEventDispositionUndefined),
       mouse_wheel_result_(kEventDispositionUndefined),
       current_overscroll_params_(nullptr),
       has_ongoing_compositor_scroll_fling_pinch_(false),
+      is_first_gesture_scroll_update_(false),
       tick_clock_(std::make_unique<base::DefaultTickClock>()) {
   DCHECK(client);
   input_handler_->BindToClient(this,
@@ -215,8 +219,17 @@
     bool is_scroll_end_from_wheel =
         gesture_event.source_device == blink::kWebGestureDeviceTouchpad &&
         gesture_event.GetType() == blink::WebGestureEvent::kGestureScrollEnd;
+    bool scroll_update_has_blocking_wheel_source =
+        gesture_event.source_device == blink::kWebGestureDeviceTouchpad &&
+        gesture_event.GetType() ==
+            blink::WebGestureEvent::kGestureScrollUpdate &&
+        (!async_wheel_events_enabled_ || is_first_gesture_scroll_update_);
+    if (gesture_event.GetType() ==
+        blink::WebGestureEvent::kGestureScrollUpdate) {
+      is_first_gesture_scroll_update_ = false;
+    }
     if (is_from_set_non_blocking_touch || is_scroll_end_from_wheel ||
-        synchronous_input_handler_) {
+        scroll_update_has_blocking_wheel_source || synchronous_input_handler_) {
       // 1. Gesture events was already delayed by blocking events in rAF aligned
       // queue. We want to avoid additional one frame delay by flushing the
       // VSync queue immediately.
@@ -285,6 +298,7 @@
 
   switch (event_with_callback->event().GetType()) {
     case blink::WebGestureEvent::kGestureScrollBegin:
+      is_first_gesture_scroll_update_ = true;
     case blink::WebGestureEvent::kGestureFlingStart:
     case blink::WebGestureEvent::kGesturePinchBegin:
     case blink::WebGestureEvent::kGestureScrollUpdate:
diff --git a/ui/events/blink/input_handler_proxy.h b/ui/events/blink/input_handler_proxy.h
index b811d90..bb67ec4 100644
--- a/ui/events/blink/input_handler_proxy.h
+++ b/ui/events/blink/input_handler_proxy.h
@@ -55,7 +55,8 @@
  public:
   InputHandlerProxy(cc::InputHandler* input_handler,
                     InputHandlerProxyClient* client,
-                    bool touchpad_and_wheel_scroll_latching_enabled);
+                    bool touchpad_and_wheel_scroll_latching_enabled,
+                    bool async_wheel_events_enabled);
   ~InputHandlerProxy() override;
 
   InputScrollElasticityController* scroll_elasticity_controller() {
@@ -233,6 +234,7 @@
 
   bool smooth_scroll_enabled_;
   const bool touchpad_and_wheel_scroll_latching_enabled_;
+  const bool async_wheel_events_enabled_;
 
   // The merged result of the last touch event with previous touch events.
   // This value will get returned for subsequent TouchMove events to allow
@@ -253,6 +255,7 @@
 
   std::unique_ptr<CompositorThreadEventQueue> compositor_event_queue_;
   bool has_ongoing_compositor_scroll_fling_pinch_;
+  bool is_first_gesture_scroll_update_;
 
   std::unique_ptr<base::TickClock> tick_clock_;
 
diff --git a/ui/events/blink/input_handler_proxy_unittest.cc b/ui/events/blink/input_handler_proxy_unittest.cc
index 6e5137e..c726dcf 100644
--- a/ui/events/blink/input_handler_proxy_unittest.cc
+++ b/ui/events/blink/input_handler_proxy_unittest.cc
@@ -358,10 +358,12 @@
  public:
   TestInputHandlerProxy(cc::InputHandler* input_handler,
                         InputHandlerProxyClient* client,
-                        bool touchpad_and_wheel_scroll_latching_enabled)
+                        bool touchpad_and_wheel_scroll_latching_enabled,
+                        bool async_wheel_events_enabled)
       : InputHandlerProxy(input_handler,
                           client,
-                          touchpad_and_wheel_scroll_latching_enabled) {}
+                          touchpad_and_wheel_scroll_latching_enabled,
+                          async_wheel_events_enabled) {}
   void RecordMainThreadScrollingReasonsForTest(blink::WebGestureDevice device,
                                                uint32_t reasons) {
     RecordMainThreadScrollingReasons(device, reasons);
@@ -380,17 +382,20 @@
     : public testing::Test,
       public testing::WithParamInterface<InputHandlerProxyTestType> {
  public:
-  InputHandlerProxyTest(bool touchpad_and_wheel_scroll_latching_enabled = true)
+  InputHandlerProxyTest(bool touchpad_and_wheel_scroll_latching_enabled = true,
+                        bool async_wheel_events_enabled = true)
       : synchronous_root_scroll_(GetParam() == ROOT_SCROLL_SYNCHRONOUS_HANDLER),
         install_synchronous_handler_(
             GetParam() == ROOT_SCROLL_SYNCHRONOUS_HANDLER ||
             GetParam() == CHILD_SCROLL_SYNCHRONOUS_HANDLER),
         expected_disposition_(InputHandlerProxy::DID_HANDLE),
         touchpad_and_wheel_scroll_latching_enabled_(
-            touchpad_and_wheel_scroll_latching_enabled) {
+            touchpad_and_wheel_scroll_latching_enabled),
+        async_wheel_events_enabled_(async_wheel_events_enabled) {
     input_handler_.reset(
         new TestInputHandlerProxy(&mock_input_handler_, &mock_client_,
-                                  touchpad_and_wheel_scroll_latching_enabled_));
+                                  touchpad_and_wheel_scroll_latching_enabled_,
+                                  async_wheel_events_enabled_));
     scroll_result_did_scroll_.did_scroll = true;
     scroll_result_did_not_scroll_.did_scroll = false;
 
@@ -508,13 +513,14 @@
   cc::InputHandlerScrollResult scroll_result_did_scroll_;
   cc::InputHandlerScrollResult scroll_result_did_not_scroll_;
   bool touchpad_and_wheel_scroll_latching_enabled_;
+  bool async_wheel_events_enabled_;
 };
 
 class InputHandlerProxyWithoutWheelScrollLatchingTest
     : public InputHandlerProxyTest {
  public:
   InputHandlerProxyWithoutWheelScrollLatchingTest()
-      : InputHandlerProxyTest(false) {}
+      : InputHandlerProxyTest(false, false) {}
 };
 
 class InputHandlerProxyEventQueueTest : public testing::TestWithParam<bool> {
@@ -527,10 +533,12 @@
 
   void SetUp() override {
     bool wheel_scroll_latching_enabled = GetParam();
+    async_wheel_events_enabled_ = wheel_scroll_latching_enabled;
     event_disposition_recorder_.clear();
     latency_info_recorder_.clear();
     input_handler_proxy_ = std::make_unique<TestInputHandlerProxy>(
-        &mock_input_handler_, &mock_client_, wheel_scroll_latching_enabled);
+        &mock_input_handler_, &mock_client_, wheel_scroll_latching_enabled,
+        async_wheel_events_enabled_);
     if (input_handler_proxy_->compositor_event_queue_)
       input_handler_proxy_->compositor_event_queue_ =
           std::make_unique<CompositorThreadEventQueue>();
@@ -610,6 +618,7 @@
   testing::StrictMock<MockInputHandlerProxyClient> mock_client_;
   std::vector<InputHandlerProxy::EventDisposition> event_disposition_recorder_;
   std::vector<ui::LatencyInfo> latency_info_recorder_;
+  bool async_wheel_events_enabled_;
 
   base::MessageLoop loop_;
   base::WeakPtrFactory<InputHandlerProxyEventQueueTest> weak_ptr_factory_;
@@ -2602,7 +2611,8 @@
       mock_client;
   input_handler_.reset(
       new TestInputHandlerProxy(&mock_input_handler_, &mock_client,
-                                touchpad_and_wheel_scroll_latching_enabled_));
+                                touchpad_and_wheel_scroll_latching_enabled_,
+                                async_wheel_events_enabled_));
   if (install_synchronous_handler_) {
     EXPECT_CALL(mock_input_handler_, RequestUpdateForSynchronousInputHandler())
         .Times(1);
@@ -2644,7 +2654,7 @@
   testing::StrictMock<MockInputHandlerProxyClient> mock_client;
   testing::StrictMock<MockSynchronousInputHandler>
       mock_synchronous_input_handler;
-  ui::InputHandlerProxy proxy(&mock_input_handler, &mock_client, false);
+  ui::InputHandlerProxy proxy(&mock_input_handler, &mock_client, false, false);
 
   // When adding a SynchronousInputHandler, immediately request an
   // UpdateRootLayerStateForSynchronousInputHandler() call.
@@ -2670,7 +2680,7 @@
   testing::StrictMock<MockInputHandlerProxyClient> mock_client;
   testing::StrictMock<MockSynchronousInputHandler>
       mock_synchronous_input_handler;
-  ui::InputHandlerProxy proxy(&mock_input_handler, &mock_client, false);
+  ui::InputHandlerProxy proxy(&mock_input_handler, &mock_client, false, false);
 
   proxy.SetOnlySynchronouslyAnimateRootFlings(&mock_synchronous_input_handler);
 
@@ -2695,7 +2705,7 @@
   testing::StrictMock<MockInputHandlerProxyClient> mock_client;
   testing::StrictMock<MockSynchronousInputHandler>
       mock_synchronous_input_handler;
-  ui::InputHandlerProxy proxy(&mock_input_handler, &mock_client, false);
+  ui::InputHandlerProxy proxy(&mock_input_handler, &mock_client, false, false);
 
   proxy.SetOnlySynchronouslyAnimateRootFlings(&mock_synchronous_input_handler);
 
@@ -3324,8 +3334,6 @@
 
   EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
       .WillRepeatedly(testing::Return(kImplThreadScrollState));
-  EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput())
-      .Times(::testing::AtLeast(1));
   EXPECT_CALL(
       mock_input_handler_,
       ScrollBy(testing::Property(&cc::ScrollState::delta_y, testing::Gt(0))))
@@ -3339,16 +3347,36 @@
   HandleGestureEventWithSourceDevice(WebInputEvent::kGestureScrollUpdate,
                                      blink::kWebGestureDeviceTouchpad, -20);
 
-  // GSB will be dispatched immediately, GSU will be queued.
-  EXPECT_EQ(1ul, event_queue().size());
-  EXPECT_EQ(1ul, event_disposition_recorder_.size());
+  // Both GSB and the first GSU will be dispatched immediately since the first
+  // GSU has blocking wheel event source.
+  EXPECT_EQ(0ul, event_queue().size());
+  EXPECT_EQ(2ul, event_disposition_recorder_.size());
+
+  // When async_wheel_events_enabled_ the rest of the GSU events will get queued
+  // since they have non-blocking wheel event source.
+  if (async_wheel_events_enabled_) {
+    EXPECT_CALL(mock_input_handler_, SetNeedsAnimateInput())
+        .Times(::testing::AtLeast(1));
+    HandleGestureEventWithSourceDevice(WebInputEvent::kGestureScrollUpdate,
+                                       blink::kWebGestureDeviceTouchpad, -20);
+    EXPECT_EQ(1ul, event_queue().size());
+    EXPECT_EQ(2ul, event_disposition_recorder_.size());
+  }
 
   // Touchpad GSE will flush the queue.
   HandleGestureEventWithSourceDevice(WebInputEvent::kGestureScrollEnd,
                                      blink::kWebGestureDeviceTouchpad);
 
   EXPECT_EQ(0ul, event_queue().size());
-  EXPECT_EQ(3ul, event_disposition_recorder_.size());
+  if (async_wheel_events_enabled_) {
+    // GSB, GSU(with blocking wheel source), GSU(with non-blocking wheel
+    // source), and GSE are the sent events.
+    EXPECT_EQ(4ul, event_disposition_recorder_.size());
+  } else {
+    // GSB, GSU(with blocking wheel source), and GSE are the sent events.
+    EXPECT_EQ(3ul, event_disposition_recorder_.size());
+  }
+
   EXPECT_FALSE(
       input_handler_proxy_->gesture_scroll_on_impl_thread_for_testing());
 }
diff --git a/ui/events/devices/input_device_observer_win.cc b/ui/events/devices/input_device_observer_win.cc
index 9b3cdc8..daa63f0 100644
--- a/ui/events/devices/input_device_observer_win.cc
+++ b/ui/events/devices/input_device_observer_win.cc
@@ -9,6 +9,8 @@
 #include "base/memory/singleton.h"
 #include "base/strings/string16.h"
 
+#include <windows.h>
+
 // This macro provides the implementation for the observer notification methods.
 #define NOTIFY_OBSERVERS_METHOD(method_decl, observer_call) \
   void InputDeviceObserverWin::method_decl {                \
diff --git a/ui/gfx/animation/animation_unittest.cc b/ui/gfx/animation/animation_unittest.cc
index bf1cf01..8658d56 100644
--- a/ui/gfx/animation/animation_unittest.cc
+++ b/ui/gfx/animation/animation_unittest.cc
@@ -10,6 +10,10 @@
 #include "ui/gfx/animation/linear_animation.h"
 #include "ui/gfx/animation/test_animation_delegate.h"
 
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
 namespace gfx {
 
 class AnimationTest: public testing::Test {
diff --git a/ui/gfx/animation/animation_win.cc b/ui/gfx/animation/animation_win.cc
index 7070707e..90b64af8 100644
--- a/ui/gfx/animation/animation_win.cc
+++ b/ui/gfx/animation/animation_win.cc
@@ -4,6 +4,8 @@
 
 #include "ui/gfx/animation/animation.h"
 
+#include <windows.h>
+
 namespace gfx {
 
 // static
diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h
index 1252ad1..313ab22 100644
--- a/ui/gfx/native_widget_types.h
+++ b/ui/gfx/native_widget_types.h
@@ -52,7 +52,7 @@
 #endif  // defined(USE_AURA)
 
 #if defined(OS_WIN)
-#include <windows.h>  // NOLINT
+#include "base/win/windows_types.h"
 typedef struct HFONT__* HFONT;
 struct IAccessible;
 #elif defined(OS_IOS)
diff --git a/ui/gfx/platform_font_win.h b/ui/gfx/platform_font_win.h
index 5e8e72f4..487d4677b 100644
--- a/ui/gfx/platform_font_win.h
+++ b/ui/gfx/platform_font_win.h
@@ -14,6 +14,8 @@
 #include "ui/gfx/gfx_export.h"
 #include "ui/gfx/platform_font.h"
 
+#include <windows.h>
+
 struct IDWriteFactory;
 struct IDWriteFont;
 
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc
index 91b533d..79a7a863 100644
--- a/ui/gfx/render_text_harfbuzz.cc
+++ b/ui/gfx/render_text_harfbuzz.cc
@@ -1225,7 +1225,8 @@
             run.GetGraphemeSpanForCharRange(this, intersection);
         int start_x = std::ceil(selected_span.start() - line_start_x);
         int end_x = std::ceil(selected_span.end() - line_start_x);
-        gfx::Rect rect(start_x, 0, end_x - start_x, line.size.height());
+        gfx::Rect rect(start_x, 0, end_x - start_x,
+                       std::ceil(line.size.height()));
         rects.push_back(rect + GetLineOffset(line_index));
       }
     }
diff --git a/ui/login/display_manager.js b/ui/login/display_manager.js
index d92d8d4c..f79e622 100644
--- a/ui/login/display_manager.js
+++ b/ui/login/display_manager.js
@@ -293,10 +293,15 @@
      * The header bar should be hidden when views-based shelf is shown.
      */
     get showingViewsBasedShelf() {
-      return loadTimeData.valueExists('showMdLogin') &&
-          loadTimeData.getString('showMdLogin') == 'on' &&
+      var showingViewsLock = loadTimeData.valueExists('showViewsLock') &&
+          loadTimeData.getString('showViewsLock') == 'on' &&
           (this.displayType_ == DISPLAY_TYPE.LOCK ||
            this.displayType_ == DISPLAY_TYPE.USER_ADDING);
+      var showingViewsLogin = loadTimeData.valueExists('showViewsLogin') &&
+          loadTimeData.getString('showViewsLogin') == 'on' &&
+          (this.displayType_ == DISPLAY_TYPE.LOGIN ||
+           this.displayType_ == DISPLAY_TYPE.OOBE);
+      return showingViewsLock || showingViewsLogin;
     },
 
     /**
diff --git a/ui/ozone/platform/drm/common/drm_util.cc b/ui/ozone/platform/drm/common/drm_util.cc
index 93db1b1..d4c3dd5 100644
--- a/ui/ozone/platform/drm/common/drm_util.cc
+++ b/ui/ozone/platform/drm/common/drm_util.cc
@@ -18,11 +18,6 @@
 #include "ui/display/types/display_mode.h"
 #include "ui/display/util/edid_parser.h"
 
-#if !defined(DRM_FORMAT_R16)
-// TODO(riju): crbug.com/733703
-#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ')
-#endif
-
 namespace ui {
 
 namespace {
diff --git a/ui/ozone/platform/drm/gpu/drm_device.cc b/ui/ozone/platform/drm/gpu/drm_device.cc
index a736d4e..95a473a 100644
--- a/ui/ozone/platform/drm/gpu/drm_device.cc
+++ b/ui/ozone/platform/drm/gpu/drm_device.cc
@@ -129,72 +129,8 @@
   return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources);
 }
 
-// TODO(robert.bradford): Replace with libdrm structures after libdrm roll.
-// https://crbug.com/586475
-struct DrmColorLut {
-  uint16_t red;
-  uint16_t green;
-  uint16_t blue;
-  uint16_t reserved;
-};
-
-struct DrmColorCtm {
-  int64_t ctm_coeff[9];
-};
-
-struct DrmModeCreateBlob {
-  uint64_t data;
-  uint32_t length;
-  uint32_t blob_id;
-};
-
-struct DrmModeDestroyBlob {
-  uint32_t blob_id;
-};
-
-#ifndef DRM_IOCTL_MODE_CREATEPROPBLOB
-#define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct DrmModeCreateBlob)
-#endif
-
-#ifndef DRM_IOCTL_MODE_DESTROYPROPBLOB
-#define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct DrmModeDestroyBlob)
-#endif
-
-int CreatePropertyBlob(int fd, const void* data, size_t length, uint32_t* id) {
-  DrmModeCreateBlob create;
-  int ret;
-
-  if (length >= 0xffffffff)
-    return -ERANGE;
-
-  memset(&create, 0, sizeof(create));
-
-  create.length = length;
-  create.data = (uintptr_t)data;
-  create.blob_id = 0;
-  *id = 0;
-
-  ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create);
-  ret = ret < 0 ? -errno : ret;
-  if (ret != 0)
-    return ret;
-
-  *id = create.blob_id;
-  return 0;
-}
-
-int DestroyPropertyBlob(int fd, uint32_t id) {
-  DrmModeDestroyBlob destroy;
-  int ret;
-
-  memset(&destroy, 0, sizeof(destroy));
-  destroy.blob_id = id;
-  ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy);
-  return ret < 0 ? -errno : ret;
-}
-
-using ScopedDrmColorLutPtr = std::unique_ptr<DrmColorLut, base::FreeDeleter>;
-using ScopedDrmColorCtmPtr = std::unique_ptr<DrmColorCtm, base::FreeDeleter>;
+using ScopedDrmColorLutPtr = std::unique_ptr<drm_color_lut, base::FreeDeleter>;
+using ScopedDrmColorCtmPtr = std::unique_ptr<drm_color_ctm, base::FreeDeleter>;
 
 ScopedDrmColorLutPtr CreateLutBlob(
     const std::vector<display::GammaRampRGBEntry>& source) {
@@ -202,9 +138,9 @@
   if (source.empty())
     return nullptr;
 
-  ScopedDrmColorLutPtr lut(
-      static_cast<DrmColorLut*>(malloc(sizeof(DrmColorLut) * source.size())));
-  DrmColorLut* p = lut.get();
+  ScopedDrmColorLutPtr lut(static_cast<drm_color_lut*>(
+      malloc(sizeof(drm_color_lut) * source.size())));
+  drm_color_lut* p = lut.get();
   for (size_t i = 0; i < source.size(); ++i) {
     p[i].red = source[i].r;
     p[i].green = source[i].g;
@@ -219,15 +155,15 @@
     return nullptr;
 
   ScopedDrmColorCtmPtr ctm(
-      static_cast<DrmColorCtm*>(malloc(sizeof(DrmColorCtm))));
-  for (size_t i = 0; i < arraysize(ctm->ctm_coeff); ++i) {
+      static_cast<drm_color_ctm*>(malloc(sizeof(drm_color_ctm))));
+  for (size_t i = 0; i < arraysize(ctm->matrix); ++i) {
     if (correction_matrix[i] < 0) {
-      ctm->ctm_coeff[i] = static_cast<uint64_t>(
-          -correction_matrix[i] * (static_cast<uint64_t>(1) << 32));
-      ctm->ctm_coeff[i] |= static_cast<uint64_t>(1) << 63;
+      ctm->matrix[i] = static_cast<uint64_t>(-correction_matrix[i] *
+                                             (static_cast<uint64_t>(1) << 32));
+      ctm->matrix[i] |= static_cast<uint64_t>(1) << 63;
     } else {
-      ctm->ctm_coeff[i] = static_cast<uint64_t>(
-          correction_matrix[i] * (static_cast<uint64_t>(1) << 32));
+      ctm->matrix[i] = static_cast<uint64_t>(correction_matrix[i] *
+                                             (static_cast<uint64_t>(1) << 32));
     }
   }
   return ctm;
@@ -244,7 +180,7 @@
   int res;
 
   if (data) {
-    res = CreatePropertyBlob(fd, data, length, &blob_id);
+    res = drmModeCreatePropertyBlob(fd, data, length, &blob_id);
     if (res != 0) {
       LOG(ERROR) << "Error creating property blob: " << base::safe_strerror(res)
                  << " for property " << property_name;
@@ -261,7 +197,7 @@
     success = true;
   }
   if (blob_id != 0)
-    DestroyPropertyBlob(fd, blob_id);
+    drmModeDestroyPropertyBlob(fd, blob_id);
   return success;
 }
 
@@ -795,7 +731,7 @@
               file_.GetPlatformFile(), crtc_id, DRM_MODE_OBJECT_CRTC,
               crtc_props->props[i], property->name,
               reinterpret_cast<unsigned char*>(degamma_blob_data.get()),
-              sizeof(DrmColorLut) * degamma_lut_size))
+              sizeof(drm_color_lut) * degamma_lut_size))
         return false;
     }
     if (!strcmp(property->name, "GAMMA_LUT")) {
@@ -803,7 +739,7 @@
               file_.GetPlatformFile(), crtc_id, DRM_MODE_OBJECT_CRTC,
               crtc_props->props[i], property->name,
               reinterpret_cast<unsigned char*>(gamma_blob_data.get()),
-              sizeof(DrmColorLut) * gamma_lut_size))
+              sizeof(drm_color_lut) * gamma_lut_size))
         return false;
     }
     if (!strcmp(property->name, "CTM")) {
@@ -811,7 +747,7 @@
               file_.GetPlatformFile(), crtc_id, DRM_MODE_OBJECT_CRTC,
               crtc_props->props[i], property->name,
               reinterpret_cast<unsigned char*>(ctm_blob_data.get()),
-              sizeof(DrmColorCtm)))
+              sizeof(drm_color_ctm)))
         return false;
     }
   }
diff --git a/ui/platform_window/win/win_window.cc b/ui/platform_window/win/win_window.cc
index f2830c1..2f32390a 100644
--- a/ui/platform_window/win/win_window.cc
+++ b/ui/platform_window/win/win_window.cc
@@ -13,6 +13,8 @@
 #include "ui/gfx/win/msg_util.h"
 #include "ui/platform_window/platform_window_delegate.h"
 
+#include <windows.h>
+
 namespace ui {
 
 namespace {
diff --git a/ui/platform_window/win/win_window.h b/ui/platform_window/win/win_window.h
index 5e4859c..c6774fd 100644
--- a/ui/platform_window/win/win_window.h
+++ b/ui/platform_window/win/win_window.h
@@ -11,6 +11,8 @@
 #include "ui/platform_window/platform_window.h"
 #include "ui/platform_window/win/win_window_export.h"
 
+#include <windows.h>
+
 namespace ui {
 
 class PlatformWindowDelegate;
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc
index d4c0c6f9..7deb834 100644
--- a/ui/views/controls/button/label_button.cc
+++ b/ui/views/controls/button/label_button.cc
@@ -55,7 +55,7 @@
       style_(STYLE_TEXTBUTTON),
       border_is_themed_border_(true),
       image_label_spacing_(LayoutProvider::Get()->GetDistanceMetric(
-          DISTANCE_RELATED_CONTROL_HORIZONTAL)),
+          DISTANCE_BUTTON_IMAGE_LABEL_PADDING)),
       horizontal_alignment_(gfx::ALIGN_LEFT) {
   SetAnimationDuration(kHoverAnimationDurationMs);
   SetTextInternal(text);
diff --git a/ui/views/layout/layout_provider.cc b/ui/views/layout/layout_provider.cc
index eee5edf..1b7f61e 100644
--- a/ui/views/layout/layout_provider.cc
+++ b/ui/views/layout/layout_provider.cc
@@ -87,6 +87,7 @@
       return 13;
     case DistanceMetric::DISTANCE_RELATED_BUTTON_HORIZONTAL:
       return 6;
+    case DistanceMetric::DISTANCE_BUTTON_IMAGE_LABEL_PADDING:
     case DistanceMetric::DISTANCE_RELATED_CONTROL_HORIZONTAL:
       return 8;
     case DistanceMetric::DISTANCE_RELATED_CONTROL_VERTICAL:
diff --git a/ui/views/layout/layout_provider.h b/ui/views/layout/layout_provider.h
index cd15ef3..d6bdf428 100644
--- a/ui/views/layout/layout_provider.h
+++ b/ui/views/layout/layout_provider.h
@@ -51,6 +51,9 @@
 
   // The default padding to add on each side of a button's label.
   DISTANCE_BUTTON_HORIZONTAL_PADDING = VIEWS_DISTANCE_START,
+  // The default padding to use between the image and label of a button with
+  // both.
+  DISTANCE_BUTTON_IMAGE_LABEL_PADDING,
   // The maximum width a button can have and still influence the sizes of
   // other linked buttons.  This allows short buttons to have linked widths
   // without long buttons making things overly wide.