diff --git a/BUILD.gn b/BUILD.gn
index 95cdd60..9378182 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -102,8 +102,6 @@
       "//chrome/test/chromedriver:chromedriver_unittests",
       "//components/sync/tools:sync_client",
       "//components/sync/tools:sync_listen_notifications",
-      "//extensions:extensions_browsertests",
-      "//extensions:extensions_unittests",
       "//gpu/gles2_conform_support:gles2_conform_test",
       "//gpu/khronos_glcts_support:khronos_glcts_test",
       "//jingle:jingle_unittests",
@@ -207,7 +205,11 @@
   deps += root_extra_deps
 
   if (enable_extensions) {
-    deps += [ "//extensions/shell:app_shell_unittests" ]
+    deps += [
+      "//extensions:extensions_browsertests",
+      "//extensions:extensions_unittests",
+      "//extensions/shell:app_shell_unittests",
+    ]
   }
 
   if (enable_remoting) {
diff --git a/DEPS b/DEPS
index a0cf8672..78cf605 100644
--- a/DEPS
+++ b/DEPS
@@ -60,7 +60,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '6016a1445277f75270d263b384a34ceaf654367d',
+  'swiftshader_revision': 'f41f0332bfb9dfbf09253bbf10f3b46e820a4f8e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index c0324ab8..46e16be0 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -191,11 +191,12 @@
     (
       r'XInternAtom|xcb_intern_atom',
       (
-       'Use ui::GetAtom() or ui::X11AtomCache::GetAtom() instead of',
-       'interning atoms directly.',
+       'Use gfx::GetAtom() instead of interning atoms directly.',
       ),
       True,
       (
+        r"^gpu[\\\/]ipc[\\\/]service[\\\/]gpu_watchdog_thread\.cc$",
+        r"^remoting[\\\/]host[\\\/]linux[\\\/]x_server_clipboard\.cc$",
         r"^ui[\\\/]gfx[\\\/]x[\\\/]x11_atom_cache\.cc$",
       ),
     ),
diff --git a/ash/host/ash_window_tree_host_x11.cc b/ash/host/ash_window_tree_host_x11.cc
index 68d864a..1ac912f2 100644
--- a/ash/host/ash_window_tree_host_x11.cc
+++ b/ash/host/ash_window_tree_host_x11.cc
@@ -217,7 +217,7 @@
   if (!ui::IsXInput2Available())
     return;
   // Temporarily pause tap-to-click when the cursor is hidden.
-  Atom prop = ui::X11AtomCache::GetInstance()->GetAtom("Tap Paused");
+  Atom prop = gfx::GetAtom("Tap Paused");
   unsigned char value = state;
   const XIDeviceList& dev_list =
       ui::DeviceListCacheX11::GetInstance()->GetXI2DeviceList(xdisplay());
diff --git a/ash/login/lock_screen_controller.cc b/ash/login/lock_screen_controller.cc
index 8b99e6f..dd5a085 100644
--- a/ash/login/lock_screen_controller.cc
+++ b/ash/login/lock_screen_controller.cc
@@ -4,6 +4,7 @@
 
 #include "ash/login/lock_screen_controller.h"
 
+#include "ash/login/ui/lock_screen.h"
 #include "chromeos/cryptohome/system_salt_getter.h"
 #include "chromeos/login/auth/user_context.h"
 
@@ -21,6 +22,11 @@
   lock_screen_client_ = std::move(client);
 }
 
+void LockScreenController::ShowLockScreen(ShowLockScreenCallback on_shown) {
+  ::ash::ShowLockScreen();
+  std::move(on_shown).Run(true);
+}
+
 void LockScreenController::ShowErrorMessage(int32_t login_attempts,
                                             const std::string& error_text,
                                             const std::string& help_link_text,
@@ -53,15 +59,24 @@
   NOTIMPLEMENTED();
 }
 
-void LockScreenController::AuthenticateUser(const AccountId& account_id,
-                                            const std::string& password,
-                                            bool authenticated_by_pin) {
+void LockScreenController::AuthenticateUser(
+    const AccountId& account_id,
+    const std::string& password,
+    bool authenticated_by_pin,
+    mojom::LockScreenClient::AuthenticateUserCallback callback) {
   if (!lock_screen_client_)
     return;
 
-  chromeos::SystemSaltGetter::Get()->GetSystemSalt(base::Bind(
+  // We cannot execute auth requests directly via GetSystemSalt because it
+  // expects a base::Callback instance, but |callback| is a base::OnceCallback.
+  // Instead, we store |callback| on this object and invoke it locally once we
+  // have the system salt.
+  DCHECK(!pending_user_auth_) << "More than one concurrent auth attempt";
+  pending_user_auth_ = base::BindOnce(
       &LockScreenController::DoAuthenticateUser, base::Unretained(this),
-      account_id, password, authenticated_by_pin));
+      account_id, password, authenticated_by_pin, std::move(callback));
+  chromeos::SystemSaltGetter::Get()->GetSystemSalt(base::Bind(
+      &LockScreenController::OnGetSystemSalt, base::Unretained(this)));
 }
 
 void LockScreenController::AttemptUnlock(const AccountId& account_id) {
@@ -82,17 +97,23 @@
   lock_screen_client_->RecordClickOnLockIcon(account_id);
 }
 
-void LockScreenController::DoAuthenticateUser(const AccountId& account_id,
-                                              const std::string& password,
-                                              bool authenticated_by_pin,
-                                              const std::string& system_salt) {
+void LockScreenController::DoAuthenticateUser(
+    const AccountId& account_id,
+    const std::string& password,
+    bool authenticated_by_pin,
+    mojom::LockScreenClient::AuthenticateUserCallback callback,
+    const std::string& system_salt) {
   // Hash password before sending through mojo.
   // TODO(xiaoyinh): Pin is hashed differently by using a different salt and
   // a different hash algorithm. Update this part in PinStorage.
   chromeos::Key key(password);
   key.Transform(chromeos::Key::KEY_TYPE_SALTED_SHA256_TOP_HALF, system_salt);
-  lock_screen_client_->AuthenticateUser(account_id, key.GetSecret(),
-                                        authenticated_by_pin);
+  lock_screen_client_->AuthenticateUser(
+      account_id, key.GetSecret(), authenticated_by_pin, std::move(callback));
+}
+
+void LockScreenController::OnGetSystemSalt(const std::string& system_salt) {
+  std::move(pending_user_auth_).Run(system_salt);
 }
 
 }  // namespace ash
diff --git a/ash/login/lock_screen_controller.h b/ash/login/lock_screen_controller.h
index 6d01961..efdfdb1 100644
--- a/ash/login/lock_screen_controller.h
+++ b/ash/login/lock_screen_controller.h
@@ -20,6 +20,8 @@
 class ASH_EXPORT LockScreenController
     : NON_EXPORTED_BASE(public mojom::LockScreen) {
  public:
+  using OnShownCallback = base::OnceCallback<void(bool did_show)>;
+
   LockScreenController();
   ~LockScreenController() override;
 
@@ -28,6 +30,7 @@
 
   // mojom::LockScreen:
   void SetClient(mojom::LockScreenClientPtr client) override;
+  void ShowLockScreen(ShowLockScreenCallback callback) override;
   void ShowErrorMessage(int32_t login_attempts,
                         const std::string& error_text,
                         const std::string& help_link_text,
@@ -47,18 +50,27 @@
   // LockScreenClient(chrome) will do the authentication and request to show
   // error messages in the lock screen if auth fails, or request to clear
   // errors if auth succeeds.
-  void AuthenticateUser(const AccountId& account_id,
-                        const std::string& password,
-                        bool authenticated_by_pin);
+  void AuthenticateUser(
+      const AccountId& account_id,
+      const std::string& password,
+      bool authenticated_by_pin,
+      mojom::LockScreenClient::AuthenticateUserCallback callback);
   void AttemptUnlock(const AccountId& account_id);
   void HardlockPod(const AccountId& account_id);
   void RecordClickOnLockIcon(const AccountId& account_id);
 
  private:
-  void DoAuthenticateUser(const AccountId& account_id,
-                          const std::string& password,
-                          bool authenticated_by_pin,
-                          const std::string& system_salt);
+  using PendingAuthenticateUserCall =
+      base::OnceCallback<void(const std::string& system_salt)>;
+
+  void DoAuthenticateUser(
+      const AccountId& account_id,
+      const std::string& password,
+      bool authenticated_by_pin,
+      mojom::LockScreenClient::AuthenticateUserCallback callback,
+      const std::string& system_salt);
+
+  void OnGetSystemSalt(const std::string& system_salt);
 
   // Client interface in chrome browser. May be null in tests.
   mojom::LockScreenClientPtr lock_screen_client_;
@@ -66,9 +78,12 @@
   // Bindings for the LockScreen interface.
   mojo::BindingSet<mojom::LockScreen> bindings_;
 
+  // User authentication call that will run when we have system salt.
+  PendingAuthenticateUserCall pending_user_auth_;
+
   DISALLOW_COPY_AND_ASSIGN(LockScreenController);
 };
 
-}  // namspace ash
+}  // namespace ash
 
 #endif  // ASH_LOGIN_LOCK_SCREEN_CONTROLLER_H_
diff --git a/ash/login/lock_screen_controller_unittest.cc b/ash/login/lock_screen_controller_unittest.cc
index a1c3deb..59837be 100644
--- a/ash/login/lock_screen_controller_unittest.cc
+++ b/ash/login/lock_screen_controller_unittest.cc
@@ -15,7 +15,6 @@
 
 namespace {
 using LockScreenControllerTest = test::AshTestBase;
-}  // namespace
 
 TEST_F(LockScreenControllerTest, RequestAuthentication) {
   LockScreenController* controller = Shell::Get()->lock_screen_controller();
@@ -24,7 +23,7 @@
   AccountId id = AccountId::FromUserEmail("user1@test.com");
 
   // We hardcode the hashed password. This is fine because the password hash
-  // algorithm should never accidently change; if it does we will need to
+  // algorithm should never accidentally change; if it does we will need to
   // have cryptohome migration code and one failing test isn't a problem.
   std::string password = "password";
   std::string hashed_password = "40c7b00f3bccc7675ec5b732de4bfbe4";
@@ -32,10 +31,18 @@
 
   // Verify AuthenticateUser mojo call is run with the same account id, a
   // (hashed) password, and the correct PIN state.
-  EXPECT_CALL(*client, AuthenticateUser(id, hashed_password, false));
-  controller->AuthenticateUser(id, password, false);
+  EXPECT_CALL(*client, AuthenticateUser_(id, hashed_password, false, _));
+  base::Optional<bool> callback_result;
+  controller->AuthenticateUser(
+      id, password, false,
+      base::BindOnce([](base::Optional<bool>* result,
+                        bool did_auth) { *result = did_auth; },
+                     &callback_result));
 
   base::RunLoop().RunUntilIdle();
+
+  EXPECT_TRUE(callback_result.has_value());
+  EXPECT_TRUE(*callback_result);
 }
 
 TEST_F(LockScreenControllerTest, RequestEasyUnlock) {
@@ -60,4 +67,5 @@
   base::RunLoop().RunUntilIdle();
 }
 
+}  // namespace
 }  // namespace ash
diff --git a/ash/login/mock_lock_screen_client.cc b/ash/login/mock_lock_screen_client.cc
index 2159e68..786f639 100644
--- a/ash/login/mock_lock_screen_client.cc
+++ b/ash/login/mock_lock_screen_client.cc
@@ -19,6 +19,14 @@
   return ptr;
 }
 
+void MockLockScreenClient::AuthenticateUser(const AccountId& account_id,
+                                            const std::string& password,
+                                            bool authenticated_by_pin,
+                                            AuthenticateUserCallback callback) {
+  AuthenticateUser_(account_id, password, authenticated_by_pin, callback);
+  std::move(callback).Run(authenticate_user_callback_result_);
+}
+
 std::unique_ptr<MockLockScreenClient> BindMockLockScreenClient() {
   LockScreenController* lock_screen_controller =
       Shell::Get()->lock_screen_controller();
diff --git a/ash/login/mock_lock_screen_client.h b/ash/login/mock_lock_screen_client.h
index 3900dafa..60bbac1 100644
--- a/ash/login/mock_lock_screen_client.h
+++ b/ash/login/mock_lock_screen_client.h
@@ -18,16 +18,29 @@
 
   mojom::LockScreenClientPtr CreateInterfacePtrAndBind();
 
-  // mojom::LockScreenClient:
-  MOCK_METHOD3(AuthenticateUser,
+  MOCK_METHOD4(AuthenticateUser_,
                void(const AccountId& account_id,
                     const std::string& password,
-                    bool authenticated_by_pin));
+                    bool authenticated_by_pin,
+                    AuthenticateUserCallback& callback));
+
+  // Set the result that should be passed to |callback| in |AuthenticateUser|.
+  void set_authenticate_user_callback_result(bool value) {
+    authenticate_user_callback_result_ = value;
+  }
+
+  // mojom::LockScreenClient:
+  void AuthenticateUser(const AccountId& account_id,
+                        const std::string& password,
+                        bool authenticated_by_pin,
+                        AuthenticateUserCallback callback) override;
   MOCK_METHOD1(AttemptUnlock, void(const AccountId& account_id));
   MOCK_METHOD1(HardlockPod, void(const AccountId& account_id));
   MOCK_METHOD1(RecordClickOnLockIcon, void(const AccountId& account_id));
 
  private:
+  bool authenticate_user_callback_result_ = true;
+
   mojo::Binding<ash::mojom::LockScreenClient> binding_;
 
   DISALLOW_COPY_AND_ASSIGN(MockLockScreenClient);
@@ -38,4 +51,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_LOGIN_MOCK_LOCK_SCREEN_CLIENT_H_
\ No newline at end of file
+#endif  // ASH_LOGIN_MOCK_LOCK_SCREEN_CLIENT_H_
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc
index c0244b5..fbd5273 100644
--- a/ash/login/ui/lock_contents_view.cc
+++ b/ash/login/ui/lock_contents_view.cc
@@ -5,6 +5,7 @@
 #include "ash/login/ui/lock_contents_view.h"
 
 #include "ash/login/lock_screen_controller.h"
+#include "ash/login/ui/lock_screen.h"
 #include "ash/public/interfaces/user_info.mojom.h"
 #include "ash/session/session_controller.h"
 #include "ash/shell.h"
@@ -45,7 +46,10 @@
       Shell::Get()->session_controller()->GetUserSession(user_index);
   Shell::Get()->lock_screen_controller()->AuthenticateUser(
       user_session->user_info->account_id, std::string(),
-      false /* authenticated_by_pin */);
+      false /* authenticated_by_pin */, base::BindOnce([](bool success) {
+        if (success)
+          DestroyLockScreen();
+      }));
 }
 
 }  // namespace ash
diff --git a/ash/login/ui/lock_screen.cc b/ash/login/ui/lock_screen.cc
index baaf5bf..d13311de 100644
--- a/ash/login/ui/lock_screen.cc
+++ b/ash/login/ui/lock_screen.cc
@@ -12,15 +12,29 @@
 
 namespace ash {
 
-bool ShowLockScreen() {
-  LockWindow* window = new LockWindow();
-  window->SetBounds(display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
+namespace {
+// Reference to global lock screen instance. There can only ever be one lock
+// screen display at the same time.
+LockWindow* g_window = nullptr;
+}  // namespace
 
-  views::View* contents = new LockContentsView();
-  window->SetContentsView(contents);
-  window->Show();
+bool ShowLockScreen() {
+  CHECK(!g_window);
+  g_window = new LockWindow();
+  g_window->SetBounds(
+      display::Screen::GetScreen()->GetPrimaryDisplay().bounds());
+
+  auto* contents = new LockContentsView();
+  g_window->SetContentsView(contents);
+  g_window->Show();
 
   return true;
 }
 
+void DestroyLockScreen() {
+  CHECK(g_window);
+  g_window->Close();
+  g_window = nullptr;
+}
+
 }  // namespace ash
diff --git a/ash/login/ui/lock_screen.h b/ash/login/ui/lock_screen.h
index fcccca6..ecad2be6 100644
--- a/ash/login/ui/lock_screen.h
+++ b/ash/login/ui/lock_screen.h
@@ -9,12 +9,19 @@
 
 namespace ash {
 
+// TODO(jdufault): There's some internal state here so put ShowLockScreen and
+// DestroyLockScreen inside a (static) class, ie, ash::LockScreen::Show() and
+// ash::LockScreen::Destroy().
+
 // Creates and displays the lock screen. Returns true if the lock screen was
 // displayed.
 //
 // The lock screen communicates with the backend C++ via a mojo API.
 ASH_EXPORT bool ShowLockScreen();
 
+// Destroys the lock screen. There must be an existing lock screen instance.
+ASH_EXPORT void DestroyLockScreen();
+
 }  // namespace ash
 
 #endif  // ASH_LOGIN_UI_LOCK_SCREEN_H_
diff --git a/ash/public/interfaces/lock_screen.mojom b/ash/public/interfaces/lock_screen.mojom
index 0b4a141..5cc5c35d 100644
--- a/ash/public/interfaces/lock_screen.mojom
+++ b/ash/public/interfaces/lock_screen.mojom
@@ -34,6 +34,10 @@
   // Sets the client interface.
   SetClient(LockScreenClient client);
 
+  // Displays the lock screen. |did_show| is true iff the lock UI was
+  // successfully displayed.
+  ShowLockScreen() => (bool did_show);
+
   // Requests to show error message in the ash lock screen.
   // TODO(xiaoyinh): login_attempts is probabaly not needed from chrome,
   // remove it when we start to count the login attempts in ash lock screen.
@@ -87,9 +91,11 @@
   // |account_id|:           The account id of the user we are authenticating.
   // |hashed_password|:      The hashed password of the user.
   // |authenticated_by_pin|: True if we are using pin to authenticate.
+  //
+  // The result will be set to true if auth was successful, false if not.
   AuthenticateUser(signin.mojom.AccountId account_id,
                    string hashed_password,
-	           bool authenticated_by_pin);
+                   bool authenticated_by_pin) => (bool auth_success);
 
   // Request to attempt easy unlock in chrome.
   // |account_id|:   The account id of the user we are authenticating.
diff --git a/ash/system/network/network_info.h b/ash/system/network/network_info.h
index d0055fd..04d5b294 100644
--- a/ash/system/network/network_info.h
+++ b/ash/system/network/network_info.h
@@ -19,7 +19,7 @@
 // Includes information necessary about a network for displaying the appropriate
 // UI to the user.
 struct NetworkInfo {
-  enum class Type { UNKNOWN, WIFI, TETHER, CELLULAR };
+  enum class Type { UNKNOWN, WIFI, MOBILE };
 
   NetworkInfo();
   NetworkInfo(const std::string& guid);
diff --git a/ash/system/network/network_list.cc b/ash/system/network/network_list.cc
index f94b2f6..5415eabb 100644
--- a/ash/system/network/network_list.cc
+++ b/ash/system/network/network_list.cc
@@ -178,44 +178,42 @@
 
 namespace {
 
-class CellularHeaderRowView : public NetworkListView::SectionHeaderRowView {
+class MobileHeaderRowView : public NetworkListView::SectionHeaderRowView {
  public:
-  CellularHeaderRowView()
+  MobileHeaderRowView()
       : SectionHeaderRowView(IDS_ASH_STATUS_TRAY_NETWORK_MOBILE) {}
 
-  ~CellularHeaderRowView() override {}
+  ~MobileHeaderRowView() override {}
 
-  const char* GetClassName() const override { return "CellularHeaderRowView"; }
+  const char* GetClassName() const override { return "MobileHeaderRowView"; }
 
  protected:
   void OnToggleToggled(bool is_on) override {
     NetworkStateHandler* handler =
         NetworkHandler::Get()->network_state_handler();
-    handler->SetTechnologyEnabled(NetworkTypePattern::Cellular(), is_on,
-                                  chromeos::network_handler::ErrorCallback());
+    // The Mobile network type contains both Cellular and Tether technologies,
+    // though one or both of these may be unavailable. When Cellular technology
+    // is available, the enabled value of Tether depends on the enabled value of
+    // Cellular, so the toggle should only explicitly change the enabled value
+    // of Cellular.
+    // However, if Cellular technology is not available but Tether technology is
+    // available, the toggle should explicitly change the enabled value of
+    // Tether.
+    if (handler->IsTechnologyAvailable(NetworkTypePattern::Cellular())) {
+      handler->SetTechnologyEnabled(NetworkTypePattern::Cellular(), is_on,
+                                    chromeos::network_handler::ErrorCallback());
+    } else {
+      DCHECK(handler->IsTechnologyAvailable(NetworkTypePattern::Tether()));
+
+      handler->SetTechnologyEnabled(NetworkTypePattern::Tether(), is_on,
+                                    chromeos::network_handler::ErrorCallback());
+    }
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(CellularHeaderRowView);
+  DISALLOW_COPY_AND_ASSIGN(MobileHeaderRowView);
 };
 
-class TetherHeaderRowView : public NetworkListView::SectionHeaderRowView {
- public:
-  TetherHeaderRowView()
-      : SectionHeaderRowView(IDS_ASH_STATUS_TRAY_NETWORK_TETHER) {}
-
-  ~TetherHeaderRowView() override {}
-
-  const char* GetClassName() const override { return "TetherHeaderRowView"; }
-
- protected:
-  void OnToggleToggled(bool is_on) override {
-    // TODO (hansberry): Persist toggle to settings/preferences.
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TetherHeaderRowView);
-};
 
 class WifiHeaderRowView : public NetworkListView::SectionHeaderRowView {
  public:
@@ -296,12 +294,10 @@
     : NetworkStateListDetailedView(owner, LIST_TYPE_NETWORK, login),
       needs_relayout_(false),
       no_wifi_networks_view_(nullptr),
-      no_cellular_networks_view_(nullptr),
-      cellular_header_view_(nullptr),
-      tether_header_view_(nullptr),
+      no_mobile_networks_view_(nullptr),
+      mobile_header_view_(nullptr),
       wifi_header_view_(nullptr),
-      cellular_separator_view_(nullptr),
-      tether_separator_view_(nullptr),
+      mobile_separator_view_(nullptr),
       wifi_separator_view_(nullptr),
       connection_warning_(nullptr) {}
 
@@ -431,10 +427,8 @@
     info->connecting = network->IsConnectingState();
     if (network->Matches(NetworkTypePattern::WiFi()))
       info->type = NetworkInfo::Type::WIFI;
-    else if (network->Matches(NetworkTypePattern::Cellular()))
-      info->type = NetworkInfo::Type::CELLULAR;
-    else if (network->Matches(NetworkTypePattern::Tether()))
-      info->type = NetworkInfo::Type::TETHER;
+    else if (network->Matches(NetworkTypePattern::Mobile()))
+      info->type = NetworkInfo::Type::MOBILE;
     if (prohibited_by_policy) {
       info->tooltip =
           l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_PROHIBITED);
@@ -510,16 +504,20 @@
     PlaceViewAtIndex(connection_warning_, index++);
   }
 
-  // First add high-priority networks (not Wi-Fi nor cellular).
+  // First add high-priority networks (neither Wi-Fi nor Mobile).
   std::unique_ptr<std::set<std::string>> new_guids =
       UpdateNetworkChildren(NetworkInfo::Type::UNKNOWN, index);
   index += new_guids->size();
 
-  if (handler->IsTechnologyAvailable(NetworkTypePattern::Cellular())) {
-    index = UpdateSectionHeaderRow(
-        NetworkTypePattern::Cellular(),
-        handler->IsTechnologyEnabled(NetworkTypePattern::Cellular()), index,
-        &cellular_header_view_, &cellular_separator_view_);
+  if (handler->IsTechnologyAvailable(NetworkTypePattern::Cellular()) ||
+      handler->IsTechnologyAvailable(NetworkTypePattern::Tether())) {
+    bool is_enabled =
+        handler->IsTechnologyEnabled(NetworkTypePattern::Cellular()) ||
+        handler->IsTechnologyEnabled(NetworkTypePattern::Tether());
+
+    index = UpdateSectionHeaderRow(NetworkTypePattern::Cellular(), is_enabled,
+                                   index, &mobile_header_view_,
+                                   &mobile_separator_view_);
   }
 
   // Cellular initializing.
@@ -529,35 +527,16 @@
       !handler->FirstNetworkByType(NetworkTypePattern::Mobile())) {
     cellular_message_id = IDS_ASH_STATUS_TRAY_NO_MOBILE_NETWORKS;
   }
-  UpdateInfoLabel(cellular_message_id, index, &no_cellular_networks_view_);
+  UpdateInfoLabel(cellular_message_id, index, &no_mobile_networks_view_);
   if (cellular_message_id)
     ++index;
 
-  // Add cellular networks.
+  // Add cellular and Tether networks.
   std::unique_ptr<std::set<std::string>> new_cellular_guids =
-      UpdateNetworkChildren(NetworkInfo::Type::CELLULAR, index);
+      UpdateNetworkChildren(NetworkInfo::Type::MOBILE, index);
   index += new_cellular_guids->size();
   new_guids->insert(new_cellular_guids->begin(), new_cellular_guids->end());
 
-  // TODO (hansberry): Audit existing usage of NonVirtual and consider changing
-  // it to include Tether. See crbug.com/693647.
-  if (handler->IsTechnologyAvailable(NetworkTypePattern::Tether())) {
-    index = UpdateSectionHeaderRow(
-        NetworkTypePattern::Tether(),
-        handler->IsTechnologyEnabled(NetworkTypePattern::Tether()), index,
-        &tether_header_view_, &tether_separator_view_);
-
-    // TODO (hansberry): Should a message similar to
-    // IDS_ASH_STATUS_TRAY_NO_CELLULAR_NETWORKS be shown if Tether technology is
-    // enabled but no networks are around?
-
-    // Add Tether networks.
-    std::unique_ptr<std::set<std::string>> new_tether_guids =
-        UpdateNetworkChildren(NetworkInfo::Type::TETHER, index);
-    index += new_tether_guids->size();
-    new_guids->insert(new_tether_guids->begin(), new_tether_guids->end());
-  }
-
   index = UpdateSectionHeaderRow(
       NetworkTypePattern::WiFi(),
       handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()), index,
@@ -693,10 +672,8 @@
                                             SectionHeaderRowView** view,
                                             views::Separator** separator_view) {
   if (!*view) {
-    if (pattern.Equals(NetworkTypePattern::Cellular()))
-      *view = new CellularHeaderRowView();
-    else if (pattern.Equals(NetworkTypePattern::Tether()))
-      *view = new TetherHeaderRowView();
+    if (pattern.MatchesPattern(NetworkTypePattern::Mobile()))
+      *view = new MobileHeaderRowView();
     else if (pattern.Equals(NetworkTypePattern::WiFi()))
       *view = new WifiHeaderRowView();
     else
diff --git a/ash/system/network/network_list.h b/ash/system/network/network_list.h
index 1de25cd..3eca162a 100644
--- a/ash/system/network/network_list.h
+++ b/ash/system/network/network_list.h
@@ -121,12 +121,10 @@
   bool needs_relayout_;
 
   InfoLabel* no_wifi_networks_view_;
-  InfoLabel* no_cellular_networks_view_;
-  SectionHeaderRowView* cellular_header_view_;
-  SectionHeaderRowView* tether_header_view_;
+  InfoLabel* no_mobile_networks_view_;
+  SectionHeaderRowView* mobile_header_view_;
   SectionHeaderRowView* wifi_header_view_;
-  views::Separator* cellular_separator_view_;
-  views::Separator* tether_separator_view_;
+  views::Separator* mobile_separator_view_;
   views::Separator* wifi_separator_view_;
   TriView* connection_warning_;
 
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 131de3d..7735309 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -966,7 +966,6 @@
     "trace_event/memory_allocator_dump_guid.h",
     "trace_event/memory_dump_manager.cc",
     "trace_event/memory_dump_manager.h",
-    "trace_event/memory_dump_manager_test_utils.h",
     "trace_event/memory_dump_provider.h",
     "trace_event/memory_dump_provider_info.cc",
     "trace_event/memory_dump_provider_info.h",
diff --git a/base/files/memory_mapped_file_posix.cc b/base/files/memory_mapped_file_posix.cc
index 55b754d..f0b391e 100644
--- a/base/files/memory_mapped_file_posix.cc
+++ b/base/files/memory_mapped_file_posix.cc
@@ -130,6 +130,13 @@
         struct stat statbuf;
         if (fstat(file_.GetPlatformFile(), &statbuf) == 0)
           block_size = statbuf.st_blksize;
+#if defined(OS_FUCHSIA)
+        // TODO(fuchsia): Fuchsia stat() currently returns 0 for st_blksize,
+        // which hangs the loop below. Remove this after the next SDK update.
+        // https://crbug.com/706592 and MG-815.
+        if (block_size == 0)
+          block_size = 512;
+#endif  // defined(OS_FUCHSIA)
         const off_t map_end = map_start + static_cast<off_t>(map_size);
         for (off_t i = map_start; i < map_end; i += block_size) {
           char existing_byte;
diff --git a/base/message_loop/message_pump_fuchsia.cc b/base/message_loop/message_pump_fuchsia.cc
index 6f96564d..c69cd281 100644
--- a/base/message_loop/message_pump_fuchsia.cc
+++ b/base/message_loop/message_pump_fuchsia.cc
@@ -4,6 +4,8 @@
 
 #include "base/message_loop/message_pump_fuchsia.h"
 
+#include <magenta/syscalls.h>
+
 #include "base/logging.h"
 
 namespace base {
@@ -11,30 +13,82 @@
 MessagePumpFuchsia::FileDescriptorWatcher::FileDescriptorWatcher(
     const tracked_objects::Location& from_here)
     : created_from_location_(from_here) {
-  NOTIMPLEMENTED();
 }
 
-MessagePumpFuchsia::FileDescriptorWatcher::~FileDescriptorWatcher() {}
+MessagePumpFuchsia::FileDescriptorWatcher::~FileDescriptorWatcher() {
+  StopWatchingFileDescriptor();
+  __mxio_release(io_);
+  if (was_destroyed_) {
+    DCHECK(!*was_destroyed_);
+    *was_destroyed_ = true;
+  }
+}
 
 bool MessagePumpFuchsia::FileDescriptorWatcher::StopWatchingFileDescriptor() {
-  NOTIMPLEMENTED();
-  return false;
+  uint64_t controller_as_key =
+      static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this));
+  return mx_port_cancel(port_, handle_, controller_as_key) == NO_ERROR;
 }
 
-MessagePumpFuchsia::MessagePumpFuchsia()
-    : keep_running_(true),
-      event_(WaitableEvent::ResetPolicy::AUTOMATIC,
-             WaitableEvent::InitialState::NOT_SIGNALED) {}
+MessagePumpFuchsia::MessagePumpFuchsia() : keep_running_(true) {
+  CHECK(mx_port_create(MX_PORT_OPT_V2, &port_) == NO_ERROR);
+}
 
-MessagePumpFuchsia::~MessagePumpFuchsia() {}
+MessagePumpFuchsia::~MessagePumpFuchsia() {
+  mx_status_t status = mx_handle_close(port_);
+  if (status != NO_ERROR) {
+    DLOG(ERROR) << "mx_handle_close failed: " << status;
+  }
+}
 
 bool MessagePumpFuchsia::WatchFileDescriptor(int fd,
                                              bool persistent,
                                              int mode,
                                              FileDescriptorWatcher* controller,
                                              Watcher* delegate) {
-  NOTIMPLEMENTED();
-  return false;
+  DCHECK_GE(fd, 0);
+  DCHECK(controller);
+  DCHECK(delegate);
+  DCHECK(!persistent);  // TODO(fuchsia): Not yet implemented.
+  DCHECK(mode == WATCH_READ || mode == WATCH_WRITE || mode == WATCH_READ_WRITE);
+
+  uint32_t events;
+  switch (mode) {
+    case WATCH_READ:
+      events = MXIO_EVT_READABLE;
+      break;
+    case WATCH_WRITE:
+      events = MXIO_EVT_WRITABLE;
+      break;
+    case WATCH_READ_WRITE:
+      events = MXIO_EVT_READABLE | MXIO_EVT_WRITABLE;
+      break;
+    default:
+      DLOG(ERROR) << "unexpected mode: " << mode;
+      return false;
+  }
+
+  controller->watcher_ = delegate;
+  controller->fd_ = fd;
+  controller->desired_events_ = events;
+
+  controller->io_ = __mxio_fd_to_io(fd);
+  uint32_t signals;
+  __mxio_wait_begin(controller->io_, events, &controller->handle_, &signals);
+  if (controller->handle_ == MX_HANDLE_INVALID)
+    return false;
+  controller->port_ = port_;
+
+  uint64_t controller_as_key =
+      static_cast<uint64_t>(reinterpret_cast<uintptr_t>(controller));
+  mx_status_t status =
+      mx_object_wait_async(controller->handle_, port_, controller_as_key,
+                           signals, MX_WAIT_ASYNC_ONCE);
+  if (status != NO_ERROR) {
+    DLOG(ERROR) << "mx_object_wait_async failed: " << status;
+    return false;
+  }
+  return true;
 }
 
 void MessagePumpFuchsia::Run(Delegate* delegate) {
@@ -59,17 +113,59 @@
     if (did_work)
       continue;
 
-    if (delayed_work_time_.is_null()) {
-      event_.Wait();
-    } else {
-      // No need to handle already expired |delayed_work_time_| in any special
-      // way. When |delayed_work_time_| is in the past TimeWaitUntil returns
-      // promptly and |delayed_work_time_| will re-initialized on a next
-      // DoDelayedWork call which has to be called in order to get here again.
-      event_.TimedWaitUntil(delayed_work_time_);
+    mx_time_t deadline = delayed_work_time_.is_null()
+                             ? MX_TIME_INFINITE
+                             : mx_time_get(MX_CLOCK_MONOTONIC) +
+                                   delayed_work_time_.ToInternalValue();
+    mx_port_packet_t packet;
+    const mx_status_t wait_status = mx_port_wait(port_, deadline, &packet, 0);
+    if (wait_status != NO_ERROR && wait_status != ERR_TIMED_OUT) {
+      NOTREACHED() << "unexpected wait status: " << wait_status;
+      continue;
     }
 
-    // TODO(fuchsia): Handle file descriptor watching here. (maybe?)
+    if (packet.type == MX_PKT_TYPE_SIGNAL_ONE) {
+      // A watched fd caused the wakeup via mx_object_wait_async().
+      DCHECK(packet.status == NO_ERROR);
+      FileDescriptorWatcher* controller =
+          reinterpret_cast<FileDescriptorWatcher*>(
+              static_cast<uintptr_t>(packet.key));
+
+      DCHECK(packet.signal.trigger & packet.signal.observed);
+
+      uint32_t events;
+      __mxio_wait_end(controller->io_, packet.signal.observed, &events);
+      // .observed can include other spurious things, in particular, that the fd
+      // is writable, when we only asked to know when it was readable. In that
+      // case, we don't want to call both the CanWrite and CanRead callback,
+      // when the caller asked for only, for example, readable callbacks. So,
+      // mask with the events that we actually wanted to know about.
+      events &= controller->desired_events_;
+
+      if ((events & (MXIO_EVT_READABLE | MXIO_EVT_WRITABLE)) ==
+          (MXIO_EVT_READABLE | MXIO_EVT_WRITABLE)) {
+        // Both callbacks to be called, must check controller destruction after
+        // the first callback is run, which is done by letting the destructor
+        // set a bool here (which is located on the stack). If it's set during
+        // the first callback, then the controller was destroyed during the
+        // first callback so we do not call the second one, as the controller
+        // pointer is now invalid.
+        bool controller_was_destroyed = false;
+        controller->was_destroyed_ = &controller_was_destroyed;
+        controller->watcher_->OnFileCanWriteWithoutBlocking(controller->fd_);
+        if (!controller_was_destroyed)
+          controller->watcher_->OnFileCanReadWithoutBlocking(controller->fd_);
+        if (!controller_was_destroyed)
+          controller->was_destroyed_ = nullptr;
+      } else if (events & MXIO_EVT_WRITABLE) {
+        controller->watcher_->OnFileCanWriteWithoutBlocking(controller->fd_);
+      } else if (events & MXIO_EVT_READABLE) {
+        controller->watcher_->OnFileCanReadWithoutBlocking(controller->fd_);
+      }
+    } else {
+      // Wakeup caused by ScheduleWork().
+      DCHECK(packet.type == MX_PKT_TYPE_USER);
+    }
   }
 
   keep_running_ = true;
@@ -80,16 +176,21 @@
 }
 
 void MessagePumpFuchsia::ScheduleWork() {
-  // Since this can be called on any thread, we need to ensure that our Run
-  // loop wakes up.
-  event_.Signal();
+  // Since this can be called on any thread, we need to ensure that our Run loop
+  // wakes up.
+  mx_port_packet_t packet = {};
+  packet.type = MX_PKT_TYPE_USER;
+  mx_status_t status = mx_port_queue(port_, &packet, 0);
+  if (status != NO_ERROR) {
+    DLOG(ERROR) << "mx_port_queue failed: " << status;
+  }
 }
 
 void MessagePumpFuchsia::ScheduleDelayedWork(
     const TimeTicks& delayed_work_time) {
-  // We know that we can't be blocked on Wait right now since this method can
-  // only be called on the same thread as Run, so we only need to update our
-  // record of how long to sleep when we do sleep.
+  // We know that we can't be blocked right now since this method can only be
+  // called on the same thread as Run, so we only need to update our record of
+  // how long to sleep when we do sleep.
   delayed_work_time_ = delayed_work_time;
 }
 
diff --git a/base/message_loop/message_pump_fuchsia.h b/base/message_loop/message_pump_fuchsia.h
index 479c2c3b..f468b50 100644
--- a/base/message_loop/message_pump_fuchsia.h
+++ b/base/message_loop/message_pump_fuchsia.h
@@ -8,7 +8,10 @@
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/message_loop/message_pump.h"
-#include "base/synchronization/waitable_event.h"
+
+#include <magenta/syscalls/port.h>
+#include <mxio/io.h>
+#include <mxio/private.h>
 
 namespace base {
 
@@ -40,7 +43,23 @@
     }
 
    private:
+    friend class MessagePumpFuchsia;
+
     const tracked_objects::Location created_from_location_;
+    Watcher* watcher_ = nullptr;
+    mx_handle_t port_ = MX_HANDLE_INVALID;
+    mx_handle_t handle_ = MX_HANDLE_INVALID;
+    mxio_t* io_ = nullptr;
+    int fd_ = -1;
+    uint32_t desired_events_ = 0;
+
+    // This bool is used during calling |Watcher| callbacks. This object's
+    // lifetime is owned by the user of this class. If the message loop is woken
+    // up in the case where it needs to call both the readable and writable
+    // callbacks, we need to take care not to call the second one if this object
+    // is destroyed by the first one. The bool points to the stack, and is set
+    // to true in ~FileDescriptorWatcher() to handle this case.
+    bool* was_destroyed_ = nullptr;
 
     DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher);
   };
@@ -70,8 +89,7 @@
   // This flag is set to false when Run should return.
   bool keep_running_;
 
-  // Used to sleep until there is more work to do.
-  WaitableEvent event_;
+  mx_handle_t port_;
 
   // The time at which we should call DoDelayedWork.
   TimeTicks delayed_work_time_;
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc
index 1ce86367..59e5629b 100644
--- a/base/trace_event/memory_dump_manager.cc
+++ b/base/trace_event/memory_dump_manager.cc
@@ -131,6 +131,9 @@
     TRACE_DISABLED_BY_DEFAULT("memory-infra");
 
 // static
+const char* const MemoryDumpManager::kLogPrefix = "Memory-infra dump";
+
+// static
 const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3;
 
 // static
@@ -156,7 +159,6 @@
 // static
 std::unique_ptr<MemoryDumpManager>
 MemoryDumpManager::CreateInstanceForTesting() {
-  DCHECK(!g_instance_for_testing);
   std::unique_ptr<MemoryDumpManager> instance(new MemoryDumpManager());
   g_instance_for_testing = instance.get();
   return instance;
@@ -426,8 +428,10 @@
     MemoryDumpType dump_type,
     MemoryDumpLevelOfDetail level_of_detail,
     const GlobalMemoryDumpCallback& callback) {
-  if (!is_initialized()) {
-    VLOG(1) << "RequestGlobalDump() FAIL: MemoryDumpManager is not initialized";
+  // If |request_dump_function_| is null MDM hasn't been initialized yet.
+  if (request_dump_function_.is_null()) {
+    VLOG(1) << kLogPrefix << " failed because"
+            << " memory dump manager is not enabled.";
     if (!callback.is_null())
       callback.Run(0u /* guid */, false /* success */);
     return;
@@ -464,8 +468,7 @@
 void MemoryDumpManager::RequestGlobalDump(
     MemoryDumpType dump_type,
     MemoryDumpLevelOfDetail level_of_detail) {
-  auto noop_callback = [](uint64_t dump_guid, bool success) {};
-  RequestGlobalDump(dump_type, level_of_detail, Bind(noop_callback));
+  RequestGlobalDump(dump_type, level_of_detail, GlobalMemoryDumpCallback());
 }
 
 bool MemoryDumpManager::IsDumpProviderRegisteredForTesting(
@@ -496,15 +499,6 @@
 void MemoryDumpManager::CreateProcessDump(
     const MemoryDumpRequestArgs& args,
     const ProcessMemoryDumpCallback& callback) {
-  if (!is_initialized()) {
-    VLOG(1) << "CreateProcessDump() FAIL: MemoryDumpManager is not initialized";
-    if (!callback.is_null()) {
-      callback.Run(args.dump_guid, false /* success */,
-                   Optional<MemoryDumpCallbackResult>());
-    }
-    return;
-  }
-
   char guid_str[20];
   sprintf(guid_str, "0x%" PRIx64, args.dump_guid);
   TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(kTraceCategory, "ProcessMemoryDump",
@@ -738,7 +732,7 @@
 
   // The results struct to fill.
   // TODO(hjd): Transitional until we send the full PMD. See crbug.com/704203
-  Optional<MemoryDumpCallbackResult> result;
+  base::Optional<MemoryDumpCallbackResult> result;
 
   bool dump_successful = pmd_async_state->dump_successful;
 
@@ -868,7 +862,7 @@
     }
   }
 
-  // Only coordinator process triggers periodic memory dumps.
+  // Only coordinator process triggers periodic global memory dumps.
   if (is_coordinator_ && !periodic_config.triggers.empty()) {
     MemoryDumpScheduler::GetInstance()->Start(periodic_config,
                                               GetOrCreateBgTaskRunnerLocked());
diff --git a/base/trace_event/memory_dump_manager.h b/base/trace_event/memory_dump_manager.h
index e7726f4..1018e453 100644
--- a/base/trace_event/memory_dump_manager.h
+++ b/base/trace_event/memory_dump_manager.h
@@ -46,6 +46,7 @@
                              const GlobalMemoryDumpCallback& callback)>;
 
   static const char* const kTraceCategory;
+  static const char* const kLogPrefix;
 
   // This value is returned as the tracing id of the child processes by
   // GetTracingProcessId() when tracing is not enabled.
@@ -112,12 +113,13 @@
   // to notify about the completion of the global dump (i.e. after all the
   // processes have dumped) and its success (true iff all the dumps were
   // successful).
-  void RequestGlobalDump(MemoryDumpType,
-                         MemoryDumpLevelOfDetail,
-                         const GlobalMemoryDumpCallback&);
+  void RequestGlobalDump(MemoryDumpType dump_type,
+                         MemoryDumpLevelOfDetail level_of_detail,
+                         const GlobalMemoryDumpCallback& callback);
 
   // Same as above (still asynchronous), but without callback.
-  void RequestGlobalDump(MemoryDumpType, MemoryDumpLevelOfDetail);
+  void RequestGlobalDump(MemoryDumpType dump_type,
+                         MemoryDumpLevelOfDetail level_of_detail);
 
   // Prepare MemoryDumpManager for RequestGlobalMemoryDump calls for tracing
   // related modes (non-SUMMARY_ONLY).
@@ -278,9 +280,6 @@
   void GetDumpProvidersForPolling(
       std::vector<scoped_refptr<MemoryDumpProviderInfo>>*);
 
-  // Returns true if Initialize() has been called, false otherwise.
-  bool is_initialized() const { return !request_dump_function_.is_null(); }
-
   // An ordererd set of registered MemoryDumpProviderInfo(s), sorted by task
   // runner affinity (MDPs belonging to the same task runners are adjacent).
   MemoryDumpProviderInfo::OrderedSet dump_providers_;
diff --git a/base/trace_event/memory_dump_manager_test_utils.h b/base/trace_event/memory_dump_manager_test_utils.h
deleted file mode 100644
index bb32f5c..0000000
--- a/base/trace_event/memory_dump_manager_test_utils.h
+++ /dev/null
@@ -1,46 +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 BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_TEST_UTILS_H_
-#define BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_TEST_UTILS_H_
-
-#include "base/bind.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/memory_dump_request_args.h"
-
-namespace base {
-namespace trace_event {
-
-// Short-circuit the RequestGlobalDump() calls to CreateProcessDump().
-// Rationale: only the in-process logic is required for unittests.
-void RequestGlobalDumpForInProcessTesting(
-    const MemoryDumpRequestArgs& args,
-    const GlobalMemoryDumpCallback& global_callback) {
-  // Turns a ProcessMemoryDumpCallback into a GlobalMemoryDumpCallback.
-  auto callback_adapter = [](const GlobalMemoryDumpCallback& global_callback,
-                             uint64_t dump_guid, bool success,
-                             const Optional<MemoryDumpCallbackResult>& result) {
-    if (!global_callback.is_null())
-      global_callback.Run(dump_guid, success);
-  };
-  MemoryDumpManager::GetInstance()->CreateProcessDump(
-      args, Bind(callback_adapter, global_callback));
-};
-
-// Short circuits the RequestGlobalDumpFunction() to CreateProcessDump(),
-// effectively allowing to use both in unittests with the same behavior.
-// Unittests are in-process only and don't require all the multi-process
-// dump handshaking (which would require bits outside of base).
-void InitializeMemoryDumpManagerForInProcessTesting(bool is_coordinator) {
-  MemoryDumpManager* instance = MemoryDumpManager::GetInstance();
-  instance->set_dumper_registrations_ignored_for_testing(true);
-  instance->Initialize(BindRepeating(&RequestGlobalDumpForInProcessTesting),
-                       is_coordinator);
-  instance->set_dumper_registrations_ignored_for_testing(false);
-}
-
-}  // namespace trace_event
-}  // namespace base
-
-#endif  // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_TEST_UTILS_H_
diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc
index 14fb7a1b..fe1b2fe 100644
--- a/base/trace_event/memory_dump_manager_unittest.cc
+++ b/base/trace_event/memory_dump_manager_unittest.cc
@@ -27,9 +27,7 @@
 #include "base/threading/sequenced_worker_pool.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "base/trace_event/memory_dump_manager_test_utils.h"
 #include "base/trace_event/memory_dump_provider.h"
-#include "base/trace_event/memory_dump_request_args.h"
 #include "base/trace_event/memory_dump_scheduler.h"
 #include "base/trace_event/memory_infra_background_whitelist.h"
 #include "base/trace_event/process_memory_dump.h"
@@ -101,6 +99,15 @@
   mdm->set_dumper_registrations_ignored_for_testing(true);
 }
 
+void OnTraceDataCollected(Closure quit_closure,
+                          trace_event::TraceResultBuffer* buffer,
+                          const scoped_refptr<RefCountedString>& json,
+                          bool has_more_events) {
+  buffer->AddFragment(json->data());
+  if (!has_more_events)
+    quit_closure.Run();
+}
+
 // Posts |task| to |task_runner| and blocks until it is executed.
 void PostTaskAndWait(const tracked_objects::Location& from_here,
                      SequencedTaskRunner* task_runner,
@@ -115,6 +122,37 @@
   event.Wait();
 }
 
+// Adapts a ProcessMemoryDumpCallback into a GlobalMemoryDumpCallback
+// and keeps around the process-local result.
+void ProcessDumpCallbackAdapter(
+    GlobalMemoryDumpCallback callback,
+    uint64_t dump_guid,
+    bool success,
+    const base::Optional<base::trace_event::MemoryDumpCallbackResult>&) {
+  callback.Run(dump_guid, success);
+}
+
+// This mocks the RequestGlobalDumpFunction which is typically handled by
+// process_local_dump_manager_impl.cc, by short-circuiting dump requests locally
+// to the MemoryDumpManager without an actual service.
+class GlobalMemoryDumpHandler {
+ public:
+  MOCK_METHOD2(RequestGlobalMemoryDump,
+               void(const MemoryDumpRequestArgs& args,
+                    const GlobalMemoryDumpCallback& callback));
+
+  GlobalMemoryDumpHandler() {
+    ON_CALL(*this, RequestGlobalMemoryDump(_, _))
+        .WillByDefault(Invoke([this](const MemoryDumpRequestArgs& args,
+                                     const GlobalMemoryDumpCallback& callback) {
+          ProcessMemoryDumpCallback process_callback =
+              Bind(&ProcessDumpCallbackAdapter, callback);
+          MemoryDumpManager::GetInstance()->CreateProcessDump(args,
+                                                              process_callback);
+        }));
+  }
+};
+
 class MockMemoryDumpProvider : public MemoryDumpProvider {
  public:
   MOCK_METHOD0(Destructor, void());
@@ -190,16 +228,8 @@
   buffer.SetOutputCallback(trace_output.GetCallback());
   RunLoop run_loop;
   buffer.Start();
-  auto on_trace_data_collected =
-      [](Closure quit_closure, trace_event::TraceResultBuffer* buffer,
-         const scoped_refptr<RefCountedString>& json, bool has_more_events) {
-        buffer->AddFragment(json->data());
-        if (!has_more_events)
-          quit_closure.Run();
-      };
-
-  trace_event::TraceLog::GetInstance()->Flush(Bind(
-      on_trace_data_collected, run_loop.QuitClosure(), Unretained(&buffer)));
+  trace_event::TraceLog::GetInstance()->Flush(
+      Bind(&OnTraceDataCollected, run_loop.QuitClosure(), Unretained(&buffer)));
   run_loop.Run();
   buffer.Finish();
 
@@ -215,9 +245,11 @@
   MemoryDumpManagerTest() : testing::Test(), kDefaultOptions() {}
 
   void SetUp() override {
+    last_callback_success_ = false;
     message_loop_.reset(new MessageLoop());
     mdm_ = MemoryDumpManager::CreateInstanceForTesting();
     ASSERT_EQ(mdm_.get(), MemoryDumpManager::GetInstance());
+    results_.clear();
   }
 
   void TearDown() override {
@@ -226,46 +258,35 @@
     TraceLog::DeleteForTesting();
   }
 
+  // Turns a Closure into a GlobalMemoryDumpCallback, keeping track of the
+  // callback result and taking care of posting the closure on the correct task
+  // runner.
+  void GlobalDumpCallbackAdapter(
+      scoped_refptr<SingleThreadTaskRunner> task_runner,
+      Closure closure,
+      uint64_t dump_guid,
+      bool success) {
+    last_callback_success_ = success;
+    task_runner->PostTask(FROM_HERE, closure);
+  }
+
  protected:
-  // Blocks the current thread (spinning a nested message loop) until the
-  // memory dump is complete. Returns:
-  // - return value: the |success| from the CreateProcessDump() callback.
-  // - (optional) |result|: the summarized metrics for TestSummaryComputation.
-  bool RequestProcessDumpAndWait(
-      MemoryDumpType dump_type,
-      MemoryDumpLevelOfDetail level_of_detail,
-      Optional<MemoryDumpCallbackResult>* result = nullptr) {
+  void InitializeMemoryDumpManager(bool is_coordinator) {
+    mdm_->set_dumper_registrations_ignored_for_testing(true);
+    mdm_->Initialize(
+        BindRepeating(&GlobalMemoryDumpHandler::RequestGlobalMemoryDump,
+                      Unretained(&global_dump_handler_)),
+        is_coordinator);
+  }
+
+  void RequestGlobalDumpAndWait(MemoryDumpType dump_type,
+                                MemoryDumpLevelOfDetail level_of_detail) {
     RunLoop run_loop;
-    bool success = false;
-    static uint64_t test_guid = 1;
-    test_guid++;
-    MemoryDumpRequestArgs request_args{test_guid, dump_type, level_of_detail};
-
-    // The signature of the callback delivered by MemoryDumpManager is:
-    // void ProcessMemoryDumpCallback(uint64_t dump_guid,
-    //                                bool success,
-    //                                const Optional<MemoryDumpCallbackResult>&)
-    // The extra arguments prepended to the |callback| below (the ones with the
-    // "curried_" prefix) are just passed from the Bind(). This is just to get
-    // around the limitation of Bind() in supporting only capture-less lambdas.
-    ProcessMemoryDumpCallback callback = Bind(
-        [](bool* curried_success, Closure curried_quit_closure,
-           uint64_t curried_expected_guid,
-           Optional<MemoryDumpCallbackResult>* curried_result,
-           uint64_t dump_guid, bool success,
-           const Optional<MemoryDumpCallbackResult>& callback_result) {
-          *curried_success = success;
-          EXPECT_EQ(curried_expected_guid, dump_guid);
-          if (curried_result)
-            *curried_result = callback_result;
-          ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-                                                  curried_quit_closure);
-        },
-        Unretained(&success), run_loop.QuitClosure(), test_guid, result);
-
-    mdm_->CreateProcessDump(request_args, callback);
+    GlobalMemoryDumpCallback callback = Bind(
+        &MemoryDumpManagerTest::GlobalDumpCallbackAdapter, Unretained(this),
+        ThreadTaskRunnerHandle::Get(), run_loop.QuitClosure());
+    mdm_->RequestGlobalDump(dump_type, level_of_detail, callback);
     run_loop.Run();
-    return success;
   }
 
   void EnableTracingWithLegacyCategories(const char* category) {
@@ -288,30 +309,51 @@
     return MemoryDumpManager::kMaxConsecutiveFailuresCount;
   }
 
+  const std::vector<MemoryDumpCallbackResult>* GetResults() const {
+    return &results_;
+  }
+
   const MemoryDumpProvider::Options kDefaultOptions;
   std::unique_ptr<MemoryDumpManager> mdm_;
+  GlobalMemoryDumpHandler global_dump_handler_;
+  bool last_callback_success_;
+
+  // Adapts a ProcessMemoryDumpCallback into a GlobalMemoryDumpCallback by
+  // trimming off the result argument and calling the global callback.
+  void ProcessDumpRecordingCallbackAdapter(
+      GlobalMemoryDumpCallback callback,
+      uint64_t dump_guid,
+      bool success,
+      const base::Optional<MemoryDumpCallbackResult>& result) {
+    if (result.has_value()) {
+      results_.push_back(result.value());
+    }
+    callback.Run(dump_guid, success);
+  }
 
  private:
   std::unique_ptr<MessageLoop> message_loop_;
+  std::vector<MemoryDumpCallbackResult> results_;
 
-  // To tear down the singleton instance after each test.
+  // We want our singleton torn down after each test.
   ShadowingAtExitManager at_exit_manager_;
 };
 
 // Basic sanity checks. Registers a memory dump provider and checks that it is
 // called.
 TEST_F(MemoryDumpManagerTest, SingleDumper) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   MockMemoryDumpProvider mdp;
   RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
 
   // Now repeat enabling the memory category and check that the dumper is
   // invoked this time.
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-  EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3);
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(3);
+  EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true));
   for (int i = 0; i < 3; ++i) {
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
   }
   DisableTracing();
 
@@ -320,10 +362,12 @@
   // Finally check the unregister logic: the global dump handler will be invoked
   // but not the dump provider, as it has been unregistered.
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(3);
   EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0);
+
   for (int i = 0; i < 3; ++i) {
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
   }
   DisableTracing();
 }
@@ -331,14 +375,15 @@
 // Checks that requesting dumps with high level of detail actually propagates
 // the level of the detail properly to OnMemoryDump() call on dump providers.
 TEST_F(MemoryDumpManagerTest, CheckMemoryDumpArgs) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   MockMemoryDumpProvider mdp;
 
   RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-  EXPECT_CALL(mdp, OnMemoryDump(IsDetailedDump(), _));
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::DETAILED));
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
+  EXPECT_CALL(mdp, OnMemoryDump(IsDetailedDump(), _)).WillOnce(Return(true));
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::DETAILED);
   DisableTracing();
   mdm_->UnregisterDumpProvider(&mdp);
 
@@ -346,9 +391,10 @@
   // OnMemoryDump() call on dump providers.
   RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-  EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _));
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::LIGHT));
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
+  EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _)).WillOnce(Return(true));
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::LIGHT);
   DisableTracing();
   mdm_->UnregisterDumpProvider(&mdp);
 }
@@ -356,7 +402,7 @@
 // Checks that the HeapProfilerSerializationState object is actually
 // shared over time.
 TEST_F(MemoryDumpManagerTest, HeapProfilerSerializationState) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   MockMemoryDumpProvider mdp1;
   MockMemoryDumpProvider mdp2;
   RegisterDumpProvider(&mdp1, nullptr);
@@ -365,6 +411,7 @@
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
   const HeapProfilerSerializationState* heap_profiler_serialization_state =
       mdm_->heap_profiler_serialization_state_for_testing().get();
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(2);
   EXPECT_CALL(mdp1, OnMemoryDump(_, _))
       .Times(2)
       .WillRepeatedly(
@@ -385,8 +432,8 @@
           }));
 
   for (int i = 0; i < 2; ++i) {
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
   }
 
   DisableTracing();
@@ -394,36 +441,39 @@
 
 // Checks that the (Un)RegisterDumpProvider logic behaves sanely.
 TEST_F(MemoryDumpManagerTest, MultipleDumpers) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   MockMemoryDumpProvider mdp1;
   MockMemoryDumpProvider mdp2;
 
   // Enable only mdp1.
   RegisterDumpProvider(&mdp1, ThreadTaskRunnerHandle::Get());
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-  EXPECT_CALL(mdp1, OnMemoryDump(_, _));
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
+  EXPECT_CALL(mdp1, OnMemoryDump(_, _)).WillOnce(Return(true));
   EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0);
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::DETAILED));
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::DETAILED);
   DisableTracing();
 
-  // Invert: enable mdp2 and disable mdp1.
+  // Invert: enable mdp1 and disable mdp2.
   mdm_->UnregisterDumpProvider(&mdp1);
   RegisterDumpProvider(&mdp2, nullptr);
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
   EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0);
-  EXPECT_CALL(mdp2, OnMemoryDump(_, _));
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::DETAILED));
+  EXPECT_CALL(mdp2, OnMemoryDump(_, _)).WillOnce(Return(true));
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::DETAILED);
   DisableTracing();
 
   // Enable both mdp1 and mdp2.
   RegisterDumpProvider(&mdp1, nullptr);
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-  EXPECT_CALL(mdp1, OnMemoryDump(_, _));
-  EXPECT_CALL(mdp2, OnMemoryDump(_, _));
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::DETAILED));
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
+  EXPECT_CALL(mdp1, OnMemoryDump(_, _)).WillOnce(Return(true));
+  EXPECT_CALL(mdp2, OnMemoryDump(_, _)).WillOnce(Return(true));
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::DETAILED);
   DisableTracing();
 }
 
@@ -436,26 +486,28 @@
 #define MAYBE_RegistrationConsistency RegistrationConsistency
 #endif
 TEST_F(MemoryDumpManagerTest, MAYBE_RegistrationConsistency) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   MockMemoryDumpProvider mdp;
 
   RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
 
   {
-    EXPECT_CALL(mdp, OnMemoryDump(_, _));
+    EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
+    EXPECT_CALL(mdp, OnMemoryDump(_, _)).WillOnce(Return(true));
     EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
     DisableTracing();
   }
 
   mdm_->UnregisterDumpProvider(&mdp);
 
   {
+    EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
     EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0);
     EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
     DisableTracing();
   }
 
@@ -463,10 +515,11 @@
   mdm_->UnregisterDumpProvider(&mdp);
 
   {
+    EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
     EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0);
     EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
     DisableTracing();
   }
 
@@ -475,10 +528,11 @@
   RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
 
   {
-    EXPECT_CALL(mdp, OnMemoryDump(_, _));
+    EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
+    EXPECT_CALL(mdp, OnMemoryDump(_, _)).WillOnce(Return(true));
     EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
     DisableTracing();
   }
 }
@@ -488,7 +542,7 @@
 // threads and registering a MemoryDumpProvider on each of them. At each
 // iteration, one thread is removed, to check the live unregistration logic.
 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   const uint32_t kNumInitialThreads = 8;
 
   std::vector<std::unique_ptr<Thread>> threads;
@@ -516,8 +570,11 @@
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
 
   while (!threads.empty()) {
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    last_callback_success_ = false;
+    EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
+    EXPECT_TRUE(last_callback_success_);
 
     // Unregister a MDP and destroy one thread at each iteration to check the
     // live unregistration logic. The unregistration needs to happen on the same
@@ -543,7 +600,7 @@
 // SequencedTaskRunner case and that the dump provider gets disabled when
 // PostTask fails, but the dump still succeeds.
 TEST_F(MemoryDumpManagerTest, PostTaskForSequencedTaskRunner) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   std::vector<MockMemoryDumpProvider> mdps(3);
   scoped_refptr<TestSequencedTaskRunner> task_runner1(
       make_scoped_refptr(new TestSequencedTaskRunner()));
@@ -559,29 +616,34 @@
   EXPECT_CALL(mdps[0], OnMemoryDump(_, _)).Times(0);
   EXPECT_CALL(mdps[1], OnMemoryDump(_, _)).Times(2);
   EXPECT_CALL(mdps[2], OnMemoryDump(_, _)).Times(2);
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(2);
 
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
 
   task_runner1->set_enabled(false);
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::DETAILED));
+  last_callback_success_ = false;
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::DETAILED);
   // Tasks should be individually posted even if |mdps[1]| and |mdps[2]| belong
   // to same task runner.
   EXPECT_EQ(1u, task_runner1->no_of_post_tasks());
   EXPECT_EQ(2u, task_runner2->no_of_post_tasks());
+  EXPECT_TRUE(last_callback_success_);
 
   task_runner1->set_enabled(true);
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::DETAILED));
+  last_callback_success_ = false;
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::DETAILED);
   EXPECT_EQ(2u, task_runner1->no_of_post_tasks());
   EXPECT_EQ(4u, task_runner2->no_of_post_tasks());
+  EXPECT_TRUE(last_callback_success_);
   DisableTracing();
 }
 
 // Checks that providers get disabled after 3 consecutive failures, but not
 // otherwise (e.g., if interleaved).
 TEST_F(MemoryDumpManagerTest, DisableFailingDumpers) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   MockMemoryDumpProvider mdp1;
   MockMemoryDumpProvider mdp2;
 
@@ -589,6 +651,10 @@
   RegisterDumpProvider(&mdp2, nullptr);
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
 
+  const int kNumDumps = 2 * GetMaxConsecutiveFailuresCount();
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _))
+      .Times(kNumDumps);
+
   EXPECT_CALL(mdp1, OnMemoryDump(_, _))
       .Times(GetMaxConsecutiveFailuresCount())
       .WillRepeatedly(Return(false));
@@ -601,10 +667,9 @@
       .WillOnce(Return(true))
       .WillOnce(Return(false));
 
-  const int kNumDumps = 2 * GetMaxConsecutiveFailuresCount();
   for (int i = 0; i < kNumDumps; i++) {
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
   }
 
   DisableTracing();
@@ -613,13 +678,15 @@
 // Sneakily registers an extra memory dump provider while an existing one is
 // dumping and expect it to take part in the already active tracing session.
 TEST_F(MemoryDumpManagerTest, RegisterDumperWhileDumping) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   MockMemoryDumpProvider mdp1;
   MockMemoryDumpProvider mdp2;
 
   RegisterDumpProvider(&mdp1, nullptr);
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
 
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(4);
+
   EXPECT_CALL(mdp1, OnMemoryDump(_, _))
       .Times(4)
       .WillOnce(Return(true))
@@ -627,15 +694,18 @@
           Invoke([&mdp2](const MemoryDumpArgs&, ProcessMemoryDump*) -> bool {
             RegisterDumpProvider(&mdp2, nullptr);
             return true;
-          }));
+          }))
+      .WillRepeatedly(Return(true));
 
   // Depending on the insertion order (before or after mdp1), mdp2 might be
   // called also immediately after it gets registered.
-  EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(Between(2, 3));
+  EXPECT_CALL(mdp2, OnMemoryDump(_, _))
+      .Times(Between(2, 3))
+      .WillRepeatedly(Return(true));
 
   for (int i = 0; i < 4; i++) {
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
   }
 
   DisableTracing();
@@ -643,7 +713,7 @@
 
 // Like RegisterDumperWhileDumping, but unregister the dump provider instead.
 TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileDumping) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   MockMemoryDumpProvider mdp1;
   MockMemoryDumpProvider mdp2;
 
@@ -651,6 +721,8 @@
   RegisterDumpProvider(&mdp2, ThreadTaskRunnerHandle::Get(), kDefaultOptions);
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
 
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(4);
+
   EXPECT_CALL(mdp1, OnMemoryDump(_, _))
       .Times(4)
       .WillOnce(Return(true))
@@ -658,15 +730,18 @@
           Invoke([&mdp2](const MemoryDumpArgs&, ProcessMemoryDump*) -> bool {
             MemoryDumpManager::GetInstance()->UnregisterDumpProvider(&mdp2);
             return true;
-          }));
+          }))
+      .WillRepeatedly(Return(true));
 
   // Depending on the insertion order (before or after mdp1), mdp2 might have
   // been already called when UnregisterDumpProvider happens.
-  EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(Between(1, 2));
+  EXPECT_CALL(mdp2, OnMemoryDump(_, _))
+      .Times(Between(1, 2))
+      .WillRepeatedly(Return(true));
 
   for (int i = 0; i < 4; i++) {
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
   }
 
   DisableTracing();
@@ -675,7 +750,7 @@
 // Checks that the dump does not abort when unregistering a provider while
 // dumping from a different thread than the dumping thread.
 TEST_F(MemoryDumpManagerTest, UnregisterDumperFromThreadWhileDumping) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   std::vector<std::unique_ptr<TestIOThread>> threads;
   std::vector<std::unique_ptr<MockMemoryDumpProvider>> mdps;
 
@@ -714,16 +789,19 @@
         .WillOnce(Invoke(on_dump));
   }
 
+  last_callback_success_ = false;
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::DETAILED));
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::DETAILED);
   ASSERT_EQ(1, on_memory_dump_call_count);
+  ASSERT_TRUE(last_callback_success_);
 
   DisableTracing();
 }
 
 TEST_F(MemoryDumpManagerTest, TestPollingOnDumpThread) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider());
   std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider());
   mdp1->enable_mock_destructor = true;
@@ -775,7 +853,7 @@
 // If a thread (with a dump provider living on it) is torn down during a dump
 // its dump provider should be skipped but the dump itself should succeed.
 TEST_F(MemoryDumpManagerTest, TearDownThreadWhileDumping) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   std::vector<std::unique_ptr<TestIOThread>> threads;
   std::vector<std::unique_ptr<MockMemoryDumpProvider>> mdps;
 
@@ -813,23 +891,28 @@
         .WillOnce(Invoke(on_dump));
   }
 
+  last_callback_success_ = false;
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::DETAILED));
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::DETAILED);
   ASSERT_EQ(1, on_memory_dump_call_count);
+  ASSERT_TRUE(last_callback_success_);
 
   DisableTracing();
 }
 
-// Checks that a NACK callback is invoked if CreateProcessDump() is called when
+// Checks that a NACK callback is invoked if RequestGlobalDump() is called when
 // tracing is not enabled.
 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
-  MockMemoryDumpProvider mdp;
-  RegisterDumpProvider(&mdp, nullptr);
-  EXPECT_CALL(mdp, OnMemoryDump(_, _));
-  EXPECT_FALSE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                         MemoryDumpLevelOfDetail::DETAILED));
+  InitializeMemoryDumpManager(false /* is_coordinator */);
+  MockMemoryDumpProvider mdp1;
+  RegisterDumpProvider(&mdp1, nullptr);
+
+  last_callback_success_ = true;
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::DETAILED);
+  EXPECT_FALSE(last_callback_success_);
 }
 
 // Checks that is the MemoryDumpManager is initialized after tracing already
@@ -839,23 +922,24 @@
   RegisterDumpProvider(&mdp, nullptr);
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
 
-  // First check that a CreateProcessDump() issued before the MemoryDumpManager
+  // First check that a RequestGlobalDump() issued before the MemoryDumpManager
   // initialization gets NACK-ed cleanly.
   {
-    testing::InSequence sequence;
     EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0);
-    EXPECT_FALSE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                           MemoryDumpLevelOfDetail::DETAILED));
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
+    EXPECT_FALSE(last_callback_success_);
   }
 
   // Now late-initialize the MemoryDumpManager and check that the
-  // CreateProcessDump() completes successfully.
+  // RequestGlobalDump completes successfully.
   {
-    testing::InSequence sequence;
-    InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+    InitializeMemoryDumpManager(false /* is_coordinator */);
     EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1);
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
+    EXPECT_TRUE(last_callback_success_);
   }
   DisableTracing();
 }
@@ -865,10 +949,15 @@
 // dumps in memory-infra, handling gracefully the transition between the legacy
 // and the new-style (JSON-based) TraceConfig.
 TEST_F(MemoryDumpManagerTest, TraceConfigExpectations) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
 
-  // We don't need to create any dump in this test, only check whether the dumps
+  // Don't trigger the default behavior of the global dump handler in this test,
+  // which would short-circuit the dump request to the actual
+  // CreateProcessDump().
+  // We don't want to create any dump in this test, only check whether the dumps
   // are requested or not.
+  ON_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _))
+      .WillByDefault(Return());
 
   // Enabling memory-infra in a non-coordinator process should not trigger any
   // periodic dumps.
@@ -886,7 +975,9 @@
 }
 
 TEST_F(MemoryDumpManagerTest, TraceConfigExpectationsWhenIsCoordinator) {
-  InitializeMemoryDumpManagerForInProcessTesting(true /* is_coordinator */);
+  InitializeMemoryDumpManager(true /* is_coordinator */);
+  ON_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _))
+      .WillByDefault(Return());
 
   // Enabling memory-infra with the legacy TraceConfig (category filter) in
   // a coordinator process should not enable periodic dumps.
@@ -922,25 +1013,26 @@
   const int kHeavyDumpRate = 5;
   const int kLightDumpPeriodMs = 1;
   const int kHeavyDumpPeriodMs = kHeavyDumpRate * kLightDumpPeriodMs;
-
   // The expected sequence with light=1ms, heavy=5ms is H,L,L,L,L,H,...
-  MockMemoryDumpProvider mdp;
-  RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
-
   testing::InSequence sequence;
-  EXPECT_CALL(mdp, OnMemoryDump(IsDetailedDump(), _));
-  EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _)).Times(kHeavyDumpRate - 1);
-  EXPECT_CALL(mdp, OnMemoryDump(IsDetailedDump(), _));
-  EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _)).Times(kHeavyDumpRate - 2);
-  EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _))
-      .WillOnce(Invoke([test_task_runner, quit_closure](const MemoryDumpArgs&,
-                                                        ProcessMemoryDump*) {
+  EXPECT_CALL(global_dump_handler_,
+              RequestGlobalMemoryDump(IsDetailedDump(), _));
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(IsLightDump(), _))
+      .Times(kHeavyDumpRate - 1);
+  EXPECT_CALL(global_dump_handler_,
+              RequestGlobalMemoryDump(IsDetailedDump(), _));
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(IsLightDump(), _))
+      .Times(kHeavyDumpRate - 2);
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(IsLightDump(), _))
+      .WillOnce(Invoke([test_task_runner, quit_closure](
+                           const MemoryDumpRequestArgs& args,
+                           const GlobalMemoryDumpCallback& callback) {
         test_task_runner->PostTask(FROM_HERE, quit_closure);
-        return true;
       }));
 
   // Swallow all the final spurious calls until tracing gets disabled.
-  EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(AnyNumber());
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _))
+      .Times(AnyNumber());
 
   EnableTracingWithTraceConfig(
       TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers(
@@ -952,7 +1044,7 @@
 TEST_F(MemoryDumpManagerTest, DumpOnBehalfOfOtherProcess) {
   using trace_analyzer::Query;
 
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
 
   // Standard provider with default options (create dump for current process).
   MemoryDumpProvider::Options options;
@@ -970,11 +1062,12 @@
   RegisterDumpProvider(&mdp3, nullptr, options);
 
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-  EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1);
-  EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1);
-  EXPECT_CALL(mdp3, OnMemoryDump(_, _)).Times(1);
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::DETAILED));
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
+  EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true));
+  EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true));
+  EXPECT_CALL(mdp3, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true));
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::DETAILED);
   DisableTracing();
 
   std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer =
@@ -993,8 +1086,7 @@
 }
 
 TEST_F(MemoryDumpManagerTest, SummaryOnlyWhitelisting) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
-
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   // Summary only MDPs are a subset of background MDPs.
   SetDumpProviderWhitelistForTesting(kTestMDPWhitelist);
   SetDumpProviderSummaryWhitelistForTesting(kTestMDPWhitelistForSummary);
@@ -1008,18 +1100,18 @@
                        kBackgroundButNotSummaryWhitelistedMDPName);
 
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
   EXPECT_CALL(backgroundMdp, OnMemoryDump(_, _)).Times(0);
   EXPECT_CALL(summaryMdp, OnMemoryDump(_, _)).Times(1);
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::SUMMARY_ONLY,
-                                        MemoryDumpLevelOfDetail::BACKGROUND));
+  RequestGlobalDumpAndWait(MemoryDumpType::SUMMARY_ONLY,
+                           MemoryDumpLevelOfDetail::BACKGROUND);
   DisableTracing();
 }
 
 TEST_F(MemoryDumpManagerTest, SummaryOnlyDumpsArentAddedToTrace) {
   using trace_analyzer::Query;
 
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   SetDumpProviderSummaryWhitelistForTesting(kTestMDPWhitelistForSummary);
   SetDumpProviderWhitelistForTesting(kTestMDPWhitelist);
 
@@ -1028,12 +1120,12 @@
   RegisterDumpProvider(&mdp, nullptr, kDefaultOptions, kWhitelistedMDPName);
 
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-
-  EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(2);
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::BACKGROUND));
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::SUMMARY_ONLY,
-                                        MemoryDumpLevelOfDetail::BACKGROUND));
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(2);
+  EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(2).WillRepeatedly(Return(true));
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::BACKGROUND);
+  RequestGlobalDumpAndWait(MemoryDumpType::SUMMARY_ONLY,
+                           MemoryDumpLevelOfDetail::BACKGROUND);
   DisableTracing();
 
   std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer =
@@ -1051,7 +1143,7 @@
 // Tests the basics of the UnregisterAndDeleteDumpProviderSoon(): the
 // unregistration should actually delete the providers and not leak them.
 TEST_F(MemoryDumpManagerTest, UnregisterAndDeleteDumpProviderSoon) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   static const int kNumProviders = 3;
   int dtor_count = 0;
   std::vector<std::unique_ptr<MemoryDumpProvider>> mdps;
@@ -1078,7 +1170,7 @@
 // from another thread. The OnMemoryDump() and the dtor call are expected to
 // happen on the same thread (the MemoryDumpManager utility thread).
 TEST_F(MemoryDumpManagerTest, UnregisterAndDeleteDumpProviderSoonDuringDump) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   std::unique_ptr<MockMemoryDumpProvider> mdp(new MockMemoryDumpProvider);
   mdp->enable_mock_destructor = true;
   RegisterDumpProvider(mdp.get(), nullptr, kDefaultOptions);
@@ -1107,15 +1199,16 @@
       }));
 
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(2);
   for (int i = 0; i < 2; ++i) {
-    EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                          MemoryDumpLevelOfDetail::DETAILED));
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
   }
   DisableTracing();
 }
 
 TEST_F(MemoryDumpManagerTest, TestWhitelistingMDP) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   SetDumpProviderWhitelistForTesting(kTestMDPWhitelist);
   std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider);
   RegisterDumpProvider(mdp1.get(), nullptr);
@@ -1124,39 +1217,41 @@
                        kWhitelistedMDPName);
 
   EXPECT_CALL(*mdp1, OnMemoryDump(_, _)).Times(0);
-  EXPECT_CALL(*mdp2, OnMemoryDump(_, _)).Times(1);
+  EXPECT_CALL(*mdp2, OnMemoryDump(_, _)).Times(1).WillOnce(Return(true));
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1);
 
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
   EXPECT_FALSE(IsPeriodicDumpingEnabled());
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::BACKGROUND));
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::BACKGROUND);
   DisableTracing();
 }
 
-// Configures periodic dumps with MemoryDumpLevelOfDetail::BACKGROUND triggers
-// and tests that only BACKGROUND are added to the trace, but not LIGHT or
-// DETAILED, even if requested explicitly.
 TEST_F(MemoryDumpManagerTest, TestBackgroundTracingSetup) {
-  InitializeMemoryDumpManagerForInProcessTesting(true /* is_coordinator */);
+  InitializeMemoryDumpManager(true /* is_coordinator */);
 
-  SetDumpProviderWhitelistForTesting(kTestMDPWhitelist);
+  // We now need an MDP to hit the code path where the dump will be rejected
+  // since this happens at the point you try to serialize a process dump.
   MockMemoryDumpProvider mdp;
-  RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get(), kDefaultOptions,
-                       kWhitelistedMDPName);
+  RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
 
   RunLoop run_loop;
   auto test_task_runner = ThreadTaskRunnerHandle::Get();
   auto quit_closure = run_loop.QuitClosure();
 
   testing::InSequence sequence;
-  EXPECT_CALL(mdp, OnMemoryDump(IsBackgroundDump(), _)).Times(3);
-  EXPECT_CALL(mdp, OnMemoryDump(IsBackgroundDump(), _))
-      .WillOnce(Invoke([test_task_runner, quit_closure](const MemoryDumpArgs&,
-                                                        ProcessMemoryDump*) {
+  EXPECT_CALL(global_dump_handler_,
+              RequestGlobalMemoryDump(IsBackgroundDump(), _))
+      .Times(5);
+  EXPECT_CALL(global_dump_handler_,
+              RequestGlobalMemoryDump(IsBackgroundDump(), _))
+      .WillOnce(Invoke([test_task_runner, quit_closure](
+                           const MemoryDumpRequestArgs& args,
+                           const GlobalMemoryDumpCallback& callback) {
         test_task_runner->PostTask(FROM_HERE, quit_closure);
-        return true;
       }));
-  EXPECT_CALL(mdp, OnMemoryDump(IsBackgroundDump(), _)).Times(AnyNumber());
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _))
+      .Times(AnyNumber());
 
   EnableTracingWithTraceConfig(
       TraceConfigMemoryTestUtil::GetTraceConfig_BackgroundTrigger(
@@ -1164,42 +1259,23 @@
 
   run_loop.Run();
 
-  // When requesting non-BACKGROUND dumps the MDP will be invoked but the
-  // data is expected to be dropped on the floor, hence the EXPECT_FALSE.
-  EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _));
-  EXPECT_FALSE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                         MemoryDumpLevelOfDetail::LIGHT));
-
-  EXPECT_CALL(mdp, OnMemoryDump(IsDetailedDump(), _));
-  EXPECT_FALSE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                         MemoryDumpLevelOfDetail::DETAILED));
+  // Only background mode dumps should be allowed with the trace config.
+  last_callback_success_ = false;
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::LIGHT);
+  EXPECT_FALSE(last_callback_success_);
+  last_callback_success_ = false;
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::DETAILED);
+  EXPECT_FALSE(last_callback_success_);
 
   ASSERT_TRUE(IsPeriodicDumpingEnabled());
   DisableTracing();
 }
 
-// Tests that the MemoryDumpProvider(s) are invoked even if tracing has not
-// been initialized.
-TEST_F(MemoryDumpManagerTest, DumpWithoutInitializingTracing) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
-  MockMemoryDumpProvider mdp;
-  RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
-  DisableTracing();
-  EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3);
-  for (int i = 0; i < 3; ++i) {
-    // The callback result will be false for the moment. true result means that
-    // as well as the dump being successful we also managed to add the dump to
-    // the trace. But the latter won't happen here.
-    EXPECT_FALSE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                           MemoryDumpLevelOfDetail::DETAILED));
-  }
-  mdm_->UnregisterDumpProvider(&mdp);
-}
-
-// Similar to DumpWithoutInitializingTracing. Tracing is initialized but not
-// enabled.
-TEST_F(MemoryDumpManagerTest, DumpWithTracingInitializedButDisabled) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+// Tests that we can manually take a dump without enabling tracing.
+TEST_F(MemoryDumpManagerTest, DumpWithTracingDisabled) {
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   MockMemoryDumpProvider mdp;
   RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
 
@@ -1209,27 +1285,71 @@
       TraceConfig(TraceConfigMemoryTestUtil::GetTraceConfig_NoTriggers());
   const TraceConfig::MemoryDumpConfig& memory_dump_config =
       trace_config.memory_dump_config();
+
   mdm_->SetupForTracing(memory_dump_config);
 
-  EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3);
-  for (int i = 0; i < 3; ++i) {
-    // Same as the above. Even if the MDP(s) are invoked, this will return false
-    // while attempting to add the dump into the trace.
-    EXPECT_FALSE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                           MemoryDumpLevelOfDetail::DETAILED));
-  }
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(3);
+  EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true));
+  last_callback_success_ = true;
+  for (int i = 0; i < 3; ++i)
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
+  // The callback result should actually be false since (for the moment at
+  // least) a true result means that as well as the dump generally being
+  // successful we also managed to add the dump to the trace.
+  EXPECT_FALSE(last_callback_success_);
+
   mdm_->TeardownForTracing();
+
+  mdm_->UnregisterDumpProvider(&mdp);
+}
+
+// Tests that we can do a dump without enabling/disabling.
+TEST_F(MemoryDumpManagerTest, DumpWithoutTracing) {
+  InitializeMemoryDumpManager(false /* is_coordinator */);
+  MockMemoryDumpProvider mdp;
+  RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
+
+  DisableTracing();
+
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(3);
+  EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true));
+  last_callback_success_ = true;
+  for (int i = 0; i < 3; ++i)
+    RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                             MemoryDumpLevelOfDetail::DETAILED);
+  // The callback result should be false since (for the moment at
+  // least) a true result means that as well as the dump being
+  // successful we also managed to add the dump to the trace which shouldn't
+  // happen when tracing is not enabled.
+  EXPECT_FALSE(last_callback_success_);
+
   mdm_->UnregisterDumpProvider(&mdp);
 }
 
 TEST_F(MemoryDumpManagerTest, TestSummaryComputation) {
-  InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */);
+  InitializeMemoryDumpManager(false /* is_coordinator */);
   MockMemoryDumpProvider mdp;
   RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get());
 
+  const HeapProfilerSerializationState* heap_profiler_serialization_state =
+      mdm_->heap_profiler_serialization_state_for_testing().get();
+
+  EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _))
+      .WillOnce(Invoke([this](const MemoryDumpRequestArgs& args,
+                              const GlobalMemoryDumpCallback& callback) {
+        ProcessMemoryDumpCallback process_callback =
+            Bind(&MemoryDumpManagerTest_TestSummaryComputation_Test::
+                     ProcessDumpRecordingCallbackAdapter,
+                 Unretained(this), callback);
+        mdm_->CreateProcessDump(args, process_callback);
+      }));
+
   EXPECT_CALL(mdp, OnMemoryDump(_, _))
-      .WillOnce(Invoke([](const MemoryDumpArgs&,
-                          ProcessMemoryDump* pmd) -> bool {
+      .Times(1)
+      .WillRepeatedly(Invoke([heap_profiler_serialization_state](
+                                 const MemoryDumpArgs&,
+                                 ProcessMemoryDump* pmd) -> bool {
         auto* size = MemoryAllocatorDump::kNameSize;
         auto* bytes = MemoryAllocatorDump::kUnitsBytes;
         const uint32_t kB = 1024;
@@ -1246,7 +1366,6 @@
         pmd->CreateAllocatorDump("v8/bar")->AddScalar(size, bytes, 2 * kB);
         pmd->CreateAllocatorDump("v8")->AddScalar(size, bytes, 99 * kB);
 
-        // All the 99 KB values here are expected to be ignored.
         pmd->CreateAllocatorDump("partition_alloc")
             ->AddScalar(size, bytes, 99 * kB);
         pmd->CreateAllocatorDump("partition_alloc/allocated_objects")
@@ -1255,39 +1374,37 @@
             ->AddScalar(size, bytes, 99 * kB);
         pmd->CreateAllocatorDump("partition_alloc/partitions")
             ->AddScalar(size, bytes, 99 * kB);
-        pmd->CreateAllocatorDump("partition_alloc/partitions/not_ignored_1")
+        pmd->CreateAllocatorDump("partition_alloc/partitions/foo")
             ->AddScalar(size, bytes, 2 * kB);
-        pmd->CreateAllocatorDump("partition_alloc/partitions/not_ignored_2")
+        pmd->CreateAllocatorDump("partition_alloc/partitions/bar")
             ->AddScalar(size, bytes, 2 * kB);
         pmd->process_totals()->set_resident_set_bytes(5 * kB);
         pmd->set_has_process_totals();
         return true;
       }));
 
+  last_callback_success_ = false;
+
   EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
-  Optional<MemoryDumpCallbackResult> result;
-  EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
-                                        MemoryDumpLevelOfDetail::LIGHT,
-                                        &result));
+  RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
+                           MemoryDumpLevelOfDetail::LIGHT);
   DisableTracing();
 
-  ASSERT_TRUE(result);
-
+  // We shouldn't see any of the 99 values from above.
+  EXPECT_TRUE(last_callback_success_);
+  ASSERT_EQ(1u, GetResults()->size());
+  MemoryDumpCallbackResult result = GetResults()->front();
   // For malloc we only count the root "malloc" not children "malloc/*".
-  EXPECT_EQ(1u, result->chrome_dump.malloc_total_kb);
-
+  EXPECT_EQ(1u, result.chrome_dump.malloc_total_kb);
   // For blink_gc we only count the root "blink_gc" not children "blink_gc/*".
-  EXPECT_EQ(2u, result->chrome_dump.blink_gc_total_kb);
-
+  EXPECT_EQ(2u, result.chrome_dump.blink_gc_total_kb);
   // For v8 we count the children ("v8/*") as the root total is not given.
-  EXPECT_EQ(3u, result->chrome_dump.v8_total_kb);
-
+  EXPECT_EQ(3u, result.chrome_dump.v8_total_kb);
   // partition_alloc has partition_alloc/allocated_objects/* which is a subset
   // of partition_alloc/partitions/* so we only count the latter.
-  EXPECT_EQ(4u, result->chrome_dump.partition_alloc_total_kb);
-
+  EXPECT_EQ(4u, result.chrome_dump.partition_alloc_total_kb);
   // resident_set_kb should read from process_totals.
-  EXPECT_EQ(5u, result->os_dump.resident_set_kb);
+  EXPECT_EQ(5u, result.os_dump.resident_set_kb);
 };
 
 }  // namespace trace_event
diff --git a/build/linux/BUILD.gn b/build/linux/BUILD.gn
index 4f555dc..caa860e 100644
--- a/build/linux/BUILD.gn
+++ b/build/linux/BUILD.gn
@@ -29,20 +29,10 @@
     # GYP build.
     #ignore_libs = true  # Loader generated below.
   }
-
-  deps = [
-    "//build/linux/libgio",
-  ]
 }
 
 # Looking for libspeechd? Use //third_party/speech-dispatcher
 
-group("fontconfig") {
-  public_deps = [
-    "//third_party/fontconfig",
-  ]
-}
-
 if (!is_chromecast) {
   # Only provided for distributions which prefer to keep linking to FreeType on
   # the system, use with caution,for details see build/config/freetype/BUILD.gn.
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 0b3436a..390d5d5 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -793,7 +793,7 @@
   DCHECK(transform_tree_index() != TransformTree::kInvalidNodeId);
 
   auto& property_trees = *layer_tree_host_->property_trees();
-  property_trees.scroll_tree.SetScrollOffset(id(), scroll_offset);
+  property_trees.scroll_tree.SetScrollOffset(element_id(), scroll_offset);
   auto* transform_node =
       property_trees.transform_tree.Node(transform_tree_index());
   DCHECK_EQ(transform_tree_index(), transform_node->id);
@@ -1212,7 +1212,7 @@
   if (ScrollOffsetAnimationWasInterrupted())
     layer->layer_tree_impl()
         ->property_trees()
-        ->scroll_tree.SetScrollOffsetClobberActiveValue(layer->id());
+        ->scroll_tree.SetScrollOffsetClobberActiveValue(layer->element_id());
 
   if (needs_show_scrollbars_)
     layer->set_needs_show_scrollbars(true);
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 23d5abe..0e5badd 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -704,12 +704,12 @@
 
 void LayerImpl::SetCurrentScrollOffset(const gfx::ScrollOffset& scroll_offset) {
   DCHECK(IsActive());
-  if (GetScrollTree().SetScrollOffset(id(), scroll_offset))
-    layer_tree_impl()->DidUpdateScrollOffset(id());
+  if (GetScrollTree().SetScrollOffset(element_id(), scroll_offset))
+    layer_tree_impl()->DidUpdateScrollOffset(element_id());
 }
 
 gfx::ScrollOffset LayerImpl::CurrentScrollOffset() const {
-  return GetScrollTree().current_scroll_offset(id());
+  return GetScrollTree().current_scroll_offset(element_id());
 }
 
 void LayerImpl::UpdatePropertyTreeScrollOffset() {
diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc
index e857606..721d4ca 100644
--- a/cc/layers/layer_impl_unittest.cc
+++ b/cc/layers/layer_impl_unittest.cc
@@ -108,10 +108,10 @@
   EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties());
 
 static gfx::Vector2dF ScrollDelta(LayerImpl* layer_impl) {
-  gfx::ScrollOffset delta =
-      layer_impl->layer_tree_impl()
-          ->property_trees()
-          ->scroll_tree.GetScrollOffsetDeltaForTesting(layer_impl->id());
+  gfx::ScrollOffset delta = layer_impl->layer_tree_impl()
+                                ->property_trees()
+                                ->scroll_tree.GetScrollOffsetDeltaForTesting(
+                                    layer_impl->element_id());
   return gfx::Vector2dF(delta.x(), delta.y());
 }
 
@@ -355,10 +355,10 @@
   VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->ScrollBy(arbitrary_vector2d));
   VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->ScrollBy(gfx::Vector2d()));
   VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
-      layer->layer_tree_impl()->DidUpdateScrollOffset(layer->id()));
+      layer->layer_tree_impl()->DidUpdateScrollOffset(layer->element_id()));
   layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.SetScrollOffsetDeltaForTesting(layer->id(),
+      ->scroll_tree.SetScrollOffsetDeltaForTesting(layer->element_id(),
                                                    gfx::Vector2dF());
   VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetCurrentScrollOffset(
       gfx::ScrollOffset(arbitrary_vector2d.x(), arbitrary_vector2d.y())));
@@ -536,37 +536,37 @@
   // offset is bounded by the range [0, max scroll offset].
 
   EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->CurrentScrollOffset());
-  EXPECT_VECTOR_EQ(
-      gfx::Vector2dF(),
-      scroll_tree(layer())->GetScrollOffsetBaseForTesting(layer()->id()));
+  EXPECT_VECTOR_EQ(gfx::Vector2dF(),
+                   scroll_tree(layer())->GetScrollOffsetBaseForTesting(
+                       layer()->element_id()));
   EXPECT_VECTOR_EQ(gfx::Vector2dF(), ScrollDelta(layer()));
 
   layer()->ScrollBy(gfx::Vector2dF(-100, 100));
   EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->CurrentScrollOffset());
 
   EXPECT_VECTOR_EQ(ScrollDelta(layer()), layer()->CurrentScrollOffset());
-  EXPECT_VECTOR_EQ(
-      gfx::Vector2dF(),
-      scroll_tree(layer())->GetScrollOffsetBaseForTesting(layer()->id()));
+  EXPECT_VECTOR_EQ(gfx::Vector2dF(),
+                   scroll_tree(layer())->GetScrollOffsetBaseForTesting(
+                       layer()->element_id()));
 
   layer()->ScrollBy(gfx::Vector2dF(100, -100));
   EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), layer()->CurrentScrollOffset());
 
   EXPECT_VECTOR_EQ(ScrollDelta(layer()), layer()->CurrentScrollOffset());
-  EXPECT_VECTOR_EQ(
-      gfx::Vector2dF(),
-      scroll_tree(layer())->GetScrollOffsetBaseForTesting(layer()->id()));
+  EXPECT_VECTOR_EQ(gfx::Vector2dF(),
+                   scroll_tree(layer())->GetScrollOffsetBaseForTesting(
+                       layer()->element_id()));
 }
 
 TEST_F(LayerImplScrollTest, ScrollByWithNonZeroOffset) {
   gfx::ScrollOffset scroll_offset(10, 5);
-  scroll_tree(layer())->UpdateScrollOffsetBaseForTesting(layer()->id(),
+  scroll_tree(layer())->UpdateScrollOffsetBaseForTesting(layer()->element_id(),
                                                          scroll_offset);
 
   EXPECT_VECTOR_EQ(scroll_offset, layer()->CurrentScrollOffset());
-  EXPECT_VECTOR_EQ(
-      scroll_offset,
-      scroll_tree(layer())->GetScrollOffsetBaseForTesting(layer()->id()));
+  EXPECT_VECTOR_EQ(scroll_offset,
+                   scroll_tree(layer())->GetScrollOffsetBaseForTesting(
+                       layer()->element_id()));
   EXPECT_VECTOR_EQ(gfx::Vector2dF(), ScrollDelta(layer()));
 
   layer()->ScrollBy(gfx::Vector2dF(-100, 100));
@@ -575,9 +575,9 @@
   EXPECT_VECTOR_EQ(
       gfx::ScrollOffsetWithDelta(scroll_offset, ScrollDelta(layer())),
       layer()->CurrentScrollOffset());
-  EXPECT_VECTOR_EQ(
-      scroll_offset,
-      scroll_tree(layer())->GetScrollOffsetBaseForTesting(layer()->id()));
+  EXPECT_VECTOR_EQ(scroll_offset,
+                   scroll_tree(layer())->GetScrollOffsetBaseForTesting(
+                       layer()->element_id()));
 
   layer()->ScrollBy(gfx::Vector2dF(100, -100));
   EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), layer()->CurrentScrollOffset());
@@ -585,9 +585,9 @@
   EXPECT_VECTOR_EQ(
       gfx::ScrollOffsetWithDelta(scroll_offset, ScrollDelta(layer())),
       layer()->CurrentScrollOffset());
-  EXPECT_VECTOR_EQ(
-      scroll_offset,
-      scroll_tree(layer())->GetScrollOffsetBaseForTesting(layer()->id()));
+  EXPECT_VECTOR_EQ(scroll_offset,
+                   scroll_tree(layer())->GetScrollOffsetBaseForTesting(
+                       layer()->element_id()));
 }
 
 TEST_F(LayerImplScrollTest, ApplySentScrollsNoListener) {
@@ -595,7 +595,7 @@
   gfx::Vector2dF scroll_delta(20.5f, 8.5f);
   gfx::Vector2d sent_scroll_delta(12, -3);
 
-  scroll_tree(layer())->UpdateScrollOffsetBaseForTesting(layer()->id(),
+  scroll_tree(layer())->UpdateScrollOffsetBaseForTesting(layer()->element_id(),
                                                          scroll_offset);
   layer()->ScrollBy(sent_scroll_delta);
   scroll_tree(layer())->CollectScrollDeltasForTesting();
@@ -605,18 +605,18 @@
   EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta),
                    layer()->CurrentScrollOffset());
   EXPECT_VECTOR_EQ(scroll_delta, ScrollDelta(layer()));
-  EXPECT_VECTOR_EQ(
-      scroll_offset,
-      scroll_tree(layer())->GetScrollOffsetBaseForTesting(layer()->id()));
+  EXPECT_VECTOR_EQ(scroll_offset,
+                   scroll_tree(layer())->GetScrollOffsetBaseForTesting(
+                       layer()->element_id()));
 
   scroll_tree(layer())->ApplySentScrollDeltasFromAbortedCommit();
 
   EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta),
                    layer()->CurrentScrollOffset());
   EXPECT_VECTOR_EQ(scroll_delta - sent_scroll_delta, ScrollDelta(layer()));
-  EXPECT_VECTOR_EQ(
-      gfx::ScrollOffsetWithDelta(scroll_offset, sent_scroll_delta),
-      scroll_tree(layer())->GetScrollOffsetBaseForTesting(layer()->id()));
+  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, sent_scroll_delta),
+                   scroll_tree(layer())->GetScrollOffsetBaseForTesting(
+                       layer()->element_id()));
 }
 
 TEST_F(LayerImplScrollTest, ScrollUserUnscrollableLayer) {
@@ -626,7 +626,7 @@
   layer()->test_properties()->user_scrollable_vertical = false;
   layer()->layer_tree_impl()->property_trees()->needs_rebuild = true;
   layer()->layer_tree_impl()->BuildLayerListAndPropertyTreesForTesting();
-  scroll_tree(layer())->UpdateScrollOffsetBaseForTesting(layer()->id(),
+  scroll_tree(layer())->UpdateScrollOffsetBaseForTesting(layer()->element_id(),
                                                          scroll_offset);
   gfx::Vector2dF unscrolled = layer()->ScrollBy(scroll_delta);
 
@@ -640,7 +640,7 @@
 
   host_impl().CreatePendingTree();
 
-  scroll_tree(layer())->UpdateScrollOffsetBaseForTesting(layer()->id(),
+  scroll_tree(layer())->UpdateScrollOffsetBaseForTesting(layer()->element_id(),
                                                          scroll_offset);
   gfx::Vector2dF unscrolled = layer()->ScrollBy(scroll_delta);
 
@@ -651,8 +651,10 @@
 
   std::unique_ptr<LayerImpl> pending_layer =
       LayerImpl::Create(host_impl().sync_tree(), layer()->id());
+  pending_layer->SetElementId(
+      LayerIdToElementIdForTesting(pending_layer->id()));
   scroll_tree(pending_layer.get())
-      ->UpdateScrollOffsetBaseForTesting(pending_layer->id(),
+      ->UpdateScrollOffsetBaseForTesting(pending_layer->element_id(),
                                          layer()->CurrentScrollOffset());
 
   pending_layer->PushPropertiesTo(layer());
diff --git a/cc/layers/layer_position_constraint_unittest.cc b/cc/layers/layer_position_constraint_unittest.cc
index ff886dbe79..952d9bf 100644
--- a/cc/layers/layer_position_constraint_unittest.cc
+++ b/cc/layers/layer_position_constraint_unittest.cc
@@ -119,11 +119,16 @@
     root_->SetBounds(clip_bounds);
 
     inner_viewport_container_layer_->SetMasksToBounds(true);
+    scroll_layer_->SetElementId(
+        LayerIdToElementIdForTesting(scroll_layer_->id()));
     scroll_layer_->SetScrollClipLayerId(inner_viewport_container_layer_->id());
     scroll_layer_->SetIsContainerForFixedPositionLayers(true);
 
     outer_viewport_container_layer_->SetMasksToBounds(true);
+    child_->SetElementId(LayerIdToElementIdForTesting(child_->id()));
     child_->SetScrollClipLayerId(outer_viewport_container_layer_->id());
+    grand_child_->SetElementId(
+        LayerIdToElementIdForTesting(grand_child_->id()));
     grand_child_->SetScrollClipLayerId(outer_viewport_container_layer_->id());
 
     grand_child_->AddChild(great_grand_child_);
@@ -207,9 +212,10 @@
                                    const gfx::Vector2dF& delta) {
     if (layer_impl->layer_tree_impl()
             ->property_trees()
-            ->scroll_tree.SetScrollOffsetDeltaForTesting(layer_impl->id(),
-                                                         delta))
-      layer_impl->layer_tree_impl()->DidUpdateScrollOffset(layer_impl->id());
+            ->scroll_tree.SetScrollOffsetDeltaForTesting(
+                layer_impl->element_id(), delta))
+      layer_impl->layer_tree_impl()->DidUpdateScrollOffset(
+          layer_impl->element_id());
   }
 };
 
@@ -1058,6 +1064,8 @@
   child_->SetIsContainerForFixedPositionLayers(true);
   grand_child_->SetPositionConstraint(fixed_to_top_left_);
   great_grand_child_->SetIsContainerForFixedPositionLayers(true);
+  great_grand_child_->SetElementId(
+      LayerIdToElementIdForTesting(great_grand_child_->id()));
   great_grand_child_->SetScrollClipLayerId(root_->id());
   great_great_grand_child->SetPositionConstraint(fixed_to_top_left_);
 
diff --git a/cc/layers/picture_layer_impl_perftest.cc b/cc/layers/picture_layer_impl_perftest.cc
index a8f51685..3f5033a 100644
--- a/cc/layers/picture_layer_impl_perftest.cc
+++ b/cc/layers/picture_layer_impl_perftest.cc
@@ -105,7 +105,7 @@
     host_impl_.pending_tree()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            pending_layer_->id(),
+            pending_layer_->element_id(),
             gfx::ScrollOffset(viewport.x(), viewport.y()));
     bool update_lcd_text = false;
     host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
@@ -155,7 +155,7 @@
     host_impl_.pending_tree()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            pending_layer_->id(),
+            pending_layer_->element_id(),
             gfx::ScrollOffset(viewport.x(), viewport.y()));
     bool update_lcd_text = false;
     host_impl_.pending_tree()->UpdateDrawProperties(update_lcd_text);
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc
index 4f56a7a..a1dea9d5e 100644
--- a/cc/paint/paint_op_buffer.cc
+++ b/cc/paint/paint_op_buffer.cc
@@ -719,8 +719,6 @@
                                    SkPicture::AbortCallback* callback) const {
   if (!op_count_)
     return;
-  if (callback && callback->abort())
-    return;
 
 #if DCHECK_IS_ON()
   DCHECK(!range_starts.empty());   // Don't call this then.
@@ -759,6 +757,12 @@
     ++iter;
   while (const PaintOp* op =
              NextOp(range_starts, range_indices, &stack, &iter, &range_index)) {
+    // Check if we should abort. This should happen at the start of loop since
+    // there are a couple of raster branches below, and we need to ensure that
+    // we do this check after every one of them.
+    if (callback && callback->abort())
+      return;
+
     // Optimize out save/restores or save/draw/restore that can be a single
     // draw.  See also: similar code in SkRecordOpts.
     // TODO(enne): consider making this recursive?
@@ -799,8 +803,6 @@
     // are so we can skip them correctly.
 
     op->Raster(canvas, original);
-    if (callback && callback->abort())
-      return;
   }
 }
 
diff --git a/cc/surfaces/compositor_frame_sink_support.cc b/cc/surfaces/compositor_frame_sink_support.cc
index 37d7ae1..6ac4753f 100644
--- a/cc/surfaces/compositor_frame_sink_support.cc
+++ b/cc/surfaces/compositor_frame_sink_support.cc
@@ -181,9 +181,6 @@
 void CompositorFrameSinkSupport::UpdateSurfaceReferences(
     const LocalSurfaceId& local_surface_id,
     const std::vector<SurfaceId>& active_referenced_surfaces) {
-  if (!surface_manager_->using_surface_references())
-    return;
-
   SurfaceId surface_id(frame_sink_id_, local_surface_id);
 
   const base::flat_set<SurfaceId>& existing_referenced_surfaces =
diff --git a/cc/surfaces/compositor_frame_sink_support_unittest.cc b/cc/surfaces/compositor_frame_sink_support_unittest.cc
index 52da6a41..913247f 100644
--- a/cc/surfaces/compositor_frame_sink_support_unittest.cc
+++ b/cc/surfaces/compositor_frame_sink_support_unittest.cc
@@ -663,6 +663,12 @@
           &fake_support_client_, &manager_, kYetAnotherArbitraryFrameSinkId,
           kIsChildRoot, kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
   manager_.RegisterFrameSinkId(kAnotherArbitraryFrameSinkId);
+  // Give local_surface_id_ an initial frame so another client can refer to
+  // that surface.
+  {
+    CompositorFrame frame = MakeCompositorFrame();
+    support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
+  }
   // Give id2 a frame that references local_surface_id_.
   {
     CompositorFrame frame = MakeCompositorFrame();
diff --git a/cc/surfaces/surface_manager.cc b/cc/surfaces/surface_manager.cc
index 83f909ee..bd78370 100644
--- a/cc/surfaces/surface_manager.cc
+++ b/cc/surfaces/surface_manager.cc
@@ -41,13 +41,11 @@
 SurfaceManager::~SurfaceManager() {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  if (using_surface_references()) {
-    // Remove all temporary references on shutdown.
-    temporary_references_.clear();
-    temporary_reference_ranges_.clear();
+  // Remove all temporary references on shutdown.
+  temporary_references_.clear();
+  temporary_reference_ranges_.clear();
 
-    GarbageCollectSurfaces();
-  }
+  GarbageCollectSurfaces();
 
   for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin();
        it != surfaces_to_destroy_.end();
@@ -153,19 +151,17 @@
 void SurfaceManager::InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) {
   framesink_manager_.InvalidateFrameSinkId(frame_sink_id);
 
-  if (using_surface_references()) {
-    // Remove any temporary references owned by |frame_sink_id|.
-    std::vector<SurfaceId> temp_refs_to_clear;
-    for (auto& map_entry : temporary_references_) {
-      base::Optional<FrameSinkId>& owner = map_entry.second;
-      if (owner.has_value() && owner.value() == frame_sink_id)
-        temp_refs_to_clear.push_back(map_entry.first);
-    }
-
-    for (auto& surface_id : temp_refs_to_clear)
-      RemoveTemporaryReference(surface_id, false);
+  // Remove any temporary references owned by |frame_sink_id|.
+  std::vector<SurfaceId> temp_refs_to_clear;
+  for (auto& map_entry : temporary_references_) {
+    base::Optional<FrameSinkId>& owner = map_entry.second;
+    if (owner.has_value() && owner.value() == frame_sink_id)
+      temp_refs_to_clear.push_back(map_entry.first);
   }
 
+  for (auto& surface_id : temp_refs_to_clear)
+    RemoveTemporaryReference(surface_id, false);
+
   GarbageCollectSurfaces();
 }
 
@@ -176,7 +172,6 @@
 void SurfaceManager::AddSurfaceReferences(
     const std::vector<SurfaceReference>& references) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(using_surface_references());
 
   for (const auto& reference : references)
     AddSurfaceReferenceImpl(reference.parent_id(), reference.child_id());
@@ -185,7 +180,6 @@
 void SurfaceManager::RemoveSurfaceReferences(
     const std::vector<SurfaceReference>& references) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(using_surface_references());
 
   for (const auto& reference : references)
     RemoveSurfaceReferenceImpl(reference.parent_id(), reference.child_id());
@@ -314,12 +308,8 @@
     Surface* surf = surface_map_[live_surfaces[i]];
     DCHECK(surf);
 
-    // TODO(fsamuel): We should probably keep alive pending referenced surfaces
-    // too.
-    if (!surf->active_referenced_surfaces())
-      continue;
-
-    for (const SurfaceId& id : *surf->active_referenced_surfaces()) {
+    const auto& children = GetSurfacesReferencedByParent(surf->surface_id());
+    for (const SurfaceId& id : children) {
       if (live_surfaces_set.count(id))
         continue;
 
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index ddf318c5..79538563 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -59,8 +59,12 @@
 
   inner_viewport_scroll_layer->SetScrollClipLayerId(
       inner_viewport_container_layer->id());
+  inner_viewport_scroll_layer->SetElementId(
+      LayerIdToElementIdForTesting(inner_viewport_scroll_layer->id()));
   outer_scroll_layer->SetScrollClipLayerId(
       outer_viewport_container_layer->id());
+  outer_scroll_layer->SetElementId(
+      LayerIdToElementIdForTesting(outer_scroll_layer->id()));
 
   inner_viewport_container_layer->SetBounds(inner_bounds);
   inner_viewport_scroll_layer->SetBounds(outer_bounds);
@@ -514,10 +518,10 @@
 }
 
 gfx::Vector2dF LayerTreeTest::ScrollDelta(LayerImpl* layer_impl) {
-  gfx::ScrollOffset delta =
-      layer_impl->layer_tree_impl()
-          ->property_trees()
-          ->scroll_tree.GetScrollOffsetDeltaForTesting(layer_impl->id());
+  gfx::ScrollOffset delta = layer_impl->layer_tree_impl()
+                                ->property_trees()
+                                ->scroll_tree.GetScrollOffsetDeltaForTesting(
+                                    layer_impl->element_id());
   return gfx::Vector2dF(delta.x(), delta.y());
 }
 
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 57c8142..9d6cb1de 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -753,7 +753,7 @@
 
 void LayerTreeHost::ApplyViewportDeltas(ScrollAndScaleSet* info) {
   gfx::Vector2dF inner_viewport_scroll_delta;
-  if (info->inner_viewport_scroll.layer_id != Layer::INVALID_ID)
+  if (!info->inner_viewport_scroll.element_id)
     inner_viewport_scroll_delta = info->inner_viewport_scroll.scroll_delta;
 
   if (inner_viewport_scroll_delta.IsZero() && info->page_scale_delta == 1.f &&
@@ -803,7 +803,7 @@
 
   if (root_layer_) {
     for (size_t i = 0; i < info->scrolls.size(); ++i) {
-      Layer* layer = LayerById(info->scrolls[i].layer_id);
+      Layer* layer = LayerByElementId(info->scrolls[i].element_id);
       if (!layer)
         continue;
       layer->SetScrollOffsetFromImplSide(gfx::ScrollOffsetWithDelta(
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index 93b3335..ffac534 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -153,12 +153,9 @@
                                         device_scale_factor,
                                         render_surface_list) {}
 
-LayerTreeHostCommon::ScrollUpdateInfo::ScrollUpdateInfo()
-    : layer_id(Layer::INVALID_ID) {}
-
 bool LayerTreeHostCommon::ScrollUpdateInfo::operator==(
     const LayerTreeHostCommon::ScrollUpdateInfo& other) const {
-  return layer_id == other.layer_id && scroll_delta == other.scroll_delta;
+  return element_id == other.element_id && scroll_delta == other.scroll_delta;
 }
 
 LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo()
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h
index 522ef93c..56799bf 100644
--- a/cc/trees/layer_tree_host_common.h
+++ b/cc/trees/layer_tree_host_common.h
@@ -129,13 +129,11 @@
                                         const Function& function);
 
   struct CC_EXPORT ScrollUpdateInfo {
-    int layer_id;
+    ElementId element_id;
     // TODO(miletus): Use ScrollOffset once LayerTreeHost/Blink fully supports
     // fractional scroll offset.
     gfx::Vector2d scroll_delta;
 
-    ScrollUpdateInfo();
-
     bool operator==(const ScrollUpdateInfo& other) const;
   };
 
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index ff0a6cc9..cb43d5ff 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -75,9 +75,10 @@
                                    const gfx::Vector2dF& delta) {
     if (layer_impl->layer_tree_impl()
             ->property_trees()
-            ->scroll_tree.SetScrollOffsetDeltaForTesting(layer_impl->id(),
-                                                         delta))
-      layer_impl->layer_tree_impl()->DidUpdateScrollOffset(layer_impl->id());
+            ->scroll_tree.SetScrollOffsetDeltaForTesting(
+                layer_impl->element_id(), delta))
+      layer_impl->layer_tree_impl()->DidUpdateScrollOffset(
+          layer_impl->element_id());
   }
 
   static float GetMaximumAnimationScale(LayerImpl* layer_impl) {
@@ -540,6 +541,7 @@
       LayerImpl::Create(host_impl.active_tree(), 4));
   LayerImpl* clip_layer = clip_layer_scoped_ptr.get();
 
+  scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id()));
   scroll_layer->SetScrollClipLayer(clip_layer->id());
   clip_layer->SetBounds(
       gfx::Size(scroll_layer->bounds().width() + kMaxScrollOffset.x(),
@@ -552,8 +554,8 @@
   clip_layer->test_properties()->AddChild(std::move(scroll_layer_scoped_ptr));
   scroll_layer_raw_ptr->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer_raw_ptr->id(),
-                                                     kScrollOffset);
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(
+          scroll_layer_raw_ptr->element_id(), kScrollOffset);
 
   std::unique_ptr<LayerImpl> root(
       LayerImpl::Create(host_impl.active_tree(), 3));
@@ -5321,6 +5323,7 @@
   intervening->SetMasksToBounds(true);
   clip_parent->SetMasksToBounds(true);
   intervening->SetScrollClipLayer(clip_parent->id());
+  intervening->SetElementId(LayerIdToElementIdForTesting(intervening->id()));
   intervening->SetCurrentScrollOffset(gfx::ScrollOffset(3, 3));
 
   gfx::Transform translation_transform;
@@ -6122,6 +6125,7 @@
   constraint.set_is_fixed_position(true);
   fixed->test_properties()->position_constraint = constraint;
 
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayer(container->id());
 
   gfx::Transform container_transform;
@@ -6245,6 +6249,7 @@
   surface->test_properties()->force_render_surface = true;
   container->SetBounds(gfx::Size(50, 50));
   scroller->SetBounds(gfx::Size(100, 100));
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayer(container->id());
   scroller->SetDrawsContent(true);
 
@@ -6287,6 +6292,7 @@
   container->AddChild(scroller);
   host()->SetRootLayer(root);
 
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
   scroll_child->SetScrollParent(scroller.get());
 
@@ -6334,6 +6340,7 @@
   container->AddChild(scroller);
   scroller->AddChild(sticky_pos);
   host()->SetRootLayer(root);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
 
   LayerStickyPositionConstraint sticky_position;
@@ -6406,6 +6413,7 @@
   root->AddChild(sticky_pos);
   sticky_pos->SetScrollParent(scroller.get());
   host()->SetRootLayer(root);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
 
   // The sticky layer has already been scrolled on the main thread side, and has
@@ -6481,6 +6489,7 @@
   container->AddChild(scroller);
   scroller->AddChild(sticky_pos);
   host()->SetRootLayer(root);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
 
   LayerStickyPositionConstraint sticky_position;
@@ -6526,6 +6535,7 @@
   container->AddChild(scroller);
   scroller->AddChild(sticky_pos);
   host()->SetRootLayer(root);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
 
   LayerStickyPositionConstraint sticky_position;
@@ -6593,6 +6603,7 @@
   root->AddChild(scroller);
   scroller->AddChild(sticky_pos);
   host()->SetRootLayer(root);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(root->id());
   LayerTreeHost::ViewportLayers viewport_layers;
   viewport_layers.page_scale = root;
@@ -6668,6 +6679,7 @@
   outer_clip->AddChild(outer_viewport);
   outer_viewport->AddChild(sticky_pos);
   host()->SetRootLayer(root);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(root->id());
   outer_viewport->SetScrollClipLayerId(outer_clip->id());
   LayerTreeHost::ViewportLayers viewport_layers;
@@ -6750,6 +6762,7 @@
   container->AddChild(scroller);
   scroller->AddChild(sticky_pos);
   host()->SetRootLayer(root);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
 
   LayerStickyPositionConstraint sticky_position;
@@ -6854,6 +6867,7 @@
   container->AddChild(scroller);
   scroller->AddChild(sticky_pos);
   host()->SetRootLayer(root);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
 
   LayerStickyPositionConstraint sticky_position;
@@ -6947,6 +6961,7 @@
   scroller->AddChild(sticky_container);
   sticky_container->AddChild(sticky_pos);
   host()->SetRootLayer(root);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
 
   LayerStickyPositionConstraint sticky_position;
@@ -7045,6 +7060,7 @@
   container->AddChild(scroller);
   scroller->AddChild(sticky_pos);
   host()->SetRootLayer(root);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
   gfx::Transform t;
   t.Scale(2, 2);
@@ -7123,6 +7139,7 @@
   scroller->AddChild(sticky_container);
   sticky_container->AddChild(sticky_pos);
   host()->SetRootLayer(root);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
   gfx::Transform t;
   t.Scale(2, 2);
@@ -7201,6 +7218,7 @@
   scroller->AddChild(outer_sticky);
   outer_sticky->AddChild(inner_sticky);
   host()->SetRootLayer(root);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
 
   root->SetBounds(gfx::Size(100, 100));
@@ -7301,6 +7319,7 @@
 
   LayerPositionConstraint fixed_position;
   fixed_position.set_is_fixed_position(true);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
   fixed_pos->SetPositionConstraint(fixed_position);
 
@@ -7345,6 +7364,7 @@
 
   LayerPositionConstraint fixed_position;
   fixed_position.set_is_fixed_position(true);
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayerId(container->id());
   fixed_pos->SetPositionConstraint(fixed_position);
 
@@ -8587,7 +8607,9 @@
   frame_clip->SetMasksToBounds(true);
   frame_clip->SetDrawsContent(true);
   scroller->SetBounds(gfx::Size(1000, 1000));
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetCurrentScrollOffset(gfx::ScrollOffset(100, 100));
+  scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
   scroller->SetScrollClipLayer(frame_clip->id());
   scroller->SetDrawsContent(true);
   fixed->SetPosition(gfx::PointF(100, 100));
@@ -8676,6 +8698,8 @@
   EXPECT_EQ(gfx::Rect(25, 25), scroll_child->visible_layer_rect());
 
   scroll_child->SetPosition(gfx::PointF(0, -10.f));
+  scroll_parent->SetElementId(
+      LayerIdToElementIdForTesting(scroll_parent->id()));
   scroll_parent->SetCurrentScrollOffset(gfx::ScrollOffset(0.f, 10.f));
   root->layer_tree_impl()->property_trees()->needs_rebuild = true;
   ExecuteCalculateDrawProperties(root);
@@ -10038,6 +10062,7 @@
       MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
   parent2->AddMainThreadScrollingReasons(
       MainThreadScrollingReason::kScrollbarScrolling);
+  parent2->SetElementId(LayerIdToElementIdForTesting(parent2->id()));
   parent2->SetScrollClipLayerId(root1->id());
   child6->AddMainThreadScrollingReasons(
       MainThreadScrollingReason::kScrollbarScrolling);
@@ -10045,9 +10070,12 @@
       MainThreadScrollingReason::kScrollbarScrolling);
 
   child7->SetScrollClipLayerId(parent3->id());
+  child7->SetElementId(LayerIdToElementIdForTesting(child7->id()));
 
   child8->SetScrollParent(child7.get());
   grand_child11->SetScrollClipLayerId(parent3->id());
+  grand_child11->SetElementId(
+      LayerIdToElementIdForTesting(grand_child11->id()));
 
   parent5->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
   parent5->SetBounds(gfx::Size(10, 10));
@@ -10092,6 +10120,7 @@
   ScrollNode scroll_parent2;
   scroll_parent2.id = 2;
   scroll_parent2.owning_layer_id = parent2->id();
+  scroll_parent2.element_id = parent2->element_id();
   scroll_parent2.scrollable = true;
   scroll_parent2.main_thread_scrolling_reasons =
       parent2->main_thread_scrolling_reasons();
@@ -10124,6 +10153,7 @@
   ScrollNode scroll_child7;
   scroll_child7.id = 4;
   scroll_child7.owning_layer_id = child7->id();
+  scroll_child7.element_id = child7->element_id();
   scroll_child7.scrollable = true;
   scroll_child7.scroll_clip_layer_bounds = parent3->bounds();
   scroll_child7.bounds = child7->bounds();
@@ -10138,6 +10168,7 @@
   ScrollNode scroll_grand_child11;
   scroll_grand_child11.id = 5;
   scroll_grand_child11.owning_layer_id = grand_child11->id();
+  scroll_grand_child11.element_id = grand_child11->element_id();
   scroll_grand_child11.scrollable = true;
   scroll_grand_child11.user_scrollable_horizontal = true;
   scroll_grand_child11.user_scrollable_vertical = true;
@@ -10160,9 +10191,11 @@
   expected_scroll_tree.SetOwningLayerIdForNode(expected_scroll_tree.back(),
                                                parent5->id());
 
-  expected_scroll_tree.SetScrollOffset(parent2->id(), gfx::ScrollOffset(0, 0));
-  expected_scroll_tree.SetScrollOffset(child7->id(), gfx::ScrollOffset(0, 0));
-  expected_scroll_tree.SetScrollOffset(grand_child11->id(),
+  expected_scroll_tree.SetScrollOffset(parent2->element_id(),
+                                       gfx::ScrollOffset(0, 0));
+  expected_scroll_tree.SetScrollOffset(child7->element_id(),
+                                       gfx::ScrollOffset(0, 0));
+  expected_scroll_tree.SetScrollOffset(grand_child11->element_id(),
                                        gfx::ScrollOffset(0, 0));
   expected_scroll_tree.set_needs_update(false);
 
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 52b6bc4..f55d4d6 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -2960,7 +2960,7 @@
     adjusted_scroll.set_y(0);
 
   gfx::ScrollOffset old_offset =
-      scroll_tree.current_scroll_offset(scroll_node->owning_layer_id);
+      scroll_tree.current_scroll_offset(scroll_node->element_id);
   gfx::ScrollOffset new_offset = scroll_tree.ClampScrollOffsetToLimits(
       old_offset + gfx::ScrollOffset(adjusted_scroll), scroll_node);
 
@@ -2984,7 +2984,7 @@
   scroll_tree.set_currently_scrolling_node(scroll_node->id);
 
   gfx::ScrollOffset current_offset =
-      scroll_tree.current_scroll_offset(scroll_node->owning_layer_id);
+      scroll_tree.current_scroll_offset(scroll_node->element_id);
   gfx::ScrollOffset target_offset = scroll_tree.ClampScrollOffsetToLimits(
       current_offset + gfx::ScrollOffset(delta), scroll_node);
   DCHECK_EQ(
@@ -3152,11 +3152,11 @@
 
   // Apply the scroll delta.
   gfx::ScrollOffset previous_offset =
-      scroll_tree->current_scroll_offset(scroll_node->owning_layer_id);
+      scroll_tree->current_scroll_offset(scroll_node->element_id);
   scroll_tree->ScrollBy(scroll_node, local_end_point - local_start_point,
                         active_tree());
   gfx::ScrollOffset scrolled =
-      scroll_tree->current_scroll_offset(scroll_node->owning_layer_id) -
+      scroll_tree->current_scroll_offset(scroll_node->element_id) -
       previous_offset;
 
   // Get the end point in the layer's content space so we can apply its
@@ -3182,12 +3182,12 @@
     LayerTreeImpl* layer_tree_impl) {
   ScrollTree& scroll_tree = layer_tree_impl->property_trees()->scroll_tree;
   gfx::ScrollOffset previous_offset =
-      scroll_tree.current_scroll_offset(scroll_node->owning_layer_id);
+      scroll_tree.current_scroll_offset(scroll_node->element_id);
   gfx::Vector2dF delta = local_delta;
   delta.Scale(1.f / page_scale_factor);
   scroll_tree.ScrollBy(scroll_node, delta, layer_tree_impl);
   gfx::ScrollOffset scrolled =
-      scroll_tree.current_scroll_offset(scroll_node->owning_layer_id) -
+      scroll_tree.current_scroll_offset(scroll_node->element_id) -
       previous_offset;
   gfx::Vector2dF consumed_scroll(scrolled.x(), scrolled.y());
   consumed_scroll.Scale(page_scale_factor);
@@ -3596,13 +3596,13 @@
   if (tree_impl->LayerListIsEmpty())
     return;
 
-  int inner_viewport_layer_id =
+  ElementId inner_viewport_scroll_element_id =
       tree_impl->InnerViewportScrollLayer()
-          ? tree_impl->InnerViewportScrollLayer()->id()
-          : Layer::INVALID_ID;
+          ? tree_impl->InnerViewportScrollLayer()->element_id()
+          : ElementId();
 
   tree_impl->property_trees()->scroll_tree.CollectScrollDeltas(
-      scroll_info, inner_viewport_layer_id);
+      scroll_info, inner_viewport_scroll_element_id);
 }
 
 static void CollectScrollbarUpdates(
@@ -4140,14 +4140,13 @@
   if (!tree)
     return;
 
-  const int layer_id = tree->LayerIdByElementId(element_id);
   PropertyTrees* property_trees = tree->property_trees();
   DCHECK_EQ(1u,
             property_trees->element_id_to_scroll_node_index.count(element_id));
   const int scroll_node_index =
       property_trees->element_id_to_scroll_node_index[element_id];
   property_trees->scroll_tree.OnScrollOffsetAnimated(
-      layer_id, scroll_node_index, scroll_offset, tree);
+      element_id, scroll_node_index, scroll_offset, tree);
   // Run mutation callbacks to respond to updated scroll offset.
   Mutate(CurrentBeginFrameArgs().frame_time);
 }
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 176e8b34..69fd2ff3 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -250,10 +250,10 @@
   }
 
   static gfx::Vector2dF ScrollDelta(LayerImpl* layer_impl) {
-    gfx::ScrollOffset delta =
-        layer_impl->layer_tree_impl()
-            ->property_trees()
-            ->scroll_tree.GetScrollOffsetDeltaForTesting(layer_impl->id());
+    gfx::ScrollOffset delta = layer_impl->layer_tree_impl()
+                                  ->property_trees()
+                                  ->scroll_tree.GetScrollOffsetDeltaForTesting(
+                                      layer_impl->element_id());
     return gfx::Vector2dF(delta.x(), delta.y());
   }
 
@@ -264,12 +264,12 @@
 
   static ::testing::AssertionResult ScrollInfoContains(
       const ScrollAndScaleSet& scroll_info,
-      int id,
+      ElementId id,
       const gfx::Vector2d& scroll_delta) {
     int times_encountered = 0;
 
     for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
-      if (scroll_info.scrolls[i].layer_id != id)
+      if (scroll_info.scrolls[i].element_id != id)
         continue;
 
       if (scroll_delta != scroll_info.scrolls[i].scroll_delta) {
@@ -280,7 +280,7 @@
       times_encountered++;
     }
 
-    if (id == scroll_info.inner_viewport_scroll.layer_id) {
+    if (id == scroll_info.inner_viewport_scroll.element_id) {
       if (scroll_delta != scroll_info.inner_viewport_scroll.scroll_delta) {
         return ::testing::AssertionFailure()
                << "Expected " << scroll_delta.ToString() << ", not "
@@ -290,15 +290,15 @@
     }
 
     if (times_encountered != 1)
-      return ::testing::AssertionFailure() << "No layer found with id " << id;
+      return ::testing::AssertionFailure() << "No scroll found with id " << id;
     return ::testing::AssertionSuccess();
   }
 
-  static void ExpectNone(const ScrollAndScaleSet& scroll_info, int id) {
+  static void ExpectNone(const ScrollAndScaleSet& scroll_info, ElementId id) {
     int times_encountered = 0;
 
     for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
-      if (scroll_info.scrolls[i].layer_id != id)
+      if (scroll_info.scrolls[i].element_id != id)
         continue;
       times_encountered++;
     }
@@ -333,8 +333,8 @@
         true;
     inner_scroll->layer_tree_impl()
         ->property_trees()
-        ->scroll_tree.UpdateScrollOffsetBaseForTesting(inner_scroll->id(),
-                                                       gfx::ScrollOffset());
+        ->scroll_tree.UpdateScrollOffsetBaseForTesting(
+            inner_scroll->element_id(), gfx::ScrollOffset());
 
     std::unique_ptr<LayerImpl> inner_clip =
         LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId);
@@ -363,8 +363,8 @@
         LayerIdToElementIdForTesting(outer_scroll->id()));
     outer_scroll->layer_tree_impl()
         ->property_trees()
-        ->scroll_tree.UpdateScrollOffsetBaseForTesting(outer_scroll->id(),
-                                                       gfx::ScrollOffset());
+        ->scroll_tree.UpdateScrollOffsetBaseForTesting(
+            outer_scroll->element_id(), gfx::ScrollOffset());
     outer_scroll->SetBounds(content_size);
     outer_scroll->SetPosition(gfx::PointF());
 
@@ -515,9 +515,10 @@
                                    const gfx::Vector2dF& delta) {
     if (layer_impl->layer_tree_impl()
             ->property_trees()
-            ->scroll_tree.SetScrollOffsetDeltaForTesting(layer_impl->id(),
-                                                         delta))
-      layer_impl->layer_tree_impl()->DidUpdateScrollOffset(layer_impl->id());
+            ->scroll_tree.SetScrollOffsetDeltaForTesting(
+                layer_impl->element_id(), delta))
+      layer_impl->layer_tree_impl()->DidUpdateScrollOffset(
+          layer_impl->element_id());
   }
 
   void BeginImplFrameAndAnimate(BeginFrameArgs begin_frame_args,
@@ -741,7 +742,8 @@
   root->SetElementId(LayerIdToElementIdForTesting(root->id()));
   root->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(root->id(), scroll_offset);
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(root->element_id(),
+                                                     scroll_offset);
   host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_clip_owned));
   host_impl_->active_tree()->BuildPropertyTreesForTesting();
 
@@ -750,18 +752,19 @@
   root->ScrollBy(scroll_delta);
   scroll_info = host_impl_->ProcessScrollDeltas();
   ASSERT_EQ(scroll_info->scrolls.size(), 1u);
-  EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(), scroll_delta));
+  EXPECT_TRUE(
+      ScrollInfoContains(*scroll_info, root->element_id(), scroll_delta));
 
   gfx::Vector2d scroll_delta2(-5, 27);
   root->ScrollBy(scroll_delta2);
   scroll_info = host_impl_->ProcessScrollDeltas();
   ASSERT_EQ(scroll_info->scrolls.size(), 1u);
-  EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(),
+  EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->element_id(),
                                  scroll_delta + scroll_delta2));
 
   root->ScrollBy(gfx::Vector2d());
   scroll_info = host_impl_->ProcessScrollDeltas();
-  EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->id(),
+  EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->element_id(),
                                  scroll_delta + scroll_delta2));
 }
 
@@ -922,8 +925,8 @@
   host_impl_->ScrollEnd(EndState().get());
   std::unique_ptr<ScrollAndScaleSet> scroll_info =
       host_impl_->ProcessScrollDeltas();
-  EXPECT_TRUE(
-      ScrollInfoContains(*scroll_info, scroll_layer->id(), scroll_delta));
+  EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
+                                 scroll_delta));
 }
 
 TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) {
@@ -1428,7 +1431,7 @@
   overflow->SetElementId(LayerIdToElementIdForTesting(overflow->id()));
   overflow->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->id(),
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(),
                                                      gfx::ScrollOffset());
   overflow->SetPosition(gfx::PointF());
   host_impl_->active_tree()->BuildPropertyTreesForTesting();
@@ -1802,7 +1805,7 @@
     std::unique_ptr<ScrollAndScaleSet> scroll_info =
         host_impl_->ProcessScrollDeltas();
     EXPECT_TRUE(ScrollInfoContains(
-        *scroll_info.get(), scroll_layer->id(),
+        *scroll_info.get(), scroll_layer->element_id(),
         gfx::Vector2d(0, scroll_delta.y() / page_scale_delta)));
   }
 }
@@ -2283,7 +2286,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->id(), gfx::ScrollOffset(50, 50));
+            scroll_layer->element_id(), gfx::ScrollOffset(50, 50));
 
     float page_scale_delta = 0.1f;
     host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
@@ -2311,7 +2314,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->id(), gfx::ScrollOffset(20, 20));
+            scroll_layer->element_id(), gfx::ScrollOffset(20, 20));
 
     float page_scale_delta = 1.f;
     host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
@@ -2339,7 +2342,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->id(), gfx::ScrollOffset(20, 20));
+            scroll_layer->element_id(), gfx::ScrollOffset(20, 20));
 
     float page_scale_delta = 1.f;
     host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
@@ -2355,7 +2358,7 @@
     std::unique_ptr<ScrollAndScaleSet> scroll_info =
         host_impl_->ProcessScrollDeltas();
     EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
+    EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
                                    gfx::Vector2d(-10, -10)));
   }
 
@@ -2368,8 +2371,8 @@
         ->scroll_tree.CollectScrollDeltasForTesting();
     scroll_layer->layer_tree_impl()
         ->property_trees()
-        ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
-                                                       gfx::ScrollOffset(0, 0));
+        ->scroll_tree.UpdateScrollOffsetBaseForTesting(
+            scroll_layer->element_id(), gfx::ScrollOffset(0, 0));
 
     host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
                             InputHandler::TOUCHSCREEN);
@@ -2389,7 +2392,7 @@
     std::unique_ptr<ScrollAndScaleSet> scroll_info =
         host_impl_->ProcessScrollDeltas();
     EXPECT_EQ(scroll_info->page_scale_delta, 2.f);
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
+    EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
                                    gfx::Vector2d(10, 10)));
   }
 }
@@ -2420,7 +2423,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->id(), gfx::ScrollOffset(50, 50));
+            scroll_layer->element_id(), gfx::ScrollOffset(50, 50));
 
     did_request_redraw_ = false;
     did_request_next_frame_ = false;
@@ -2466,7 +2469,7 @@
     std::unique_ptr<ScrollAndScaleSet> scroll_info =
         host_impl_->ProcessScrollDeltas();
     EXPECT_EQ(scroll_info->page_scale_delta, 2);
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
+    EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
                                    gfx::Vector2d(-50, -50)));
   }
 
@@ -2481,7 +2484,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->id(), gfx::ScrollOffset(50, 50));
+            scroll_layer->element_id(), gfx::ScrollOffset(50, 50));
 
     did_request_redraw_ = false;
     did_request_next_frame_ = false;
@@ -2519,7 +2522,7 @@
         host_impl_->ProcessScrollDeltas();
     EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
     // Pushed to (0,0) via clamping against contents layer size.
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
+    EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
                                    gfx::Vector2d(-50, -50)));
   }
 }
@@ -2550,7 +2553,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->id(), gfx::ScrollOffset(50, 50));
+            scroll_layer->element_id(), gfx::ScrollOffset(50, 50));
 
     host_impl_->active_tree()->SetPendingPageScaleAnimation(
         std::unique_ptr<PendingPageScaleAnimation>(
@@ -2580,7 +2583,7 @@
     std::unique_ptr<ScrollAndScaleSet> scroll_info =
         host_impl_->ProcessScrollDeltas();
     EXPECT_EQ(scroll_info->page_scale_delta, 1);
-    ExpectNone(*scroll_info, scroll_layer->id());
+    ExpectNone(*scroll_info, scroll_layer->element_id());
   }
 }
 
@@ -2615,7 +2618,7 @@
 
   scroll_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
                                                      gfx::ScrollOffset(50, 50));
 
   // Make sure TakePageScaleAnimation works properly.
@@ -2705,7 +2708,7 @@
   std::unique_ptr<ScrollAndScaleSet> scroll_info =
       host_impl_->ProcessScrollDeltas();
   EXPECT_EQ(scroll_info->page_scale_delta, target_scale);
-  EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->id(),
+  EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
                                  gfx::Vector2d(-50, -50)));
 }
 
@@ -2729,7 +2732,7 @@
   host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
   scroll_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
                                                      gfx::ScrollOffset(50, 50));
 
   did_complete_page_scale_animation_ = false;
@@ -2990,10 +2993,10 @@
     if (host_impl_->active_tree()
             ->property_trees()
             ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-                host_impl_->InnerViewportScrollLayer()->id(),
+                host_impl_->InnerViewportScrollLayer()->element_id(),
                 gfx::ScrollOffset(5, 5)))
       host_impl_->active_tree()->DidUpdateScrollOffset(
-          host_impl_->InnerViewportScrollLayer()->id());
+          host_impl_->InnerViewportScrollLayer()->element_id());
     EXPECT_FALSE(did_request_next_frame_);
     EXPECT_FALSE(did_request_redraw_);
     EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
@@ -4175,8 +4178,8 @@
       host_impl_->pending_tree()->OuterViewportScrollLayer();
   pending_outer_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(pending_outer_layer->id(),
-                                                     pending_scroll);
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(
+          pending_outer_layer->element_id(), pending_scroll);
 
   host_impl_->ActivateSyncTree();
   // Scrolloffsets on the active tree will be clamped after activation.
@@ -5219,7 +5222,7 @@
   {
     host_impl_->pending_tree()
         ->property_trees()
-        ->scroll_tree.SetScrollOffsetDeltaForTesting(outer_scroll->id(),
+        ->scroll_tree.SetScrollOffsetDeltaForTesting(outer_scroll->element_id(),
                                                      gfx::Vector2dF(0, 1050));
     host_impl_->ActivateSyncTree();
 
@@ -5424,7 +5427,7 @@
 
   std::unique_ptr<ScrollAndScaleSet> scroll_info =
       host_impl_->ProcessScrollDeltas();
-  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(),
+  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->element_id(),
                                  expected_scroll_delta));
 
   // The scroll range should also have been updated.
@@ -5483,7 +5486,7 @@
   // The scroll delta is not scaled because the main thread did not scale.
   std::unique_ptr<ScrollAndScaleSet> scroll_info =
       host_impl_->ProcessScrollDeltas();
-  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(),
+  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->element_id(),
                                  expected_scroll_delta));
 
   // The scroll range should also have been updated.
@@ -5582,7 +5585,7 @@
 
   std::unique_ptr<ScrollAndScaleSet> scroll_info =
       host_impl_->ProcessScrollDeltas();
-  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->id(),
+  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->element_id(),
                                  expected_scroll_delta));
 
   // The scroll range should not have changed.
@@ -5618,11 +5621,11 @@
 
   grand_child_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(),
-                                                     gfx::ScrollOffset(0, 5));
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(
+          grand_child_layer->element_id(), gfx::ScrollOffset(0, 5));
   child_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(),
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(),
                                                      gfx::ScrollOffset(3, 0));
 
   host_impl_->SetViewportSize(surface_size);
@@ -5645,11 +5648,12 @@
                            ->root_layer_for_testing()
                            ->test_properties()
                            ->children[0];
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child_layer->id(),
+    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(),
+                                   grand_child_layer->element_id(),
                                    gfx::Vector2d(0, -5)));
 
     // The child should not have scrolled.
-    ExpectNone(*scroll_info.get(), child->id());
+    ExpectNone(*scroll_info.get(), child->element_id());
   }
 }
 
@@ -5684,11 +5688,11 @@
 
   grand_child_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(),
-                                                     gfx::ScrollOffset(0, 30));
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(
+          grand_child_layer->element_id(), gfx::ScrollOffset(0, 30));
   child_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(),
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(),
                                                      gfx::ScrollOffset(0, 50));
 
   host_impl_->SetViewportSize(surface_size);
@@ -5797,11 +5801,11 @@
 
   grand_child_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(),
-                                                     gfx::ScrollOffset(0, 2));
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(
+          grand_child_layer->element_id(), gfx::ScrollOffset(0, 2));
   child_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(),
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(),
                                                      gfx::ScrollOffset(0, 3));
 
   DrawFrame();
@@ -5828,11 +5832,11 @@
                            ->test_properties()
                            ->children[0];
     LayerImpl* grand_child = child->test_properties()->children[0];
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
-                                   gfx::Vector2d(0, -2)));
+    EXPECT_TRUE(ScrollInfoContains(
+        *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, -2)));
 
     // The child should not have scrolled.
-    ExpectNone(*scroll_info.get(), child->id());
+    ExpectNone(*scroll_info.get(), child->element_id());
 
     // The next time we scroll we should only scroll the parent.
     scroll_delta = gfx::Vector2d(0, -3);
@@ -5851,12 +5855,12 @@
     scroll_info = host_impl_->ProcessScrollDeltas();
 
     // The child should have scrolled up to its limit.
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->id(),
+    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(),
                                    gfx::Vector2d(0, -3)));
 
     // The grand child should not have scrolled.
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
-                                   gfx::Vector2d(0, -2)));
+    EXPECT_TRUE(ScrollInfoContains(
+        *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, -2)));
 
     // After scrolling the parent, another scroll on the opposite direction
     // should still scroll the child.
@@ -5876,11 +5880,11 @@
     scroll_info = host_impl_->ProcessScrollDeltas();
 
     // The grand child should have scrolled.
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
-                                   gfx::Vector2d(0, 5)));
+    EXPECT_TRUE(ScrollInfoContains(
+        *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, 5)));
 
     // The child should not have scrolled.
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->id(),
+    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(),
                                    gfx::Vector2d(0, -3)));
 
     // Scrolling should be adjusted from viewport space.
@@ -5901,8 +5905,8 @@
     scroll_info = host_impl_->ProcessScrollDeltas();
 
     // Should have scrolled by half the amount in layer space (5 - 2/2)
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(),
-                                   gfx::Vector2d(0, 4)));
+    EXPECT_TRUE(ScrollInfoContains(
+        *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, 4)));
   }
 }
 TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) {
@@ -5927,7 +5931,7 @@
   child->test_properties()->is_container_for_fixed_position_layers = true;
   root_scroll->SetBounds(content_size);
 
-  int root_scroll_id = root_scroll->id();
+  ElementId root_scroll_id = root_scroll->element_id();
   root_scroll->test_properties()->AddChild(std::move(child));
   root_clip->test_properties()->AddChild(std::move(root_scroll));
   root_ptr->test_properties()->AddChild(std::move(root_clip));
@@ -6080,7 +6084,7 @@
   // The layer should have scrolled down in its local coordinates.
   std::unique_ptr<ScrollAndScaleSet> scroll_info =
       host_impl_->ProcessScrollDeltas();
-  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
+  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(),
                                  gfx::Vector2d(0, gesture_scroll_delta.x())));
 
   // Reset and scroll down with the wheel.
@@ -6096,7 +6100,7 @@
 
   // The layer should have scrolled down in its local coordinates.
   scroll_info = host_impl_->ProcessScrollDeltas();
-  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
+  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(),
                                  wheel_scroll_delta));
 }
 
@@ -6130,6 +6134,8 @@
   scroll_layer->test_properties()->AddChild(std::move(clip_layer));
   host_impl_->active_tree()->BuildPropertyTreesForTesting();
 
+  ElementId child_scroll_id = LayerIdToElementIdForTesting(child_layer_id);
+
   gfx::Size surface_size(50, 50);
   host_impl_->SetViewportSize(surface_size);
   DrawFrame();
@@ -6151,7 +6157,7 @@
                std::cos(MathUtil::Deg2Rad(child_layer_angle)));
     std::unique_ptr<ScrollAndScaleSet> scroll_info =
         host_impl_->ProcessScrollDeltas();
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id,
+    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_id,
                                    expected_scroll_delta));
 
     // The root scroll layer should not have scrolled, because the input delta
@@ -6176,11 +6182,11 @@
                std::sin(MathUtil::Deg2Rad(child_layer_angle)));
     std::unique_ptr<ScrollAndScaleSet> scroll_info =
         host_impl_->ProcessScrollDeltas();
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id,
+    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_id,
                                    expected_scroll_delta));
 
     // The root scroll layer shouldn't have scrolled.
-    ExpectNone(*scroll_info.get(), scroll_layer->id());
+    ExpectNone(*scroll_info.get(), scroll_layer->element_id());
   }
 }
 
@@ -6255,7 +6261,8 @@
     host_impl_->ScrollEnd(EndState().get());
 
     scroll_info = host_impl_->ProcessScrollDeltas();
-    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_layer_id,
+    ElementId child_scroll_id = LayerIdToElementIdForTesting(child_layer_id);
+    EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_id,
                                    expected_scroll_deltas[i]));
 
     // The root scroll layer should not have scrolled, because the input delta
@@ -6293,7 +6300,7 @@
   // amount.
   std::unique_ptr<ScrollAndScaleSet> scroll_info =
       host_impl_->ProcessScrollDeltas();
-  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
+  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(),
                                  gfx::Vector2d(0, scroll_delta.y() / scale)));
 
   // Reset and scroll down with the wheel.
@@ -6309,7 +6316,7 @@
 
   // It should apply the scale factor to the scroll delta for the wheel event.
   scroll_info = host_impl_->ProcessScrollDeltas();
-  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->id(),
+  EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(),
                                  wheel_scroll_delta));
 }
 
@@ -6345,7 +6352,7 @@
   gfx::Vector2dF initial_scroll_delta(10.f, 10.f);
   scroll_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
                                                      gfx::ScrollOffset());
   SetScrollOffsetDelta(scroll_layer, initial_scroll_delta);
 
@@ -6637,12 +6644,12 @@
 
   child_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->id(),
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(),
                                                      gfx::ScrollOffset(0, 3));
   grand_child_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child_layer->id(),
-                                                     gfx::ScrollOffset(0, 2));
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(
+          grand_child_layer->element_id(), gfx::ScrollOffset(0, 2));
 
   host_impl_->SetViewportSize(surface_size);
   DrawFrame();
@@ -8514,8 +8521,8 @@
 
   scrolling_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scrolling_layer->id(),
-                                                     scroll_offset);
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(
+          scrolling_layer->element_id(), scroll_offset);
   host_impl_->ActivateSyncTree();
 
   bool update_lcd_text = false;
@@ -8940,7 +8947,7 @@
       CreateScrollableLayer(2, content_size, root_clip.get());
 
   root_scroll->test_properties()->AddChild(std::move(child));
-  int root_id = root_scroll->id();
+  ElementId root_id = root_scroll->element_id();
   root_clip->test_properties()->AddChild(std::move(root_scroll));
   root_ptr->test_properties()->AddChild(std::move(root_clip));
 
@@ -9007,11 +9014,11 @@
 
   child->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(child->id(),
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(child->element_id(),
                                                      gfx::ScrollOffset(0, 4));
   grand_child->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child->id(),
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(grand_child->element_id(),
                                                      gfx::ScrollOffset(0, 2));
 
   host_impl_->SetViewportSize(surface_size);
@@ -9032,8 +9039,10 @@
     // The grand child should have scrolled up to its limit.
     scroll_info = host_impl_->ProcessScrollDeltas();
     ASSERT_EQ(1u, scroll_info->scrolls.size());
+    ElementId grand_child_scroll_id =
+        LayerIdToElementIdForTesting(grand_child->id());
     EXPECT_TRUE(
-        ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta));
+        ScrollInfoContains(*scroll_info, grand_child_scroll_id, scroll_delta));
     EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
               grand_child->scroll_tree_index());
 
@@ -9044,8 +9053,8 @@
     scroll_info = host_impl_->ProcessScrollDeltas();
     ASSERT_EQ(1u, scroll_info->scrolls.size());
     EXPECT_TRUE(
-        ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta));
-    ExpectNone(*scroll_info, child->id());
+        ScrollInfoContains(*scroll_info, grand_child_scroll_id, scroll_delta));
+    ExpectNone(*scroll_info, child->element_id());
     EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
               grand_child->scroll_tree_index());
 
@@ -9061,8 +9070,8 @@
     scroll_info = host_impl_->ProcessScrollDeltas();
     ASSERT_EQ(1u, scroll_info->scrolls.size());
     EXPECT_TRUE(
-        ScrollInfoContains(*scroll_info, grand_child->id(), scroll_delta));
-    ExpectNone(*scroll_info, child->id());
+        ScrollInfoContains(*scroll_info, grand_child_scroll_id, scroll_delta));
+    ExpectNone(*scroll_info, child->element_id());
 
     // As the locked layer is at it's limit, no further scrolling can occur.
     EXPECT_FALSE(
@@ -9083,7 +9092,7 @@
   root_clip->test_properties()->force_render_surface = true;
   std::unique_ptr<LayerImpl> root_scroll =
       CreateScrollableLayer(11, content_size, root_clip);
-  int root_scroll_id = root_scroll->id();
+  ElementId root_scroll_id = root_scroll->element_id();
   std::unique_ptr<LayerImpl> child =
       CreateScrollableLayer(12, content_size, root_clip);
 
@@ -9461,7 +9470,7 @@
   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
   scroll_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
                                                      gfx::ScrollOffset(0, 10));
   BeginFrameArgs begin_frame_args =
       CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2);
@@ -9502,7 +9511,7 @@
   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
   scroll_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(),
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
                                                      gfx::ScrollOffset(0, 10));
   host_impl_->DidChangeBrowserControlsPosition();
   EXPECT_TRUE(did_request_next_frame_);
@@ -9719,7 +9728,8 @@
   scroll_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-          scroll_layer->id(), gfx::ScrollOffset(0, initial_scroll_offset));
+          scroll_layer->element_id(),
+          gfx::ScrollOffset(0, initial_scroll_offset));
   DrawFrame();
 
   EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
@@ -9796,7 +9806,8 @@
   scroll_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-          scroll_layer->id(), gfx::ScrollOffset(0, initial_scroll_offset));
+          scroll_layer->element_id(),
+          gfx::ScrollOffset(0, initial_scroll_offset));
   DrawFrame();
 
   EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
@@ -10027,8 +10038,8 @@
         true;
     inner_scroll->layer_tree_impl()
         ->property_trees()
-        ->scroll_tree.UpdateScrollOffsetBaseForTesting(inner_scroll->id(),
-                                                       gfx::ScrollOffset());
+        ->scroll_tree.UpdateScrollOffsetBaseForTesting(
+            inner_scroll->element_id(), gfx::ScrollOffset());
 
     std::unique_ptr<LayerImpl> inner_clip =
         LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId);
@@ -10056,8 +10067,8 @@
         LayerIdToElementIdForTesting(outer_scroll->id()));
     outer_scroll->layer_tree_impl()
         ->property_trees()
-        ->scroll_tree.UpdateScrollOffsetBaseForTesting(outer_scroll->id(),
-                                                       gfx::ScrollOffset());
+        ->scroll_tree.UpdateScrollOffsetBaseForTesting(
+            outer_scroll->element_id(), gfx::ScrollOffset());
     outer_scroll->SetBounds(content_size);
     outer_scroll->SetPosition(gfx::PointF());
 
@@ -10270,6 +10281,8 @@
       std::move(child));
   host_impl_->active_tree()->BuildPropertyTreesForTesting();
 
+  ElementId child_scroll_id = LayerIdToElementIdForTesting(child_scroll->id());
+
   DrawFrame();
   {
     std::unique_ptr<ScrollAndScaleSet> scroll_info;
@@ -10290,7 +10303,7 @@
     scroll_info = host_impl_->ProcessScrollDeltas();
     ASSERT_EQ(1u, scroll_info->scrolls.size());
     EXPECT_TRUE(
-        ScrollInfoContains(*scroll_info, child_scroll->id(), scroll_delta));
+        ScrollInfoContains(*scroll_info, child_scroll_id, scroll_delta));
     EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
               child_scroll->scroll_tree_index());
 
@@ -10309,8 +10322,8 @@
     scroll_info = host_impl_->ProcessScrollDeltas();
     ASSERT_EQ(1u, scroll_info->scrolls.size());
     EXPECT_TRUE(
-        ScrollInfoContains(*scroll_info, child_scroll->id(), scroll_delta));
-    ExpectNone(*scroll_info, inner_scroll->id());
+        ScrollInfoContains(*scroll_info, child_scroll_id, scroll_delta));
+    ExpectNone(*scroll_info, inner_scroll->element_id());
 
     // As the locked layer is at its limit, no further scrolling can occur.
     EXPECT_FALSE(
@@ -12146,11 +12159,11 @@
     gfx::ScrollOffset pending_base =
         pending_tree->property_trees()
             ->scroll_tree.GetScrollOffsetBaseForTesting(
-                last_scrolled_layer->id());
+                last_scrolled_layer->element_id());
     pending_tree->BuildPropertyTreesForTesting();
     pending_tree->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            last_scrolled_layer->id(), pending_base);
+            last_scrolled_layer->element_id(), pending_base);
     pending_tree->LayerById(content_layer->id())->SetNeedsPushProperties();
 
     pending_tree->set_needs_update_draw_properties();
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index e9a1e5d..d3ac199 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -134,14 +134,14 @@
       case 0:
         EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer)
                                               ->GetScrollOffsetBaseForTesting(
-                                                  scroll_layer->id()));
+                                                  scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer));
         PostSetNeedsCommitToMainThread();
         break;
       case 1:
         EXPECT_VECTOR_EQ(second_scroll_, ScrollTreeForLayer(scroll_layer)
                                              ->GetScrollOffsetBaseForTesting(
-                                                 scroll_layer->id()));
+                                                 scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer));
         EndTest();
         break;
@@ -206,9 +206,9 @@
       scroll_layer->ScrollBy(scroll_amount_);
       EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer));
 
-      EXPECT_VECTOR_EQ(initial_scroll_,
-                       ScrollTreeForLayer(scroll_layer)
-                           ->GetScrollOffsetBaseForTesting(scroll_layer->id()));
+      EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer)
+                                            ->GetScrollOffsetBaseForTesting(
+                                                scroll_layer->element_id()));
       PostSetNeedsRedrawToMainThread();
     } else if (impl->active_tree()->source_frame_number() == 0 &&
                impl->SourceAnimationFrameNumberForTesting() == 2) {
@@ -348,9 +348,10 @@
       EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(root_scroll_layer));
       root_scroll_layer->ScrollBy(impl_scroll_);
       EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer));
-      EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(root_scroll_layer)
-                                            ->GetScrollOffsetBaseForTesting(
-                                                root_scroll_layer->id()));
+      EXPECT_VECTOR_EQ(
+          initial_scroll_,
+          ScrollTreeForLayer(root_scroll_layer)
+              ->GetScrollOffsetBaseForTesting(root_scroll_layer->element_id()));
 
       EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
       EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
@@ -371,7 +372,7 @@
       EXPECT_VECTOR_EQ(
           gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_),
           ScrollTreeForLayer(root_scroll_layer)
-              ->GetScrollOffsetBaseForTesting(root_scroll_layer->id()));
+              ->GetScrollOffsetBaseForTesting(root_scroll_layer->element_id()));
 
       EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
       EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor());
@@ -395,7 +396,7 @@
       EXPECT_VECTOR_EQ(
           gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
           ScrollTreeForLayer(root_scroll_layer)
-              ->GetScrollOffsetBaseForTesting(root_scroll_layer->id()));
+              ->GetScrollOffsetBaseForTesting(root_scroll_layer->element_id()));
     } else if (impl->active_tree()->source_frame_number() == 2 &&
                impl->SourceAnimationFrameNumberForTesting() == 4) {
       // Final draw after the second aborted commit.
@@ -405,7 +406,7 @@
       EXPECT_VECTOR_EQ(
           gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
           ScrollTreeForLayer(root_scroll_layer)
-              ->GetScrollOffsetBaseForTesting(root_scroll_layer->id()));
+              ->GetScrollOffsetBaseForTesting(root_scroll_layer->element_id()));
       EndTest();
     } else {
       // Commit for source frame 3 is aborted.
@@ -462,7 +463,7 @@
         EXPECT_VECTOR_EQ(
             gfx::Vector2d(0, 0),
             ScrollTreeForLayer(scroll_layer)
-                ->GetScrollOffsetBaseForTesting(scroll_layer->id()));
+                ->GetScrollOffsetBaseForTesting(scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(gfx::Vector2d(0, 0), ScrollDelta(scroll_layer));
         PostSetNeedsCommitToMainThread();
         break;
@@ -470,7 +471,7 @@
         EXPECT_VECTOR_EQ(
             gfx::ToFlooredVector2d(scroll_amount_),
             ScrollTreeForLayer(scroll_layer)
-                ->GetScrollOffsetBaseForTesting(scroll_layer->id()));
+                ->GetScrollOffsetBaseForTesting(scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(gfx::Vector2dF(fmod(scroll_amount_.x(), 1.0f), 0.0f),
                          ScrollDelta(scroll_layer));
         PostSetNeedsCommitToMainThread();
@@ -479,7 +480,7 @@
         EXPECT_VECTOR_EQ(
             gfx::ToFlooredVector2d(scroll_amount_ + scroll_amount_),
             ScrollTreeForLayer(scroll_layer)
-                ->GetScrollOffsetBaseForTesting(scroll_layer->id()));
+                ->GetScrollOffsetBaseForTesting(scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(
             gfx::Vector2dF(fmod(2.0f * scroll_amount_.x(), 1.0f), 0.0f),
             ScrollDelta(scroll_layer));
@@ -715,7 +716,7 @@
         EXPECT_VECTOR_EQ(initial_offset_,
                          ScrollTreeForLayer(expected_scroll_layer_impl)
                              ->GetScrollOffsetBaseForTesting(
-                                 expected_scroll_layer_impl->id()));
+                                 expected_scroll_layer_impl->element_id()));
         EXPECT_VECTOR_EQ(scroll_amount_,
                          ScrollDelta(expected_scroll_layer_impl));
         break;
@@ -735,7 +736,7 @@
         EXPECT_VECTOR_EQ(javascript_scroll_,
                          ScrollTreeForLayer(expected_scroll_layer_impl)
                              ->GetScrollOffsetBaseForTesting(
-                                 expected_scroll_layer_impl->id()));
+                                 expected_scroll_layer_impl->element_id()));
         EXPECT_VECTOR_EQ(scroll_amount_,
                          ScrollDelta(expected_scroll_layer_impl));
         break;
@@ -746,7 +747,7 @@
             gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_),
             ScrollTreeForLayer(expected_scroll_layer_impl)
                 ->GetScrollOffsetBaseForTesting(
-                    expected_scroll_layer_impl->id()));
+                    expected_scroll_layer_impl->element_id()));
         EXPECT_VECTOR_EQ(gfx::Vector2d(),
                          ScrollDelta(expected_scroll_layer_impl));
 
@@ -887,9 +888,10 @@
           EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer));
           scroll_layer->ScrollBy(impl_thread_scroll1_);
 
-          EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer)
-                                                ->GetScrollOffsetBaseForTesting(
-                                                    scroll_layer->id()));
+          EXPECT_VECTOR_EQ(
+              initial_scroll_,
+              ScrollTreeForLayer(scroll_layer)
+                  ->GetScrollOffsetBaseForTesting(scroll_layer->element_id()));
           EXPECT_VECTOR_EQ(impl_thread_scroll1_, ScrollDelta(scroll_layer));
           PostSetNeedsCommitToMainThread();
 
@@ -901,9 +903,10 @@
           EXPECT_EQ(impl->pending_tree()->source_frame_number(), 1);
 
           scroll_layer->ScrollBy(impl_thread_scroll2_);
-          EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer)
-                                                ->GetScrollOffsetBaseForTesting(
-                                                    scroll_layer->id()));
+          EXPECT_VECTOR_EQ(
+              initial_scroll_,
+              ScrollTreeForLayer(scroll_layer)
+                  ->GetScrollOffsetBaseForTesting(scroll_layer->element_id()));
           EXPECT_VECTOR_EQ(impl_thread_scroll1_ + impl_thread_scroll2_,
                            ScrollDelta(scroll_layer));
 
@@ -913,7 +916,8 @@
               gfx::ScrollOffsetWithDelta(
                   initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_),
               ScrollTreeForLayer(pending_scroll_layer)
-                  ->GetScrollOffsetBaseForTesting(pending_scroll_layer->id()));
+                  ->GetScrollOffsetBaseForTesting(
+                      pending_scroll_layer->element_id()));
           EXPECT_VECTOR_EQ(impl_thread_scroll2_,
                            ScrollDelta(pending_scroll_layer));
         }
@@ -924,7 +928,7 @@
             gfx::ScrollOffsetWithDelta(
                 initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_),
             ScrollTreeForLayer(scroll_layer)
-                ->GetScrollOffsetBaseForTesting(scroll_layer->id()));
+                ->GetScrollOffsetBaseForTesting(scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(impl_thread_scroll2_, ScrollDelta(scroll_layer));
         EndTest();
         break;
@@ -1011,27 +1015,27 @@
     ASSERT_TRUE(pending_scroll_layer);
     switch (impl->pending_tree()->source_frame_number()) {
       case 0:
-        EXPECT_VECTOR_EQ(
-            initial_scroll_,
-            ScrollTreeForLayer(pending_scroll_layer)
-                ->GetScrollOffsetBaseForTesting(pending_scroll_layer->id()));
+        EXPECT_VECTOR_EQ(initial_scroll_,
+                         ScrollTreeForLayer(pending_scroll_layer)
+                             ->GetScrollOffsetBaseForTesting(
+                                 pending_scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(pending_scroll_layer));
         EXPECT_FALSE(active_root);
         break;
       case 1:
         // Even though the scroll happened during the commit, both layers
         // should have the appropriate scroll delta.
-        EXPECT_VECTOR_EQ(
-            initial_scroll_,
-            ScrollTreeForLayer(pending_scroll_layer)
-                ->GetScrollOffsetBaseForTesting(pending_scroll_layer->id()));
+        EXPECT_VECTOR_EQ(initial_scroll_,
+                         ScrollTreeForLayer(pending_scroll_layer)
+                             ->GetScrollOffsetBaseForTesting(
+                                 pending_scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(impl_thread_scroll_,
                          ScrollDelta(pending_scroll_layer));
         ASSERT_TRUE(active_root);
-        EXPECT_VECTOR_EQ(
-            initial_scroll_,
-            ScrollTreeForLayer(active_scroll_layer)
-                ->GetScrollOffsetBaseForTesting(active_scroll_layer->id()));
+        EXPECT_VECTOR_EQ(initial_scroll_,
+                         ScrollTreeForLayer(active_scroll_layer)
+                             ->GetScrollOffsetBaseForTesting(
+                                 active_scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(impl_thread_scroll_, ScrollDelta(active_scroll_layer));
         break;
       case 2:
@@ -1039,7 +1043,8 @@
         EXPECT_VECTOR_EQ(
             gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll_),
             ScrollTreeForLayer(pending_scroll_layer)
-                ->GetScrollOffsetBaseForTesting(pending_scroll_layer->id()));
+                ->GetScrollOffsetBaseForTesting(
+                    pending_scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(pending_scroll_layer));
         break;
     }
@@ -1055,7 +1060,7 @@
       case 0:
         EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer)
                                               ->GetScrollOffsetBaseForTesting(
-                                                  scroll_layer->id()));
+                                                  scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer));
         EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
         EXPECT_EQ(1.f, impl->active_tree()->current_page_scale_factor());
@@ -1064,7 +1069,7 @@
       case 1:
         EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer)
                                               ->GetScrollOffsetBaseForTesting(
-                                                  scroll_layer->id()));
+                                                  scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(impl_thread_scroll_, ScrollDelta(scroll_layer));
         EXPECT_EQ(impl_scale_, impl->active_tree()->page_scale_delta());
         EXPECT_EQ(impl_scale_,
@@ -1457,9 +1462,10 @@
                                    const gfx::Vector2dF& delta) {
     if (layer_impl->layer_tree_impl()
             ->property_trees()
-            ->scroll_tree.SetScrollOffsetDeltaForTesting(layer_impl->id(),
-                                                         delta))
-      layer_impl->layer_tree_impl()->DidUpdateScrollOffset(layer_impl->id());
+            ->scroll_tree.SetScrollOffsetDeltaForTesting(
+                layer_impl->element_id(), delta))
+      layer_impl->layer_tree_impl()->DidUpdateScrollOffset(
+          layer_impl->element_id());
   }
 
   FakeLayerScrollClient root_scroll_layer_client_;
@@ -1556,7 +1562,7 @@
         EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer));
         EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer)
                                               ->GetScrollOffsetBaseForTesting(
-                                                  scroll_layer->id()));
+                                                  scroll_layer->element_id()));
         Scroll(impl);
         EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer));
         // Ask for commit after we've scrolled.
@@ -1566,7 +1572,7 @@
         EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer));
         EXPECT_VECTOR_EQ(second_scroll_, ScrollTreeForLayer(scroll_layer)
                                              ->GetScrollOffsetBaseForTesting(
-                                                 scroll_layer->id()));
+                                                 scroll_layer->element_id()));
         Scroll(impl);
         EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer));
         break;
@@ -1575,7 +1581,7 @@
         EXPECT_VECTOR_EQ(scroll_amount_, ScrollDelta(scroll_layer));
         EXPECT_VECTOR_EQ(third_scroll_, ScrollTreeForLayer(scroll_layer)
                                             ->GetScrollOffsetBaseForTesting(
-                                                scroll_layer->id()));
+                                                scroll_layer->element_id()));
         EndTest();
         break;
     }
@@ -1738,10 +1744,10 @@
             EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(root_scroll_layer));
             root_scroll_layer->ScrollBy(impl_scroll_);
             EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer));
-            EXPECT_VECTOR_EQ(
-                initial_scroll_,
-                ScrollTreeForLayer(root_scroll_layer)
-                    ->GetScrollOffsetBaseForTesting(root_scroll_layer->id()));
+            EXPECT_VECTOR_EQ(initial_scroll_,
+                             ScrollTreeForLayer(root_scroll_layer)
+                                 ->GetScrollOffsetBaseForTesting(
+                                     root_scroll_layer->element_id()));
             impl->SetNeedsCommit();
             break;
           }
@@ -1751,10 +1757,10 @@
             root_scroll_layer->ScrollBy(impl_scroll_);
             EXPECT_VECTOR_EQ(impl_scroll_ + impl_scroll_,
                              ScrollDelta(root_scroll_layer));
-            EXPECT_VECTOR_EQ(
-                initial_scroll_,
-                ScrollTreeForLayer(root_scroll_layer)
-                    ->GetScrollOffsetBaseForTesting(root_scroll_layer->id()));
+            EXPECT_VECTOR_EQ(initial_scroll_,
+                             ScrollTreeForLayer(root_scroll_layer)
+                                 ->GetScrollOffsetBaseForTesting(
+                                     root_scroll_layer->element_id()));
             // Ask for another commit (which will abort).
             impl->SetNeedsCommit();
             break;
@@ -1777,7 +1783,8 @@
             EXPECT_VECTOR_EQ(
                 gfx::ScrollOffsetWithDelta(initial_scroll_, prev_delta),
                 ScrollTreeForLayer(root_scroll_layer)
-                    ->GetScrollOffsetBaseForTesting(root_scroll_layer->id()));
+                    ->GetScrollOffsetBaseForTesting(
+                        root_scroll_layer->element_id()));
             // Ask for another commit (which will abort).
             impl->SetNeedsCommit();
             break;
@@ -1785,10 +1792,10 @@
           case 2: {
             gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + impl_scroll_ +
                                    second_main_scroll_;
-            EXPECT_VECTOR_EQ(
-                gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
-                ScrollTreeForLayer(root_scroll_layer)
-                    ->GetScrollOffsetBaseForTesting(root_scroll_layer->id()));
+            EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
+                             ScrollTreeForLayer(root_scroll_layer)
+                                 ->GetScrollOffsetBaseForTesting(
+                                     root_scroll_layer->element_id()));
             // End test after second aborted commit (fourth commit request).
             EndTest();
             break;
@@ -2046,7 +2053,7 @@
       case 0:
         EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer)
                                               ->GetScrollOffsetBaseForTesting(
-                                                  scroll_layer->id()));
+                                                  scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(
             initial_scroll_,
             scroll_layer->layer_tree_impl()
@@ -2058,7 +2065,7 @@
       case 1:
         EXPECT_VECTOR_EQ(second_scroll_, ScrollTreeForLayer(scroll_layer)
                                              ->GetScrollOffsetBaseForTesting(
-                                                 scroll_layer->id()));
+                                                 scroll_layer->element_id()));
         EXPECT_VECTOR_EQ(
             second_scroll_,
             scroll_layer->layer_tree_impl()
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 94023cd..014c4ab 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -151,7 +151,7 @@
   }
 }
 
-void LayerTreeImpl::DidUpdateScrollOffset(int layer_id) {
+void LayerTreeImpl::DidUpdateScrollOffset(ElementId id) {
   // Scrollbar positions depend on the current scroll offset.
   SetScrollbarGeometriesNeedUpdate();
 
@@ -163,7 +163,10 @@
   // If pending tree topology changed and we still want to notify the pending
   // tree about scroll offset in the active tree, we may not find the
   // corresponding pending layer.
-  if (auto* layer = LayerById(layer_id)) {
+  // TODO(pdr): Remove this use of LayerByElementId and instead look up the
+  // scroll node via ElementId and then set transform_id to the scroll node's
+  // transform node index.
+  if (auto* layer = LayerByElementId(id)) {
     // TODO(sunxd): when we have a layer_id to property_tree index map in
     // property trees, use the transform_id parameter instead of looking for
     // indices from LayerImpls.
@@ -175,8 +178,8 @@
 
   if (transform_id != TransformTree::kInvalidNodeId) {
     TransformNode* node = transform_tree.Node(transform_id);
-    if (node->scroll_offset != scroll_tree.current_scroll_offset(layer_id)) {
-      node->scroll_offset = scroll_tree.current_scroll_offset(layer_id);
+    if (node->scroll_offset != scroll_tree.current_scroll_offset(id)) {
+      node->scroll_offset = scroll_tree.current_scroll_offset(id);
       node->needs_local_transform_update = true;
       transform_tree.set_needs_update(true);
     }
@@ -186,7 +189,7 @@
   }
 
   if (IsActiveTree() && layer_tree_host_impl_->pending_tree())
-    layer_tree_host_impl_->pending_tree()->DidUpdateScrollOffset(layer_id);
+    layer_tree_host_impl_->pending_tree()->DidUpdateScrollOffset(id);
 }
 
 void LayerTreeImpl::UpdateScrollbarGeometries() {
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index 29e9c097..d78f1b7 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -497,7 +497,7 @@
       std::unique_ptr<PendingPageScaleAnimation> pending_animation);
   std::unique_ptr<PendingPageScaleAnimation> TakePendingPageScaleAnimation();
 
-  void DidUpdateScrollOffset(int layer_id);
+  void DidUpdateScrollOffset(ElementId id);
 
   // Mark the scrollbar geometries (e.g., thumb size and position) as needing an
   // update.
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index 51d0d0d..fc84ecf 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -365,7 +365,7 @@
       property_trees.transform_tree.Node(scroll_node->transform_id);
   const auto& scroll_offset = transform_node->scroll_offset;
   DCHECK(property_trees.scroll_tree.current_scroll_offset(
-             scroll_node->owning_layer_id) == scroll_offset);
+             scroll_node->element_id) == scroll_offset);
   gfx::PointF scroll_position(scroll_offset.x(), scroll_offset.y());
   if (transform_node->scrolls) {
     // The scroll position does not include snapping which shifts the scroll
@@ -1172,7 +1172,7 @@
 
 ScrollTree::ScrollTree()
     : currently_scrolling_node_id_(kInvalidNodeId),
-      layer_id_to_scroll_offset_map_(ScrollTree::ScrollOffsetMap()) {}
+      scroll_offset_map_(ScrollTree::ScrollOffsetMap()) {}
 
 ScrollTree::~ScrollTree() {}
 
@@ -1188,10 +1188,9 @@
 }
 
 bool ScrollTree::operator==(const ScrollTree& other) const {
-  if (layer_id_to_scroll_offset_map_ != other.layer_id_to_scroll_offset_map_)
+  if (scroll_offset_map_ != other.scroll_offset_map_)
     return false;
-  if (layer_id_to_synced_scroll_offset_map_ !=
-      other.layer_id_to_synced_scroll_offset_map_)
+  if (synced_scroll_offset_map_ != other.synced_scroll_offset_map_)
     return false;
 
   bool is_currently_scrolling_node_equal =
@@ -1203,9 +1202,8 @@
 #if DCHECK_IS_ON()
 void ScrollTree::CopyCompleteTreeState(const ScrollTree& other) {
   currently_scrolling_node_id_ = other.currently_scrolling_node_id_;
-  layer_id_to_scroll_offset_map_ = other.layer_id_to_scroll_offset_map_;
-  layer_id_to_synced_scroll_offset_map_ =
-      other.layer_id_to_synced_scroll_offset_map_;
+  scroll_offset_map_ = other.scroll_offset_map_;
+  synced_scroll_offset_map_ = other.synced_scroll_offset_map_;
 }
 #endif
 
@@ -1222,16 +1220,15 @@
 
   if (property_trees()->is_main_thread) {
     currently_scrolling_node_id_ = kInvalidNodeId;
-    layer_id_to_scroll_offset_map_.clear();
+    scroll_offset_map_.clear();
   }
 
 #if DCHECK_IS_ON()
   ScrollTree tree;
   if (!property_trees()->is_main_thread) {
-    DCHECK(layer_id_to_scroll_offset_map_.empty());
+    DCHECK(scroll_offset_map_.empty());
     tree.currently_scrolling_node_id_ = currently_scrolling_node_id_;
-    tree.layer_id_to_synced_scroll_offset_map_ =
-        layer_id_to_synced_scroll_offset_map_;
+    tree.synced_scroll_offset_map_ = synced_scroll_offset_map_;
   }
   DCHECK(tree == *this);
 #endif
@@ -1271,7 +1268,7 @@
   return max_offset;
 }
 
-void ScrollTree::OnScrollOffsetAnimated(int layer_id,
+void ScrollTree::OnScrollOffsetAnimated(ElementId id,
                                         int scroll_tree_index,
                                         const gfx::ScrollOffset& scroll_offset,
                                         LayerTreeImpl* layer_tree_impl) {
@@ -1281,9 +1278,9 @@
     return;
 
   ScrollNode* scroll_node = Node(scroll_tree_index);
-  if (SetScrollOffset(layer_id,
+  if (SetScrollOffset(id,
                       ClampScrollOffsetToLimits(scroll_offset, scroll_node)))
-    layer_tree_impl->DidUpdateScrollOffset(layer_id);
+    layer_tree_impl->DidUpdateScrollOffset(id);
   layer_tree_impl->DidAnimateScrollOffset();
 }
 
@@ -1343,33 +1340,28 @@
   return screen_space_transform;
 }
 
-SyncedScrollOffset* ScrollTree::GetOrCreateSyncedScrollOffset(int layer_id) {
+SyncedScrollOffset* ScrollTree::GetOrCreateSyncedScrollOffset(ElementId id) {
   DCHECK(!property_trees()->is_main_thread);
-  if (layer_id_to_synced_scroll_offset_map_.find(layer_id) ==
-      layer_id_to_synced_scroll_offset_map_.end()) {
-    layer_id_to_synced_scroll_offset_map_[layer_id] = new SyncedScrollOffset;
+  if (synced_scroll_offset_map_.find(id) == synced_scroll_offset_map_.end()) {
+    synced_scroll_offset_map_[id] = new SyncedScrollOffset;
   }
-  return layer_id_to_synced_scroll_offset_map_[layer_id].get();
+  return synced_scroll_offset_map_[id].get();
 }
 
 const SyncedScrollOffset* ScrollTree::GetSyncedScrollOffset(
-    int layer_id) const {
+    ElementId id) const {
   DCHECK(!property_trees()->is_main_thread);
-  auto it = layer_id_to_synced_scroll_offset_map_.find(layer_id);
-  return it != layer_id_to_synced_scroll_offset_map_.end() ? it->second.get()
-                                                           : nullptr;
+  auto it = synced_scroll_offset_map_.find(id);
+  return it != synced_scroll_offset_map_.end() ? it->second.get() : nullptr;
 }
 
-const gfx::ScrollOffset ScrollTree::current_scroll_offset(int layer_id) const {
+const gfx::ScrollOffset ScrollTree::current_scroll_offset(ElementId id) const {
   if (property_trees()->is_main_thread) {
-    ScrollOffsetMap::const_iterator it =
-        layer_id_to_scroll_offset_map_.find(layer_id);
-    return it != layer_id_to_scroll_offset_map_.end() ? it->second
-                                                      : gfx::ScrollOffset();
+    ScrollOffsetMap::const_iterator it = scroll_offset_map_.find(id);
+    return it != scroll_offset_map_.end() ? it->second : gfx::ScrollOffset();
   }
-  return GetSyncedScrollOffset(layer_id)
-             ? GetSyncedScrollOffset(layer_id)->Current(
-                   property_trees()->is_active)
+  return GetSyncedScrollOffset(id)
+             ? GetSyncedScrollOffset(id)->Current(property_trees()->is_active)
              : gfx::ScrollOffset();
 }
 
@@ -1392,24 +1384,25 @@
   return delta;
 }
 
-void ScrollTree::CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
-                                     int inner_viewport_layer_id) {
+void ScrollTree::CollectScrollDeltas(
+    ScrollAndScaleSet* scroll_info,
+    ElementId inner_viewport_scroll_element_id) {
   DCHECK(!property_trees()->is_main_thread);
-  for (auto map_entry : layer_id_to_synced_scroll_offset_map_) {
+  for (auto map_entry : synced_scroll_offset_map_) {
     gfx::ScrollOffset scroll_delta =
         PullDeltaForMainThread(map_entry.second.get());
 
     gfx::Vector2d scroll_delta_vector(scroll_delta.x(), scroll_delta.y());
-    int layer_id = map_entry.first;
+    ElementId id = map_entry.first;
 
     if (!scroll_delta.IsZero()) {
-      if (layer_id == inner_viewport_layer_id) {
+      if (id == inner_viewport_scroll_element_id) {
         // Inner (visual) viewport is stored separately.
-        scroll_info->inner_viewport_scroll.layer_id = layer_id;
+        scroll_info->inner_viewport_scroll.element_id = id;
         scroll_info->inner_viewport_scroll.scroll_delta = scroll_delta_vector;
       } else {
         LayerTreeHostCommon::ScrollUpdateInfo scroll;
-        scroll.layer_id = layer_id;
+        scroll.element_id = id;
         scroll.scroll_delta = scroll_delta_vector;
         scroll_info->scrolls.push_back(scroll);
       }
@@ -1418,7 +1411,7 @@
 }
 
 void ScrollTree::CollectScrollDeltasForTesting() {
-  for (auto map_entry : layer_id_to_synced_scroll_offset_map_) {
+  for (auto map_entry : synced_scroll_offset_map_) {
     PullDeltaForMainThread(map_entry.second.get());
   }
 }
@@ -1428,23 +1421,23 @@
     LayerTreeImpl* sync_tree) {
   DCHECK(!property_trees()->is_main_thread);
   const ScrollOffsetMap& main_scroll_offset_map =
-      main_property_trees->scroll_tree.layer_id_to_scroll_offset_map_;
+      main_property_trees->scroll_tree.scroll_offset_map_;
 
   // We first want to clear SyncedProperty instances for layers which were
   // destroyed or became non-scrollable on the main thread.
-  for (auto map_entry = layer_id_to_synced_scroll_offset_map_.begin();
-       map_entry != layer_id_to_synced_scroll_offset_map_.end();) {
-    int layer_id = map_entry->first;
-    if (main_scroll_offset_map.find(layer_id) == main_scroll_offset_map.end())
-      map_entry = layer_id_to_synced_scroll_offset_map_.erase(map_entry);
+  for (auto map_entry = synced_scroll_offset_map_.begin();
+       map_entry != synced_scroll_offset_map_.end();) {
+    ElementId id = map_entry->first;
+    if (main_scroll_offset_map.find(id) == main_scroll_offset_map.end())
+      map_entry = synced_scroll_offset_map_.erase(map_entry);
     else
       map_entry++;
   }
 
   for (auto map_entry : main_scroll_offset_map) {
-    int layer_id = map_entry.first;
+    ElementId id = map_entry.first;
     SyncedScrollOffset* synced_scroll_offset =
-        GetOrCreateSyncedScrollOffset(layer_id);
+        GetOrCreateSyncedScrollOffset(id);
 
     bool changed = synced_scroll_offset->PushFromMainThread(map_entry.second);
     // If we are committing directly to the active tree, push pending to active
@@ -1453,7 +1446,7 @@
       changed |= synced_scroll_offset->PushPendingToActive();
 
     if (changed)
-      sync_tree->DidUpdateScrollOffset(layer_id);
+      sync_tree->DidUpdateScrollOffset(id);
   }
 }
 
@@ -1467,10 +1460,10 @@
   // When pushing to the active tree, we can simply copy over the map from the
   // pending tree. The pending and active tree hold a reference to the same
   // SyncedProperty instances.
-  layer_id_to_synced_scroll_offset_map_.clear();
-  for (auto map_entry : pending_property_trees->scroll_tree
-                            .layer_id_to_synced_scroll_offset_map_) {
-    layer_id_to_synced_scroll_offset_map_[map_entry.first] = map_entry.second;
+  synced_scroll_offset_map_.clear();
+  for (auto map_entry :
+       pending_property_trees->scroll_tree.synced_scroll_offset_map_) {
+    synced_scroll_offset_map_[map_entry.first] = map_entry.second;
     if (map_entry.second->PushPendingToActive())
       active_tree->DidUpdateScrollOffset(map_entry.first);
   }
@@ -1478,77 +1471,75 @@
 
 void ScrollTree::ApplySentScrollDeltasFromAbortedCommit() {
   DCHECK(property_trees()->is_active);
-  for (auto& map_entry : layer_id_to_synced_scroll_offset_map_)
+  for (auto& map_entry : synced_scroll_offset_map_)
     map_entry.second->AbortCommit();
 }
 
-bool ScrollTree::SetBaseScrollOffset(int layer_id,
+bool ScrollTree::SetBaseScrollOffset(ElementId id,
                                      const gfx::ScrollOffset& scroll_offset) {
   if (property_trees()->is_main_thread) {
-    layer_id_to_scroll_offset_map_[layer_id] = scroll_offset;
+    scroll_offset_map_[id] = scroll_offset;
     return true;
   }
 
   // Scroll offset updates on the impl thread should only be for layers which
   // were created on the main thread. But this method is called when we build
   // PropertyTrees on the impl thread from LayerTreeImpl.
-  return GetOrCreateSyncedScrollOffset(layer_id)->PushFromMainThread(
-      scroll_offset);
+  return GetOrCreateSyncedScrollOffset(id)->PushFromMainThread(scroll_offset);
 }
 
-bool ScrollTree::SetScrollOffset(int layer_id,
+bool ScrollTree::SetScrollOffset(ElementId id,
                                  const gfx::ScrollOffset& scroll_offset) {
   if (property_trees()->is_main_thread) {
-    if (layer_id_to_scroll_offset_map_[layer_id] == scroll_offset)
+    if (scroll_offset_map_[id] == scroll_offset)
       return false;
-    layer_id_to_scroll_offset_map_[layer_id] = scroll_offset;
+    scroll_offset_map_[id] = scroll_offset;
     return true;
   }
 
   if (property_trees()->is_active) {
-    return GetOrCreateSyncedScrollOffset(layer_id)->SetCurrent(scroll_offset);
+    return GetOrCreateSyncedScrollOffset(id)->SetCurrent(scroll_offset);
   }
 
   return false;
 }
 
 bool ScrollTree::UpdateScrollOffsetBaseForTesting(
-    int layer_id,
+    ElementId id,
     const gfx::ScrollOffset& offset) {
   DCHECK(!property_trees()->is_main_thread);
-  SyncedScrollOffset* synced_scroll_offset =
-      GetOrCreateSyncedScrollOffset(layer_id);
+  SyncedScrollOffset* synced_scroll_offset = GetOrCreateSyncedScrollOffset(id);
   bool changed = synced_scroll_offset->PushFromMainThread(offset);
   if (property_trees()->is_active)
     changed |= synced_scroll_offset->PushPendingToActive();
   return changed;
 }
 
-bool ScrollTree::SetScrollOffsetDeltaForTesting(int layer_id,
+bool ScrollTree::SetScrollOffsetDeltaForTesting(ElementId id,
                                                 const gfx::Vector2dF& delta) {
-  return GetOrCreateSyncedScrollOffset(layer_id)->SetCurrent(
-      GetOrCreateSyncedScrollOffset(layer_id)->ActiveBase() +
+  return GetOrCreateSyncedScrollOffset(id)->SetCurrent(
+      GetOrCreateSyncedScrollOffset(id)->ActiveBase() +
       gfx::ScrollOffset(delta));
 }
 
 const gfx::ScrollOffset ScrollTree::GetScrollOffsetBaseForTesting(
-    int layer_id) const {
+    ElementId id) const {
   DCHECK(!property_trees()->is_main_thread);
-  if (GetSyncedScrollOffset(layer_id))
+  if (GetSyncedScrollOffset(id))
     return property_trees()->is_active
-               ? GetSyncedScrollOffset(layer_id)->ActiveBase()
-               : GetSyncedScrollOffset(layer_id)->PendingBase();
+               ? GetSyncedScrollOffset(id)->ActiveBase()
+               : GetSyncedScrollOffset(id)->PendingBase();
   else
     return gfx::ScrollOffset();
 }
 
 const gfx::ScrollOffset ScrollTree::GetScrollOffsetDeltaForTesting(
-    int layer_id) const {
+    ElementId id) const {
   DCHECK(!property_trees()->is_main_thread);
-  if (GetSyncedScrollOffset(layer_id))
+  if (GetSyncedScrollOffset(id))
     return property_trees()->is_active
-               ? GetSyncedScrollOffset(layer_id)->Delta()
-               : GetSyncedScrollOffset(layer_id)->PendingDelta().get();
+               ? GetSyncedScrollOffset(id)->Delta()
+               : GetSyncedScrollOffset(id)->PendingDelta().get();
   else
     return gfx::ScrollOffset();
 }
@@ -1581,12 +1572,11 @@
   if (!scroll_node->user_scrollable_vertical)
     adjusted_scroll.set_y(0);
   DCHECK(scroll_node->scrollable);
-  gfx::ScrollOffset old_offset =
-      current_scroll_offset(scroll_node->owning_layer_id);
+  gfx::ScrollOffset old_offset = current_scroll_offset(scroll_node->element_id);
   gfx::ScrollOffset new_offset =
       ClampScrollOffsetToLimits(old_offset + adjusted_scroll, scroll_node);
-  if (SetScrollOffset(scroll_node->owning_layer_id, new_offset))
-    layer_tree_impl->DidUpdateScrollOffset(scroll_node->owning_layer_id);
+  if (SetScrollOffset(scroll_node->element_id, new_offset))
+    layer_tree_impl->DidUpdateScrollOffset(scroll_node->element_id);
 
   gfx::ScrollOffset unscrolled =
       old_offset + gfx::ScrollOffset(scroll) - new_offset;
diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h
index 2efdf72..d7273fb 100644
--- a/cc/trees/property_tree.h
+++ b/cc/trees/property_tree.h
@@ -455,7 +455,7 @@
   void clear();
 
   gfx::ScrollOffset MaxScrollOffset(int scroll_node_id) const;
-  void OnScrollOffsetAnimated(int layer_id,
+  void OnScrollOffsetAnimated(ElementId id,
                               int scroll_tree_index,
                               const gfx::ScrollOffset& scroll_offset,
                               LayerTreeImpl* layer_tree_impl);
@@ -471,13 +471,13 @@
   // Returns the current scroll offset. On the main thread this would return the
   // value for the LayerTree while on the impl thread this is the current value
   // on the active tree.
-  const gfx::ScrollOffset current_scroll_offset(int layer_id) const;
+  const gfx::ScrollOffset current_scroll_offset(ElementId id) const;
 
   // Collects deltas for scroll changes on the impl thread that need to be
   // reported to the main thread during the main frame. As such, should only be
   // called on the impl thread side PropertyTrees.
   void CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
-                           int inner_viewport_layer_id);
+                           ElementId inner_viewport_scroll_element_id);
 
   // Applies deltas sent in the previous main frame onto the impl thread state.
   // Should only be called on the impl thread side PropertyTrees.
@@ -493,18 +493,18 @@
   void PushScrollUpdatesFromPendingTree(PropertyTrees* pending_property_trees,
                                         LayerTreeImpl* active_tree);
 
-  bool SetBaseScrollOffset(int layer_id,
+  bool SetBaseScrollOffset(ElementId id,
                            const gfx::ScrollOffset& scroll_offset);
-  bool SetScrollOffset(int layer_id, const gfx::ScrollOffset& scroll_offset);
-  void SetScrollOffsetClobberActiveValue(int layer_id) {
-    GetOrCreateSyncedScrollOffset(layer_id)->set_clobber_active_value();
+  bool SetScrollOffset(ElementId id, const gfx::ScrollOffset& scroll_offset);
+  void SetScrollOffsetClobberActiveValue(ElementId id) {
+    GetOrCreateSyncedScrollOffset(id)->set_clobber_active_value();
   }
-  bool UpdateScrollOffsetBaseForTesting(int layer_id,
+  bool UpdateScrollOffsetBaseForTesting(ElementId id,
                                         const gfx::ScrollOffset& offset);
-  bool SetScrollOffsetDeltaForTesting(int layer_id,
+  bool SetScrollOffsetDeltaForTesting(ElementId id,
                                       const gfx::Vector2dF& delta);
-  const gfx::ScrollOffset GetScrollOffsetBaseForTesting(int layer_id) const;
-  const gfx::ScrollOffset GetScrollOffsetDeltaForTesting(int layer_id) const;
+  const gfx::ScrollOffset GetScrollOffsetBaseForTesting(ElementId id) const;
+  const gfx::ScrollOffset GetScrollOffsetDeltaForTesting(ElementId id) const;
   void CollectScrollDeltasForTesting();
 
   void DistributeScroll(ScrollNode* scroll_node, ScrollState* scroll_state);
@@ -514,7 +514,7 @@
   gfx::ScrollOffset ClampScrollOffsetToLimits(gfx::ScrollOffset offset,
                                               ScrollNode* scroll_node) const;
 
-  const SyncedScrollOffset* GetSyncedScrollOffset(int layer_id) const;
+  const SyncedScrollOffset* GetSyncedScrollOffset(ElementId id) const;
 
 #if DCHECK_IS_ON()
   void CopyCompleteTreeState(const ScrollTree& other);
@@ -523,9 +523,9 @@
   ScrollNode* FindNodeFromElementId(ElementId id);
 
  private:
-  using ScrollOffsetMap = base::flat_map<int, gfx::ScrollOffset>;
+  using ScrollOffsetMap = base::flat_map<ElementId, gfx::ScrollOffset>;
   using SyncedScrollOffsetMap =
-      base::flat_map<int, scoped_refptr<SyncedScrollOffset>>;
+      base::flat_map<ElementId, scoped_refptr<SyncedScrollOffset>>;
 
   int currently_scrolling_node_id_;
 
@@ -534,10 +534,10 @@
   // thread stores a map of SyncedProperty instances in order to track
   // additional state necessary to synchronize scroll changes between the main
   // and impl threads.
-  ScrollOffsetMap layer_id_to_scroll_offset_map_;
-  SyncedScrollOffsetMap layer_id_to_synced_scroll_offset_map_;
+  ScrollOffsetMap scroll_offset_map_;
+  SyncedScrollOffsetMap synced_scroll_offset_map_;
 
-  SyncedScrollOffset* GetOrCreateSyncedScrollOffset(int layer_id);
+  SyncedScrollOffset* GetOrCreateSyncedScrollOffset(ElementId id);
   gfx::ScrollOffset PullDeltaForMainThread(SyncedScrollOffset* scroll_offset);
 };
 
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc
index dd1642bc..4ad6e53 100644
--- a/cc/trees/property_tree_builder.cc
+++ b/cc/trees/property_tree_builder.cc
@@ -1089,7 +1089,7 @@
 
     if (node.scrollable) {
       data_for_children->property_trees->scroll_tree.SetBaseScrollOffset(
-          layer->id(), layer->CurrentScrollOffset());
+          layer->element_id(), layer->CurrentScrollOffset());
     }
   }
 
diff --git a/cc/trees/tree_synchronizer_unittest.cc b/cc/trees/tree_synchronizer_unittest.cc
index 1def71a2..18ab0a7 100644
--- a/cc/trees/tree_synchronizer_unittest.cc
+++ b/cc/trees/tree_synchronizer_unittest.cc
@@ -559,6 +559,9 @@
   transient_scroll_layer->AddChild(scroll_clip_layer);
   scroll_clip_layer->AddChild(scroll_layer);
 
+  ElementId transient_scroll_element_id = ElementId(7);
+  transient_scroll_layer->SetElementId(transient_scroll_element_id);
+
   transient_scroll_layer->SetScrollClipLayerId(
       transient_scroll_clip_layer->id());
   scroll_layer->SetScrollClipLayerId(scroll_clip_layer->id());
@@ -585,37 +588,38 @@
       scroll_layer_offset.get(),
       host_impl->active_tree()
           ->property_trees()
-          ->scroll_tree.GetSyncedScrollOffset(scroll_layer->id())));
+          ->scroll_tree.GetSyncedScrollOffset(scroll_layer->element_id())));
 
   scoped_refptr<SyncedScrollOffset> transient_scroll_layer_offset =
       new SyncedScrollOffset;
   transient_scroll_layer_offset->PushFromMainThread(
       transient_scroll_layer->scroll_offset());
   transient_scroll_layer_offset->PushPendingToActive();
-  EXPECT_TRUE(AreScrollOffsetsEqual(
-      transient_scroll_layer_offset.get(),
-      host_impl->active_tree()
-          ->property_trees()
-          ->scroll_tree.GetSyncedScrollOffset(transient_scroll_layer->id())));
+  EXPECT_TRUE(
+      AreScrollOffsetsEqual(transient_scroll_layer_offset.get(),
+                            host_impl->active_tree()
+                                ->property_trees()
+                                ->scroll_tree.GetSyncedScrollOffset(
+                                    transient_scroll_layer->element_id())));
 
   // Set ScrollOffset active delta: gfx::ScrollOffset(10, 10)
   LayerImpl* scroll_layer_impl =
       host_impl->active_tree()->LayerById(scroll_layer->id());
   ScrollTree& scroll_tree =
       host_impl->active_tree()->property_trees()->scroll_tree;
-  scroll_tree.SetScrollOffset(scroll_layer_impl->id(),
+  scroll_tree.SetScrollOffset(scroll_layer_impl->element_id(),
                               gfx::ScrollOffset(20, 30));
 
   // Pull ScrollOffset delta for main thread, and change offset on main thread
   std::unique_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet());
-  scroll_tree.CollectScrollDeltas(scroll_info.get(), Layer::INVALID_ID);
+  scroll_tree.CollectScrollDeltas(scroll_info.get(), ElementId());
   host_->proxy()->SetNeedsCommit();
   host_->ApplyScrollAndScale(scroll_info.get());
   EXPECT_EQ(gfx::ScrollOffset(20, 30), scroll_layer->scroll_offset());
   scroll_layer->SetScrollOffset(gfx::ScrollOffset(100, 100));
 
   // More update to ScrollOffset active delta: gfx::ScrollOffset(20, 20)
-  scroll_tree.SetScrollOffset(scroll_layer_impl->id(),
+  scroll_tree.SetScrollOffset(scroll_layer_impl->element_id(),
                               gfx::ScrollOffset(40, 50));
   host_impl->active_tree()->SetCurrentlyScrollingNode(
       scroll_tree.Node(scroll_layer_impl->scroll_tree_index()));
@@ -639,11 +643,11 @@
       scroll_layer_offset.get(),
       host_impl->active_tree()
           ->property_trees()
-          ->scroll_tree.GetSyncedScrollOffset(scroll_layer->id())));
+          ->scroll_tree.GetSyncedScrollOffset(scroll_layer->element_id())));
   EXPECT_EQ(nullptr, host_impl->active_tree()
                          ->property_trees()
                          ->scroll_tree.GetSyncedScrollOffset(
-                             transient_scroll_layer->id()));
+                             transient_scroll_layer->element_id()));
 }
 
 TEST_F(TreeSynchronizerTest, RefreshPropertyTreesCachedData) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
index 9057dfe..9dfdb56 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
@@ -220,9 +220,9 @@
                 private PhotoPickerDialog mDialog;
 
                 @Override
-                public void showPhotoPicker(
-                        Context context, PhotoPickerListener listener, boolean allowMultiple) {
-                    mDialog = new PhotoPickerDialog(context, listener, allowMultiple);
+                public void showPhotoPicker(Context context, PhotoPickerListener listener,
+                        boolean allowMultiple, List<String> mimeTypes) {
+                    mDialog = new PhotoPickerDialog(context, listener, allowMultiple, mimeTypes);
                     mDialog.getWindow().getAttributes().windowAnimations =
                             R.style.PhotoPickerDialogAnimation;
                     mDialog.show();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java
index d566f9d..db9b9c2 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialog.java
@@ -14,6 +14,8 @@
 import org.chromium.chrome.R;
 import org.chromium.ui.PhotoPickerListener;
 
+import java.util.List;
+
 /**
  * UI for the photo chooser that shows on the Android platform as a result of
  * &lt;input type=file accept=image &gt; form element.
@@ -28,14 +30,15 @@
      * @param listener The listener object that gets notified when an action is taken.
      * @param multiSelectionAllowed Whether the photo picker should allow multiple items to be
      *                              selected.
+     * @param mimeTypes A list of mime types to show in the dialog.
      */
-    public PhotoPickerDialog(
-            Context context, PhotoPickerListener listener, boolean multiSelectionAllowed) {
+    public PhotoPickerDialog(Context context, PhotoPickerListener listener,
+            boolean multiSelectionAllowed, List<String> mimeTypes) {
         super(context, R.style.FullscreenWhite);
 
         // Initialize the main content view.
         mCategoryView = new PickerCategoryView(context);
-        mCategoryView.initialize(this, listener, multiSelectionAllowed);
+        mCategoryView.initialize(this, listener, multiSelectionAllowed, mimeTypes);
         setView(mCategoryView);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java
index 171718d..e276039 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java
@@ -27,7 +27,6 @@
 import org.chromium.ui.PhotoPickerListener;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -108,6 +107,9 @@
     // Whether the connection to the service has been established.
     private boolean mServiceReady;
 
+    // The MIME types requested.
+    private List<String> mMimeTypes;
+
     // A list of files to use for testing (instead of reading files on disk).
     private static List<PickerBitmap> sTestFiles;
 
@@ -127,8 +129,6 @@
         mDecoderServiceHost = new DecoderServiceHost(this);
         mDecoderServiceHost.bind(mContext);
 
-        enumerateBitmaps();
-
         mSelectionDelegate = new SelectionDelegate<PickerBitmap>();
 
         View root = LayoutInflater.from(context).inflate(R.layout.photo_picker_dialog, this);
@@ -191,14 +191,18 @@
      * @param dialog The dialog showing us.
      * @param listener The listener who should be notified of actions.
      * @param multiSelectionAllowed Whether to allow the user to select more than one image.
+     * @param mimeTypes A list of mime types to show in the dialog.
      */
-    public void initialize(
-            PhotoPickerDialog dialog, PhotoPickerListener listener, boolean multiSelectionAllowed) {
+    public void initialize(PhotoPickerDialog dialog, PhotoPickerListener listener,
+            boolean multiSelectionAllowed, List<String> mimeTypes) {
         if (!multiSelectionAllowed) mSelectionDelegate.setSingleSelectionMode();
 
         mDialog = dialog;
         mMultiSelectionAllowed = multiSelectionAllowed;
         mListener = listener;
+        mMimeTypes = new ArrayList<>(mimeTypes);
+
+        enumerateBitmaps();
 
         mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
             @Override
@@ -340,8 +344,7 @@
             mWorkerTask.cancel(true);
         }
 
-        mWorkerTask =
-                new FileEnumWorkerTask(this, new MimeTypeFileFilter(Arrays.asList("image/*")));
+        mWorkerTask = new FileEnumWorkerTask(this, new MimeTypeFileFilter(mMimeTypes));
         mWorkerTask.execute();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java
index ae7234a..a24b6ef 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java
@@ -9,13 +9,11 @@
 import android.content.Intent;
 
 import org.chromium.base.ContextUtils;
-import org.chromium.base.Log;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.chrome.browser.preferences.autofill.AutofillAndPaymentsPreferences;
 import org.chromium.chrome.browser.preferences.password.SavePasswordsPreferences;
 import org.chromium.chrome.browser.preferences.privacy.ClearBrowsingDataPreferences;
 import org.chromium.chrome.browser.preferences.privacy.ClearBrowsingDataTabsFragment;
-import org.chromium.chrome.browser.tab.Tab;
 
 /**
  * A utility class for launching Chrome Settings.
@@ -78,20 +76,4 @@
         launchSettingsPage(
                 ContextUtils.getApplicationContext(), SavePasswordsPreferences.class.getName());
     }
-
-    /**
-     * Opens the UI to clear browsing data.
-     * @param tab The tab that triggered the request.
-     */
-    @CalledByNative
-    private static void openClearBrowsingData(Tab tab) {
-        Activity activity = tab.getWindowAndroid().getActivity().get();
-        if (activity == null) {
-            Log.e(TAG, "Attempting to open clear browsing data for a tab without a valid activity");
-            return;
-        }
-
-        Intent intent = createIntentForClearBrowsingDataPage(activity);
-        activity.startActivity(intent);
-    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java
index 83cc376..6d74b14 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/photo_picker/PhotoPickerDialogTest.java
@@ -103,13 +103,14 @@
         return (RecyclerView) mDialog.findViewById(R.id.recycler_view);
     }
 
-    private PhotoPickerDialog createDialog(final boolean multiselect) throws Exception {
+    private PhotoPickerDialog createDialog(final boolean multiselect, final List<String> mimeTypes)
+            throws Exception {
         final PhotoPickerDialog dialog =
                 ThreadUtils.runOnUiThreadBlocking(new Callable<PhotoPickerDialog>() {
                     @Override
                     public PhotoPickerDialog call() {
                         final PhotoPickerDialog dialog = new PhotoPickerDialog(
-                                getActivity(), PhotoPickerDialogTest.this, multiselect);
+                                getActivity(), PhotoPickerDialogTest.this, multiselect, mimeTypes);
                         dialog.show();
                         return dialog;
                     }
@@ -170,7 +171,7 @@
 
     @LargeTest
     public void testNoSelection() throws Throwable {
-        createDialog(false); // Multi-select = false.
+        createDialog(false, Arrays.asList("image/*")); // Multi-select = false.
         assertTrue(mDialog.isShowing());
 
         int expectedSelectionCount = 1;
@@ -185,7 +186,7 @@
 
     @LargeTest
     public void testSingleSelectionPhoto() throws Throwable {
-        createDialog(false); // Multi-select = false.
+        createDialog(false, Arrays.asList("image/*")); // Multi-select = false.
         assertTrue(mDialog.isShowing());
 
         // Expected selection count is 1 because clicking on a new view unselects other.
@@ -203,7 +204,7 @@
 
     @LargeTest
     public void testMultiSelectionPhoto() throws Throwable {
-        createDialog(true); // Multi-select = true.
+        createDialog(true, Arrays.asList("image/*")); // Multi-select = true.
         assertTrue(mDialog.isShowing());
 
         // Multi-selection is enabled, so each click is counted.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java
index 1e9504f..c95d242 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTest.java
@@ -23,7 +23,6 @@
 
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisableIf;
-import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.MinAndroidSdkLevel;
 import org.chromium.base.test.util.Restriction;
 import org.chromium.chrome.R;
@@ -164,8 +163,7 @@
      * Tests that non-focused tabs cannot get pose information.
      */
     @Test
-    // @SmallTest
-    @DisabledTest(message = "Flaky. http://crbug.com/726986")
+    @SmallTest
     public void testPoseDataUnfocusedTab() throws InterruptedException {
         mVrTestRule.loadUrlAndAwaitInitialization(
                 VrTestRule.getHtmlTestFile("test_pose_data_unfocused_tab"), PAGE_LOAD_TIMEOUT_S);
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index a2b2b26..e787e8d 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -757,6 +757,15 @@
         </message>
       </if>
 
+      <if expr="toolkit_views">
+        <message name="IDS_ENTERPRISE_FORCE_SIGNOUT_EXPLANATION" desc="Text of the reason to sign out">
+          Authentication certificate failed. Please sign in to Chromium again as <ph name="USER_NAME">$1<ex>pat@example.com</ex></ph> or contact your administrator for more information. <ph name="ADDITIONAL_EXPLANATION">$2</ph>
+        </message>
+        <message name="IDS_ENTERPRISE_FORCE_SIGNOUT_EXPLANATION_WITHOUT_USER_NAME" desc="Text of the reason to sign out when there is no valid email address">
+          Authentication certificate failed. Please sign in to Chromium again or contact your administrator for more information. <ph name="ADDITIONAL_EXPLANATION">$2</ph>
+        </message>
+      </if>
+
       <!-- Signin Email Confirmation tab modal dialog -->
       <if expr="not chromeos">
         <message name="IDS_SIGNIN_EMAIL_CONFIRMATION_TITLE" desc="Title of the signin email confirmation tab modal dialog.">
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 3c74dba8..6af0496a 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -8107,6 +8107,21 @@
         This account is managed by <ph name="DOMAIN">$1<ex>example.com</ex></ph>
       </message>
 
+      <!-- Enterprise force-sign-out dialog-->
+      <message name="IDS_ENTERPRISE_FORCE_SIGNOUT_TITLE" desc="The title of the dialog shown when the user closes a browser and force sign in is enabled and local auth info is not valid.">
+        Sign in certification is not valid, window closing in <ph name="MINUTES">{0,number,00}<ex>5</ex></ph> : <ph name="SECONDS">{1,number,00}<ex>00</ex></ph>
+      </message>
+      <message name="IDS_ENTERPRISE_FORCE_SIGNOUT_CLOSE_CONFIRM" desc="Text of the button to sign in again immediately.">
+        Sign in now
+      </message>
+      <message name="IDS_ENTERPRISE_FORCE_SIGNOUT_CLOSE_DELAY" desc="Text of the button to sign in again later">
+        Cancel
+      </message>
+      <message name="IDS_ENTERPRISE_FORCE_SIGNOUT_ADDITIONAL_EXPLANATION" desc="Text of auto close warning">
+        All browser windows will soon be closed automatically without sign in.
+      </message>
+
+
       <!-- Cookies Window -->
       <message name="IDS_COOKIES_WEBSITE_PERMISSIONS_WINDOW_TITLE" desc="The title of the redesigned Cookies Window that lets you manage cookies, storage quota for websites and other permissions per-website">
         Cookies and site data
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index b3c93a2..c49a0f1 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -761,6 +761,15 @@
         </message>
       </if>
 
+      <if expr="toolkit_views">
+        <message name="IDS_ENTERPRISE_FORCE_SIGNOUT_EXPLANATION" desc="Text of the reason to sign out">
+          Authentication certificate failed. Please sign in to Google Chrome again as <ph name="USER_NAME">$1<ex>pat@example.com</ex></ph> or contact your administrator for more information. <ph name="ADDITIONAL_EXPLANATION">$2</ph>
+        </message>
+        <message name="IDS_ENTERPRISE_FORCE_SIGNOUT_EXPLANATION_WITHOUT_USER_NAME" desc="Text of the reason to sign out when there is no valid email address">
+          Authentication certificate failed. Please sign in to Google Chrome again or contact your administrator for more information. <ph name="ADDITIONAL_EXPLANATION">$2</ph>
+      </message>
+      </if>
+
       <!-- Signin Email Confirmation tab modal dialog -->
       <if expr="not chromeos">
         <message name="IDS_SIGNIN_EMAIL_CONFIRMATION_TITLE" desc="Title of the signin email confirmation tab modal dialog.">
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 0feb321..f8fb33c 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -3829,7 +3829,7 @@
 
   if (is_linux) {
     if (use_aura) {
-      deps += [ "//build/linux:fontconfig" ]
+      deps += [ "//third_party/fontconfig" ]
       if (use_dbus) {
         deps += [ "//dbus" ]
       }
diff --git a/chrome/browser/android/preferences/preferences_launcher.cc b/chrome/browser/android/preferences/preferences_launcher.cc
index 9fa570f..c2c139a 100644
--- a/chrome/browser/android/preferences/preferences_launcher.cc
+++ b/chrome/browser/android/preferences/preferences_launcher.cc
@@ -22,13 +22,5 @@
       base::android::AttachCurrentThread());
 }
 
-void PreferencesLauncher::OpenClearBrowsingData(
-    content::WebContents* web_contents) {
-  TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
-  DCHECK(tab);
-  Java_PreferencesLauncher_openClearBrowsingData(
-      base::android::AttachCurrentThread(), tab->GetJavaObject());
-}
-
 }  // namespace android
 }  // namespace chrome
diff --git a/chrome/browser/android/preferences/preferences_launcher.h b/chrome/browser/android/preferences/preferences_launcher.h
index 7e9fab5..80e8091 100644
--- a/chrome/browser/android/preferences/preferences_launcher.h
+++ b/chrome/browser/android/preferences/preferences_launcher.h
@@ -7,10 +7,6 @@
 
 #include "base/macros.h"
 
-namespace content {
-class WebContents;
-}
-
 namespace chrome {
 namespace android {
 
@@ -22,9 +18,6 @@
   // Opens the password settings page.
   static void ShowPasswordSettings();
 
-  // Open the clear browsing data UI.
-  static void OpenClearBrowsingData(content::WebContents* web_contents);
-
  private:
   PreferencesLauncher() {}
   ~PreferencesLauncher() {}
diff --git a/chrome/browser/chrome_notification_types.h b/chrome/browser/chrome_notification_types.h
index 1d72e8f1..666b99b 100644
--- a/chrome/browser/chrome_notification_types.h
+++ b/chrome/browser/chrome_notification_types.h
@@ -265,24 +265,6 @@
   // Source is the WebContents that holds the print job.
   NOTIFICATION_PRINT_JOB_RELEASED,
 
-  // Upgrade notifications ---------------------------------------------------
-
-  // Sent when Chrome believes an update has been installed and available for
-  // long enough with the user shutting down to let it take effect. See
-  // upgrade_detector.cc for details on how long it waits. No details are
-  // expected.
-  NOTIFICATION_UPGRADE_RECOMMENDED,
-
-  // Sent when a critical update has been installed. No details are expected.
-  NOTIFICATION_CRITICAL_UPGRADE_INSTALLED,
-
-  // Sent when the current install is outdated. No details are expected.
-  NOTIFICATION_OUTDATED_INSTALL,
-
-  // Sent when the current install is outdated and auto-update (AU) is disabled.
-  // No details are expected.
-  NOTIFICATION_OUTDATED_INSTALL_NO_AU,
-
   // Content Settings --------------------------------------------------------
 
   // Sent when the collect cookies dialog is shown. The source is a
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 031d14c8..363edaaa2 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -42,7 +42,6 @@
     "//ash:ash_with_content",
     "//ash/autoclick/mus/public/interfaces",
     "//ash/public/cpp:ash_public_cpp",
-    "//build/linux:fontconfig",
     "//chrome/browser/devtools",
     "//chrome/browser/extensions",
     "//chrome/browser/safe_browsing:chunk_proto",
@@ -76,6 +75,7 @@
     "//components/session_manager/core",
     "//components/sync_wifi",
     "//components/user_manager",
+    "//third_party/fontconfig",
 
     # This depends directly on the variations target, rather than just
     # transitively via the common target because the proto sources need to
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index 348bdb7..56bba14 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -218,7 +218,7 @@
     chromeos::switches::kLoginProfile,
     chromeos::switches::kNaturalScrollDefault,
     chromeos::switches::kShowMdLogin,
-    chromeos::switches::kShowNonViewMdLogin,
+    chromeos::switches::kShowNonMdLogin,
     chromeos::switches::kSystemInDevMode,
     policy::switches::kDeviceManagementUrl,
     wm::switches::kWindowAnimationsDisabled,
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.cc b/chrome/browser/chromeos/login/lock/screen_locker.cc
index 12622cf..8c0d3b7 100644
--- a/chrome/browser/chromeos/login/lock/screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock/screen_locker.cc
@@ -218,11 +218,12 @@
     views_screen_locker_->Init();
 
     // Create and display lock screen.
-    // TODO(jdufault): Calling ash::ShowLockScreenInWidget should be a mojo
-    // call. We should only set the session state to locked after the mojo call
-    // has completed.
-    if (ash::ShowLockScreen())
-      views_screen_locker_->OnLockScreenReady();
+    LockScreenClient::Get()->ShowLockScreen(base::BindOnce(
+        [](ViewsScreenLocker* screen_locker, bool did_show) {
+          CHECK(did_show);
+          screen_locker->OnLockScreenReady();
+        },
+        views_screen_locker_.get()));
   } else {
     web_ui_.reset(new WebUIScreenLocker(this));
     delegate_ = web_ui_.get();
@@ -265,6 +266,9 @@
 
   if (auth_status_consumer_)
     auth_status_consumer_->OnAuthFailure(error);
+
+  if (on_auth_complete_)
+    std::move(on_auth_complete_).Run(false);
 }
 
 void ScreenLocker::OnAuthSuccess(const UserContext& user_context) {
@@ -319,6 +323,9 @@
                             weak_factory_.GetWeakPtr()),
       base::TimeDelta::FromMilliseconds(kUnlockGuardTimeoutMs));
   delegate_->AnimateAuthenticationSuccess();
+
+  if (on_auth_complete_)
+    std::move(on_auth_complete_).Run(true);
 }
 
 void ScreenLocker::OnPasswordAuthSuccess(const UserContext& user_context) {
@@ -348,10 +355,14 @@
   chromeos::ScreenLocker::Hide();
 }
 
-void ScreenLocker::Authenticate(const UserContext& user_context) {
+void ScreenLocker::Authenticate(const UserContext& user_context,
+                                AuthenticateCallback callback) {
   LOG_ASSERT(IsUserLoggedIn(user_context.GetAccountId()))
       << "Invalid user trying to unlock.";
 
+  DCHECK(!on_auth_complete_);
+  on_auth_complete_ = std::move(callback);
+
   authentication_start_time_ = base::Time::Now();
   delegate_->SetPasswordInputEnabled(false);
   if (user_context.IsUsingPin())
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.h b/chrome/browser/chromeos/login/lock/screen_locker.h
index 0be7666c..58965642 100644
--- a/chrome/browser/chromeos/login/lock/screen_locker.h
+++ b/chrome/browser/chromeos/login/lock/screen_locker.h
@@ -102,6 +102,8 @@
     DISALLOW_COPY_AND_ASSIGN(Delegate);
   };
 
+  using AuthenticateCallback = base::OnceCallback<void(bool auth_success)>;
+
   explicit ScreenLocker(const user_manager::UserList& users);
 
   // Returns the default instance if it has been created.
@@ -127,7 +129,8 @@
   void UnlockOnLoginSuccess();
 
   // Authenticates the user with given |user_context|.
-  void Authenticate(const UserContext& user_context);
+  void Authenticate(const UserContext& user_context,
+                    AuthenticateCallback callback);
 
   // Close message bubble to clear error messages.
   void ClearErrors();
@@ -269,6 +272,9 @@
   // Type of the last unlock attempt.
   UnlockType unlock_attempt_type_ = AUTH_PASSWORD;
 
+  // Callback to run, if any, when authentication is done.
+  AuthenticateCallback on_auth_complete_;
+
   // Copy of parameters passed to last call of OnLoginSuccess for usage in
   // UnlockOnLoginSuccess().
   std::unique_ptr<AuthenticationParametersCapture> authentication_capture_;
diff --git a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
index d7f5cb1..b48de8e4 100644
--- a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
@@ -317,7 +317,8 @@
 
 void WebUIScreenLocker::Login(const UserContext& user_context,
                               const SigninSpecifics& specifics) {
-  chromeos::ScreenLocker::default_screen_locker()->Authenticate(user_context);
+  chromeos::ScreenLocker::default_screen_locker()->Authenticate(
+      user_context, ScreenLocker::AuthenticateCallback());
 }
 
 void WebUIScreenLocker::MigrateUserData(const std::string& old_password) {
diff --git a/chrome/browser/chromeos/tether/tether_service.cc b/chrome/browser/chromeos/tether/tether_service.cc
index 65fd44f4..173b014 100644
--- a/chrome/browser/chromeos/tether/tether_service.cc
+++ b/chrome/browser/chromeos/tether/tether_service.cc
@@ -183,8 +183,8 @@
   if (is_enabled != was_pref_enabled) {
     profile_->GetPrefs()->SetBoolean(prefs::kInstantTetheringEnabled,
                                      is_enabled);
-    UpdateTetherTechnologyState();
   }
+  UpdateTetherTechnologyState();
 }
 
 void TetherService::OnPrefsChanged() {
@@ -220,11 +220,14 @@
   } else if (!IsAllowedByPolicy()) {
     return chromeos::NetworkStateHandler::TechnologyState::
         TECHNOLOGY_PROHIBITED;
-  } else if (!IsBluetoothAvailable()) {
-    // TODO (hansberry): This unfortunately results in a weird UI state for
-    // Settings where the toggle is clickable but immediately becomes disabled
-    // after enabling it. Possible solution: grey out the toggle and tell the
-    // user to turn Bluetooth on?
+  } else if (!IsBluetoothAvailable() || IsCellularAvailableButNotEnabled()) {
+    // If Cellular technology is available, then Tether technology is treated
+    // as a subset of Cellular, and it should only be enabled when Cellular
+    // technology is enabled.
+    // TODO (hansberry): When !IsBluetoothAvailable(), this results in a weird
+    // UI state for Settings where the toggle is clickable but immediately
+    // becomes disabled after enabling it.  Possible solution: grey out the
+    // toggle and tell the user to turn Bluetooth on?
     return chromeos::NetworkStateHandler::TechnologyState::
         TECHNOLOGY_UNINITIALIZED;
   } else if (!IsEnabledbyPreference()) {
@@ -247,6 +250,13 @@
   return adapter_.get() && adapter_->IsPresent() && adapter_->IsPowered();
 }
 
+bool TetherService::IsCellularAvailableButNotEnabled() const {
+  return (network_state_handler_->IsTechnologyAvailable(
+              chromeos::NetworkTypePattern::Cellular()) &&
+          !network_state_handler_->IsTechnologyEnabled(
+              chromeos::NetworkTypePattern::Cellular()));
+}
+
 bool TetherService::IsAllowedByPolicy() const {
   return profile_->GetPrefs()->GetBoolean(prefs::kInstantTetheringAllowed);
 }
diff --git a/chrome/browser/chromeos/tether/tether_service.h b/chrome/browser/chromeos/tether/tether_service.h
index 27f1fface..3a97135 100644
--- a/chrome/browser/chromeos/tether/tether_service.h
+++ b/chrome/browser/chromeos/tether/tether_service.h
@@ -103,6 +103,8 @@
 
   bool IsBluetoothAvailable() const;
 
+  bool IsCellularAvailableButNotEnabled() const;
+
   // Whether Tether is allowed to be used. If the controlling preference
   // is set (from policy), this returns the preference value. Otherwise, it is
   // permitted if the flag is enabled.
diff --git a/chrome/browser/chromeos/tether/tether_service_unittest.cc b/chrome/browser/chromeos/tether/tether_service_unittest.cc
index e2a794f..9eeb2599 100644
--- a/chrome/browser/chromeos/tether/tether_service_unittest.cc
+++ b/chrome/browser/chromeos/tether/tether_service_unittest.cc
@@ -173,6 +173,13 @@
                   TECHNOLOGY_AVAILABLE);
   }
 
+  void SetCellularTechnologyStateEnabled(bool enabled) {
+    network_state_handler()->SetTechnologyEnabled(
+        chromeos::NetworkTypePattern::Cellular(), enabled,
+        chromeos::network_handler::ErrorCallback());
+    base::RunLoop().RunUntilIdle();
+  }
+
   content::TestBrowserThreadBundle thread_bundle_;
 
   std::unique_ptr<TestingProfile> profile_;
@@ -283,6 +290,72 @@
           chromeos::NetworkTypePattern::Tether()));
 }
 
+TEST_F(TetherServiceTest, TestCellularIsUnavailable) {
+  test_manager_client()->RemoveTechnology(shill::kTypeCellular);
+  ASSERT_EQ(
+      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
+      network_state_handler()->GetTechnologyState(
+          chromeos::NetworkTypePattern::Cellular()));
+
+  CreateTetherService();
+
+  SetTetherTechnologyStateEnabled(false);
+  EXPECT_EQ(
+      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE,
+      network_state_handler()->GetTechnologyState(
+          chromeos::NetworkTypePattern::Tether()));
+
+  SetTetherTechnologyStateEnabled(true);
+  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
+            network_state_handler()->GetTechnologyState(
+                chromeos::NetworkTypePattern::Tether()));
+}
+
+TEST_F(TetherServiceTest, TestCellularIsAvailable) {
+  // TODO (lesliewatkins): Investigate why cellular needs to be removed and
+  // re-added for NetworkStateHandler to return the correct TechnologyState.
+  test_manager_client()->RemoveTechnology(shill::kTypeCellular);
+  test_manager_client()->AddTechnology(shill::kTypeCellular, false);
+
+  CreateTetherService();
+
+  // Cellular disabled
+  SetCellularTechnologyStateEnabled(false);
+  ASSERT_EQ(
+      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE,
+      network_state_handler()->GetTechnologyState(
+          chromeos::NetworkTypePattern::Cellular()));
+
+  SetTetherTechnologyStateEnabled(false);
+  EXPECT_EQ(
+      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED,
+      network_state_handler()->GetTechnologyState(
+          chromeos::NetworkTypePattern::Tether()));
+
+  SetTetherTechnologyStateEnabled(true);
+  EXPECT_EQ(
+      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED,
+      network_state_handler()->GetTechnologyState(
+          chromeos::NetworkTypePattern::Tether()));
+
+  // Cellular enabled
+  SetCellularTechnologyStateEnabled(true);
+  ASSERT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
+            network_state_handler()->GetTechnologyState(
+                chromeos::NetworkTypePattern::Cellular()));
+
+  SetTetherTechnologyStateEnabled(false);
+  EXPECT_EQ(
+      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_AVAILABLE,
+      network_state_handler()->GetTechnologyState(
+          chromeos::NetworkTypePattern::Tether()));
+
+  SetTetherTechnologyStateEnabled(true);
+  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
+            network_state_handler()->GetTechnologyState(
+                chromeos::NetworkTypePattern::Tether()));
+}
+
 TEST_F(TetherServiceTest, TestEnabled) {
   CreateTetherService();
 
@@ -312,19 +385,24 @@
 // state than the user preference.
 TEST_F(TetherServiceTest, TestEnabledMultipleChanges) {
   CreateTetherService();
-  // CreateTetherService calls RunUntilIdle() so OnBluetoothAdapterFetched()
-  // will have been called which calls UpdateTetherTechnologyState().
-  EXPECT_EQ(1, tether_service_->updated_technology_state_count());
+  // CreateTetherService calls RunUntilIdle() so  UpdateTetherTechnologyState()
+  // may be called multiple times in the initialization process.
+  int updated_technology_state_count =
+      tether_service_->updated_technology_state_count();
 
   SetTetherTechnologyStateEnabled(false);
   SetTetherTechnologyStateEnabled(false);
   SetTetherTechnologyStateEnabled(false);
 
-  EXPECT_EQ(2, tether_service_->updated_technology_state_count());
+  updated_technology_state_count++;
+  EXPECT_EQ(updated_technology_state_count,
+            tether_service_->updated_technology_state_count());
 
   SetTetherTechnologyStateEnabled(true);
   SetTetherTechnologyStateEnabled(true);
   SetTetherTechnologyStateEnabled(true);
 
-  EXPECT_EQ(3, tether_service_->updated_technology_state_count());
+  updated_technology_state_count++;
+  EXPECT_EQ(updated_technology_state_count,
+            tether_service_->updated_technology_state_count());
 }
diff --git a/chrome/browser/chromeos/upgrade_detector_chromeos.cc b/chrome/browser/chromeos/upgrade_detector_chromeos.cc
index c84d67a8..ea175b00 100644
--- a/chrome/browser/chromeos/upgrade_detector_chromeos.cc
+++ b/chrome/browser/chromeos/upgrade_detector_chromeos.cc
@@ -132,7 +132,7 @@
     return;  // Not ready to recommend upgrade.
   }
 
-  NotifyUpgradeRecommended();
+  NotifyUpgrade();
 }
 
 void UpgradeDetectorChromeos::OnChannelsReceived(
diff --git a/chrome/browser/devtools/devtools_file_helper.cc b/chrome/browser/devtools/devtools_file_helper.cc
index 28599b7b..463cedea 100644
--- a/chrome/browser/devtools/devtools_file_helper.cc
+++ b/chrome/browser/devtools/devtools_file_helper.cc
@@ -212,12 +212,6 @@
       delegate_(delegate),
       weak_factory_(this) {
   pref_change_registrar_.Init(profile_->GetPrefs());
-  pref_change_registrar_.Add(prefs::kDevToolsFileSystemPaths,
-      base::Bind(&DevToolsFileHelper::FileSystemPathsSettingChanged,
-                 base::Unretained(this)));
-  file_watcher_.reset(new DevToolsFileWatcher(
-      base::Bind(&DevToolsFileHelper::FilePathsChanged,
-                 weak_factory_.GetWeakPtr())));
 }
 
 DevToolsFileHelper::~DevToolsFileHelper() {
@@ -392,6 +386,14 @@
 DevToolsFileHelper::GetFileSystems() {
   file_system_paths_ = GetAddedFileSystemPaths(profile_);
   std::vector<FileSystem> file_systems;
+  if (!file_watcher_) {
+    file_watcher_.reset(new DevToolsFileWatcher(base::Bind(
+        &DevToolsFileHelper::FilePathsChanged, weak_factory_.GetWeakPtr())));
+    pref_change_registrar_.Add(
+        prefs::kDevToolsFileSystemPaths,
+        base::Bind(&DevToolsFileHelper::FileSystemPathsSettingChanged,
+                   base::Unretained(this)));
+  }
   for (auto file_system_path : file_system_paths_) {
     base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system_path);
     std::string file_system_id = RegisterFileSystem(web_contents_, path);
@@ -428,6 +430,7 @@
 void DevToolsFileHelper::FileSystemPathsSettingChanged() {
   std::set<std::string> remaining;
   remaining.swap(file_system_paths_);
+  DCHECK(file_watcher_.get());
 
   for (auto file_system_path : GetAddedFileSystemPaths(profile_)) {
     if (remaining.find(file_system_path) == remaining.end()) {
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc
index cbdff1523..55158c2 100644
--- a/chrome/browser/devtools/devtools_ui_bindings.cc
+++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -1354,6 +1354,8 @@
 
 void DevToolsUIBindings::Reload() {
   reloading_ = true;
+  if (agent_host_)
+    agent_host_->DetachClient(this);
   web_contents_->GetController().Reload(content::ReloadType::NORMAL, false);
 }
 
@@ -1397,10 +1399,8 @@
   if (!reloading_)
     return;
   reloading_ = false;
-  if (agent_host_.get()) {
-    agent_host_->DetachClient(this);
+  if (agent_host_.get())
     agent_host_->AttachClient(this);
-  }
 }
 
 void DevToolsUIBindings::DocumentOnLoadCompletedInMainFrame() {
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index 1186a9b..1764a87 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -1032,7 +1032,7 @@
   }
 
   if (is_linux) {
-    deps += [ "//build/linux:fontconfig" ]
+    deps += [ "//third_party/fontconfig" ]
 
     if (use_dbus) {
       deps += [ "//dbus" ]
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 66bbac7..2e7bc53a 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -60,6 +60,7 @@
 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
 #include "chrome/browser/ui/webui/favicon_source.h"
 #include "chrome/browser/ui/webui/theme_source.h"
+#include "chrome/browser/upgrade_detector.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/crash_keys.h"
 #include "chrome/common/extensions/extension_constants.h"
@@ -351,12 +352,12 @@
                  content::NotificationService::AllBrowserContextsAndSources());
   registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
                  content::NotificationService::AllBrowserContextsAndSources());
-  registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
-                 content::NotificationService::AllBrowserContextsAndSources());
   registrar_.Add(this,
                  chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED,
                  content::Source<Profile>(profile_));
 
+  UpgradeDetector::GetInstance()->AddObserver(this);
+
   extensions::ExtensionManagementFactory::GetForBrowserContext(profile_)
       ->AddObserver(this);
 
@@ -413,6 +414,7 @@
 }
 
 ExtensionService::~ExtensionService() {
+  UpgradeDetector::GetInstance()->RemoveObserver(this);
   // No need to unload extensions here because they are profile-scoped, and the
   // profile is in the process of being deleted.
   for (const auto& provider : external_extension_providers_)
@@ -2248,12 +2250,6 @@
                          system_->info_map(), process->GetID()));
       break;
     }
-    case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: {
-      // Notify observers that chrome update is available.
-      for (auto& observer : update_observers_)
-        observer.OnChromeUpdateAvailable();
-      break;
-    }
     case chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED: {
       OnProfileDestructionStarted();
       break;
@@ -2359,6 +2355,12 @@
       base::Bind(&ExtensionService::ManageBlacklist, AsWeakPtr()));
 }
 
+void ExtensionService::OnUpgradeRecommended() {
+  // Notify observers that chrome update is available.
+  for (auto& observer : update_observers_)
+    observer.OnChromeUpdateAvailable();
+}
+
 void ExtensionService::ManageBlacklist(
     const extensions::Blacklist::BlacklistStateMap& state_map) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 2dca7c3..a22448b 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -22,6 +22,7 @@
 #include "chrome/browser/extensions/extension_management.h"
 #include "chrome/browser/extensions/install_gate.h"
 #include "chrome/browser/extensions/pending_extension_manager.h"
+#include "chrome/browser/upgrade_observer.h"
 #include "components/sync/model/string_ordinal.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -180,7 +181,8 @@
       public extensions::ExternalProviderInterface::VisitorInterface,
       public content::NotificationObserver,
       public extensions::Blacklist::Observer,
-      public extensions::ExtensionManagement::Observer {
+      public extensions::ExtensionManagement::Observer,
+      public UpgradeObserver {
  public:
   // Attempts to uninstall an extension from a given ExtensionService. Returns
   // true iff the target extension exists.
@@ -462,6 +464,9 @@
   // extensions::Blacklist::Observer implementation.
   void OnBlacklistUpdated() override;
 
+  // UpgradeObserver implementation.
+  void OnUpgradeRecommended() override;
+
   // Similar to FinishInstallation, but first checks if there still is an update
   // pending for the extension, and makes sure the extension is still idle.
   void MaybeFinishDelayedInstallation(const std::string& extension_id);
diff --git a/chrome/browser/media/webrtc/window_icon_util_x11.cc b/chrome/browser/media/webrtc/window_icon_util_x11.cc
index e9b34ae5..927b938 100644
--- a/chrome/browser/media/webrtc/window_icon_util_x11.cc
+++ b/chrome/browser/media/webrtc/window_icon_util_x11.cc
@@ -8,6 +8,7 @@
 #include <X11/Xutil.h>
 
 #include "ui/base/x/x11_util.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_error_tracker.h"
 #include "ui/gfx/x/x11_types.h"
 
@@ -15,7 +16,7 @@
   DCHECK(id.type == content::DesktopMediaID::TYPE_WINDOW);
 
   Display* display = gfx::GetXDisplay();
-  Atom property = ui::GetAtom("_NET_WM_ICON");
+  Atom property = gfx::GetAtom("_NET_WM_ICON");
   Atom actual_type;
   int actual_format;
   unsigned long bytes_after;  // NOLINT: type required by XGetWindowProperty
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index b6c0edbd..0c9d90c2 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -424,12 +424,14 @@
 }
 
 void ChromePasswordManagerClient::CheckProtectedPasswordEntry(
-    const std::string& password_saved_domain) {
+    const std::string& password_saved_domain,
+    bool password_field_exists) {
   safe_browsing::PasswordProtectionService* pps =
       GetPasswordProtectionService();
   if (pps) {
     pps->MaybeStartProtectedPasswordEntryRequest(
-        web_contents(), GetMainFrameURL(), password_saved_domain);
+        web_contents(), GetMainFrameURL(), password_saved_domain,
+        password_field_exists);
   }
 }
 #endif
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index 9ec30cf..dc920d3 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -111,8 +111,8 @@
   void CheckSafeBrowsingReputation(const GURL& form_action,
                                    const GURL& frame_url) override;
 
-  void CheckProtectedPasswordEntry(
-      const std::string& password_saved_domain) override;
+  void CheckProtectedPasswordEntry(const std::string& password_saved_domain,
+                                   bool password_field_exists) override;
 #endif
 
   static void CreateForWebContentsWithAutofillClient(
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index de65bda..eb0011af 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -87,8 +87,8 @@
   MOCK_METHOD0(IsHistorySyncEnabled, bool());
   MOCK_METHOD4(MaybeStartPasswordFieldOnFocusRequest,
                void(WebContents*, const GURL&, const GURL&, const GURL&));
-  MOCK_METHOD3(MaybeStartProtectedPasswordEntryRequest,
-               void(WebContents*, const GURL&, const std::string&));
+  MOCK_METHOD4(MaybeStartProtectedPasswordEntryRequest,
+               void(WebContents*, const GURL&, const std::string&, bool));
   MOCK_METHOD3(ShowPhishingInterstitial,
                void(const GURL&, const std::string&, content::WebContents*));
 
@@ -635,9 +635,9 @@
   std::unique_ptr<MockChromePasswordManagerClient> client(
       new MockChromePasswordManagerClient(test_web_contents.get()));
   EXPECT_CALL(*client->password_protection_service(),
-              MaybeStartProtectedPasswordEntryRequest(_, _, _))
+              MaybeStartProtectedPasswordEntryRequest(_, _, _, true))
       .Times(1);
-  client->CheckProtectedPasswordEntry(std::string("saved_domain.com"));
+  client->CheckProtectedPasswordEntry(std::string("saved_domain.com"), true);
 }
 
 #endif
diff --git a/chrome/browser/resources/settings/search_engines_page/search_engines_page.js b/chrome/browser/resources/settings/search_engines_page/search_engines_page.js
index f5cccbd..526b22ab 100644
--- a/chrome/browser/resources/settings/search_engines_page/search_engines_page.js
+++ b/chrome/browser/resources/settings/search_engines_page/search_engines_page.js
@@ -81,7 +81,13 @@
    */
   enginesChanged_: function(searchEnginesInfo) {
     this.defaultEngines = searchEnginesInfo['defaults'];
-    this.otherEngines = searchEnginesInfo['others'];
+
+    // Sort |otherEngines| in alphabetical order.
+    this.otherEngines = searchEnginesInfo['others'].sort(function(a, b) {
+      return a.name.toLocaleLowerCase().localeCompare(
+          b.name.toLocaleLowerCase());
+    });
+
     this.extensions = searchEnginesInfo['extensions'];
   },
 
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
index 348c10c5..e7670c2 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
@@ -134,7 +134,7 @@
   void InitializeRequest(LoginReputationClientRequest::TriggerType type) {
     request_ = new PasswordProtectionRequest(web_contents(), GURL(kPhishingURL),
                                              GURL(), GURL(), std::string(),
-                                             type, service_.get(), 0);
+                                             type, true, service_.get(), 0);
   }
 
   void InitializeVerdict(LoginReputationClientResponse::VerdictType type) {
diff --git a/chrome/browser/service_process/service_process_control.cc b/chrome/browser/service_process/service_process_control.cc
index c049900..887ca122 100644
--- a/chrome/browser/service_process/service_process_control.cc
+++ b/chrome/browser/service_process/service_process_control.cc
@@ -25,12 +25,10 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/upgrade_detector.h"
 #include "chrome/common/service_messages.h"
 #include "chrome/common/service_process_util.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_service.h"
 #include "ipc/ipc_channel_mojo.h"
 #include "mojo/edk/embedder/embedder.h"
 #include "mojo/edk/embedder/named_platform_handle.h"
@@ -87,9 +85,13 @@
 }  // namespace
 
 // ServiceProcessControl implementation.
-ServiceProcessControl::ServiceProcessControl() : weak_factory_(this) {}
+ServiceProcessControl::ServiceProcessControl()
+    : apply_changes_from_upgrade_observer_(false), weak_factory_(this) {
+  UpgradeDetector::GetInstance()->AddObserver(this);
+}
 
 ServiceProcessControl::~ServiceProcessControl() {
+  UpgradeDetector::GetInstance()->RemoveObserver(this);
 }
 
 void ServiceProcessControl::ConnectInternal() {
@@ -242,13 +244,11 @@
 
   // We just established a channel with the service process. Notify it if an
   // upgrade is available.
-  if (UpgradeDetector::GetInstance()->notify_upgrade()) {
+  if (UpgradeDetector::GetInstance()->notify_upgrade())
     Send(new ServiceMsg_UpdateAvailable);
-  } else {
-    if (registrar_.IsEmpty())
-      registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
-                     content::NotificationService::AllSources());
-  }
+  else
+    apply_changes_from_upgrade_observer_ = true;
+
   RunConnectDoneTasks();
 }
 
@@ -270,13 +270,9 @@
   return channel_->Send(message);
 }
 
-// content::NotificationObserver implementation.
-void ServiceProcessControl::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-  DCHECK_EQ(chrome::NOTIFICATION_UPGRADE_RECOMMENDED, type);
-  Send(new ServiceMsg_UpdateAvailable);
+void ServiceProcessControl::OnUpgradeRecommended() {
+  if (apply_changes_from_upgrade_observer_)
+    Send(new ServiceMsg_UpdateAvailable);
 }
 
 void ServiceProcessControl::OnCloudPrintProxyInfo(
diff --git a/chrome/browser/service_process/service_process_control.h b/chrome/browser/service_process/service_process_control.h
index 80210d0a..d6801627 100644
--- a/chrome/browser/service_process/service_process_control.h
+++ b/chrome/browser/service_process/service_process_control.h
@@ -20,8 +20,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/process/process.h"
 #include "build/build_config.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
+#include "chrome/browser/upgrade_observer.h"
 #include "ipc/ipc_channel_proxy.h"
 #include "ipc/ipc_listener.h"
 #include "ipc/ipc_sender.h"
@@ -52,7 +51,7 @@
 // talks to the IPC channel on the IO thread.
 class ServiceProcessControl : public IPC::Sender,
                               public IPC::Listener,
-                              public content::NotificationObserver {
+                              public UpgradeObserver {
  public:
   enum ServiceProcessEvent {
     SERVICE_EVENT_INITIALIZE,
@@ -114,10 +113,8 @@
   // IPC::Sender implementation
   bool Send(IPC::Message* message) override;
 
-  // content::NotificationObserver implementation.
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
+  // UpgradeObserver implementation.
+  void OnUpgradeRecommended() override;
 
   // Send a shutdown message to the service process. IPC channel will be
   // destroyed after calling this method.
@@ -241,12 +238,15 @@
   // the service process.
   base::Closure histograms_callback_;
 
-  content::NotificationRegistrar registrar_;
-
   // Callback that gets invoked if service didn't reply in time.
   base::CancelableClosure histograms_timeout_callback_;
 
+  // If true changes to UpgradeObserver are applied, if false they are ignored.
+  bool apply_changes_from_upgrade_observer_;
+
   base::WeakPtrFactory<ServiceProcessControl> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ServiceProcessControl);
 };
 
 #endif  // CHROME_BROWSER_SERVICE_PROCESS_SERVICE_PROCESS_CONTROL_H_
diff --git a/chrome/browser/sessions/better_session_restore_browsertest.cc b/chrome/browser/sessions/better_session_restore_browsertest.cc
index 3b1a30a..4619174 100644
--- a/chrome/browser/sessions/better_session_restore_browsertest.cc
+++ b/chrome/browser/sessions/better_session_restore_browsertest.cc
@@ -433,8 +433,8 @@
       ->SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
 }
 
-// Crashes on Mac only. http://crbug.com/656211
-#if defined(OS_MACOSX)
+// Crashes on Mac and Windows. http://crbug.com/656211
+#if defined(OS_MACOSX) || defined(OS_WIN)
 #define MAYBE_LocalStorageClearedOnExit DISABLED_LocalStorageClearedOnExit
 #else
 #define MAYBE_LocalStorageClearedOnExit LocalStorageClearedOnExit
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 11a6a60..0c512601 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -209,8 +209,6 @@
     "webui/about_ui.h",
     "webui/bluetooth_internals/bluetooth_internals_ui.cc",
     "webui/bluetooth_internals/bluetooth_internals_ui.h",
-    "webui/browsing_history_handler.cc",
-    "webui/browsing_history_handler.h",
     "webui/chrome_web_ui_controller_factory.cc",
     "webui/chrome_web_ui_controller_factory.h",
     "webui/chromeos/bluetooth_pairing_ui.cc",
@@ -912,6 +910,8 @@
       "webui/app_launcher_login_handler.h",
       "webui/bookmarks_ui.cc",
       "webui/bookmarks_ui.h",
+      "webui/browsing_history_handler.cc",
+      "webui/browsing_history_handler.h",
       "webui/chrome_web_contents_handler.cc",
       "webui/chrome_web_contents_handler.h",
       "webui/constrained_web_dialog_delegate_base.cc",
@@ -1639,6 +1639,8 @@
         "views/frame/opaque_browser_frame_view_linux.h",
         "views/frame/opaque_browser_frame_view_platform_specific.cc",
         "views/frame/opaque_browser_frame_view_platform_specific.h",
+        "views/profiles/forced_reauthentication_dialog.cc",
+        "views/profiles/forced_reauthentication_dialog.h",
         "views/profiles/profile_chooser_view.cc",
         "views/profiles/profile_chooser_view.h",
         "views/screen_capture_notification_ui_views.cc",
@@ -1970,6 +1972,7 @@
         ]
       }
     }
+
     if (use_ash) {
       sources += [
         "views/frame/browser_frame_ash.cc",
@@ -3217,7 +3220,7 @@
       "webui/certificate_viewer_webui.h",
     ]
     if (use_aura) {
-      deps += [ "//build/linux:fontconfig" ]
+      deps += [ "//third_party/fontconfig" ]
       if (use_dbus) {
         deps += [ "//dbus" ]
       }
diff --git a/chrome/browser/ui/ash/lock_screen_client.cc b/chrome/browser/ui/ash/lock_screen_client.cc
index d42c00a..802366a5 100644
--- a/chrome/browser/ui/ash/lock_screen_client.cc
+++ b/chrome/browser/ui/ash/lock_screen_client.cc
@@ -41,7 +41,8 @@
 
 void LockScreenClient::AuthenticateUser(const AccountId& account_id,
                                         const std::string& hashed_password,
-                                        bool authenticated_by_pin) {
+                                        bool authenticated_by_pin,
+                                        AuthenticateUserCallback callback) {
   // TODO(xiaoyinh): Complete the implementation below.
   // It should be similar as SigninScreenHandler::HandleAuthenticateUser.
   chromeos::UserContext user_context(account_id);
@@ -49,7 +50,13 @@
                     std::string(), hashed_password);
   user_context.SetKey(key);
   user_context.SetIsUsingPin(authenticated_by_pin);
-  chromeos::ScreenLocker::default_screen_locker()->Authenticate(user_context);
+  chromeos::ScreenLocker::default_screen_locker()->Authenticate(
+      user_context, std::move(callback));
+}
+
+void LockScreenClient::ShowLockScreen(
+    ash::mojom::LockScreen::ShowLockScreenCallback on_shown) {
+  lock_screen_->ShowLockScreen(std::move(on_shown));
 }
 
 void LockScreenClient::AttemptUnlock(const AccountId& account_id) {
diff --git a/chrome/browser/ui/ash/lock_screen_client.h b/chrome/browser/ui/ash/lock_screen_client.h
index bb5d5431..d33c5de 100644
--- a/chrome/browser/ui/ash/lock_screen_client.h
+++ b/chrome/browser/ui/ash/lock_screen_client.h
@@ -9,8 +9,8 @@
 #include "base/macros.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
-// Handles method calls delegated back to chrome from ash. Also notifies ash of
-// relevant state changes in chrome.
+// Handles method calls sent from ash to chrome. Also sends messages from chrome
+// to ash.
 class LockScreenClient : public ash::mojom::LockScreenClient {
  public:
   LockScreenClient();
@@ -34,12 +34,14 @@
   // ash::mojom::LockScreenClient:
   void AuthenticateUser(const AccountId& account_id,
                         const std::string& hashed_password,
-                        bool authenticated_by_pin) override;
+                        bool authenticated_by_pin,
+                        AuthenticateUserCallback callback) override;
   void AttemptUnlock(const AccountId& account_id) override;
   void HardlockPod(const AccountId& account_id) override;
   void RecordClickOnLockIcon(const AccountId& account_id) override;
 
   // Wrappers around the mojom::LockScreen interface.
+  void ShowLockScreen(ash::mojom::LockScreen::ShowLockScreenCallback on_shown);
   void ShowErrorMessage(int32_t login_attempts,
                         const std::string& error_text,
                         const std::string& help_link_text,
diff --git a/chrome/browser/ui/ash/system_tray_client.cc b/chrome/browser/ui/ash/system_tray_client.cc
index 9821513f..0db2e059 100644
--- a/chrome/browser/ui/ash/system_tray_client.cc
+++ b/chrome/browser/ui/ash/system_tray_client.cc
@@ -13,7 +13,6 @@
 #include "base/metrics/user_metrics.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_util.h"
 #include "chrome/browser/chromeos/bluetooth/bluetooth_pairing_dialog.h"
 #include "chrome/browser/chromeos/login/help_app_launcher.h"
@@ -44,7 +43,6 @@
 #include "chromeos/network/tether_constants.h"
 #include "components/session_manager/core/session_manager.h"
 #include "components/user_manager/user_manager.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/common/service_manager_connection.h"
 #include "device/bluetooth/bluetooth_device.h"
 #include "extensions/browser/api/vpn_provider/vpn_service.h"
@@ -108,9 +106,6 @@
   // be queued on |system_tray_|.
   g_browser_process->platform_part()->GetSystemClock()->AddObserver(this);
 
-  registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
-                 content::NotificationService::AllSources());
-
   // If an upgrade is available at startup then tell ash about it.
   if (UpgradeDetector::GetInstance()->notify_upgrade())
     HandleUpdateAvailable();
@@ -483,19 +478,16 @@
   system_tray_->SetUse24HourClock(clock->ShouldUse24HourClock());
 }
 
-void SystemTrayClient::Observe(int type,
-                               const content::NotificationSource& source,
-                               const content::NotificationDetails& details) {
-  DCHECK_EQ(chrome::NOTIFICATION_UPGRADE_RECOMMENDED, type);
-  HandleUpdateAvailable();
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // UpgradeDetector::UpgradeObserver:
 void SystemTrayClient::OnUpdateOverCellularAvailable() {
   HandleUpdateOverCellularAvailable();
 }
 
+void SystemTrayClient::OnUpgradeRecommended() {
+  HandleUpdateAvailable();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // policy::CloudPolicyStore::Observer
 void SystemTrayClient::OnStoreLoaded(policy::CloudPolicyStore* store) {
diff --git a/chrome/browser/ui/ash/system_tray_client.h b/chrome/browser/ui/ash/system_tray_client.h
index 12fa7915..1237ff224 100644
--- a/chrome/browser/ui/ash/system_tray_client.h
+++ b/chrome/browser/ui/ash/system_tray_client.h
@@ -10,8 +10,6 @@
 #include "chrome/browser/chromeos/system/system_clock_observer.h"
 #include "chrome/browser/upgrade_observer.h"
 #include "components/policy/core/common/cloud/cloud_policy_store.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
 namespace ash {
@@ -29,7 +27,6 @@
 class SystemTrayClient : public ash::mojom::SystemTrayClient,
                          public chromeos::system::SystemClockObserver,
                          public policy::CloudPolicyStore::Observer,
-                         public content::NotificationObserver,
                          public UpgradeObserver {
  public:
   SystemTrayClient();
@@ -101,8 +98,9 @@
   // chromeos::system::SystemClockObserver:
   void OnSystemClockChanged(chromeos::system::SystemClock* clock) override;
 
-  // UpgradeObserver:
+  // UpgradeObserver implementation.
   void OnUpdateOverCellularAvailable() override;
+  void OnUpgradeRecommended() override;
 
   // policy::CloudPolicyStore::Observer
   void OnStoreLoaded(policy::CloudPolicyStore* store) override;
@@ -110,11 +108,6 @@
 
   void UpdateEnterpriseDomain();
 
-  // content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
-
   // System tray mojo service in ash.
   ash::mojom::SystemTrayPtr system_tray_;
 
@@ -129,8 +122,6 @@
   std::string last_enterprise_domain_;
   bool last_active_directory_managed_ = false;
 
-  content::NotificationRegistrar registrar_;
-
   DISALLOW_COPY_AND_ASSIGN(SystemTrayClient);
 };
 
diff --git a/chrome/browser/ui/ash/system_tray_client_browsertest.cc b/chrome/browser/ui/ash/system_tray_client_browsertest.cc
index 63f22ad..a85d76f 100644
--- a/chrome/browser/ui/ash/system_tray_client_browsertest.cc
+++ b/chrome/browser/ui/ash/system_tray_client_browsertest.cc
@@ -35,7 +35,7 @@
   EXPECT_FALSE(tray_update->tray_view()->visible());
 
   // Simulate an upgrade. This sends a mojo message to ash.
-  UpgradeDetector::GetInstance()->NotifyUpgradeRecommended();
+  UpgradeDetector::GetInstance()->NotifyUpgrade();
   content::RunAllPendingInMessageLoop();
 
   // Tray icon is now visible.
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 5458271..72c580bf 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browsing_data/browsing_data_helper.h"
 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/devtools/devtools_window.h"
 #include "chrome/browser/dom_distiller/tab_utils.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
@@ -75,7 +74,6 @@
 #include "content/public/browser/devtools_agent_host.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/browser/page_navigator.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
@@ -1139,15 +1137,9 @@
 
 void OpenUpdateChromeDialog(Browser* browser) {
   if (UpgradeDetector::GetInstance()->is_outdated_install()) {
-    content::NotificationService::current()->Notify(
-        chrome::NOTIFICATION_OUTDATED_INSTALL,
-        content::NotificationService::AllSources(),
-        content::NotificationService::NoDetails());
+    UpgradeDetector::GetInstance()->NotifyOutdatedInstall();
   } else if (UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
-    content::NotificationService::current()->Notify(
-        chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU,
-        content::NotificationService::AllSources(),
-        content::NotificationService::NoDetails());
+    UpgradeDetector::GetInstance()->NotifyOutdatedInstallNoAutoUpdate();
   } else {
     base::RecordAction(UserMetricsAction("UpdateChrome"));
     browser->window()->ShowUpdateChromeDialog();
diff --git a/chrome/browser/ui/toolbar/app_menu_icon_controller.cc b/chrome/browser/ui/toolbar/app_menu_icon_controller.cc
index 2d67da2..79b6acb 100644
--- a/chrome/browser/ui/toolbar/app_menu_icon_controller.cc
+++ b/chrome/browser/ui/toolbar/app_menu_icon_controller.cc
@@ -71,11 +71,11 @@
   DCHECK(profile_);
   DCHECK(delegate_);
 
-  registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
-                 content::NotificationService::AllSources());
   registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED,
                  content::Source<Profile>(profile_));
 
+  UpgradeDetector::GetInstance()->AddObserver(this);
+
 #if defined(OS_WIN)
   auto* modules = EnumerateModulesModel::GetInstance();
   modules->AddObserver(this);
@@ -84,6 +84,8 @@
 }
 
 AppMenuIconController::~AppMenuIconController() {
+  UpgradeDetector::GetInstance()->RemoveObserver(this);
+
 #if defined(OS_WIN)
   EnumerateModulesModel::GetInstance()->RemoveObserver(this);
 #endif
@@ -131,5 +133,10 @@
     int type,
     const content::NotificationSource& source,
     const content::NotificationDetails& details) {
+  DCHECK_EQ(chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED, type);
+  UpdateDelegate();
+}
+
+void AppMenuIconController::OnUpgradeRecommended() {
   UpdateDelegate();
 }
diff --git a/chrome/browser/ui/toolbar/app_menu_icon_controller.h b/chrome/browser/ui/toolbar/app_menu_icon_controller.h
index 81f6a75..2e7a98e5 100644
--- a/chrome/browser/ui/toolbar/app_menu_icon_controller.h
+++ b/chrome/browser/ui/toolbar/app_menu_icon_controller.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_TOOLBAR_APP_MENU_ICON_CONTROLLER_H_
 
 #include "base/macros.h"
+#include "chrome/browser/upgrade_observer.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -23,7 +24,8 @@
 #if defined(OS_WIN)
     public EnumerateModulesModel::Observer,
 #endif
-    public content::NotificationObserver {
+    public content::NotificationObserver,
+    public UpgradeObserver {
  public:
   enum class IconType {
     NONE,
@@ -69,6 +71,9 @@
                const content::NotificationSource& source,
                const content::NotificationDetails& details) override;
 
+  // UpgradeObserver implementation.
+  void OnUpgradeRecommended() override;
+
 #if defined(OS_WIN)
   // EnumerateModulesModel:
   void OnScanCompleted() override;
diff --git a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
index af9e915..df9bb751 100644
--- a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
+++ b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
@@ -127,7 +127,7 @@
   EXPECT_GT(itemCount, 10);
 
   UpgradeDetector* detector = UpgradeDetector::GetInstance();
-  detector->NotifyUpgradeRecommended();
+  detector->NotifyUpgrade();
   EXPECT_TRUE(detector->notify_upgrade());
   EXPECT_EQ(browser_defaults::kShowUpgradeMenuItem,
             model.IsCommandIdVisible(IDC_UPGRADE_DIALOG));
diff --git a/chrome/browser/ui/views/browser_modal_dialog_unittest.cc b/chrome/browser/ui/views/browser_modal_dialog_unittest.cc
new file mode 100644
index 0000000..1f3387d6
--- /dev/null
+++ b/chrome/browser/ui/views/browser_modal_dialog_unittest.cc
@@ -0,0 +1,55 @@
+// 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 "chrome/browser/ui/views/browser_modal_dialog.h"
+
+#include <memory>
+
+#include "base/memory/ptr_util.h"
+#include "chrome/browser/ui/browser.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::Return;
+
+class MockBrowserModalDialog : public BrowserModalDialog {
+ public:
+  MockBrowserModalDialog() {
+    BrowserModalDialogList::GetInstance()->AddDialog(this);
+  }
+  ~MockBrowserModalDialog() override {
+    BrowserModalDialogList::GetInstance()->RemoveDialog(this);
+  }
+  MOCK_METHOD1(ActivateModalDialog, void(Browser*));
+  MOCK_METHOD0(IsShowing, bool());
+};
+
+class BrowserModalDialogTest : public ::testing::Test {
+ public:
+  BrowserModalDialogTest() {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BrowserModalDialogTest);
+};
+
+TEST_F(BrowserModalDialogTest, ShowDialog) {
+  BrowserModalDialogList* dialog_list = BrowserModalDialogList::GetInstance();
+  ASSERT_FALSE(dialog_list->IsShowing());
+  MockBrowserModalDialog dialog;
+  EXPECT_CALL(dialog, IsShowing()).Times(2).WillRepeatedly(Return(true));
+  EXPECT_CALL(dialog, ActivateModalDialog(_)).Times(1);
+  ASSERT_TRUE(dialog_list->IsShowing());
+  dialog_list->ActivateModalDialog(nullptr);
+}
+
+TEST_F(BrowserModalDialogTest, RemoveDialog) {
+  BrowserModalDialogList* dialog_list = BrowserModalDialogList::GetInstance();
+  std::unique_ptr<MockBrowserModalDialog> dialog =
+      base::MakeUnique<MockBrowserModalDialog>();
+  EXPECT_CALL(*dialog, IsShowing()).Times(1).WillRepeatedly(Return(true));
+  ASSERT_TRUE(dialog_list->IsShowing());
+  dialog.reset();
+  ASSERT_FALSE(dialog_list->IsShowing());
+}
diff --git a/chrome/browser/ui/views/profiles/forced_reauthentication_dialog.cc b/chrome/browser/ui/views/profiles/forced_reauthentication_dialog.cc
new file mode 100644
index 0000000..dcf0c489
--- /dev/null
+++ b/chrome/browser/ui/views/profiles/forced_reauthentication_dialog.cc
@@ -0,0 +1,250 @@
+// 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 "chrome/browser/ui/views/profiles/forced_reauthentication_dialog.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/i18n/message_formatter.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/sync/profile_signin_confirmation_helper.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/grit/chromium_strings.h"
+#include "chrome/grit/generated_resources.h"
+#include "components/constrained_window/constrained_window_views.h"
+#include "components/signin/core/browser/signin_manager.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/views/background.h"
+#include "ui/views/border.h"
+#include "ui/views/controls/styled_label.h"
+#include "ui/views/layout/grid_layout.h"
+#include "ui/views/layout/layout_constants.h"
+#include "ui/views/layout/layout_provider.h"
+#include "ui/views/view.h"
+#include "ui/views/window/dialog_client_view.h"
+
+namespace {
+
+// Refresh title of the dialog every second.
+constexpr int kRefreshTitleTimer = 1;
+
+// If browser windows are going to be closed soon, close browser window before
+// showing sign in dialog because there might not be enough time for user to
+// finish sign in.
+constexpr int kCloseDirectlyTimer = 60;
+
+void Signout(SigninManager* signin_manager) {
+  signin_manager->SignOut(
+      signin_metrics::AUTHENTICATION_FAILED_WITH_FORCE_SIGNIN,
+      signin_metrics::SignoutDelete::KEEPING);
+}
+
+bool IsMatchingBrowser(Browser* browser, Profile* profile) {
+  return browser->profile()->GetOriginalProfile() ==
+             profile->GetOriginalProfile() &&
+         !browser->tab_strip_model()->empty() &&
+         BrowserView::GetBrowserViewForBrowser(browser)->frame()->IsVisible();
+}
+
+// Find a browser that is assoicated with |profile| to show the dialog for
+// Sign out warning.
+Browser* FindBrowserWithProfile(Profile* profile) {
+  Browser* browser = BrowserList::GetInstance()->GetLastActive();
+  if (browser && IsMatchingBrowser(browser, profile))
+    return browser;
+  for (auto* browser : *BrowserList::GetInstance()) {
+    if (IsMatchingBrowser(browser, profile)) {
+      return browser;
+    }
+  }
+  return nullptr;
+}
+
+// PromptLabel overrides the default insets of StyledLabel.
+class PromptLabel : public views::StyledLabel {
+ public:
+  PromptLabel(const base::string16& text, views::StyledLabelListener* listener)
+      : views::StyledLabel(text, listener) {}
+
+  gfx::Insets GetInsets() const override {
+    return views::LayoutProvider::Get()->GetInsetsMetric(
+        views::INSETS_DIALOG_CONTENTS);
+  }
+};
+
+}  // namespace
+
+ForcedReauthenticationDialog::ForcedReauthenticationDialog(
+    Browser* browser,
+    SigninManager* signin_manager,
+    const base::TimeDelta& countdown_duration)
+    : browser_(browser),
+      signin_manager_(signin_manager),
+      desired_close_time_(base::TimeTicks::Now() + countdown_duration) {
+  constrained_window::CreateBrowserModalDialogViews(
+      this, browser->window()->GetNativeWindow())
+      ->Show();
+  browser->window()->FlashFrame(true);
+  browser->window()->Activate();
+}
+
+ForcedReauthenticationDialog::~ForcedReauthenticationDialog() {}
+
+// static
+ForcedReauthenticationDialog* ForcedReauthenticationDialog::ShowDialog(
+    Profile* profile,
+    SigninManager* signin_manager,
+    const base::TimeDelta& countdown_duration) {
+  Browser* browser = FindBrowserWithProfile(profile);
+  if (browser == nullptr) {  // If there is no browser, we can just sign
+                             // out profile directly.
+    Signout(signin_manager);
+    return nullptr;
+  }
+
+  return new ForcedReauthenticationDialog(browser, signin_manager,
+                                          countdown_duration);
+}
+
+bool ForcedReauthenticationDialog::Accept() {
+  if (GetTimeRemaining() < base::TimeDelta::FromSeconds(kCloseDirectlyTimer)) {
+    Signout(signin_manager_);
+  } else {
+    browser_->signin_view_controller()->ShowModalSignin(
+        profiles::BubbleViewMode::BUBBLE_VIEW_MODE_GAIA_REAUTH, browser_,
+        signin_metrics::AccessPoint::ACCESS_POINT_FORCE_SIGNIN_WARNING);
+  }
+  return true;
+}
+
+bool ForcedReauthenticationDialog::Cancel() {
+  return true;
+}
+
+void ForcedReauthenticationDialog::WindowClosing() {
+  refresh_timer_.Stop();
+}
+
+base::string16 ForcedReauthenticationDialog::GetWindowTitle() const {
+  base::TimeDelta time_left = GetTimeRemaining();
+  return base::i18n::MessageFormatter::FormatWithNumberedArgs(
+      l10n_util::GetStringUTF16(IDS_ENTERPRISE_FORCE_SIGNOUT_TITLE),
+      time_left.InMinutes(), time_left.InSeconds() % 60);
+}
+
+base::string16 ForcedReauthenticationDialog::GetDialogButtonLabel(
+    ui::DialogButton button) const {
+  if (button == ui::DIALOG_BUTTON_OK) {
+    return l10n_util::GetStringUTF16(
+        IDS_ENTERPRISE_FORCE_SIGNOUT_CLOSE_CONFIRM);
+  }
+  return l10n_util::GetStringUTF16(IDS_ENTERPRISE_FORCE_SIGNOUT_CLOSE_DELAY);
+}
+
+ui::ModalType ForcedReauthenticationDialog::GetModalType() const {
+  return ui::MODAL_TYPE_WINDOW;
+}
+
+void ForcedReauthenticationDialog::AddedToWidget() {
+  const SkColor prompt_bar_background_color =
+      GetSigninConfirmationPromptBarColor(
+          GetNativeTheme(), ui::kSigninConfirmationPromptBarBackgroundAlpha);
+  // Create the prompt label.
+  size_t offset;
+  std::string email = signin_manager_->GetAuthenticatedAccountInfo().email;
+  const base::string16 domain =
+      base::ASCIIToUTF16(gaia::ExtractDomainName(email));
+  const base::string16 prompt_text =
+      l10n_util::GetStringFUTF16(IDS_ENTERPRISE_SIGNIN_ALERT, domain, &offset);
+
+  // Create the prompt label.
+  PromptLabel* prompt_label = new PromptLabel(prompt_text, nullptr);
+  prompt_label->SetDisplayedOnBackgroundColor(prompt_bar_background_color);
+
+  views::StyledLabel::RangeStyleInfo bold_style;
+  bold_style.weight = gfx::Font::Weight::BOLD;
+  prompt_label->AddStyleRange(gfx::Range(offset, offset + domain.size()),
+                              bold_style);
+
+  prompt_label->SetBorder(views::CreateSolidSidedBorder(
+      1, 0, 1, 0,
+      ui::GetSigninConfirmationPromptBarColor(
+          GetNativeTheme(), ui::kSigninConfirmationPromptBarBorderAlpha)));
+  prompt_label->SetBackground(
+      views::CreateSolidBackground(prompt_bar_background_color));
+
+  // Create the explanation label.
+  base::string16 signin_explanation_text;
+  base::string16 close_warning;
+  close_warning = l10n_util::GetStringUTF16(
+      IDS_ENTERPRISE_FORCE_SIGNOUT_ADDITIONAL_EXPLANATION);
+  if (email.empty()) {
+    signin_explanation_text = l10n_util::GetStringFUTF16(
+        IDS_ENTERPRISE_FORCE_SIGNOUT_EXPLANATION_WITHOUT_USER_NAME,
+        close_warning);
+  } else {
+    signin_explanation_text =
+        l10n_util::GetStringFUTF16(IDS_ENTERPRISE_FORCE_SIGNOUT_EXPLANATION,
+                                   base::ASCIIToUTF16(email), close_warning);
+  }
+  views::StyledLabel* explanation_label =
+      new views::StyledLabel(signin_explanation_text, nullptr);
+
+  // Layout the components.
+  const gfx::Insets panel_insets =
+      views::LayoutProvider::Get()->GetInsetsMetric(
+          views::INSETS_DIALOG_CONTENTS);
+  SetBorder(views::CreateEmptyBorder(panel_insets.top(), 0,
+                                     panel_insets.bottom(), 0));
+  views::GridLayout* dialog_layout = new views::GridLayout(this);
+  SetLayoutManager(dialog_layout);
+
+  // Use a column set with no padding.
+  dialog_layout->AddColumnSet(0)->AddColumn(views::GridLayout::FILL,
+                                            views::GridLayout::FILL, 100,
+                                            views::GridLayout::USE_PREF, 0, 0);
+  dialog_layout->StartRow(0, 0);
+  dialog_layout->AddView(prompt_label, 1, 1, views::GridLayout::FILL,
+                         views::GridLayout::FILL, 0, 0);
+
+  // Use a new column set for the explanation label so we can add padding.
+  dialog_layout->AddPaddingRow(0.0, views::kPanelVertMargin);
+  views::ColumnSet* explanation_columns = dialog_layout->AddColumnSet(1);
+  explanation_columns->AddPaddingColumn(0.0, views::kButtonHEdgeMarginNew);
+  explanation_columns->AddColumn(views::GridLayout::FILL,
+                                 views::GridLayout::FILL, 100,
+                                 views::GridLayout::USE_PREF, 0, 0);
+  explanation_columns->AddPaddingColumn(0.0, views::kButtonHEdgeMarginNew);
+  dialog_layout->StartRow(0, 1);
+  const int kPreferredWidth = 440;
+  dialog_layout->AddView(explanation_label, 1, 1, views::GridLayout::FILL,
+                         views::GridLayout::FILL, kPreferredWidth,
+                         explanation_label->GetHeightForWidth(kPreferredWidth));
+  refresh_timer_.Start(FROM_HERE,
+                       base::TimeDelta::FromSeconds(kRefreshTitleTimer), this,
+                       &ForcedReauthenticationDialog::OnCountDown);
+}
+
+void ForcedReauthenticationDialog::OnCountDown() {
+  if (desired_close_time_ <= base::TimeTicks::Now()) {
+    Cancel();
+    GetWidget()->Close();
+  }
+  GetWidget()->UpdateWindowTitle();
+}
+
+base::TimeDelta ForcedReauthenticationDialog::GetTimeRemaining() const {
+  base::TimeTicks now = base::TimeTicks::Now();
+  if (desired_close_time_ <= now)
+    return base::TimeDelta();
+  return desired_close_time_ - now;
+}
diff --git a/chrome/browser/ui/views/profiles/forced_reauthentication_dialog.h b/chrome/browser/ui/views/profiles/forced_reauthentication_dialog.h
new file mode 100644
index 0000000..3e377d10
--- /dev/null
+++ b/chrome/browser/ui/views/profiles/forced_reauthentication_dialog.h
@@ -0,0 +1,69 @@
+// 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 CHROME_BROWSER_UI_VIEWS_PROFILES_FORCED_REAUTHENTICATION_DIALOG_H_
+#define CHROME_BROWSER_UI_VIEWS_PROFILES_FORCED_REAUTHENTICATION_DIALOG_H_
+
+#include <memory>
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/timer/timer.h"
+#include "ui/views/controls/button/button.h"
+#include "ui/views/window/dialog_delegate.h"
+
+class Browser;
+class Profile;
+class SigninManager;
+
+// A modal dialog that displays a warning message of the auth failure
+// and ask user to sign in again.
+class ForcedReauthenticationDialog : public views::DialogDelegateView {
+ public:
+  ~ForcedReauthenticationDialog() override;
+
+  // Shows a warning dialog for |profile|. If there are no Browser windows
+  // associated with |profile|, signs out the profile immediately, otherwise the
+  // user can clicks accept to sign in again. Dialog will be closed after
+  // |countdown_duration| seconds.
+  // Dialog will delete itself after closing.
+  static ForcedReauthenticationDialog* ShowDialog(
+      Profile* profile,
+      SigninManager* signin_manager,
+      const base::TimeDelta& countdown_duration);
+
+  // override views::DialogDelegateView
+  bool Accept() override;
+  bool Cancel() override;
+  void WindowClosing() override;
+  base::string16 GetWindowTitle() const override;
+  base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
+  ui::ModalType GetModalType() const override;
+
+  // override views::View
+  void AddedToWidget() override;
+
+ private:
+  // Show the dialog for |browser|. The dialog will delete itself after closing.
+  ForcedReauthenticationDialog(Browser* browser,
+                               SigninManager* signin_manager,
+                               const base::TimeDelta& countdown_duration);
+
+  void OnCountDown();
+  base::TimeDelta GetTimeRemaining() const;
+
+  Browser* browser_;
+  SigninManager* signin_manager_;
+
+  const base::TimeTicks desired_close_time_;
+
+  // The timer which is used to refresh the dialog title to display the
+  // remaining time.
+  base::RepeatingTimer refresh_timer_;
+
+  DISALLOW_COPY_AND_ASSIGN(ForcedReauthenticationDialog);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_PROFILES_FORCED_REAUTHENTICATION_DIALOG_H_
diff --git a/chrome/browser/ui/views/profiles/forced_reauthentication_dialog_browsertest.cc b/chrome/browser/ui/views/profiles/forced_reauthentication_dialog_browsertest.cc
new file mode 100644
index 0000000..4639449
--- /dev/null
+++ b/chrome/browser/ui/views/profiles/forced_reauthentication_dialog_browsertest.cc
@@ -0,0 +1,62 @@
+// 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 "chrome/browser/ui/views/profiles/forced_reauthentication_dialog.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/memory/ptr_util.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/ui/browser.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 "components/signin/core/browser/signin_manager.h"
+#include "ui/base/ui_base_types.h"
+
+class ForcedReauthenticationDialogBrowserTest : public DialogBrowserTest {
+ public:
+  ForcedReauthenticationDialogBrowserTest() {}
+
+  // override DialogBrowserTest
+  void ShowDialog(const std::string& name) override {
+    Profile* profile = browser()->profile();
+    SigninManager* manager = SigninManagerFactory::GetForProfile(profile);
+    manager->SetAuthenticatedAccountInfo("test1", "test@xyz.com");
+    ForcedReauthenticationDialog::ShowDialog(profile, manager,
+                                             base::TimeDelta::FromSeconds(60));
+  }
+
+  // An integer represents the buttons of dialog.
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ForcedReauthenticationDialogBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(ForcedReauthenticationDialogBrowserTest,
+                       InvokeDialog_default) {
+  RunDialog();
+}
+
+// Dialog will not be display if there is no valid browser window.
+IN_PROC_BROWSER_TEST_F(ForcedReauthenticationDialogBrowserTest,
+                       NotOpenDialogDueToNoBrowser) {
+  Profile* profile = browser()->profile();
+  CloseBrowserSynchronously(browser());
+  EXPECT_EQ(nullptr, ForcedReauthenticationDialog::ShowDialog(
+                         profile, SigninManagerFactory::GetForProfile(profile),
+                         base::TimeDelta::FromSeconds(60)));
+}
+
+IN_PROC_BROWSER_TEST_F(ForcedReauthenticationDialogBrowserTest,
+                       NotOpenDialogDueToNoTabs) {
+  Profile* profile = browser()->profile();
+  TabStripModel* model = browser()->tab_strip_model();
+  ASSERT_EQ(1, model->count());
+  model->CloseWebContentsAt(0, TabStripModel::CLOSE_NONE);
+  ASSERT_TRUE(model->empty());
+  EXPECT_EQ(nullptr, ForcedReauthenticationDialog::ShowDialog(
+                         profile, SigninManagerFactory::GetForProfile(profile),
+                         base::TimeDelta::FromSeconds(60)));
+}
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc
index 72eaaa1..df3e48b 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -14,7 +14,6 @@
 #include "build/build_config.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/app/vector_icons/vector_icons.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/command_updater.h"
 #include "chrome/browser/extensions/extension_util.h"
 #include "chrome/browser/profiles/profile.h"
@@ -45,6 +44,7 @@
 #include "chrome/browser/ui/views/toolbar/toolbar_button.h"
 #include "chrome/browser/ui/views/translate/translate_bubble_view.h"
 #include "chrome/browser/ui/views/translate/translate_icon_view.h"
+#include "chrome/browser/upgrade_detector.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/chromium_strings.h"
@@ -53,7 +53,6 @@
 #include "components/prefs/pref_service.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/browser_accessibility_state.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/accessibility/ax_node_data.h"
@@ -135,19 +134,12 @@
   chrome::AddCommandObserver(browser_, IDC_HOME, this);
   chrome::AddCommandObserver(browser_, IDC_LOAD_NEW_TAB_PAGE, this);
 
-  if (OutdatedUpgradeBubbleView::IsAvailable()) {
-    registrar_.Add(this, chrome::NOTIFICATION_OUTDATED_INSTALL,
-                   content::NotificationService::AllSources());
-    registrar_.Add(this, chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU,
-                   content::NotificationService::AllSources());
-  }
-#if defined(OS_WIN)
-  registrar_.Add(this, chrome::NOTIFICATION_CRITICAL_UPGRADE_INSTALLED,
-                 content::NotificationService::AllSources());
-#endif
+  UpgradeDetector::GetInstance()->AddObserver(this);
 }
 
 ToolbarView::~ToolbarView() {
+  UpgradeDetector::GetInstance()->RemoveObserver(this);
+
   // NOTE: Don't remove the command observers here.  This object gets destroyed
   // after the Browser (which owns the CommandUpdater), so the CommandUpdater is
   // already gone.
@@ -451,26 +443,21 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// ToolbarView, content::NotificationObserver implementation:
+// ToolbarView, UpgradeObserver implementation:
+void ToolbarView::OnOutdatedInstall() {
+  if (OutdatedUpgradeBubbleView::IsAvailable())
+    ShowOutdatedInstallNotification(true);
+}
 
-void ToolbarView::Observe(int type,
-                          const content::NotificationSource& source,
-                          const content::NotificationDetails& details) {
-  switch (type) {
-    case chrome::NOTIFICATION_OUTDATED_INSTALL:
-      ShowOutdatedInstallNotification(true);
-      break;
-    case chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU:
-      ShowOutdatedInstallNotification(false);
-      break;
+void ToolbarView::OnOutdatedInstallNoAutoUpdate() {
+  if (OutdatedUpgradeBubbleView::IsAvailable())
+    ShowOutdatedInstallNotification(false);
+}
+
+void ToolbarView::OnCriticalUpgradeInstalled() {
 #if defined(OS_WIN)
-    case chrome::NOTIFICATION_CRITICAL_UPGRADE_INSTALLED:
-      ShowCriticalNotification();
-      break;
+  ShowCriticalNotification();
 #endif
-    default:
-      NOTREACHED();
-  }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.h b/chrome/browser/ui/views/toolbar/toolbar_view.h
index 983977ac..a90982b 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_view.h
+++ b/chrome/browser/ui/views/toolbar/toolbar_view.h
@@ -13,6 +13,7 @@
 #include "chrome/browser/ui/toolbar/app_menu_icon_controller.h"
 #include "chrome/browser/ui/toolbar/back_forward_menu_model.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
+#include "chrome/browser/upgrade_observer.h"
 #include "components/prefs/pref_member.h"
 #include "components/translate/core/browser/translate_step.h"
 #include "components/translate/core/common/translate_errors.h"
@@ -43,10 +44,10 @@
                     public views::MenuButtonListener,
                     public ui::AcceleratorProvider,
                     public LocationBarView::Delegate,
-                    public content::NotificationObserver,
                     public CommandObserver,
                     public views::ButtonListener,
-                    public AppMenuIconController::Delegate {
+                    public AppMenuIconController::Delegate,
+                    public UpgradeObserver {
  public:
   // The view class name.
   static const char kViewClassName[];
@@ -130,10 +131,10 @@
   // views::ButtonListener:
   void ButtonPressed(views::Button* sender, const ui::Event& event) override;
 
-  // content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
+  // UpgradeObserver implementation.
+  void OnOutdatedInstall() override;
+  void OnOutdatedInstallNoAutoUpdate() override;
+  void OnCriticalUpgradeInstalled() override;
 
   // ui::AcceleratorProvider:
   bool GetAcceleratorForCommandId(int command_id,
@@ -210,8 +211,6 @@
   // The display mode used when laying out the toolbar.
   const DisplayMode display_mode_;
 
-  content::NotificationRegistrar registrar_;
-
   DISALLOW_IMPLICIT_CONSTRUCTORS(ToolbarView);
 };
 
diff --git a/chrome/browser/ui/webui/browsing_history_handler.cc b/chrome/browser/ui/webui/browsing_history_handler.cc
index 0ed2cb5..78faf8d 100644
--- a/chrome/browser/ui/webui/browsing_history_handler.cc
+++ b/chrome/browser/ui/webui/browsing_history_handler.cc
@@ -27,6 +27,7 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/webui/favicon_source.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/features.h"
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/browser/bookmark_utils.h"
@@ -51,12 +52,6 @@
 #include "chrome/browser/supervised_user/supervised_user_url_filter.h"
 #endif
 
-#if defined(OS_ANDROID)
-#include "chrome/browser/android/preferences/preferences_launcher.h"
-#else
-#include "chrome/common/chrome_features.h"
-#endif
-
 using bookmarks::BookmarkModel;
 
 namespace {
@@ -148,12 +143,10 @@
       base::i18n::AdjustStringForLocaleDirection(&title_to_set);
   }
 
-#if !defined(OS_ANDROID)
   // Number of chars to truncate titles when making them "short".
   static const size_t kShortTitleLength = 300;
   if (title_to_set.size() > kShortTitleLength)
     title_to_set.resize(kShortTitleLength);
-#endif
 
   result->SetString("title", title_to_set);
 }
@@ -387,16 +380,11 @@
 
 void BrowsingHistoryHandler::HandleClearBrowsingData(
     const base::ListValue* args) {
-#if defined(OS_ANDROID)
-  chrome::android::PreferencesLauncher::OpenClearBrowsingData(
-      web_ui()->GetWebContents());
-#else
   // TODO(beng): This is an improper direct dependency on Browser. Route this
   // through some sort of delegate.
   Browser* browser = chrome::FindBrowserWithWebContents(
       web_ui()->GetWebContents());
   chrome::ShowClearBrowsingDataDialog(browser);
-#endif
 }
 
 void BrowsingHistoryHandler::HandleRemoveBookmark(const base::ListValue* args) {
@@ -502,8 +490,6 @@
       "queryEndTime",
       GetRelativeDateLocalized(clock_.get(), query_results_info->end_time));
 
-// Not used in mobile UI, and cause ~16kb of code bloat (crbug/683386).
-#ifndef OS_ANDROID
   // TODO(calamity): Clean up grouped-specific fields once grouped history is
   // removed.
   results_info.SetString(
@@ -514,7 +500,6 @@
       base::DateIntervalFormat(query_results_info->start_time,
                                query_results_info->end_time,
                                base::DATE_FORMAT_MONTH_WEEKDAY_DAY));
-#endif
 
   web_ui()->CallJavascriptFunctionUnsafe("historyResult", results_info,
                                          results_value);
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
index 42b7413..f9043f0 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -143,20 +143,20 @@
                             IDR_CUSTOM_ELEMENTS_OOBE_HTML);
     source->AddResourcePath(kCustomElementsJSPath, IDR_CUSTOM_ELEMENTS_OOBE_JS);
   } else if (display_type == OobeUI::kLockDisplay) {
-    if (command_line->HasSwitch(chromeos::switches::kShowNonViewMdLogin)) {
-      source->SetDefaultResource(IDR_MD_LOCK_HTML);
-      source->AddResourcePath(kLockJSPath, IDR_MD_LOCK_JS);
-      source->AddResourcePath(kCustomElementsPinKeyboardHTMLPath,
-                              IDR_MD_CUSTOM_ELEMENTS_PIN_KEYBOARD_HTML);
-      source->AddResourcePath(kCustomElementsPinKeyboardJSPath,
-                              IDR_MD_CUSTOM_ELEMENTS_PIN_KEYBOARD_JS);
-    } else {
+    if (command_line->HasSwitch(chromeos::switches::kShowNonMdLogin)) {
       source->SetDefaultResource(IDR_LOCK_HTML);
       source->AddResourcePath(kLockJSPath, IDR_LOCK_JS);
       source->AddResourcePath(kCustomElementsPinKeyboardHTMLPath,
                               IDR_CUSTOM_ELEMENTS_PIN_KEYBOARD_HTML);
       source->AddResourcePath(kCustomElementsPinKeyboardJSPath,
                               IDR_CUSTOM_ELEMENTS_PIN_KEYBOARD_JS);
+    } else {
+      source->SetDefaultResource(IDR_MD_LOCK_HTML);
+      source->AddResourcePath(kLockJSPath, IDR_MD_LOCK_JS);
+      source->AddResourcePath(kCustomElementsPinKeyboardHTMLPath,
+                              IDR_MD_CUSTOM_ELEMENTS_PIN_KEYBOARD_HTML);
+      source->AddResourcePath(kCustomElementsPinKeyboardJSPath,
+                              IDR_MD_CUSTOM_ELEMENTS_PIN_KEYBOARD_JS);
     }
     source->AddResourcePath(kCustomElementsHTMLPath,
                             IDR_CUSTOM_ELEMENTS_LOCK_HTML);
@@ -164,13 +164,12 @@
     source->AddResourcePath(kCustomElementsUserPodHTMLPath,
                             IDR_CUSTOM_ELEMENTS_USER_POD_HTML);
   } else {
-    if (command_line->HasSwitch(chromeos::switches::kShowMdLogin) ||
-        command_line->HasSwitch(chromeos::switches::kShowNonViewMdLogin)) {
-      source->SetDefaultResource(IDR_MD_LOGIN_HTML);
-      source->AddResourcePath(kLoginJSPath, IDR_MD_LOGIN_JS);
-    } else {
+    if (command_line->HasSwitch(chromeos::switches::kShowNonMdLogin)) {
       source->SetDefaultResource(IDR_LOGIN_HTML);
       source->AddResourcePath(kLoginJSPath, IDR_LOGIN_JS);
+    } else {
+      source->SetDefaultResource(IDR_MD_LOGIN_HTML);
+      source->AddResourcePath(kLoginJSPath, IDR_MD_LOGIN_JS);
     }
     source->AddResourcePath(kCustomElementsHTMLPath,
                             IDR_CUSTOM_ELEMENTS_LOGIN_HTML);
diff --git a/chrome/browser/ui/webui/help/help_handler.cc b/chrome/browser/ui/webui/help/help_handler.cc
index 6f729d16..c818d55 100644
--- a/chrome/browser/ui/webui/help/help_handler.cc
+++ b/chrome/browser/ui/webui/help/help_handler.cc
@@ -26,13 +26,13 @@
 #include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/obsolete_system/obsolete_system.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/upgrade_detector.h"
 #include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_content_client.h"
 #include "chrome/common/pref_names.h"
@@ -46,7 +46,6 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -207,12 +206,15 @@
 
 HelpHandler::HelpHandler()
     : policy_registrar_(
-        g_browser_process->policy_service(),
-        policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string())),
+          g_browser_process->policy_service(),
+          policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string())),
+      apply_changes_from_upgrade_observer_(false),
       weak_factory_(this) {
+  UpgradeDetector::GetInstance()->AddObserver(this);
 }
 
 HelpHandler::~HelpHandler() {
+  UpgradeDetector::GetInstance()->RemoveObserver(this);
 }
 
 void HelpHandler::GetLocalizedValues(base::DictionaryValue* localized_strings) {
@@ -374,8 +376,7 @@
 
 void HelpHandler::RegisterMessages() {
   version_updater_.reset(VersionUpdater::Create(web_ui()->GetWebContents()));
-  registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
-                 content::NotificationService::AllSources());
+  apply_changes_from_upgrade_observer_ = true;
   policy_registrar_.Observe(
       policy::key::kDeviceAutoUpdateDisabled,
       base::Bind(&HelpHandler::OnDeviceAutoUpdatePolicyChanged,
@@ -409,13 +410,12 @@
 #endif
 }
 
-void HelpHandler::Observe(int type, const content::NotificationSource& source,
-                          const content::NotificationDetails& details) {
-  DCHECK_EQ(chrome::NOTIFICATION_UPGRADE_RECOMMENDED, type);
-
-  // A version update is installed and ready to go. Refresh the UI so the
-  // correct state will be shown.
-  RequestUpdate(nullptr);
+void HelpHandler::OnUpgradeRecommended() {
+  if (apply_changes_from_upgrade_observer_) {
+    // A version update is installed and ready to go. Refresh the UI so the
+    // correct state will be shown.
+    RequestUpdate(nullptr);
+  }
 }
 
 // static
diff --git a/chrome/browser/ui/webui/help/help_handler.h b/chrome/browser/ui/webui/help/help_handler.h
index 82b088b..5aea40c 100644
--- a/chrome/browser/ui/webui/help/help_handler.h
+++ b/chrome/browser/ui/webui/help/help_handler.h
@@ -13,9 +13,8 @@
 #include "base/strings/string16.h"
 #include "build/build_config.h"
 #include "chrome/browser/ui/webui/help/version_updater.h"
+#include "chrome/browser/upgrade_observer.h"
 #include "components/policy/core/common/policy_service.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/web_ui_message_handler.h"
 
 #if defined(OS_CHROMEOS)
@@ -32,7 +31,7 @@
 
 // WebUI message handler for the help page.
 class HelpHandler : public content::WebUIMessageHandler,
-                    public content::NotificationObserver {
+                    public UpgradeObserver {
  public:
   HelpHandler();
   ~HelpHandler() override;
@@ -43,10 +42,8 @@
   // Adds string values for the UI to |localized_strings|.
   static void GetLocalizedValues(base::DictionaryValue* localized_strings);
 
-  // NotificationObserver implementation.
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
+  // UpgradeObserver implementation.
+  void OnUpgradeRecommended() override;
 
   // Returns the browser version as a string.
   static base::string16 BuildBrowserVersionString();
@@ -124,12 +121,12 @@
   // Specialized instance of the VersionUpdater used to update the browser.
   std::unique_ptr<VersionUpdater> version_updater_;
 
-  // Used to observe notifications.
-  content::NotificationRegistrar registrar_;
-
   // Used to observe changes in the |kDeviceAutoUpdateDisabled| policy.
   policy::PolicyChangeRegistrar policy_registrar_;
 
+  // If true changes to UpgradeObserver are applied, if false they are ignored.
+  bool apply_changes_from_upgrade_observer_;
+
   // Used for callbacks.
   base::WeakPtrFactory<HelpHandler> weak_factory_;
 
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc
index 05db7d11..d3ebb82 100644
--- a/chrome/browser/ui/webui/settings/about_handler.cc
+++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -27,12 +27,12 @@
 #include "base/values.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/obsolete_system/obsolete_system.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/chrome_pages.h"
+#include "chrome/browser/upgrade_detector.h"
 #include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_content_client.h"
 #include "chrome/common/pref_names.h"
@@ -46,7 +46,6 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
@@ -265,9 +264,14 @@
 
 namespace settings {
 
-AboutHandler::AboutHandler() : weak_factory_(this) {}
+AboutHandler::AboutHandler()
+    : apply_changes_from_upgrade_observer_(false), weak_factory_(this) {
+  UpgradeDetector::GetInstance()->AddObserver(this);
+}
 
-AboutHandler::~AboutHandler() {}
+AboutHandler::~AboutHandler() {
+  UpgradeDetector::GetInstance()->RemoveObserver(this);
+}
 
 AboutHandler* AboutHandler::Create(content::WebUIDataSource* html_source,
                                    Profile* profile) {
@@ -385,9 +389,8 @@
 }
 
 void AboutHandler::OnJavascriptAllowed() {
+  apply_changes_from_upgrade_observer_ = true;
   version_updater_.reset(VersionUpdater::Create(web_ui()->GetWebContents()));
-  registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
-                 content::NotificationService::AllSources());
   policy_registrar_.reset(new policy::PolicyChangeRegistrar(
       g_browser_process->policy_service(),
       policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string())));
@@ -398,20 +401,17 @@
 }
 
 void AboutHandler::OnJavascriptDisallowed() {
+  apply_changes_from_upgrade_observer_ = false;
   version_updater_.reset();
   policy_registrar_.reset();
-  registrar_.Remove(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
-                    content::NotificationService::AllSources());
 }
 
-void AboutHandler::Observe(int type,
-                           const content::NotificationSource& source,
-                           const content::NotificationDetails& details) {
-  DCHECK_EQ(chrome::NOTIFICATION_UPGRADE_RECOMMENDED, type);
-
-  // A version update is installed and ready to go. Refresh the UI so the
-  // correct state will be shown.
-  RequestUpdate();
+void AboutHandler::OnUpgradeRecommended() {
+  if (apply_changes_from_upgrade_observer_) {
+    // A version update is installed and ready to go. Refresh the UI so the
+    // correct state will be shown.
+    RequestUpdate();
+  }
 }
 
 void AboutHandler::OnDeviceAutoUpdatePolicyChanged(
diff --git a/chrome/browser/ui/webui/settings/about_handler.h b/chrome/browser/ui/webui/settings/about_handler.h
index 5dc9d23..3c657751 100644
--- a/chrome/browser/ui/webui/settings/about_handler.h
+++ b/chrome/browser/ui/webui/settings/about_handler.h
@@ -15,9 +15,8 @@
 #include "build/build_config.h"
 #include "chrome/browser/ui/webui/help/version_updater.h"
 #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "chrome/browser/upgrade_observer.h"
 #include "components/policy/core/common/policy_service.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/web_ui_message_handler.h"
 
 #if defined(OS_CHROMEOS)
@@ -41,7 +40,7 @@
 
 // WebUI message handler for the help page.
 class AboutHandler : public settings::SettingsPageUIHandler,
-                     public content::NotificationObserver {
+                     public UpgradeObserver {
  public:
   AboutHandler();
   ~AboutHandler() override;
@@ -54,10 +53,8 @@
   void OnJavascriptAllowed() override;
   void OnJavascriptDisallowed() override;
 
-  // NotificationObserver implementation.
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
+  // UpgradeObserver implementation.
+  void OnUpgradeRecommended() override;
 
   // Returns the browser version as a string.
   static base::string16 BuildBrowserVersionString();
@@ -151,12 +148,12 @@
   // Specialized instance of the VersionUpdater used to update the browser.
   std::unique_ptr<VersionUpdater> version_updater_;
 
-  // Used to observe notifications.
-  content::NotificationRegistrar registrar_;
-
   // Used to observe changes in the |kDeviceAutoUpdateDisabled| policy.
   std::unique_ptr<policy::PolicyChangeRegistrar> policy_registrar_;
 
+  // If true changes to UpgradeObserver are applied, if false they are ignored.
+  bool apply_changes_from_upgrade_observer_;
+
   // Used for callbacks.
   base::WeakPtrFactory<AboutHandler> weak_factory_;
 
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler.cc b/chrome/browser/ui/webui/signin/inline_login_handler.cc
index 72d748e..71e633b 100644
--- a/chrome/browser/ui/webui/signin/inline_login_handler.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_handler.cc
@@ -177,6 +177,10 @@
       base::RecordAction(
           base::UserMetricsAction("Signin_Signin_FromTabSwitcher"));
       break;
+    case signin_metrics::AccessPoint::ACCESS_POINT_FORCE_SIGNIN_WARNING:
+      base::RecordAction(
+          base::UserMetricsAction("Signin_Signin_FromForceSigninWarning"));
+      break;
     case signin_metrics::AccessPoint::ACCESS_POINT_MAX:
       NOTREACHED();
       break;
diff --git a/chrome/browser/upgrade_detector.cc b/chrome/browser/upgrade_detector.cc
index 68215d2..3a0763d 100644
--- a/chrome/browser/upgrade_detector.cc
+++ b/chrome/browser/upgrade_detector.cc
@@ -7,13 +7,11 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "chrome/app/vector_icons/vector_icons.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/ui/browser_otr_state.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_registry_simple.h"
-#include "content/public/browser/notification_service.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/paint_vector_icon.h"
 
@@ -73,20 +71,40 @@
 UpgradeDetector::~UpgradeDetector() {
 }
 
-void UpgradeDetector::NotifyUpgradeRecommended() {
+void UpgradeDetector::NotifyOutdatedInstall() {
+  for (auto& observer : observer_list_)
+    observer.OnOutdatedInstall();
+}
+
+void UpgradeDetector::NotifyOutdatedInstallNoAutoUpdate() {
+  for (auto& observer : observer_list_)
+    observer.OnOutdatedInstallNoAutoUpdate();
+}
+
+void UpgradeDetector::NotifyUpgrade() {
   notify_upgrade_ = true;
 
-  TriggerNotification(chrome::NOTIFICATION_UPGRADE_RECOMMENDED);
+  NotifyUpgradeRecommended();
   if (upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL) {
-    TriggerNotification(chrome::NOTIFICATION_OUTDATED_INSTALL);
+    NotifyOutdatedInstall();
   } else if (upgrade_available_ == UPGRADE_NEEDED_OUTDATED_INSTALL_NO_AU) {
-    TriggerNotification(chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU);
+    NotifyOutdatedInstallNoAutoUpdate();
   } else if (upgrade_available_ == UPGRADE_AVAILABLE_CRITICAL ||
              critical_experiment_updates_available_) {
     TriggerCriticalUpdate();
   }
 }
 
+void UpgradeDetector::NotifyUpgradeRecommended() {
+  for (auto& observer : observer_list_)
+    observer.OnUpgradeRecommended();
+}
+
+void UpgradeDetector::NotifyCriticalUpgradeInstalled() {
+  for (auto& observer : observer_list_)
+    observer.OnCriticalUpgradeInstalled();
+}
+
 void UpgradeDetector::NotifyUpdateOverCellularAvailable() {
   for (auto& observer : observer_list_)
     observer.OnUpdateOverCellularAvailable();
@@ -110,13 +128,6 @@
                                     base::Unretained(this)));
 }
 
-void UpgradeDetector::TriggerNotification(chrome::NotificationType type) {
-  content::NotificationService::current()->Notify(
-      type,
-      content::Source<UpgradeDetector>(this),
-      content::NotificationService::NoDetails());
-}
-
 void UpgradeDetector::IdleCallback(ui::IdleState state) {
   // Don't proceed while an incognito window is open. The timer will still
   // keep firing, so this function will get a chance to re-evaluate this.
@@ -132,7 +143,7 @@
     case ui::IDLE_STATE_IDLE:
       // Computer has been idle for long enough, show warning.
       idle_check_timer_.Stop();
-      TriggerNotification(chrome::NOTIFICATION_CRITICAL_UPGRADE_INSTALLED);
+      NotifyCriticalUpgradeInstalled();
       break;
     case ui::IDLE_STATE_ACTIVE:
     case ui::IDLE_STATE_UNKNOWN:
diff --git a/chrome/browser/upgrade_detector.h b/chrome/browser/upgrade_detector.h
index 3936606c..fce8e2f7 100644
--- a/chrome/browser/upgrade_detector.h
+++ b/chrome/browser/upgrade_detector.h
@@ -9,7 +9,6 @@
 #include "base/macros.h"
 #include "base/observer_list.h"
 #include "base/timer/timer.h"
-#include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/upgrade_observer.h"
 #include "ui/base/idle/idle.h"
 #include "ui/gfx/image/image.h"
@@ -86,6 +85,13 @@
 
   void RemoveObserver(UpgradeObserver* observer);
 
+  // Notifies that the current install is outdated. No details are expected.
+  void NotifyOutdatedInstall();
+
+  // Notifies that the current install is outdated and auto-update (AU) is
+  // disabled. No details are expected.
+  void NotifyOutdatedInstallNoAutoUpdate();
+
  protected:
   enum UpgradeAvailable {
     // If no update is available and current install is recent enough.
@@ -105,9 +111,17 @@
 
   UpgradeDetector();
 
-  // Sends out UPGRADE_RECOMMENDED notification and set notify_upgrade_.
+  // Notifies that update is recommended and triggers different actions based
+  // on the update availability.
+  void NotifyUpgrade();
+
+  // Notifies that update is recommended.
   void NotifyUpgradeRecommended();
 
+  // Notifies that a critical update has been installed. No details are
+  // expected.
+  void NotifyCriticalUpgradeInstalled();
+
   // The function that sends out a notification that lets the rest of the UI
   // know we should notify the user that a new update is available to download
   // over cellular connection.
@@ -156,9 +170,6 @@
   // input events since the specified time.
   void IdleCallback(ui::IdleState state);
 
-  // Triggers a global notification of the specified |type|.
-  void TriggerNotification(chrome::NotificationType type);
-
   // Whether any software updates are available (experiment updates are tracked
   // separately via additional member variables below).
   UpgradeAvailable upgrade_available_;
diff --git a/chrome/browser/upgrade_detector_impl.cc b/chrome/browser/upgrade_detector_impl.cc
index f9ec43d..c2dbf4a 100644
--- a/chrome/browser/upgrade_detector_impl.cc
+++ b/chrome/browser/upgrade_detector_impl.cc
@@ -494,7 +494,7 @@
     }
   }
 
-  NotifyUpgradeRecommended();
+  NotifyUpgrade();
 }
 
 void UpgradeDetectorImpl::NotifyOnUpgrade() {
diff --git a/chrome/browser/upgrade_detector_impl_unittest.cc b/chrome/browser/upgrade_detector_impl_unittest.cc
index 4a0b400b..dd30a18 100644
--- a/chrome/browser/upgrade_detector_impl_unittest.cc
+++ b/chrome/browser/upgrade_detector_impl_unittest.cc
@@ -7,11 +7,8 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "chrome/browser/upgrade_observer.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/notification_service.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -42,31 +39,28 @@
   DISALLOW_COPY_AND_ASSIGN(TestUpgradeDetectorImpl);
 };
 
-class TestUpgradeNotificationListener : public content::NotificationObserver {
+class TestUpgradeNotificationListener : public UpgradeObserver {
  public:
-  TestUpgradeNotificationListener() {
-    registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
-                   content::NotificationService::AllSources());
+  explicit TestUpgradeNotificationListener(UpgradeDetector* detector)
+      : notifications_count_(0), detector_(detector) {
+    detector_->AddObserver(this);
   }
-  ~TestUpgradeNotificationListener() override {}
+  ~TestUpgradeNotificationListener() override {
+    if (detector_)
+      detector_->RemoveObserver(this);
+  }
 
-  const std::vector<int>& notifications_received() const {
-    return notifications_received_;
-  }
+  int get_notifications_count() const { return notifications_count_; }
 
  private:
-  // content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override {
-    notifications_received_.push_back(type);
-  }
+  // UpgradeObserver implementation.
+  void OnUpgradeRecommended() override { notifications_count_ += 1; }
 
-  // Registrar for listening to notifications.
-  content::NotificationRegistrar registrar_;
+  // Keeps track of the number of upgrade recommended notifications that were
+  // received.
+  int notifications_count_;
 
-  // Keeps track of the number and types of notifications that were received.
-  std::vector<int> notifications_received_;
+  UpgradeDetector* detector_;
 
   DISALLOW_COPY_AND_ASSIGN(TestUpgradeNotificationListener);
 };
@@ -74,21 +68,19 @@
 TEST(UpgradeDetectorImplTest, VariationsChanges) {
   content::TestBrowserThreadBundle bundle;
 
-  TestUpgradeNotificationListener notifications_listener;
   TestUpgradeDetectorImpl detector;
+  TestUpgradeNotificationListener notifications_listener(&detector);
   EXPECT_FALSE(detector.notify_upgrade());
-  EXPECT_TRUE(notifications_listener.notifications_received().empty());
+  EXPECT_EQ(0, notifications_listener.get_notifications_count());
 
   detector.OnExperimentChangesDetected(
       variations::VariationsService::Observer::BEST_EFFORT);
   EXPECT_FALSE(detector.notify_upgrade());
-  EXPECT_TRUE(notifications_listener.notifications_received().empty());
+  EXPECT_EQ(0, notifications_listener.get_notifications_count());
 
   detector.NotifyOnUpgradeWithTimePassed(base::TimeDelta::FromDays(30));
   EXPECT_TRUE(detector.notify_upgrade());
-  ASSERT_EQ(1U, notifications_listener.notifications_received().size());
-  EXPECT_EQ(chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
-            notifications_listener.notifications_received().front());
+  EXPECT_EQ(1, notifications_listener.get_notifications_count());
   EXPECT_EQ(0, detector.trigger_critical_update_call_count());
 
   // Execute tasks sent to FILE thread by |detector| referencing it
@@ -99,21 +91,19 @@
 TEST(UpgradeDetectorImplTest, VariationsCriticalChanges) {
   content::TestBrowserThreadBundle bundle;
 
-  TestUpgradeNotificationListener notifications_listener;
   TestUpgradeDetectorImpl detector;
+  TestUpgradeNotificationListener notifications_listener(&detector);
   EXPECT_FALSE(detector.notify_upgrade());
-  EXPECT_TRUE(notifications_listener.notifications_received().empty());
+  EXPECT_EQ(0, notifications_listener.get_notifications_count());
 
   detector.OnExperimentChangesDetected(
       variations::VariationsService::Observer::CRITICAL);
   EXPECT_FALSE(detector.notify_upgrade());
-  EXPECT_TRUE(notifications_listener.notifications_received().empty());
+  EXPECT_EQ(0, notifications_listener.get_notifications_count());
 
   detector.NotifyOnUpgradeWithTimePassed(base::TimeDelta::FromDays(30));
   EXPECT_TRUE(detector.notify_upgrade());
-  ASSERT_EQ(1U, notifications_listener.notifications_received().size());
-  EXPECT_EQ(chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
-            notifications_listener.notifications_received().front());
+  EXPECT_EQ(1, notifications_listener.get_notifications_count());
   EXPECT_EQ(1, detector.trigger_critical_update_call_count());
 
   // Execute tasks sent to FILE thread by |detector| referencing it
diff --git a/chrome/browser/upgrade_observer.h b/chrome/browser/upgrade_observer.h
index 51af04f..4dd8b0a 100644
--- a/chrome/browser/upgrade_observer.h
+++ b/chrome/browser/upgrade_observer.h
@@ -11,7 +11,24 @@
  public:
   // Triggered when a software update is available, but downloading requires
   // user's agreement as current connection is cellular.
-  virtual void OnUpdateOverCellularAvailable() = 0;
+  virtual void OnUpdateOverCellularAvailable() {}
+
+  // Triggered when Chrome believes an update has been installed and available
+  // for long enough with the user shutting down to let it take effect. See
+  // upgrade_detector.cc for details on how long it waits. No details are
+  // expected.
+  virtual void OnUpgradeRecommended() {}
+
+  // Triggered when a critical update has been installed. No details are
+  // expected.
+  virtual void OnCriticalUpgradeInstalled() {}
+
+  // Triggered when the current install is outdated. No details are expected.
+  virtual void OnOutdatedInstall() {}
+
+  // Triggered when the current install is outdated and auto-update (AU) is
+  // disabled. No details are expected.
+  virtual void OnOutdatedInstallNoAutoUpdate() {}
 
  protected:
   virtual ~UpgradeObserver() {}
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index f364978..38063ac 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -567,11 +567,6 @@
       deps += [ "//chrome/test/data/webui:interactive_ui_tests_js_webui" ]
     }
 
-    # TODO(rockot) bug 505926: The chrome_extensions_interactive_uitests target
-    # should be deleted and this line removed. See the
-    # chrome_extensions_interactive_uitests target for more.
-    deps += [ "//extensions:chrome_extensions_interactive_uitests" ]
-
     # Runtime dependencies
     data_deps += [
       "//ppapi:ppapi_tests",
@@ -580,6 +575,11 @@
 
     if (use_aura) {
       sources += [ "../browser/ui/views/drag_and_drop_interactive_uitest.cc" ]
+    } else {
+      sources -= [
+        "base/interactive_test_utils_aura.cc",
+        "base/interactive_test_utils_aura.h",
+      ]
     }
 
     if (toolkit_views) {
@@ -805,11 +805,11 @@
           [ "../browser/ui/app_list/app_list_service_interactive_uitest.cc" ]
     }
 
-    if (!use_aura) {
-      sources -= [
-        "base/interactive_test_utils_aura.cc",
-        "base/interactive_test_utils_aura.h",
-      ]
+    if (enable_extensions) {
+      # TODO(rockot) bug 505926: The chrome_extensions_interactive_uitests
+      # target should be deleted and this line removed. See the
+      # chrome_extensions_interactive_uitests target for more.
+      deps += [ "//extensions:chrome_extensions_interactive_uitests" ]
     }
 
     if (use_ash) {
@@ -1251,189 +1251,6 @@
       "../browser/download/download_danger_prompt_browsertest.cc",
       "../browser/download/download_started_animation_browsertest.cc",
       "../browser/download/save_page_browsertest.cc",
-      "../browser/extensions/active_tab_apitest.cc",
-      "../browser/extensions/activity_log/activity_log_browsertest.cc",
-      "../browser/extensions/alert_apitest.cc",
-      "../browser/extensions/all_urls_apitest.cc",
-      "../browser/extensions/api/activity_log_private/activity_log_private_apitest.cc",
-      "../browser/extensions/api/autofill_private/autofill_private_apitest.cc",
-      "../browser/extensions/api/automation/automation_apitest.cc",
-      "../browser/extensions/api/autotest_private/autotest_private_apitest.cc",
-      "../browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc",
-      "../browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc",
-      "../browser/extensions/api/bookmarks/bookmark_apitest.cc",
-      "../browser/extensions/api/braille_display_private/braille_display_private_apitest.cc",
-      "../browser/extensions/api/braille_display_private/mock_braille_controller.cc",
-      "../browser/extensions/api/braille_display_private/mock_braille_controller.h",
-      "../browser/extensions/api/browser/browser_apitest.cc",
-      "../browser/extensions/api/browsing_data/browsing_data_test.cc",
-      "../browser/extensions/api/cast_streaming/cast_streaming_apitest.cc",
-      "../browser/extensions/api/cloud_print_private/cloud_print_private_apitest.cc",
-      "../browser/extensions/api/command_line_private/command_line_private_apitest.cc",
-      "../browser/extensions/api/commands/command_service_browsertest.cc",
-      "../browser/extensions/api/content_settings/content_settings_apitest.cc",
-      "../browser/extensions/api/context_menus/context_menu_apitest.cc",
-      "../browser/extensions/api/cookies/cookies_apitest.cc",
-      "../browser/extensions/api/debugger/debugger_apitest.cc",
-      "../browser/extensions/api/debugger/debugger_extension_apitest.cc",
-      "../browser/extensions/api/declarative/declarative_apitest.cc",
-      "../browser/extensions/api/declarative_content/declarative_content_apitest.cc",
-      "../browser/extensions/api/declarative_content/request_content_script_apitest.cc",
-      "../browser/extensions/api/declarative_content/set_icon_apitest.cc",
-      "../browser/extensions/api/desktop_capture/desktop_capture_apitest.cc",
-      "../browser/extensions/api/developer_private/developer_private_apitest.cc",
-      "../browser/extensions/api/dial/dial_apitest.cc",
-      "../browser/extensions/api/downloads/downloads_api_browsertest.cc",
-      "../browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc",
-      "../browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc",
-      "../browser/extensions/api/extension_action/browser_action_apitest.cc",
-      "../browser/extensions/api/extension_action/browser_action_browsertest.cc",
-      "../browser/extensions/api/extension_action/page_action_apitest.cc",
-      "../browser/extensions/api/feedback_private/feedback_browsertest.cc",
-      "../browser/extensions/api/feedback_private/feedback_private_apitest.cc",
-      "../browser/extensions/api/file_system/file_system_apitest.cc",
-      "../browser/extensions/api/file_system/file_system_apitest_chromeos.cc",
-      "../browser/extensions/api/font_settings/font_settings_apitest.cc",
-      "../browser/extensions/api/gcm/gcm_apitest.cc",
-      "../browser/extensions/api/history/history_apitest.cc",
-      "../browser/extensions/api/i18n/i18n_apitest.cc",
-      "../browser/extensions/api/identity/identity_apitest.cc",
-      "../browser/extensions/api/idltest/idltest_apitest.cc",
-      "../browser/extensions/api/image_writer_private/image_writer_private_apitest.cc",
-      "../browser/extensions/api/image_writer_private/test_utils.cc",
-      "../browser/extensions/api/image_writer_private/test_utils.h",
-      "../browser/extensions/api/inline_install_private/inline_install_private_apitest.cc",
-      "../browser/extensions/api/input_ime/input_ime_apitest_chromeos.cc",
-      "../browser/extensions/api/instance_id/instance_id_apitest.cc",
-      "../browser/extensions/api/log_private/log_private_apitest_chromeos.cc",
-      "../browser/extensions/api/management/management_api_browsertest.cc",
-      "../browser/extensions/api/management/management_apitest.cc",
-      "../browser/extensions/api/management/management_browsertest.cc",
-      "../browser/extensions/api/media_galleries/media_galleries_apitest.cc",
-      "../browser/extensions/api/media_galleries/media_galleries_watch_apitest.cc",
-      "../browser/extensions/api/messaging/native_messaging_apitest.cc",
-      "../browser/extensions/api/metrics_private/metrics_apitest.cc",
-      "../browser/extensions/api/module/module_apitest.cc",
-      "../browser/extensions/api/music_manager_private/music_manager_private_browsertest.cc",
-      "../browser/extensions/api/networking_config_chromeos_apitest_chromeos.cc",
-      "../browser/extensions/api/omnibox/omnibox_api_browsertest.cc",
-      "../browser/extensions/api/page_capture/page_capture_apitest.cc",
-      "../browser/extensions/api/passwords_private/passwords_private_apitest.cc",
-      "../browser/extensions/api/permissions/permissions_apitest.cc",
-      "../browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc",
-      "../browser/extensions/api/preference/preference_apitest.cc",
-      "../browser/extensions/api/processes/processes_apitest.cc",
-      "../browser/extensions/api/proxy/proxy_apitest.cc",
-      "../browser/extensions/api/resources_private/resources_private_apitest.cc",
-      "../browser/extensions/api/screenlock_private/screenlock_private_apitest.cc",
-      "../browser/extensions/api/sessions/sessions_apitest.cc",
-      "../browser/extensions/api/settings_overrides/settings_overrides_browsertest.cc",
-      "../browser/extensions/api/settings_private/settings_private_apitest.cc",
-      "../browser/extensions/api/socket/socket_apitest.cc",
-      "../browser/extensions/api/storage/settings_apitest.cc",
-      "../browser/extensions/api/streams_private/streams_private_apitest.cc",
-      "../browser/extensions/api/sync_file_system/sync_file_system_apitest.cc",
-      "../browser/extensions/api/sync_file_system/sync_file_system_browsertest.cc",
-      "../browser/extensions/api/system_indicator/system_indicator_apitest.cc",
-      "../browser/extensions/api/system_private/system_private_apitest.cc",
-      "../browser/extensions/api/tab_capture/tab_capture_apitest.cc",
-      "../browser/extensions/api/tabs/tabs_test.cc",
-      "../browser/extensions/api/terminal/terminal_private_apitest.cc",
-      "../browser/extensions/api/test/apitest_apitest.cc",
-      "../browser/extensions/api/top_sites/top_sites_apitest.cc",
-      "../browser/extensions/api/web_navigation/web_navigation_apitest.cc",
-      "../browser/extensions/api/web_request/web_request_apitest.cc",
-      "../browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc",
-      "../browser/extensions/api/webrtc_from_web_accessible_resource_browsertest.cc",
-      "../browser/extensions/api/webrtc_logging_private/webrtc_event_log_apitest.cc",
-      "../browser/extensions/api/webrtc_logging_private/webrtc_logging_private_apitest.cc",
-      "../browser/extensions/api/webstore_private/webstore_private_apitest.cc",
-      "../browser/extensions/api_binding_perf_browsertest.cc",
-      "../browser/extensions/app_background_page_apitest.cc",
-      "../browser/extensions/app_process_apitest.cc",
-      "../browser/extensions/app_window_overrides_browsertest.cc",
-      "../browser/extensions/background_app_browsertest.cc",
-      "../browser/extensions/background_page_apitest.cc",
-      "../browser/extensions/background_scripts_apitest.cc",
-      "../browser/extensions/background_xhr_browsertest.cc",
-      "../browser/extensions/browsertest_util_browsertest.cc",
-      "../browser/extensions/chrome_app_api_browsertest.cc",
-      "../browser/extensions/chrome_theme_url_browsertest.cc",
-      "../browser/extensions/chrome_ui_overrides_browsertest.cc",
-      "../browser/extensions/content_capabilities_browsertest.cc",
-      "../browser/extensions/content_script_apitest.cc",
-      "../browser/extensions/content_security_policy_apitest.cc",
-      "../browser/extensions/content_verifier_browsertest.cc",
-      "../browser/extensions/crazy_extension_browsertest.cc",
-      "../browser/extensions/cross_origin_xhr_apitest.cc",
-      "../browser/extensions/crx_installer_browsertest.cc",
-      "../browser/extensions/docs/examples/apps/calculator_browsertest.cc",
-      "../browser/extensions/error_console/error_console_browsertest.cc",
-      "../browser/extensions/events_apitest.cc",
-      "../browser/extensions/execute_script_apitest.cc",
-      "../browser/extensions/extension_action_runner_browsertest.cc",
-      "../browser/extensions/extension_bindings_apitest.cc",
-      "../browser/extensions/extension_context_menu_browsertest.cc",
-      "../browser/extensions/extension_disabled_ui_browsertest.cc",
-      "../browser/extensions/extension_dom_clipboard_apitest.cc",
-      "../browser/extensions/extension_fileapi_apitest.cc",
-      "../browser/extensions/extension_functional_browsertest.cc",
-      "../browser/extensions/extension_geolocation_apitest.cc",
-      "../browser/extensions/extension_get_views_apitest.cc",
-      "../browser/extensions/extension_icon_source_apitest.cc",
-      "../browser/extensions/extension_incognito_apitest.cc",
-      "../browser/extensions/extension_install_prompt_browsertest.cc",
-      "../browser/extensions/extension_install_prompt_test_helper.cc",
-      "../browser/extensions/extension_install_prompt_test_helper.h",
-      "../browser/extensions/extension_install_ui_browsertest.cc",
-      "../browser/extensions/extension_javascript_url_apitest.cc",
-      "../browser/extensions/extension_loading_browsertest.cc",
-      "../browser/extensions/extension_management_test_util.cc",
-      "../browser/extensions/extension_management_test_util.h",
-      "../browser/extensions/extension_messages_apitest.cc",
-      "../browser/extensions/extension_override_apitest.cc",
-      "../browser/extensions/extension_request_limiting_throttle_browsertest.cc",
-      "../browser/extensions/extension_resource_request_policy_apitest.cc",
-      "../browser/extensions/extension_startup_browsertest.cc",
-      "../browser/extensions/extension_storage_apitest.cc",
-      "../browser/extensions/extension_storage_monitor_browsertest.cc",
-      "../browser/extensions/extension_tab_util_browsertest.cc",
-      "../browser/extensions/extension_tabs_apitest.cc",
-      "../browser/extensions/extension_unload_browsertest.cc",
-      "../browser/extensions/extension_url_rewrite_browsertest.cc",
-      "../browser/extensions/extension_view_host_factory_browsertest.cc",
-      "../browser/extensions/extension_websocket_apitest.cc",
-      "../browser/extensions/extension_webui_apitest.cc",
-      "../browser/extensions/external_install_error_browsertest.cc",
-      "../browser/extensions/fetch_apitest.cc",
-      "../browser/extensions/gpu_browsertest.cc",
-      "../browser/extensions/hotword_browsertest.cc",
-      "../browser/extensions/isolated_app_browsertest.cc",
-      "../browser/extensions/lazy_background_page_apitest.cc",
-      "../browser/extensions/lazy_background_page_test_util.h",
-      "../browser/extensions/mutation_observers_apitest.cc",
-      "../browser/extensions/native_bindings_apitest.cc",
-      "../browser/extensions/navigation_observer_browsertest.cc",
-      "../browser/extensions/options_page_apitest.cc",
-      "../browser/extensions/page_action_browsertest.cc",
-      "../browser/extensions/process_management_browsertest.cc",
-      "../browser/extensions/process_manager_browsertest.cc",
-      "../browser/extensions/renderer_initialization_browsertest.cc",
-      "../browser/extensions/sandboxed_pages_apitest.cc",
-      "../browser/extensions/service_worker_apitest.cc",
-      "../browser/extensions/shared_module_apitest.cc",
-      "../browser/extensions/startup_helper_browsertest.cc",
-      "../browser/extensions/stubs_apitest.cc",
-      "../browser/extensions/subscribe_page_action_browsertest.cc",
-      "../browser/extensions/wake_event_page_apitest.cc",
-      "../browser/extensions/web_contents_browsertest.cc",
-      "../browser/extensions/webstore_inline_installer_browsertest.cc",
-      "../browser/extensions/webstore_installer_browsertest.cc",
-      "../browser/extensions/webstore_installer_test.cc",
-      "../browser/extensions/webstore_installer_test.h",
-      "../browser/extensions/webstore_reinstaller_browsertest.cc",
-      "../browser/extensions/webstore_startup_installer_browsertest.cc",
-      "../browser/extensions/window_open_apitest.cc",
       "../browser/fast_shutdown_browsertest.cc",
       "../browser/favicon/content_favicon_driver_browsertest.cc",
       "../browser/first_run/first_run_browsertest.cc",
@@ -1793,7 +1610,6 @@
       "//components/dom_distiller/content/browser",
       "//components/dom_distiller/content/renderer",
       "//components/dom_distiller/core:test_support",
-      "//components/guest_view/browser:test_support",
       "//components/policy:chrome_settings_proto",
       "//components/resources",
       "//components/safe_browsing_db:test_database_manager",
@@ -1959,19 +1775,202 @@
       sources += [
         "../browser/apps/app_browsertest_util.cc",
         "../browser/apps/app_browsertest_util.h",
+        "../browser/extensions/active_tab_apitest.cc",
+        "../browser/extensions/activity_log/activity_log_browsertest.cc",
+        "../browser/extensions/alert_apitest.cc",
+        "../browser/extensions/all_urls_apitest.cc",
+        "../browser/extensions/api/activity_log_private/activity_log_private_apitest.cc",
+        "../browser/extensions/api/autofill_private/autofill_private_apitest.cc",
+        "../browser/extensions/api/automation/automation_apitest.cc",
+        "../browser/extensions/api/autotest_private/autotest_private_apitest.cc",
+        "../browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest_chromeos.cc",
+        "../browser/extensions/api/bookmark_manager_private/bookmark_manager_private_apitest.cc",
+        "../browser/extensions/api/bookmarks/bookmark_apitest.cc",
+        "../browser/extensions/api/braille_display_private/braille_display_private_apitest.cc",
+        "../browser/extensions/api/braille_display_private/mock_braille_controller.cc",
+        "../browser/extensions/api/braille_display_private/mock_braille_controller.h",
+        "../browser/extensions/api/browser/browser_apitest.cc",
+        "../browser/extensions/api/browsing_data/browsing_data_test.cc",
+        "../browser/extensions/api/cast_streaming/cast_streaming_apitest.cc",
+        "../browser/extensions/api/cloud_print_private/cloud_print_private_apitest.cc",
+        "../browser/extensions/api/command_line_private/command_line_private_apitest.cc",
+        "../browser/extensions/api/commands/command_service_browsertest.cc",
+        "../browser/extensions/api/content_settings/content_settings_apitest.cc",
+        "../browser/extensions/api/context_menus/context_menu_apitest.cc",
+        "../browser/extensions/api/cookies/cookies_apitest.cc",
+        "../browser/extensions/api/debugger/debugger_apitest.cc",
+        "../browser/extensions/api/debugger/debugger_extension_apitest.cc",
+        "../browser/extensions/api/declarative/declarative_apitest.cc",
+        "../browser/extensions/api/declarative_content/declarative_content_apitest.cc",
+        "../browser/extensions/api/declarative_content/request_content_script_apitest.cc",
+        "../browser/extensions/api/declarative_content/set_icon_apitest.cc",
+        "../browser/extensions/api/desktop_capture/desktop_capture_apitest.cc",
+        "../browser/extensions/api/developer_private/developer_private_apitest.cc",
+        "../browser/extensions/api/dial/dial_apitest.cc",
+        "../browser/extensions/api/downloads/downloads_api_browsertest.cc",
+        "../browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc",
+        "../browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_apitest_nss.cc",
+        "../browser/extensions/api/extension_action/browser_action_apitest.cc",
+        "../browser/extensions/api/extension_action/browser_action_browsertest.cc",
+        "../browser/extensions/api/extension_action/page_action_apitest.cc",
+        "../browser/extensions/api/feedback_private/feedback_browsertest.cc",
+        "../browser/extensions/api/feedback_private/feedback_private_apitest.cc",
+        "../browser/extensions/api/file_system/file_system_apitest.cc",
+        "../browser/extensions/api/file_system/file_system_apitest_chromeos.cc",
+        "../browser/extensions/api/font_settings/font_settings_apitest.cc",
+        "../browser/extensions/api/gcm/gcm_apitest.cc",
+        "../browser/extensions/api/history/history_apitest.cc",
+        "../browser/extensions/api/i18n/i18n_apitest.cc",
+        "../browser/extensions/api/identity/identity_apitest.cc",
+        "../browser/extensions/api/idltest/idltest_apitest.cc",
+        "../browser/extensions/api/image_writer_private/image_writer_private_apitest.cc",
+        "../browser/extensions/api/image_writer_private/test_utils.cc",
+        "../browser/extensions/api/image_writer_private/test_utils.h",
+        "../browser/extensions/api/inline_install_private/inline_install_private_apitest.cc",
+        "../browser/extensions/api/input_ime/input_ime_apitest_chromeos.cc",
+        "../browser/extensions/api/instance_id/instance_id_apitest.cc",
+        "../browser/extensions/api/log_private/log_private_apitest_chromeos.cc",
+        "../browser/extensions/api/management/management_api_browsertest.cc",
+        "../browser/extensions/api/management/management_apitest.cc",
+        "../browser/extensions/api/management/management_browsertest.cc",
+        "../browser/extensions/api/media_galleries/media_galleries_apitest.cc",
+        "../browser/extensions/api/media_galleries/media_galleries_watch_apitest.cc",
+        "../browser/extensions/api/messaging/native_messaging_apitest.cc",
+        "../browser/extensions/api/metrics_private/metrics_apitest.cc",
+        "../browser/extensions/api/module/module_apitest.cc",
+        "../browser/extensions/api/music_manager_private/music_manager_private_browsertest.cc",
+        "../browser/extensions/api/networking_config_chromeos_apitest_chromeos.cc",
+        "../browser/extensions/api/omnibox/omnibox_api_browsertest.cc",
+        "../browser/extensions/api/page_capture/page_capture_apitest.cc",
+        "../browser/extensions/api/passwords_private/passwords_private_apitest.cc",
+        "../browser/extensions/api/permissions/permissions_apitest.cc",
+        "../browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc",
+        "../browser/extensions/api/preference/preference_apitest.cc",
+        "../browser/extensions/api/processes/processes_apitest.cc",
+        "../browser/extensions/api/proxy/proxy_apitest.cc",
+        "../browser/extensions/api/resources_private/resources_private_apitest.cc",
+        "../browser/extensions/api/screenlock_private/screenlock_private_apitest.cc",
+        "../browser/extensions/api/sessions/sessions_apitest.cc",
+        "../browser/extensions/api/settings_overrides/settings_overrides_browsertest.cc",
+        "../browser/extensions/api/settings_private/settings_private_apitest.cc",
+        "../browser/extensions/api/socket/socket_apitest.cc",
+        "../browser/extensions/api/storage/settings_apitest.cc",
+        "../browser/extensions/api/streams_private/streams_private_apitest.cc",
+        "../browser/extensions/api/sync_file_system/sync_file_system_apitest.cc",
+        "../browser/extensions/api/sync_file_system/sync_file_system_browsertest.cc",
+        "../browser/extensions/api/system_indicator/system_indicator_apitest.cc",
+        "../browser/extensions/api/system_private/system_private_apitest.cc",
+        "../browser/extensions/api/tab_capture/tab_capture_apitest.cc",
+        "../browser/extensions/api/tabs/tabs_test.cc",
+        "../browser/extensions/api/terminal/terminal_private_apitest.cc",
+        "../browser/extensions/api/test/apitest_apitest.cc",
+        "../browser/extensions/api/top_sites/top_sites_apitest.cc",
+        "../browser/extensions/api/web_navigation/web_navigation_apitest.cc",
+        "../browser/extensions/api/web_request/web_request_apitest.cc",
+        "../browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc",
+        "../browser/extensions/api/webrtc_from_web_accessible_resource_browsertest.cc",
+        "../browser/extensions/api/webrtc_logging_private/webrtc_event_log_apitest.cc",
+        "../browser/extensions/api/webrtc_logging_private/webrtc_logging_private_apitest.cc",
+        "../browser/extensions/api/webstore_private/webstore_private_apitest.cc",
+        "../browser/extensions/api_binding_perf_browsertest.cc",
+        "../browser/extensions/app_background_page_apitest.cc",
+        "../browser/extensions/app_process_apitest.cc",
+        "../browser/extensions/app_window_overrides_browsertest.cc",
+        "../browser/extensions/background_app_browsertest.cc",
+        "../browser/extensions/background_page_apitest.cc",
+        "../browser/extensions/background_scripts_apitest.cc",
+        "../browser/extensions/background_xhr_browsertest.cc",
         "../browser/extensions/bookmark_app_helper_browsertest.cc",
         "../browser/extensions/browsertest_util.cc",
         "../browser/extensions/browsertest_util.h",
+        "../browser/extensions/browsertest_util_browsertest.cc",
+        "../browser/extensions/chrome_app_api_browsertest.cc",
+        "../browser/extensions/chrome_theme_url_browsertest.cc",
+        "../browser/extensions/chrome_ui_overrides_browsertest.cc",
+        "../browser/extensions/content_capabilities_browsertest.cc",
+        "../browser/extensions/content_script_apitest.cc",
+        "../browser/extensions/content_security_policy_apitest.cc",
+        "../browser/extensions/content_verifier_browsertest.cc",
+        "../browser/extensions/crazy_extension_browsertest.cc",
+        "../browser/extensions/cross_origin_xhr_apitest.cc",
+        "../browser/extensions/crx_installer_browsertest.cc",
+        "../browser/extensions/docs/examples/apps/calculator_browsertest.cc",
+        "../browser/extensions/error_console/error_console_browsertest.cc",
+        "../browser/extensions/events_apitest.cc",
+        "../browser/extensions/execute_script_apitest.cc",
+        "../browser/extensions/extension_action_runner_browsertest.cc",
         "../browser/extensions/extension_apitest.cc",
         "../browser/extensions/extension_apitest.h",
+        "../browser/extensions/extension_bindings_apitest.cc",
         "../browser/extensions/extension_browsertest.cc",
         "../browser/extensions/extension_browsertest.h",
+        "../browser/extensions/extension_context_menu_browsertest.cc",
+        "../browser/extensions/extension_disabled_ui_browsertest.cc",
+        "../browser/extensions/extension_dom_clipboard_apitest.cc",
+        "../browser/extensions/extension_fileapi_apitest.cc",
         "../browser/extensions/extension_function_test_utils.cc",
         "../browser/extensions/extension_function_test_utils.h",
+        "../browser/extensions/extension_functional_browsertest.cc",
+        "../browser/extensions/extension_geolocation_apitest.cc",
+        "../browser/extensions/extension_get_views_apitest.cc",
+        "../browser/extensions/extension_icon_source_apitest.cc",
+        "../browser/extensions/extension_incognito_apitest.cc",
+        "../browser/extensions/extension_install_prompt_browsertest.cc",
+        "../browser/extensions/extension_install_prompt_test_helper.cc",
+        "../browser/extensions/extension_install_prompt_test_helper.h",
+        "../browser/extensions/extension_install_ui_browsertest.cc",
+        "../browser/extensions/extension_javascript_url_apitest.cc",
+        "../browser/extensions/extension_loading_browsertest.cc",
+        "../browser/extensions/extension_management_test_util.cc",
+        "../browser/extensions/extension_management_test_util.h",
+        "../browser/extensions/extension_messages_apitest.cc",
+        "../browser/extensions/extension_override_apitest.cc",
+        "../browser/extensions/extension_request_limiting_throttle_browsertest.cc",
+        "../browser/extensions/extension_resource_request_policy_apitest.cc",
+        "../browser/extensions/extension_startup_browsertest.cc",
+        "../browser/extensions/extension_storage_apitest.cc",
+        "../browser/extensions/extension_storage_monitor_browsertest.cc",
+        "../browser/extensions/extension_tab_util_browsertest.cc",
+        "../browser/extensions/extension_tabs_apitest.cc",
+        "../browser/extensions/extension_unload_browsertest.cc",
+        "../browser/extensions/extension_url_rewrite_browsertest.cc",
+        "../browser/extensions/extension_view_host_factory_browsertest.cc",
+        "../browser/extensions/extension_websocket_apitest.cc",
+        "../browser/extensions/extension_webui_apitest.cc",
         "../browser/extensions/extension_with_management_policy_apitest.cc",
         "../browser/extensions/extension_with_management_policy_apitest.h",
+        "../browser/extensions/external_install_error_browsertest.cc",
+        "../browser/extensions/fetch_apitest.cc",
+        "../browser/extensions/gpu_browsertest.cc",
+        "../browser/extensions/hotword_browsertest.cc",
+        "../browser/extensions/isolated_app_browsertest.cc",
+        "../browser/extensions/lazy_background_page_apitest.cc",
+        "../browser/extensions/lazy_background_page_test_util.h",
+        "../browser/extensions/mutation_observers_apitest.cc",
+        "../browser/extensions/native_bindings_apitest.cc",
+        "../browser/extensions/navigation_observer_browsertest.cc",
+        "../browser/extensions/options_page_apitest.cc",
+        "../browser/extensions/page_action_browsertest.cc",
+        "../browser/extensions/process_management_browsertest.cc",
+        "../browser/extensions/process_manager_browsertest.cc",
+        "../browser/extensions/renderer_initialization_browsertest.cc",
+        "../browser/extensions/sandboxed_pages_apitest.cc",
+        "../browser/extensions/service_worker_apitest.cc",
+        "../browser/extensions/shared_module_apitest.cc",
+        "../browser/extensions/startup_helper_browsertest.cc",
+        "../browser/extensions/stubs_apitest.cc",
+        "../browser/extensions/subscribe_page_action_browsertest.cc",
         "../browser/extensions/updater/extension_cache_fake.cc",
         "../browser/extensions/updater/extension_cache_fake.h",
+        "../browser/extensions/wake_event_page_apitest.cc",
+        "../browser/extensions/web_contents_browsertest.cc",
+        "../browser/extensions/webstore_inline_installer_browsertest.cc",
+        "../browser/extensions/webstore_installer_browsertest.cc",
+        "../browser/extensions/webstore_installer_test.cc",
+        "../browser/extensions/webstore_installer_test.h",
+        "../browser/extensions/webstore_reinstaller_browsertest.cc",
+        "../browser/extensions/webstore_startup_installer_browsertest.cc",
+        "../browser/extensions/window_open_apitest.cc",
         "../browser/safe_browsing/settings_reset_prompt/default_settings_fetcher_browsertest.cc",
         "../browser/safe_browsing/settings_reset_prompt/settings_reset_prompt_model_browsertest_win.cc",
         "../browser/safe_browsing/settings_reset_prompt/settings_reset_prompt_test_utils.cc",
@@ -1980,6 +1979,7 @@
 
       deps += [
         "//chrome/common/extensions/api",
+        "//components/guest_view/browser:test_support",
 
         # TODO(rockot) bug 505926: The chrome_extensions_browsertests target
         # should be deleted and this line removed. See the
@@ -2065,7 +2065,10 @@
       ]
       deps += [ "//ui/views" ]
       if (!is_chromeos && (!is_mac || mac_views_browser)) {
-        sources += [ "../browser/ui/views/profiles/profile_chooser_view_browsertest.cc" ]
+        sources += [
+          "../browser/ui/views/profiles/forced_reauthentication_dialog_browsertest.cc",
+          "../browser/ui/views/profiles/profile_chooser_view_browsertest.cc",
+        ]
       }
       if (!is_mac || mac_views_browser) {
         sources += [
@@ -3283,7 +3286,6 @@
     "../browser/ui/sync/tab_contents_synced_tab_delegate_unittest.cc",
     "../browser/ui/tests/ui_gfx_image_unittest.cc",
     "../browser/ui/tests/ui_gfx_image_unittest.mm",
-    "../browser/ui/webui/browsing_history_handler_unittest.cc",
     "../browser/ui/webui/fileicon_source_unittest.cc",
     "../browser/ui/webui/local_state/local_state_ui_unittest.cc",
     "../browser/ui/webui/log_web_ui_url_unittest.cc",
@@ -3637,6 +3639,7 @@
       "../browser/ui/toolbar/toolbar_actions_bar_unittest.h",
       "../browser/ui/toolbar/toolbar_actions_model_unittest.cc",
       "../browser/ui/toolbar/toolbar_model_unittest.cc",
+      "../browser/ui/webui/browsing_history_handler_unittest.cc",
       "../browser/ui/webui/help/version_updater_chromeos_unittest.cc",
       "../browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc",
       "../browser/ui/webui/md_downloads/md_downloads_dom_handler_unittest.cc",
diff --git a/chrome/test/data/android/webvr_instrumentation/html/test_pose_data_unfocused_tab.html b/chrome/test/data/android/webvr_instrumentation/html/test_pose_data_unfocused_tab.html
index 4a5de60..30e5934a 100644
--- a/chrome/test/data/android/webvr_instrumentation/html/test_pose_data_unfocused_tab.html
+++ b/chrome/test/data/android/webvr_instrumentation/html/test_pose_data_unfocused_tab.html
@@ -29,7 +29,7 @@
           finishJavaScriptStep();
         }
         // Make sure at least one rAF call has happened so we get valid data
-        window.requestAnimationFrame(onAnimationFrame);
+        vrDisplay.requestAnimationFrame(onAnimationFrame);
       }
 
       function stepCheckFrameDataWhileNonFocusedTab() {
diff --git a/chrome/test/data/webui/settings/search_engines_page_test.js b/chrome/test/data/webui/settings/search_engines_page_test.js
index 36be7c2..55090ac 100644
--- a/chrome/test/data/webui/settings/search_engines_page_test.js
+++ b/chrome/test/data/webui/settings/search_engines_page_test.js
@@ -4,31 +4,32 @@
 
 cr.define('settings_search_engines_page', function() {
   /**
+   * @param {string} name
    * @param {boolean} canBeDefault
    * @param {boolean} canBeEdited
    * @param {boolean} canBeRemoved
    * @return {!SearchEngine}
    */
-  var createSampleSearchEngine = function(
-      canBeDefault, canBeEdited, canBeRemoved) {
+  function createSampleSearchEngine(
+      name, canBeDefault, canBeEdited, canBeRemoved) {
     return {
       canBeDefault: canBeDefault,
       canBeEdited: canBeEdited,
       canBeRemoved: canBeRemoved,
       default: false,
-      displayName: "Google displayName",
+      displayName: name + " displayName",
       iconURL: "http://www.google.com/favicon.ico",
       isOmniboxExtension: false,
       keyword: "google.com",
       modelIndex: 0,
-      name: "Google",
+      name: name,
       url: "https://search.foo.com/search?p=%s",
       urlLocked: false,
     };
-  };
+  }
 
   /** @return {!SearchEngine} */
-  var createSampleOmniboxExtension = function() {
+  function createSampleOmniboxExtension() {
     return {
       canBeDefault: false,
       canBeEdited: false,
@@ -47,7 +48,7 @@
       url: "chrome-extension://dummyextensionid/?q=%s",
       urlLocked: false
     };
-  };
+  }
 
   function registerDialogTests() {
     suite('AddSearchEngineDialogTests', function() {
@@ -146,7 +147,7 @@
       var browserProxy = null;
 
       /** @type {!SearchEngine} */
-      var searchEngine = createSampleSearchEngine(true, true, true);
+      var searchEngine = createSampleSearchEngine('G', true, true, true);
 
       setup(function() {
         browserProxy = new settings_search.TestSearchEnginesBrowserProxy();
@@ -248,24 +249,25 @@
 
       test('Remove_Disabled', function() {
         testButtonDisabled(
-            createSampleSearchEngine(true, true, false), 'delete');
+            createSampleSearchEngine('G', true, true, false), 'delete');
       });
 
       test('MakeDefault_Disabled', function() {
         testButtonDisabled(
-            createSampleSearchEngine(false, true, true), 'makeDefault');
+            createSampleSearchEngine('G', false, true, true), 'makeDefault');
       });
 
       test('Edit_Disabled', function() {
-        testButtonDisabled(createSampleSearchEngine(true, false, true), 'edit');
+        testButtonDisabled(
+            createSampleSearchEngine('G', true, false, true), 'edit');
       });
 
       test('All_Disabled', function() {
-        entry.engine = createSampleSearchEngine(true, false, false);
+        entry.engine = createSampleSearchEngine('G', true, false, false);
         Polymer.dom.flush();
         assertTrue(entry.hasAttribute('show-dots_'));
 
-        entry.engine = createSampleSearchEngine(false, false, false);
+        entry.engine = createSampleSearchEngine('G', false, false, false);
         Polymer.dom.flush();
         assertFalse(entry.hasAttribute('show-dots_'));
       });
@@ -281,14 +283,24 @@
 
       /** @type {!SearchEnginesInfo} */
       var searchEnginesInfo = {
-        defaults: [createSampleSearchEngine()],
-        others: [],
+        defaults: [createSampleSearchEngine('G', false, false, false)],
+        others: [
+          createSampleSearchEngine('B', false, false, false),
+          createSampleSearchEngine('A', false, false, false),
+        ],
         extensions: [createSampleOmniboxExtension()],
       };
 
       setup(function() {
         browserProxy = new settings_search.TestSearchEnginesBrowserProxy();
-        browserProxy.setSearchEnginesInfo(searchEnginesInfo);
+
+        // Purposefully pass a clone of |searchEnginesInfo| to avoid any
+        // mutations on ground truth data.
+        browserProxy.setSearchEnginesInfo({
+          defaults: searchEnginesInfo.defaults.slice(),
+          others: searchEnginesInfo.others.slice(),
+          extensions: searchEnginesInfo.extensions.slice(),
+        });
         settings.SearchEnginesBrowserProxyImpl.instance_ = browserProxy;
         PolymerTest.clearBody();
         page = document.createElement('settings-search-engines-page');
@@ -320,6 +332,15 @@
         assertEquals(
             searchEnginesInfo.others.length, othersEntries.length);
 
+        // Ensure that the search engines have reverse alphabetical order in the
+        // model.
+        assertGT(
+            searchEnginesInfo.others[0].name, searchEnginesInfo.others[1].name);
+
+        // Ensure that they are displayed in alphabetical order.
+        assertEquals(searchEnginesInfo.others[1].name, othersEntries[0].name);
+        assertEquals(searchEnginesInfo.others[0].name, othersEntries[1].name);
+
         var extensionEntries = Polymer.dom(page.shadowRoot).
             querySelector('iron-list').items;
         assertEquals(
@@ -329,13 +350,17 @@
       // Test that the "no other search engines" message is shown/hidden as
       // expected.
       test('NoOtherSearchEnginesMessage', function() {
+        cr.webUIListenerCallback('search-engines-changed', {
+          defaults: [], others: [], extensions: [],
+        });
+
         var message = page.root.querySelector('#noOtherEngines');
         assertTrue(!!message);
         assertFalse(message.hasAttribute('hidden'));
 
         cr.webUIListenerCallback('search-engines-changed', {
           defaults: [],
-          others: [createSampleSearchEngine()],
+          others: [createSampleSearchEngine('G', false, false, false)],
           extensions: [],
         });
         assertTrue(message.hasAttribute('hidden'));
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn
index 6b5f660..ae6c6f4 100644
--- a/chromecast/browser/BUILD.gn
+++ b/chromecast/browser/BUILD.gn
@@ -136,8 +136,8 @@
     ]
 
     deps += [
-      "//build/linux:fontconfig",
       "//components/metrics:serialization",
+      "//third_party/fontconfig",
       "//ui/aura",
     ]
   } else if (is_android) {
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
index a80de1cb..90c47745a 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
@@ -17,6 +17,7 @@
 import android.support.v4.content.LocalBroadcastManager;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
+import android.view.View;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
 import android.widget.Toast;
@@ -222,6 +223,16 @@
     }
 
     @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+        if (DEBUG) Log.d(TAG, "onWindowFocusChanged(%b)", hasFocus);
+        super.onWindowFocusChanged(hasFocus);
+        if (hasFocus) {
+            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN);
+        }
+    }
+
+    @Override
     protected void onUserLeaveHint() {
         if (DEBUG) Log.d(TAG, "onUserLeaveHint");
         mReceivedUserLeave = true;
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc
index 8c06b00..42245cb4 100644
--- a/chromeos/chromeos_switches.cc
+++ b/chromeos/chromeos_switches.cc
@@ -435,8 +435,8 @@
 // If true, the views-based md login and lock screens will be shown.
 const char kShowMdLogin[] = "show-md-login";
 
-// If true, the non-views-based md login and lock screens will be shown.
-const char kShowNonViewMdLogin[] = "show-non-view-md-login";
+// If true, the non-md login and lock screens will be shown.
+const char kShowNonMdLogin[] = "show-non-md-login";
 
 // Specifies power stub behavior:
 //  'cycle=2' - Cycles power states every 2 seconds.
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h
index 301f39f..de55381e 100644
--- a/chromeos/chromeos_switches.h
+++ b/chromeos/chromeos_switches.h
@@ -131,7 +131,7 @@
 CHROMEOS_EXPORT extern const char kOobeSkipPostLogin[];
 CHROMEOS_EXPORT extern const char kOobeTimerInterval[];
 CHROMEOS_EXPORT extern const char kShowMdLogin[];
-CHROMEOS_EXPORT extern const char kShowNonViewMdLogin[];
+CHROMEOS_EXPORT extern const char kShowNonMdLogin[];
 CHROMEOS_EXPORT extern const char kPowerStub[];
 CHROMEOS_EXPORT extern const char kShillStub[];
 CHROMEOS_EXPORT extern const char kSmsTestMessages[];
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc
index 6bf3463..fbc3612 100644
--- a/chromeos/network/network_state_handler.cc
+++ b/chromeos/network/network_state_handler.cc
@@ -423,9 +423,8 @@
   if (!network_list_sorted_)
     SortNetworkList();
 
-  if (type.MatchesPattern(NetworkTypePattern::Tether())) {
+  if (type.MatchesPattern(NetworkTypePattern::Tether()))
     GetTetherNetworkList(limit, list);
-  }
 
   int count = list->size();
 
@@ -461,8 +460,11 @@
                                                NetworkStateList* list) {
   DCHECK(list);
   list->clear();
-  int count = 0;
 
+  if (!IsTechnologyEnabled(NetworkTypePattern::Tether()))
+    return;
+
+  int count = 0;
   for (auto iter = tether_network_list_.begin();
        iter != tether_network_list_.end(); ++iter) {
     list->push_back((*iter)->AsNetworkState());
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 482b3b8..2dd5ed6f 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -172,6 +172,7 @@
       "//components/autofill/content/common:unit_tests",
       "//components/autofill/content/renderer:unit_tests",
       "//components/cast_certificate:unit_tests",
+      "//components/cast_channel:unit_tests",
       "//components/certificate_reporting:unit_tests",
       "//components/certificate_transparency:unit_tests",
       "//components/contextual_search:unit_tests",
diff --git a/components/cast_channel/BUILD.gn b/components/cast_channel/BUILD.gn
index ef44a6e..71f791ed 100644
--- a/components/cast_channel/BUILD.gn
+++ b/components/cast_channel/BUILD.gn
@@ -4,10 +4,77 @@
 
 static_library("cast_channel") {
   sources = [
+    "cast_auth_util.cc",
+    "cast_auth_util.h",
     "cast_channel_enum.cc",
     "cast_channel_enum.h",
+    "cast_framer.cc",
+    "cast_framer.h",
+    "cast_message_util.cc",
+    "cast_message_util.h",
+    "cast_socket.cc",
+    "cast_socket.h",
+    "cast_socket_service.cc",
+    "cast_socket_service.h",
+    "cast_socket_service_factory.cc",
+    "cast_socket_service_factory.h",
+    "cast_transport.cc",
+    "cast_transport.h",
+    "keep_alive_delegate.cc",
+    "keep_alive_delegate.h",
+    "logger.cc",
+    "logger.h",
   ]
   deps = [
     "//base",
+    "//components/cast_certificate",
+    "//components/cast_channel/proto:cast_channel_proto",
+    "//components/keyed_service/content",
+    "//components/keyed_service/core",
+    "//content/public/browser",
+    "//crypto",
+    "//net",
+  ]
+}
+
+static_library("test_support") {
+  testonly = true
+  sources = [
+    "cast_test_util.cc",
+    "cast_test_util.h",
+  ]
+  deps = [
+    ":cast_channel",
+    "//base",
+    "//components/cast_channel/proto:cast_channel_proto",
+    "//net",
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [
+    "cast_auth_util_unittest.cc",
+    "cast_framer_unittest.cc",
+    "cast_socket_service_unittest.cc",
+    "cast_socket_unittest.cc",
+    "cast_transport_unittest.cc",
+    "keep_alive_delegate_unittest.cc",
+    "logger_unittest.cc",
+  ]
+  deps = [
+    ":cast_channel",
+    ":test_support",
+    "//base/test:test_support",
+    "//components/cast_certificate",
+    "//components/cast_certificate:test_support",
+    "//components/cast_certificate/proto:unittest_proto",
+    "//components/cast_channel/proto:cast_channel_proto",
+    "//content/test:test_support",
+    "//net:test_support",
+    "//testing/gmock",
+    "//testing/gtest",
   ]
 }
diff --git a/components/cast_channel/DEPS b/components/cast_channel/DEPS
new file mode 100644
index 0000000..97e6b97a
--- /dev/null
+++ b/components/cast_channel/DEPS
@@ -0,0 +1,8 @@
+include_rules = [
+  "+components/cast_certificate",
+  "+components/keyed_service",
+  "+content/public/browser",
+  "+content/public/test",
+  "+crypto",
+  "+net",
+]
diff --git a/extensions/browser/api/cast_channel/cast_auth_util.cc b/components/cast_channel/cast_auth_util.cc
similarity index 97%
rename from extensions/browser/api/cast_channel/cast_auth_util.cc
rename to components/cast_channel/cast_auth_util.cc
index 9406fde8..82caae5 100644
--- a/extensions/browser/api/cast_channel/cast_auth_util.cc
+++ b/components/cast_channel/cast_auth_util.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/cast_auth_util.h"
+#include "components/cast_channel/cast_auth_util.h"
 
 #include <vector>
 
@@ -17,14 +17,12 @@
 #include "base/strings/stringprintf.h"
 #include "components/cast_certificate/cast_cert_validator.h"
 #include "components/cast_certificate/cast_crl.h"
+#include "components/cast_channel/cast_message_util.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
 #include "crypto/random.h"
-#include "extensions/browser/api/cast_channel/cast_message_util.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
 #include "net/cert/x509_certificate.h"
 #include "net/der/parse_values.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 namespace {
 
@@ -169,8 +167,7 @@
 AuthResult::AuthResult(const std::string& error_message, ErrorType error_type)
     : error_message(error_message), error_type(error_type) {}
 
-AuthResult::~AuthResult() {
-}
+AuthResult::~AuthResult() {}
 
 // static
 AuthResult AuthResult::CreateWithParseError(const std::string& error_message,
@@ -395,5 +392,3 @@
 }
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/cast_auth_util.h b/components/cast_channel/cast_auth_util.h
similarity index 92%
rename from extensions/browser/api/cast_channel/cast_auth_util.h
rename to components/cast_channel/cast_auth_util.h
index d578c56..be187738 100644
--- a/extensions/browser/api/cast_channel/cast_auth_util.h
+++ b/components/cast_channel/cast_auth_util.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 EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_AUTH_UTIL_H_
-#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_AUTH_UTIL_H_
+#ifndef COMPONENTS_CAST_CHANNEL_CAST_AUTH_UTIL_H_
+#define COMPONENTS_CAST_CHANNEL_CAST_AUTH_UTIL_H_
 
 #include <string>
 
@@ -19,8 +19,6 @@
 class TrustStore;
 }  // namespace net
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
 class AuthResponse;
@@ -120,7 +118,5 @@
     const base::Time& verification_time);
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_AUTH_UTIL_H_
+#endif  // COMPONENTS_CAST_CHANNEL_CAST_AUTH_UTIL_H_
diff --git a/extensions/browser/api/cast_channel/cast_auth_util_unittest.cc b/components/cast_channel/cast_auth_util_unittest.cc
similarity index 97%
rename from extensions/browser/api/cast_channel/cast_auth_util_unittest.cc
rename to components/cast_channel/cast_auth_util_unittest.cc
index b6580685..fba22eb1 100644
--- a/extensions/browser/api/cast_channel/cast_auth_util_unittest.cc
+++ b/components/cast_channel/cast_auth_util_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/cast_auth_util.h"
+#include "components/cast_channel/cast_auth_util.h"
 
 #include <string>
 
@@ -13,13 +13,11 @@
 #include "components/cast_certificate/cast_cert_validator_test_helpers.h"
 #include "components/cast_certificate/cast_crl.h"
 #include "components/cast_certificate/proto/test_suite.pb.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
 #include "net/cert/internal/trust_store_in_memory.h"
 #include "net/cert/x509_certificate.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 namespace {
 
@@ -335,5 +333,3 @@
 
 }  // namespace
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/cast_framer.cc b/components/cast_channel/cast_framer.cc
similarity index 93%
rename from extensions/browser/api/cast_channel/cast_framer.cc
rename to components/cast_channel/cast_framer.cc
index 0bd744fa..9b5d6fe5 100644
--- a/extensions/browser/api/cast_channel/cast_framer.cc
+++ b/components/cast_channel/cast_framer.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/cast_framer.h"
+#include "components/cast_channel/cast_framer.h"
 
 #include <stdlib.h>
 
@@ -12,21 +12,17 @@
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/sys_byteorder.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 MessageFramer::MessageFramer(scoped_refptr<net::GrowableIOBuffer> input_buffer)
     : input_buffer_(input_buffer), error_(false) {
   Reset();
 }
 
-MessageFramer::~MessageFramer() {
-}
+MessageFramer::~MessageFramer() {}
 
-MessageFramer::MessageHeader::MessageHeader() : message_size(0) {
-}
+MessageFramer::MessageHeader::MessageHeader() : message_size(0) {}
 
 void MessageFramer::MessageHeader::SetMessageSize(size_t size) {
   DCHECK_LT(size, static_cast<size_t>(std::numeric_limits<uint32_t>::max()));
@@ -102,9 +98,8 @@
     case BODY:
       bytes_left =
           (body_size_ + MessageHeader::header_size()) - message_bytes_received_;
-      DCHECK_LE(
-          bytes_left,
-          MessageHeader::max_message_size() - MessageHeader::header_size());
+      DCHECK_LE(bytes_left, MessageHeader::max_message_size() -
+                                MessageHeader::header_size());
       VLOG(2) << "Bytes needed for body: " << bytes_left;
       return bytes_left;
     default:
@@ -177,5 +172,3 @@
 }
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/cast_framer.h b/components/cast_channel/cast_framer.h
similarity index 92%
rename from extensions/browser/api/cast_channel/cast_framer.h
rename to components/cast_channel/cast_framer.h
index 8a5b6b5..657f2ad 100644
--- a/extensions/browser/api/cast_channel/cast_framer.h
+++ b/components/cast_channel/cast_framer.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 EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_FRAMER_H_
-#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_FRAMER_H_
+#ifndef COMPONENTS_CAST_CHANNEL_CAST_FRAMER_H_
+#define COMPONENTS_CAST_CHANNEL_CAST_FRAMER_H_
 
 #include <stddef.h>
 #include <stdint.h>
@@ -15,8 +15,6 @@
 #include "components/cast_channel/cast_channel_enum.h"
 #include "net/base/io_buffer.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 class CastMessage;
 
@@ -100,6 +98,4 @@
   DISALLOW_COPY_AND_ASSIGN(MessageFramer);
 };
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
-#endif  // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_FRAMER_H_
+#endif  // COMPONENTS_CAST_CHANNEL_CAST_FRAMER_H_
diff --git a/extensions/browser/api/cast_channel/cast_framer_unittest.cc b/components/cast_channel/cast_framer_unittest.cc
similarity index 90%
rename from extensions/browser/api/cast_channel/cast_framer_unittest.cc
rename to components/cast_channel/cast_framer_unittest.cc
index 87c76e4..660e074 100644
--- a/extensions/browser/api/cast_channel/cast_framer_unittest.cc
+++ b/components/cast_channel/cast_framer_unittest.cc
@@ -2,18 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/cast_framer.h"
+#include "components/cast_channel/cast_framer.h"
 
 #include <stddef.h>
 
 #include <algorithm>
 #include <string>
 
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
 using ::cast_channel::ChannelError;
@@ -115,12 +113,10 @@
   // Message header is OK, but the body is replaced with "x"en.
   std::string mangled_cast_message = cast_message_str_;
   for (size_t i = MessageFramer::MessageHeader::header_size();
-       i < mangled_cast_message.size();
-       ++i) {
+       i < mangled_cast_message.size(); ++i) {
     std::fill(mangled_cast_message.begin() +
                   MessageFramer::MessageHeader::header_size(),
-              mangled_cast_message.end(),
-              'x');
+              mangled_cast_message.end(), 'x');
   }
   WriteToBuffer(mangled_cast_message);
 
@@ -134,10 +130,9 @@
 
   // Send body, expect an error.
   std::unique_ptr<CastMessage> message;
-  EXPECT_EQ(nullptr, framer_->Ingest(framer_->BytesRequested(), &message_length,
-                                     &error).get());
+  EXPECT_EQ(nullptr,
+            framer_->Ingest(framer_->BytesRequested(), &message_length, &error)
+                .get());
   EXPECT_EQ(ChannelError::INVALID_MESSAGE, error);
 }
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/components/cast_channel/cast_message_util.cc b/components/cast_channel/cast_message_util.cc
new file mode 100644
index 0000000..50c4be1
--- /dev/null
+++ b/components/cast_channel/cast_message_util.cc
@@ -0,0 +1,87 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/cast_channel/cast_message_util.h"
+
+#include <memory>
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/values.h"
+#include "components/cast_channel/cast_auth_util.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
+
+namespace {
+static const char kAuthNamespace[] = "urn:x-cast:com.google.cast.tp.deviceauth";
+// Sender and receiver IDs to use for platform messages.
+static const char kPlatformSenderId[] = "sender-0";
+static const char kPlatformReceiverId[] = "receiver-0";
+}  // namespace
+
+namespace cast_channel {
+
+bool IsCastMessageValid(const CastMessage& message_proto) {
+  if (message_proto.namespace_().empty() || message_proto.source_id().empty() ||
+      message_proto.destination_id().empty()) {
+    return false;
+  }
+  return (message_proto.payload_type() == CastMessage_PayloadType_STRING &&
+          message_proto.has_payload_utf8()) ||
+         (message_proto.payload_type() == CastMessage_PayloadType_BINARY &&
+          message_proto.has_payload_binary());
+}
+
+std::string CastMessageToString(const CastMessage& message_proto) {
+  std::string out("{");
+  out += "namespace = " + message_proto.namespace_();
+  out += ", sourceId = " + message_proto.source_id();
+  out += ", destId = " + message_proto.destination_id();
+  out += ", type = " + base::IntToString(message_proto.payload_type());
+  out += ", str = \"" + message_proto.payload_utf8() + "\"}";
+  return out;
+}
+
+std::string AuthMessageToString(const DeviceAuthMessage& message) {
+  std::string out("{");
+  if (message.has_challenge()) {
+    out += "challenge: {}, ";
+  }
+  if (message.has_response()) {
+    out += "response: {signature: (";
+    out += base::SizeTToString(message.response().signature().length());
+    out += " bytes), certificate: (";
+    out += base::SizeTToString(
+        message.response().client_auth_certificate().length());
+    out += " bytes)}";
+  }
+  if (message.has_error()) {
+    out += ", error: {";
+    out += base::IntToString(message.error().error_type());
+    out += "}";
+  }
+  out += "}";
+  return out;
+}
+
+void CreateAuthChallengeMessage(CastMessage* message_proto,
+                                const AuthContext& auth_context) {
+  CHECK(message_proto);
+  DeviceAuthMessage auth_message;
+  auth_message.mutable_challenge()->set_sender_nonce(auth_context.nonce());
+  std::string auth_message_string;
+  auth_message.SerializeToString(&auth_message_string);
+
+  message_proto->set_protocol_version(CastMessage_ProtocolVersion_CASTV2_1_0);
+  message_proto->set_source_id(kPlatformSenderId);
+  message_proto->set_destination_id(kPlatformReceiverId);
+  message_proto->set_namespace_(kAuthNamespace);
+  message_proto->set_payload_type(CastMessage_PayloadType_BINARY);
+  message_proto->set_payload_binary(auth_message_string);
+}
+
+bool IsAuthMessage(const CastMessage& message) {
+  return message.namespace_() == kAuthNamespace;
+}
+
+}  // namespace cast_channel
diff --git a/components/cast_channel/cast_message_util.h b/components/cast_channel/cast_message_util.h
new file mode 100644
index 0000000..db30a227
--- /dev/null
+++ b/components/cast_channel/cast_message_util.h
@@ -0,0 +1,35 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CAST_CHANNEL_CAST_MESSAGE_UTIL_H_
+#define COMPONENTS_CAST_CHANNEL_CAST_MESSAGE_UTIL_H_
+
+#include <string>
+
+namespace cast_channel {
+
+class AuthContext;
+class CastMessage;
+class DeviceAuthMessage;
+
+// Checks if the contents of |message_proto| are valid.
+bool IsCastMessageValid(const CastMessage& message_proto);
+
+// Returns a human readable string for |message_proto|.
+std::string CastMessageToString(const CastMessage& message_proto);
+
+// Returns a human readable string for |message|.
+std::string AuthMessageToString(const DeviceAuthMessage& message);
+
+// Fills |message_proto| appropriately for an auth challenge request message.
+// Uses the nonce challenge in |auth_context|.
+void CreateAuthChallengeMessage(CastMessage* message_proto,
+                                const AuthContext& auth_context);
+
+// Returns whether the given message is an auth handshake message.
+bool IsAuthMessage(const CastMessage& message);
+
+}  // namespace cast_channel
+
+#endif  // COMPONENTS_CAST_CHANNEL_CAST_MESSAGE_UTIL_H_
diff --git a/extensions/browser/api/cast_channel/cast_socket.cc b/components/cast_channel/cast_socket.cc
similarity index 94%
rename from extensions/browser/api/cast_channel/cast_socket.cc
rename to components/cast_channel/cast_socket.cc
index cb258625..3675874 100644
--- a/extensions/browser/api/cast_channel/cast_socket.cc
+++ b/components/cast_channel/cast_socket.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/cast_socket.h"
+#include "components/cast_channel/cast_socket.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -22,12 +22,12 @@
 #include "base/sys_byteorder.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
-#include "extensions/browser/api/cast_channel/cast_auth_util.h"
-#include "extensions/browser/api/cast_channel/cast_framer.h"
-#include "extensions/browser/api/cast_channel/cast_message_util.h"
-#include "extensions/browser/api/cast_channel/cast_transport.h"
-#include "extensions/browser/api/cast_channel/logger.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
+#include "components/cast_channel/cast_auth_util.h"
+#include "components/cast_channel/cast_framer.h"
+#include "components/cast_channel/cast_message_util.h"
+#include "components/cast_channel/cast_transport.h"
+#include "components/cast_channel/logger.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
 #include "net/base/address_list.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/net_errors.h"
@@ -57,8 +57,6 @@
 #define VLOG_WITH_CONNECTION(level) VLOG(level) << CONNECTION_INFO()
 #define LOG_WITH_CONNECTION(level) LOG(level) << CONNECTION_INFO()
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 namespace {
 
@@ -207,8 +205,8 @@
   std::unique_ptr<net::ClientSocketHandle> connection(
       new net::ClientSocketHandle);
   connection->SetSocket(std::move(socket));
-  net::HostPortPair host_and_port = net::HostPortPair::FromIPEndPoint(
-      ip_endpoint_);
+  net::HostPortPair host_and_port =
+      net::HostPortPair::FromIPEndPoint(ip_endpoint_);
 
   return net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket(
       std::move(connection), host_and_port, ssl_config, context);
@@ -254,7 +252,7 @@
 
 void CastSocketImpl::Connect(std::unique_ptr<CastTransport::Delegate> delegate,
                              base::Callback<void(ChannelError)> callback) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   VLOG_WITH_CONNECTION(1) << "Connect readyState = "
                           << ::cast_channel::ReadyStateToString(ready_state_);
   DCHECK_EQ(proto::CONN_STATE_START_CONNECT, connect_state_);
@@ -275,8 +273,7 @@
     DCHECK(connect_timeout_callback_.IsCancelled());
     connect_timeout_callback_.Reset(
         base::Bind(&CastSocketImpl::OnConnectTimeout, base::Unretained(this)));
-    GetTimer()->Start(FROM_HERE,
-                      connect_timeout_,
+    GetTimer()->Start(FROM_HERE, connect_timeout_,
                       connect_timeout_callback_.callback());
   }
 
@@ -288,7 +285,7 @@
 }
 
 void CastSocketImpl::OnConnectTimeout() {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   // Stop all pending connection setup tasks and report back to the client.
   is_canceled_ = true;
   VLOG_WITH_CONNECTION(1) << "Timeout while establishing a connection.";
@@ -303,7 +300,7 @@
 }
 
 void CastSocketImpl::PostTaskToStartConnectLoop(int result) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   ResetConnectLoopCallback();
   base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -508,8 +505,7 @@
   }
 }
 
-void CastSocketImpl::AuthTransportDelegate::Start() {
-}
+void CastSocketImpl::AuthTransportDelegate::Start() {}
 
 int CastSocketImpl::DoAuthChallengeReplyComplete(int result) {
   VLOG_WITH_CONNECTION(1) << "DoAuthChallengeReplyComplete: " << result;
@@ -556,7 +552,7 @@
 }
 
 void CastSocketImpl::Close(const net::CompletionCallback& callback) {
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   CloseInternal();
   // Run this callback last.  It may delete the socket.
   callback.Run(net::OK);
@@ -565,7 +561,7 @@
 void CastSocketImpl::CloseInternal() {
   // TODO(mfoltz): Enforce this when CastChannelAPITest is rewritten to create
   // and free sockets on the same thread.  crbug.com/398242
-  DCHECK(CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   if (ready_state_ == ReadyState::CLOSED) {
     return;
   }
@@ -587,10 +583,6 @@
   SetReadyState(ReadyState::CLOSED);
 }
 
-bool CastSocketImpl::CalledOnValidThread() const {
-  return thread_checker_.CalledOnValidThread();
-}
-
 base::Timer* CastSocketImpl::GetTimer() {
   return connect_timeout_timer_.get();
 }
@@ -615,6 +607,4 @@
 }
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
 #undef VLOG_WITH_CONNECTION
diff --git a/extensions/browser/api/cast_channel/cast_socket.h b/components/cast_channel/cast_socket.h
similarity index 95%
rename from extensions/browser/api/cast_channel/cast_socket.h
rename to components/cast_channel/cast_socket.h
index 242508f..42b3546 100644
--- a/extensions/browser/api/cast_channel/cast_socket.h
+++ b/components/cast_channel/cast_socket.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 EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_
-#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_
+#ifndef COMPONENTS_CAST_CHANNEL_CAST_SOCKET_H_
+#define COMPONENTS_CAST_CHANNEL_CAST_SOCKET_H_
 
 #include <stdint.h>
 
@@ -16,13 +16,11 @@
 #include "base/memory/ref_counted.h"
 #include "base/threading/thread_checker.h"
 #include "base/timer/timer.h"
+#include "components/cast_channel/cast_auth_util.h"
 #include "components/cast_channel/cast_channel_enum.h"
-#include "extensions/browser/api/api_resource.h"
-#include "extensions/browser/api/api_resource_manager.h"
-#include "extensions/browser/api/cast_channel/cast_auth_util.h"
-#include "extensions/browser/api/cast_channel/cast_socket.h"
-#include "extensions/browser/api/cast_channel/cast_transport.h"
-#include "extensions/common/api/cast_channel/logging.pb.h"
+#include "components/cast_channel/cast_socket.h"
+#include "components/cast_channel/cast_transport.h"
+#include "components/cast_channel/proto/logging.pb.h"
 #include "net/base/completion_callback.h"
 #include "net/base/io_buffer.h"
 #include "net/base/ip_endpoint.h"
@@ -40,8 +38,6 @@
 class X509Certificate;
 }
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 class CastMessage;
 class Logger;
@@ -289,14 +285,12 @@
   // Runs the external connection callback and resets it.
   void DoConnectCallback();
 
-  virtual bool CalledOnValidThread() const;
-
   virtual base::Timer* GetTimer();
 
   void SetConnectState(proto::ConnectionState connect_state);
   void SetReadyState(ReadyState ready_state);
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // The id of the channel.
   int channel_id_;
@@ -396,7 +390,5 @@
   DISALLOW_COPY_AND_ASSIGN(CastSocketImpl);
 };
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_
+#endif  // COMPONENTS_CAST_CHANNEL_CAST_SOCKET_H_
diff --git a/extensions/browser/api/cast_channel/cast_socket_service.cc b/components/cast_channel/cast_socket_service.cc
similarity index 90%
rename from extensions/browser/api/cast_channel/cast_socket_service.cc
rename to components/cast_channel/cast_socket_service.cc
index e6fc923..f58c985 100644
--- a/extensions/browser/api/cast_channel/cast_socket_service.cc
+++ b/components/cast_channel/cast_socket_service.cc
@@ -2,15 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/cast_socket_service.h"
+#include "components/cast_channel/cast_socket_service.h"
 
 #include "base/memory/ptr_util.h"
 #include "content/public/browser/browser_thread.h"
 
 using content::BrowserThread;
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
 int CastSocketService::last_channel_id_ = 0;
@@ -57,5 +55,3 @@
 void CastSocketService::ShutdownOnUIThread() {}
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/cast_socket_service.h b/components/cast_channel/cast_socket_service.h
similarity index 82%
rename from extensions/browser/api/cast_channel/cast_socket_service.h
rename to components/cast_channel/cast_socket_service.h
index 13b1887..d7d016b 100644
--- a/extensions/browser/api/cast_channel/cast_socket_service.h
+++ b/components/cast_channel/cast_socket_service.h
@@ -2,20 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_SERVICE_H_
-#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_SERVICE_H_
+#ifndef COMPONENTS_CAST_CHANNEL_CAST_CHANNEL_SERVICE_H_
+#define COMPONENTS_CAST_CHANNEL_CAST_CHANNEL_SERVICE_H_
 
 #include <map>
 #include <memory>
 
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
+#include "components/cast_channel/cast_socket.h"
 #include "components/keyed_service/core/refcounted_keyed_service.h"
 #include "content/public/browser/browser_thread.h"
-#include "extensions/browser/api/cast_channel/cast_socket.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
 // This class adds, removes, and returns cast sockets created by CastChannelAPI
@@ -56,7 +54,5 @@
 };
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_SERVICE_H_
+#endif  // COMPONENTS_CAST_CHANNEL_CAST_CHANNEL_SERVICE_H_
diff --git a/extensions/browser/api/cast_channel/cast_socket_service_factory.cc b/components/cast_channel/cast_socket_service_factory.cc
similarity index 87%
rename from extensions/browser/api/cast_channel/cast_socket_service_factory.cc
rename to components/cast_channel/cast_socket_service_factory.cc
index 88e1893..bf0757d 100644
--- a/extensions/browser/api/cast_channel/cast_socket_service_factory.cc
+++ b/components/cast_channel/cast_socket_service_factory.cc
@@ -2,13 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/cast_socket_service_factory.h"
+#include "components/cast_channel/cast_socket_service_factory.h"
 
+#include "components/cast_channel/cast_socket_service.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "extensions/browser/api/cast_channel/cast_socket_service.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
 using content::BrowserContext;
@@ -53,5 +51,3 @@
 }
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/cast_socket_service_factory.h b/components/cast_channel/cast_socket_service_factory.h
similarity index 81%
rename from extensions/browser/api/cast_channel/cast_socket_service_factory.h
rename to components/cast_channel/cast_socket_service_factory.h
index 32b44a2f..f3824c7 100644
--- a/extensions/browser/api/cast_channel/cast_socket_service_factory.h
+++ b/components/cast_channel/cast_socket_service_factory.h
@@ -2,15 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_SERVICE_FACTORY_H_
-#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_SERVICE_FACTORY_H_
+#ifndef COMPONENTS_CAST_CHANNEL_CAST_SOCKET_SERVICE_FACTORY_H_
+#define COMPONENTS_CAST_CHANNEL_CAST_SOCKET_SERVICE_FACTORY_H_
 
 #include "base/lazy_instance.h"
 #include "base/macros.h"
 #include "components/keyed_service/content/refcounted_browser_context_keyed_service_factory.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
 class CastSocketService;
@@ -44,7 +42,5 @@
 };
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_SERVICE_FACTORY_H_
+#endif  // COMPONENTS_CAST_CHANNEL_CAST_SOCKET_SERVICE_FACTORY_H_
diff --git a/extensions/browser/api/cast_channel/cast_socket_service_unittest.cc b/components/cast_channel/cast_socket_service_unittest.cc
similarity index 91%
rename from extensions/browser/api/cast_channel/cast_socket_service_unittest.cc
rename to components/cast_channel/cast_socket_service_unittest.cc
index 1ac4b76..53141c7 100644
--- a/extensions/browser/api/cast_channel/cast_socket_service_unittest.cc
+++ b/components/cast_channel/cast_socket_service_unittest.cc
@@ -2,17 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/cast_socket_service.h"
+#include "components/cast_channel/cast_socket_service.h"
+#include "components/cast_channel/cast_test_util.h"
 #include "content/public/test/test_browser_thread_bundle.h"
-#include "extensions/browser/api/cast_channel/cast_test_util.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
 
 using testing::_;
 using testing::SaveArg;
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
 class CastSocketServiceTest : public testing::Test {
@@ -75,5 +73,3 @@
 }
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/cast_socket_unittest.cc b/components/cast_channel/cast_socket_unittest.cc
similarity index 95%
rename from extensions/browser/api/cast_channel/cast_socket_unittest.cc
rename to components/cast_channel/cast_socket_unittest.cc
index bbd4767..59e5eef5 100644
--- a/extensions/browser/api/cast_channel/cast_socket_unittest.cc
+++ b/components/cast_channel/cast_socket_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/cast_socket.h"
+#include "components/cast_channel/cast_socket.h"
 
 #include <stdint.h>
 
@@ -20,14 +20,14 @@
 #include "base/sys_byteorder.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/timer/mock_timer.h"
-#include "extensions/browser/api/cast_channel/cast_auth_util.h"
-#include "extensions/browser/api/cast_channel/cast_framer.h"
-#include "extensions/browser/api/cast_channel/cast_message_util.h"
-#include "extensions/browser/api/cast_channel/cast_test_util.h"
-#include "extensions/browser/api/cast_channel/cast_transport.h"
-#include "extensions/browser/api/cast_channel/logger.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
-#include "extensions/common/api/cast_channel/logging.pb.h"
+#include "components/cast_channel/cast_auth_util.h"
+#include "components/cast_channel/cast_framer.h"
+#include "components/cast_channel/cast_message_util.h"
+#include "components/cast_channel/cast_test_util.h"
+#include "components/cast_channel/cast_transport.h"
+#include "components/cast_channel/logger.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
+#include "components/cast_channel/proto/logging.pb.h"
 #include "net/base/address_list.h"
 #include "net/base/net_errors.h"
 #include "net/log/test_net_log.h"
@@ -54,8 +54,6 @@
 using ::testing::Return;
 using ::testing::SaveArg;
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 const char kAuthNamespace[] = "urn:x-cast:com.google.cast.tp.deviceauth";
 
@@ -134,10 +132,8 @@
     return true;
   }
 
-  MOCK_METHOD3(Read,
-               int(net::IOBuffer*, int, const net::CompletionCallback&));
-  MOCK_METHOD3(Write,
-               int(net::IOBuffer*, int, const net::CompletionCallback&));
+  MOCK_METHOD3(Read, int(net::IOBuffer*, int, const net::CompletionCallback&));
+  MOCK_METHOD3(Write, int(net::IOBuffer*, int, const net::CompletionCallback&));
 
   virtual void Disconnect() {
     // Do nothing in tests
@@ -236,18 +232,14 @@
   }
 
   // Socket I/O helpers.
-  void AddWriteResult(const net::MockWrite& write) {
-    writes_.push_back(write);
-  }
+  void AddWriteResult(const net::MockWrite& write) { writes_.push_back(write); }
   void AddWriteResult(net::IoMode mode, int result) {
     AddWriteResult(net::MockWrite(mode, result));
   }
   void AddWriteResultForData(net::IoMode mode, const std::string& msg) {
     AddWriteResult(mode, msg.size());
   }
-  void AddReadResult(const net::MockRead& read) {
-    reads_.push_back(read);
-  }
+  void AddReadResult(const net::MockRead& read) { reads_.push_back(read); }
   void AddReadResult(net::IoMode mode, int result) {
     AddReadResult(net::MockRead(mode, result));
   }
@@ -258,17 +250,13 @@
   // Helpers for modifying other connection-related behaviors.
   void SetupTcpConnectUnresponsive() { tcp_unresponsive_ = true; }
 
-  void SetExtractCertResult(bool value) {
-    extract_cert_result_ = value;
-  }
+  void SetExtractCertResult(bool value) { extract_cert_result_ = value; }
 
   void SetVerifyChallengeResult(bool value) {
     verify_challenge_result_ = value;
   }
 
-  void TriggerTimeout() {
-    mock_timer_->Fire();
-  }
+  void TriggerTimeout() { mock_timer_->Fire(); }
 
   bool TestVerifyChannelPolicyNone() {
     AuthResult authResult;
@@ -790,5 +778,3 @@
 }
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/cast_test_util.cc b/components/cast_channel/cast_test_util.cc
similarity index 60%
rename from extensions/browser/api/cast_channel/cast_test_util.cc
rename to components/cast_channel/cast_test_util.cc
index d5406b0..6ae2d037 100644
--- a/extensions/browser/api/cast_channel/cast_test_util.cc
+++ b/components/cast_channel/cast_test_util.cc
@@ -2,22 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/cast_test_util.h"
+#include "components/cast_channel/cast_test_util.h"
 
 #include <utility>
 
 #include "net/base/ip_address.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
-const char kTestExtensionId[] = "ddchlicdkolnonkihahngkmmmjnjlkkf";
-
-MockCastTransport::MockCastTransport() {
-}
-MockCastTransport::~MockCastTransport() {
-}
+MockCastTransport::MockCastTransport() {}
+MockCastTransport::~MockCastTransport() {}
 
 CastTransport::Delegate* MockCastTransport::current_delegate() const {
   CHECK(delegate_);
@@ -29,19 +23,14 @@
   delegate_ = std::move(delegate);
 }
 
-MockCastTransportDelegate::MockCastTransportDelegate() {
-}
-MockCastTransportDelegate::~MockCastTransportDelegate() {
-}
+MockCastTransportDelegate::MockCastTransportDelegate() {}
+MockCastTransportDelegate::~MockCastTransportDelegate() {}
 
 MockCastSocket::MockCastSocket() : mock_transport_(new MockCastTransport()) {}
-MockCastSocket::~MockCastSocket() {
-}
+MockCastSocket::~MockCastSocket() {}
 
 net::IPEndPoint CreateIPEndPointForTest() {
   return net::IPEndPoint(net::IPAddress(192, 168, 1, 1), 8009);
 }
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/cast_test_util.h b/components/cast_channel/cast_test_util.h
similarity index 84%
rename from extensions/browser/api/cast_channel/cast_test_util.h
rename to components/cast_channel/cast_test_util.h
index f70af01f..48273c2 100644
--- a/extensions/browser/api/cast_channel/cast_test_util.h
+++ b/components/cast_channel/cast_test_util.h
@@ -2,27 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_TEST_UTIL_H_
-#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_TEST_UTIL_H_
+#ifndef COMPONENTS_CAST_CHANNEL_CAST_TEST_UTIL_H_
+#define COMPONENTS_CAST_CHANNEL_CAST_TEST_UTIL_H_
 
 #include <string>
 #include <utility>
 
 #include "base/macros.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "extensions/browser/api/cast_channel/cast_socket.h"
-#include "extensions/browser/api/cast_channel/cast_transport.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
+#include "components/cast_channel/cast_socket.h"
+#include "components/cast_channel/cast_transport.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
 #include "net/base/ip_endpoint.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
-extern const char kTestExtensionId[];
-
-class MockCastTransport : public extensions::api::cast_channel::CastTransport {
+class MockCastTransport : public CastTransport {
  public:
   MockCastTransport();
   ~MockCastTransport() override;
@@ -31,7 +27,7 @@
       std::unique_ptr<CastTransport::Delegate> delegate) override;
 
   MOCK_METHOD2(SendMessage,
-               void(const extensions::api::cast_channel::CastMessage& message,
+               void(const CastMessage& message,
                     const net::CompletionCallback& callback));
 
   MOCK_METHOD0(Start, void(void));
@@ -121,7 +117,5 @@
 }
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_TEST_UTIL_H_
+#endif  // COMPONENTS_CAST_CHANNEL_CAST_TEST_UTIL_H_
diff --git a/extensions/browser/api/cast_channel/cast_transport.cc b/components/cast_channel/cast_transport.cc
similarity index 95%
rename from extensions/browser/api/cast_channel/cast_transport.cc
rename to components/cast_channel/cast_transport.cc
index 12168f4..337b15f 100644
--- a/extensions/browser/api/cast_channel/cast_transport.cc
+++ b/components/cast_channel/cast_transport.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/cast_transport.h"
+#include "components/cast_channel/cast_transport.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -17,10 +17,10 @@
 #include "base/single_thread_task_runner.h"
 #include "base/strings/stringprintf.h"
 #include "base/threading/thread_task_runner_handle.h"
-#include "extensions/browser/api/cast_channel/cast_framer.h"
-#include "extensions/browser/api/cast_channel/cast_message_util.h"
-#include "extensions/browser/api/cast_channel/logger.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
+#include "components/cast_channel/cast_framer.h"
+#include "components/cast_channel/cast_message_util.h"
+#include "components/cast_channel/logger.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
 #include "net/base/net_errors.h"
 #include "net/socket/socket.h"
 
@@ -29,8 +29,6 @@
               << ::cast_channel::ChannelAuthTypeToString(channel_auth_) \
               << "] "
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
 CastTransportImpl::CastTransportImpl(net::Socket* socket,
@@ -173,8 +171,8 @@
         FROM_HERE, base::Bind(callback, net::ERR_FAILED));
     return;
   }
-  WriteRequest write_request(
-      message.namespace_(), serialized_message, callback);
+  WriteRequest write_request(message.namespace_(), serialized_message,
+                             callback);
 
   write_queue_.push(write_request);
   if (write_state_ == WRITE_STATE_IDLE) {
@@ -196,8 +194,7 @@
 CastTransportImpl::WriteRequest::WriteRequest(const WriteRequest& other) =
     default;
 
-CastTransportImpl::WriteRequest::~WriteRequest() {
-}
+CastTransportImpl::WriteRequest::~WriteRequest() {}
 
 void CastTransportImpl::SetReadState(ReadState read_state) {
   if (read_state_ != read_state)
@@ -352,8 +349,8 @@
   // synchronously.
   int rv = result;
   do {
-    VLOG_WITH_CONNECTION(2) << "OnReadResult(state=" << read_state_
-                            << ", result=" << rv << ")";
+    VLOG_WITH_CONNECTION(2)
+        << "OnReadResult(state=" << read_state_ << ", result=" << rv << ")";
     ReadState state = read_state_;
     read_state_ = READ_STATE_UNKNOWN;
 
@@ -451,5 +448,3 @@
 }
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/cast_transport.h b/components/cast_channel/cast_transport.h
similarity index 94%
rename from extensions/browser/api/cast_channel/cast_transport.h
rename to components/cast_channel/cast_transport.h
index 68769e1..8ecdead 100644
--- a/extensions/browser/api/cast_channel/cast_transport.h
+++ b/components/cast_channel/cast_transport.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 EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_TRANSPORT_H_
-#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_TRANSPORT_H_
+#ifndef COMPONENTS_CAST_CHANNEL_CAST_TRANSPORT_H_
+#define COMPONENTS_CAST_CHANNEL_CAST_TRANSPORT_H_
 
 #include <queue>
 #include <string>
@@ -13,8 +13,8 @@
 #include "base/sequence_checker.h"
 #include "base/threading/thread_checker.h"
 #include "components/cast_channel/cast_channel_enum.h"
-#include "extensions/browser/api/cast_channel/logger.h"
-#include "extensions/common/api/cast_channel/logging.pb.h"
+#include "components/cast_channel/logger.h"
+#include "components/cast_channel/proto/logging.pb.h"
 #include "net/base/completion_callback.h"
 #include "net/base/ip_endpoint.h"
 
@@ -25,8 +25,6 @@
 class Socket;
 }  // namespace net
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 class CastMessage;
 class MessageFramer;
@@ -225,7 +223,5 @@
   DISALLOW_COPY_AND_ASSIGN(CastTransportImpl);
 };
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_TRANSPORT_H_
+#endif  // COMPONENTS_CAST_CHANNEL_CAST_TRANSPORT_H_
diff --git a/extensions/browser/api/cast_channel/cast_transport_unittest.cc b/components/cast_channel/cast_transport_unittest.cc
similarity index 96%
rename from extensions/browser/api/cast_channel/cast_transport_unittest.cc
rename to components/cast_channel/cast_transport_unittest.cc
index 90374d4..0f8e9894 100644
--- a/extensions/browser/api/cast_channel/cast_transport_unittest.cc
+++ b/components/cast_channel/cast_transport_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/cast_transport.h"
+#include "components/cast_channel/cast_transport.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -14,11 +14,11 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/test/simple_test_clock.h"
-#include "extensions/browser/api/cast_channel/cast_framer.h"
-#include "extensions/browser/api/cast_channel/cast_socket.h"
-#include "extensions/browser/api/cast_channel/cast_test_util.h"
-#include "extensions/browser/api/cast_channel/logger.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
+#include "components/cast_channel/cast_framer.h"
+#include "components/cast_channel/cast_socket.h"
+#include "components/cast_channel/cast_test_util.h"
+#include "components/cast_channel/logger.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
 #include "net/base/completion_callback.h"
 #include "net/base/net_errors.h"
 #include "net/log/test_net_log.h"
@@ -34,8 +34,6 @@
 using testing::Return;
 using testing::WithArg;
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 namespace {
 
@@ -241,8 +239,9 @@
   CompletionQueue socket_cbs;
   CompleteHandler write_handler;
   CastMessage message = CreateCastMessage();
-  EXPECT_CALL(mock_socket_, Write(NotNull(), _, _)).WillOnce(
-      DoAll(EnqueueCallback<2>(&socket_cbs), Return(net::ERR_IO_PENDING)));
+  EXPECT_CALL(mock_socket_, Write(NotNull(), _, _))
+      .WillOnce(
+          DoAll(EnqueueCallback<2>(&socket_cbs), Return(net::ERR_IO_PENDING)));
   EXPECT_CALL(write_handler, Complete(net::ERR_FAILED));
   EXPECT_CALL(*delegate_, OnError(ChannelError::CAST_SOCKET_ERROR));
   transport_->SendMessage(
@@ -483,8 +482,7 @@
 
   // Corrupt the serialized message body(set it to X's).
   for (size_t i = MessageFramer::MessageHeader::header_size();
-       i < serialized_message.size();
-       ++i) {
+       i < serialized_message.size(); ++i) {
     serialized_message[i] = 'x';
   }
 
@@ -653,8 +651,7 @@
 
   // Corrupt the serialized message body(set it to X's).
   for (size_t i = MessageFramer::MessageHeader::header_size();
-       i < serialized_message.size();
-       ++i) {
+       i < serialized_message.size(); ++i) {
     serialized_message[i] = 'x';
   }
 
@@ -683,5 +680,3 @@
   transport_->Start();
 }
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/keep_alive_delegate.cc b/components/cast_channel/keep_alive_delegate.cc
similarity index 89%
rename from extensions/browser/api/cast_channel/keep_alive_delegate.cc
rename to components/cast_channel/keep_alive_delegate.cc
index c6803eb..6bcfbeab1 100644
--- a/extensions/browser/api/cast_channel/keep_alive_delegate.cc
+++ b/components/cast_channel/keep_alive_delegate.cc
@@ -2,21 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/keep_alive_delegate.h"
+#include "components/cast_channel/keep_alive_delegate.h"
 
 #include <string>
 #include <utility>
 
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
-#include "extensions/browser/api/cast_channel/cast_socket.h"
-#include "extensions/browser/api/cast_channel/logger.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
-#include "extensions/common/api/cast_channel/logging.pb.h"
+#include "base/values.h"
+#include "components/cast_channel/cast_socket.h"
+#include "components/cast_channel/logger.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
+#include "components/cast_channel/proto/logging.pb.h"
 #include "net/base/net_errors.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 namespace {
 
@@ -88,8 +87,7 @@
   pong_message_ = CreateKeepAliveMessage(kHeartbeatPongType);
 }
 
-KeepAliveDelegate::~KeepAliveDelegate() {
-}
+KeepAliveDelegate::~KeepAliveDelegate() {}
 
 void KeepAliveDelegate::SetTimersForTest(
     std::unique_ptr<base::Timer> injected_ping_timer,
@@ -99,7 +97,7 @@
 }
 
 void KeepAliveDelegate::Start() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(!started_);
 
   VLOG(1) << "Starting keep-alive timers.";
@@ -134,7 +132,7 @@
 
 void KeepAliveDelegate::SendKeepAliveMessage(const CastMessage& message,
                                              const char* message_type) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   VLOG(2) << "Sending " << message_type;
   socket_->transport()->SendMessage(
       message, base::Bind(&KeepAliveDelegate::SendKeepAliveMessageComplete,
@@ -159,7 +157,7 @@
 
 // CastTransport::Delegate interface.
 void KeepAliveDelegate::OnError(ChannelError error_state) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   VLOG(1) << "KeepAlive::OnError: "
           << ::cast_channel::ChannelErrorToString(error_state);
   inner_delegate_->OnError(error_state);
@@ -167,7 +165,7 @@
 }
 
 void KeepAliveDelegate::OnMessage(const CastMessage& message) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   VLOG(2) << "KeepAlive::OnMessage : " << message.payload_utf8();
 
   if (started_)
@@ -196,5 +194,3 @@
 }
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/keep_alive_delegate.h b/components/cast_channel/keep_alive_delegate.h
similarity index 88%
rename from extensions/browser/api/cast_channel/keep_alive_delegate.h
rename to components/cast_channel/keep_alive_delegate.h
index 0ecdf83..9840b60 100644
--- a/extensions/browser/api/cast_channel/keep_alive_delegate.h
+++ b/components/cast_channel/keep_alive_delegate.h
@@ -2,17 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_KEEP_ALIVE_DELEGATE_H_
-#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_KEEP_ALIVE_DELEGATE_H_
+#ifndef COMPONENTS_CAST_CHANNEL_KEEP_ALIVE_DELEGATE_H_
+#define COMPONENTS_CAST_CHANNEL_KEEP_ALIVE_DELEGATE_H_
 
 #include "base/macros.h"
 #include "base/threading/thread_checker.h"
 #include "base/timer/timer.h"
-#include "extensions/browser/api/cast_channel/cast_transport.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
+#include "components/cast_channel/cast_transport.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
 class CastSocket;
@@ -105,13 +103,11 @@
   // The PONG message to send over the wire.
   CastMessage pong_message_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   DISALLOW_COPY_AND_ASSIGN(KeepAliveDelegate);
 };
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_CAST_CHANNEL_KEEP_ALIVE_DELEGATE_H_
+#endif  // COMPONENTS_CAST_CHANNEL_KEEP_ALIVE_DELEGATE_H_
diff --git a/extensions/browser/api/cast_channel/keep_alive_delegate_unittest.cc b/components/cast_channel/keep_alive_delegate_unittest.cc
similarity index 96%
rename from extensions/browser/api/cast_channel/keep_alive_delegate_unittest.cc
rename to components/cast_channel/keep_alive_delegate_unittest.cc
index cc46dd5d..f0e274b 100644
--- a/extensions/browser/api/cast_channel/keep_alive_delegate_unittest.cc
+++ b/components/cast_channel/keep_alive_delegate_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/keep_alive_delegate.h"
+#include "components/cast_channel/keep_alive_delegate.h"
 
 #include <stdint.h>
 
@@ -11,7 +11,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/timer/mock_timer.h"
-#include "extensions/browser/api/cast_channel/cast_test_util.h"
+#include "components/cast_channel/cast_test_util.h"
 #include "net/base/net_errors.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -19,8 +19,6 @@
 using testing::_;
 using testing::Sequence;
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 namespace {
 
@@ -215,5 +213,3 @@
 
 }  // namespace
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/logger.cc b/components/cast_channel/logger.cc
similarity index 91%
rename from extensions/browser/api/cast_channel/logger.cc
rename to components/cast_channel/logger.cc
index f31a8496..a2d282c 100644
--- a/extensions/browser/api/cast_channel/logger.cc
+++ b/components/cast_channel/logger.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "extensions/browser/api/cast_channel/logger.h"
+#include "components/cast_channel/logger.h"
 
 #include <stdint.h>
 
@@ -11,12 +11,10 @@
 
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_util.h"
-#include "extensions/browser/api/cast_channel/cast_auth_util.h"
-#include "extensions/browser/api/cast_channel/cast_socket.h"
+#include "components/cast_channel/cast_auth_util.h"
+#include "components/cast_channel/cast_socket.h"
 #include "net/base/net_errors.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
 using net::IPEndPoint;
@@ -96,16 +94,15 @@
 Logger::Logger() {
   // Logger may not be necessarily be created on the IO thread, but logging
   // happens exclusively there.
-  thread_checker_.DetachFromThread();
+  DETACH_FROM_THREAD(thread_checker_);
 }
 
-Logger::~Logger() {
-}
+Logger::~Logger() {}
 
 void Logger::LogSocketEventWithRv(int channel_id,
                                   EventType event_type,
                                   int rv) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   SocketEvent event = CreateEvent(event_type);
   event.set_net_return_value(rv);
@@ -115,7 +112,7 @@
 
 void Logger::LogSocketChallengeReplyEvent(int channel_id,
                                           const AuthResult& auth_result) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   SocketEvent event = CreateEvent(proto::AUTH_CHALLENGE_REPLY);
   event.set_challenge_reply_error_type(
@@ -152,5 +149,3 @@
 }
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/logger.h b/components/cast_channel/logger.h
similarity index 85%
rename from extensions/browser/api/cast_channel/logger.h
rename to components/cast_channel/logger.h
index a1f3efe..7c4c37ed 100644
--- a/extensions/browser/api/cast_channel/logger.h
+++ b/components/cast_channel/logger.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 EXTENSIONS_BROWSER_API_CAST_CHANNEL_LOGGER_H_
-#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_LOGGER_H_
+#ifndef COMPONENTS_CAST_CHANNEL_LOGGER_H_
+#define COMPONENTS_CAST_CHANNEL_LOGGER_H_
 
 #include <stddef.h>
 
@@ -15,11 +15,8 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/threading/thread_checker.h"
-#include "extensions/common/api/cast_channel/logging.pb.h"
+#include "components/cast_channel/proto/logging.pb.h"
 
-
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
 struct AuthResult;
@@ -76,12 +73,10 @@
 
   LastErrorsMap last_errors_;
 
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   DISALLOW_COPY_AND_ASSIGN(Logger);
 };
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_API_CAST_CHANNEL_LOGGER_H_
+#endif  // COMPONENTS_CAST_CHANNEL_LOGGER_H_
diff --git a/extensions/browser/api/cast_channel/logger_unittest.cc b/components/cast_channel/logger_unittest.cc
similarity index 92%
rename from extensions/browser/api/cast_channel/logger_unittest.cc
rename to components/cast_channel/logger_unittest.cc
index cf99f6a..020ab5c 100644
--- a/extensions/browser/api/cast_channel/logger_unittest.cc
+++ b/components/cast_channel/logger_unittest.cc
@@ -7,13 +7,11 @@
 
 #include <string>
 
-#include "extensions/browser/api/cast_channel/cast_auth_util.h"
-#include "extensions/browser/api/cast_channel/logger.h"
+#include "components/cast_channel/cast_auth_util.h"
+#include "components/cast_channel/logger.h"
 #include "net/base/net_errors.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace extensions {
-namespace api {
 namespace cast_channel {
 
 using proto::EventType;
@@ -67,5 +65,3 @@
 }
 
 }  // namespace cast_channel
-}  // namespace api
-}  // namespace extensions
diff --git a/extensions/common/api/cast_channel/BUILD.gn b/components/cast_channel/proto/BUILD.gn
similarity index 100%
rename from extensions/common/api/cast_channel/BUILD.gn
rename to components/cast_channel/proto/BUILD.gn
diff --git a/extensions/common/api/cast_channel/authority_keys.proto b/components/cast_channel/proto/authority_keys.proto
similarity index 89%
rename from extensions/common/api/cast_channel/authority_keys.proto
rename to components/cast_channel/proto/authority_keys.proto
index 791e831..9f62d20 100644
--- a/extensions/common/api/cast_channel/authority_keys.proto
+++ b/components/cast_channel/proto/authority_keys.proto
@@ -6,7 +6,7 @@
 
 option optimize_for = LITE_RUNTIME;
 
-package extensions.api.cast_channel.proto;
+package cast_channel.proto;
 
 message AuthorityKeys {
   message Key {
diff --git a/extensions/common/api/cast_channel/cast_channel.proto b/components/cast_channel/proto/cast_channel.proto
similarity index 96%
rename from extensions/common/api/cast_channel/cast_channel.proto
rename to components/cast_channel/proto/cast_channel.proto
index 098ecb74..4cac6db6 100644
--- a/extensions/common/api/cast_channel/cast_channel.proto
+++ b/components/cast_channel/proto/cast_channel.proto
@@ -6,14 +6,12 @@
 
 option optimize_for = LITE_RUNTIME;
 
-package extensions.api.cast_channel;
+package cast_channel;
 
 message CastMessage {
   // Always pass a version of the protocol for future compatibility
   // requirements.
-  enum ProtocolVersion {
-    CASTV2_1_0 = 0;
-  }
+  enum ProtocolVersion { CASTV2_1_0 = 0; }
   required ProtocolVersion protocol_version = 1;
 
   // source and destination ids identify the origin and destination of the
diff --git a/extensions/common/api/cast_channel/logging.proto b/components/cast_channel/proto/logging.proto
similarity index 88%
rename from extensions/common/api/cast_channel/logging.proto
rename to components/cast_channel/proto/logging.proto
index a199c01..1b20d62 100644
--- a/extensions/common/api/cast_channel/logging.proto
+++ b/components/cast_channel/proto/logging.proto
@@ -2,11 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(crbug.com/513801) to replace this file with plain enums/structs.
+
 syntax = "proto2";
 
 option optimize_for = LITE_RUNTIME;
 
-package extensions.api.cast_channel.proto;
+package cast_channel.proto;
 
 enum EventType {
   EVENT_TYPE_UNKNOWN = 0;
@@ -27,20 +29,20 @@
   AUTH_CHALLENGE_REPLY = 15;
   CONNECT_TIMED_OUT = 16;
   SEND_MESSAGE_FAILED = 17;
-  MESSAGE_ENQUEUED = 18;   // Message
-  SOCKET_WRITE = 19;       // Logged with RV.
-  MESSAGE_WRITTEN = 20;    // Message
-  SOCKET_READ = 21;        // Logged with RV.
-  MESSAGE_READ = 22;       // Message
+  MESSAGE_ENQUEUED = 18;  // Message
+  SOCKET_WRITE = 19;      // Logged with RV.
+  MESSAGE_WRITTEN = 20;   // Message
+  SOCKET_READ = 21;       // Logged with RV.
+  MESSAGE_READ = 22;      // Message
   SOCKET_CLOSED = 25;
   SSL_CERT_EXCESSIVE_LIFETIME = 26;
   CHANNEL_POLICY_ENFORCED = 27;
-  TCP_SOCKET_CONNECT_COMPLETE = 28;   // Logged with RV.
-  SSL_SOCKET_CONNECT_COMPLETE = 29;   // Logged with RV.
-  SSL_SOCKET_CONNECT_FAILED = 30;     // Logged with RV.
-  SEND_AUTH_CHALLENGE_FAILED = 31;    // Logged with RV.
+  TCP_SOCKET_CONNECT_COMPLETE = 28;  // Logged with RV.
+  SSL_SOCKET_CONNECT_COMPLETE = 29;  // Logged with RV.
+  SSL_SOCKET_CONNECT_FAILED = 30;    // Logged with RV.
+  SEND_AUTH_CHALLENGE_FAILED = 31;   // Logged with RV.
   AUTH_CHALLENGE_REPLY_INVALID = 32;
-  PING_WRITE_ERROR = 33;              // Logged with RV.
+  PING_WRITE_ERROR = 33;  // Logged with RV.
 }
 
 enum ChannelAuth {
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h
index 7004aee79..13cf9451 100644
--- a/components/password_manager/core/browser/password_manager_client.h
+++ b/components/password_manager/core/browser/password_manager_client.h
@@ -211,7 +211,8 @@
   // Checks the safe browsing reputation of the webpage where password reuse
   // happens.
   virtual void CheckProtectedPasswordEntry(
-      const std::string& password_saved_domain) = 0;
+      const std::string& password_saved_domain,
+      bool password_field_exists) = 0;
 #endif
 
  private:
diff --git a/components/password_manager/core/browser/password_reuse_detection_manager.cc b/components/password_manager/core/browser/password_reuse_detection_manager.cc
index 49a0691..27dd293 100644
--- a/components/password_manager/core/browser/password_reuse_detection_manager.cc
+++ b/components/password_manager/core/browser/password_reuse_detection_manager.cc
@@ -94,7 +94,8 @@
 #if defined(SAFE_BROWSING_DB_LOCAL)
   // TODO(jialiul): After CSD whitelist being added to Android, we should gate
   // this by either SAFE_BROWSING_DB_LOCAL or SAFE_BROWSING_DB_REMOTE.
-  client_->CheckProtectedPasswordEntry(legitimate_domain);
+  client_->CheckProtectedPasswordEntry(legitimate_domain,
+                                       password_field_detected);
 #endif
 }
 
diff --git a/components/password_manager/core/browser/stub_password_manager_client.cc b/components/password_manager/core/browser/stub_password_manager_client.cc
index 309c877e..6c8b37f7 100644
--- a/components/password_manager/core/browser/stub_password_manager_client.cc
+++ b/components/password_manager/core/browser/stub_password_manager_client.cc
@@ -75,7 +75,8 @@
     const GURL& frame_url) {}
 
 void StubPasswordManagerClient::CheckProtectedPasswordEntry(
-    const std::string& password_saved_domain) {}
+    const std::string& password_saved_domain,
+    bool password_field_exists) {}
 #endif
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/stub_password_manager_client.h b/components/password_manager/core/browser/stub_password_manager_client.h
index 77c740b..c0f9cc6 100644
--- a/components/password_manager/core/browser/stub_password_manager_client.h
+++ b/components/password_manager/core/browser/stub_password_manager_client.h
@@ -48,8 +48,8 @@
       const override;
   void CheckSafeBrowsingReputation(const GURL& form_action,
                                    const GURL& frame_url) override;
-  void CheckProtectedPasswordEntry(
-      const std::string& password_saved_domain) override;
+  void CheckProtectedPasswordEntry(const std::string& password_saved_domain,
+                                   bool password_field_exists) override;
 #endif
 
  private:
diff --git a/components/safe_browsing/password_protection/password_protection_request.cc b/components/safe_browsing/password_protection/password_protection_request.cc
index 245dcf9..909c848 100644
--- a/components/safe_browsing/password_protection/password_protection_request.cc
+++ b/components/safe_browsing/password_protection/password_protection_request.cc
@@ -28,6 +28,7 @@
     const GURL& password_form_frame_url,
     const std::string& saved_domain,
     LoginReputationClientRequest::TriggerType type,
+    bool password_field_exists,
     PasswordProtectionService* pps,
     int request_timeout_in_ms)
     : web_contents_(web_contents),
@@ -36,6 +37,7 @@
       password_form_frame_url_(password_form_frame_url),
       saved_domain_(saved_domain),
       request_type_(type),
+      password_field_exists_(password_field_exists),
       password_protection_service_(pps),
       request_timeout_in_ms_(request_timeout_in_ms),
       weakptr_factory_(this) {
@@ -126,6 +128,7 @@
       break;
     }
     case LoginReputationClientRequest::PASSWORD_REUSE_EVENT: {
+      main_frame->set_has_password_field(password_field_exists_);
       LoginReputationClientRequest::PasswordReuseEvent* reuse_event =
           request_proto_->mutable_password_reuse_event();
       reuse_event->set_is_chrome_signin_password(
diff --git a/components/safe_browsing/password_protection/password_protection_request.h b/components/safe_browsing/password_protection/password_protection_request.h
index 2bb4499..721739b 100644
--- a/components/safe_browsing/password_protection/password_protection_request.h
+++ b/components/safe_browsing/password_protection/password_protection_request.h
@@ -46,6 +46,7 @@
                             const GURL& password_form_frame_url,
                             const std::string& saved_domain,
                             LoginReputationClientRequest::TriggerType type,
+                            bool password_field_exists,
                             PasswordProtectionService* pps,
                             int request_timeout_in_ms);
 
@@ -130,6 +131,9 @@
   // If this request is for unfamiliar login page or for a password reuse event.
   const LoginReputationClientRequest::TriggerType request_type_;
 
+  // If there is a password field on the page.
+  const bool password_field_exists_;
+
   // When request is sent.
   base::TimeTicks request_start_time_;
 
diff --git a/components/safe_browsing/password_protection/password_protection_service.cc b/components/safe_browsing/password_protection/password_protection_service.cc
index a16ef3af..c7ec2a9d 100644
--- a/components/safe_browsing/password_protection/password_protection_service.cc
+++ b/components/safe_browsing/password_protection/password_protection_service.cc
@@ -272,13 +272,14 @@
     const GURL& password_form_action,
     const GURL& password_form_frame_url,
     const std::string& saved_domain,
-    LoginReputationClientRequest::TriggerType type) {
+    LoginReputationClientRequest::TriggerType type,
+    bool password_field_exists) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   scoped_refptr<PasswordProtectionRequest> request(
-      new PasswordProtectionRequest(web_contents, main_frame_url,
-                                    password_form_action,
-                                    password_form_frame_url, saved_domain, type,
-                                    this, GetRequestTimeoutInMS()));
+      new PasswordProtectionRequest(
+          web_contents, main_frame_url, password_form_action,
+          password_form_frame_url, saved_domain, type, password_field_exists,
+          this, GetRequestTimeoutInMS()));
   DCHECK(request);
   request->Start();
   requests_.insert(std::move(request));
@@ -294,18 +295,20 @@
     StartRequest(web_contents, main_frame_url, password_form_action,
                  password_form_frame_url,
                  std::string(), /* saved_domain: not used for this type */
-                 LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE);
+                 LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, true);
   }
 }
 
 void PasswordProtectionService::MaybeStartProtectedPasswordEntryRequest(
     WebContents* web_contents,
     const GURL& main_frame_url,
-    const std::string& saved_domain) {
+    const std::string& saved_domain,
+    bool password_field_exists) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (CanSendPing(kProtectedPasswordEntryPinging, main_frame_url)) {
     StartRequest(web_contents, main_frame_url, GURL(), GURL(), saved_domain,
-                 LoginReputationClientRequest::PASSWORD_REUSE_EVENT);
+                 LoginReputationClientRequest::PASSWORD_REUSE_EVENT,
+                 password_field_exists);
   }
 }
 
diff --git a/components/safe_browsing/password_protection/password_protection_service.h b/components/safe_browsing/password_protection/password_protection_service.h
index 4800ae9..89870aa 100644
--- a/components/safe_browsing/password_protection/password_protection_service.h
+++ b/components/safe_browsing/password_protection/password_protection_service.h
@@ -106,7 +106,8 @@
                     const GURL& password_form_action,
                     const GURL& password_form_frame_url,
                     const std::string& saved_domain,
-                    LoginReputationClientRequest::TriggerType type);
+                    LoginReputationClientRequest::TriggerType type,
+                    bool password_field_exists);
 
   virtual void MaybeStartPasswordFieldOnFocusRequest(
       content::WebContents* web_contents,
@@ -117,7 +118,8 @@
   virtual void MaybeStartProtectedPasswordEntryRequest(
       content::WebContents* web_contents,
       const GURL& main_frame_url,
-      const std::string& saved_domain);
+      const std::string& saved_domain,
+      bool password_field_exists);
 
   scoped_refptr<SafeBrowsingDatabaseManager> database_manager();
 
diff --git a/components/safe_browsing/password_protection/password_protection_service_unittest.cc b/components/safe_browsing/password_protection/password_protection_service_unittest.cc
index 78d638d5..d297ef1 100644
--- a/components/safe_browsing/password_protection/password_protection_service_unittest.cc
+++ b/components/safe_browsing/password_protection/password_protection_service_unittest.cc
@@ -173,7 +173,7 @@
     request_ = new PasswordProtectionRequest(
         nullptr, target_url, GURL(kFormActionUrl), GURL(kPasswordFrameUrl),
         std::string(), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE,
-        password_protection_service_.get(), timeout_in_ms);
+        true, password_protection_service_.get(), timeout_in_ms);
     request_->Start();
   }
 
@@ -186,7 +186,7 @@
 
     request_ = new PasswordProtectionRequest(
         nullptr, target_url, GURL(), GURL(), saved_domain,
-        LoginReputationClientRequest::PASSWORD_REUSE_EVENT,
+        LoginReputationClientRequest::PASSWORD_REUSE_EVENT, true,
         password_protection_service_.get(), timeout_in_ms);
     request_->Start();
   }
@@ -550,7 +550,7 @@
   password_protection_service_->StartRequest(
       nullptr, target_url, GURL("http://foo.com/submit"),
       GURL("http://foo.com/frame"), std::string(),
-      LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE);
+      LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, true);
 
   // Destroy password_protection_service_ while there is one request pending.
   password_protection_service_.reset();
@@ -653,6 +653,7 @@
             actual_request->trigger_type());
   EXPECT_EQ(1, actual_request->frames_size());
   EXPECT_EQ(kTargetUrl, actual_request->frames(0).url());
+  EXPECT_TRUE(actual_request->frames(0).has_password_field());
   ASSERT_TRUE(actual_request->has_password_reuse_event());
   ASSERT_TRUE(
       actual_request->password_reuse_event().is_chrome_signin_password());
diff --git a/components/signin/core/browser/signin_metrics.h b/components/signin/core/browser/signin_metrics.h
index 177ed1f..cc6709e 100644
--- a/components/signin/core/browser/signin_metrics.h
+++ b/components/signin/core/browser/signin_metrics.h
@@ -143,6 +143,7 @@
   ACCESS_POINT_NTP_CONTENT_SUGGESTIONS,
   ACCESS_POINT_RESIGNIN_INFOBAR,
   ACCESS_POINT_TAB_SWITCHER,
+  ACCESS_POINT_FORCE_SIGNIN_WARNING,
   ACCESS_POINT_MAX,  // This must be last.
 };
 
diff --git a/components/subresource_filter/core/common/flat/indexed_ruleset.fbs b/components/subresource_filter/core/common/flat/indexed_ruleset.fbs
index 9126228..e8e351e 100644
--- a/components/subresource_filter/core/common/flat/indexed_ruleset.fbs
+++ b/components/subresource_filter/core/common/flat/indexed_ruleset.fbs
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// TODO(pkalinnikov): Make including by absolute path work.
-include "url_pattern_index.fbs";
+include "components/subresource_filter/core/common/flat/url_pattern_index.fbs";
 
 namespace subresource_filter.flat;
 
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc
index 87724d4..1283176 100644
--- a/components/sync/engine_impl/sync_manager_impl.cc
+++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -247,7 +247,7 @@
 
   DCHECK(backing_store.get());
   share_.directory = base::MakeUnique<syncable::Directory>(
-      backing_store.release(), args->unrecoverable_error_handler,
+      std::move(backing_store), args->unrecoverable_error_handler,
       report_unrecoverable_error_function_, sync_encryption_handler_.get(),
       sync_encryption_handler_->GetCryptographerUnsafe());
   share_.sync_credentials = args->credentials;
diff --git a/components/sync/syncable/directory.cc b/components/sync/syncable/directory.cc
index b8cafaf..c0a579e 100644
--- a/components/sync/syncable/directory.cc
+++ b/components/sync/syncable/directory.cc
@@ -112,13 +112,12 @@
 Directory::Kernel::~Kernel() {}
 
 Directory::Directory(
-    DirectoryBackingStore* store,
+    std::unique_ptr<DirectoryBackingStore> store,
     const WeakHandle<UnrecoverableErrorHandler>& unrecoverable_error_handler,
     const base::Closure& report_unrecoverable_error_function,
     NigoriHandler* nigori_handler,
     Cryptographer* cryptographer)
-    : kernel_(nullptr),
-      store_(store),
+    : store_(std::move(store)),
       unrecoverable_error_handler_(unrecoverable_error_handler),
       report_unrecoverable_error_function_(report_unrecoverable_error_function),
       unrecoverable_error_set_(false),
@@ -199,7 +198,8 @@
     return result;
 
   DCHECK(!kernel_);
-  kernel_ = new Kernel(name, info, delegate, transaction_observer);
+  kernel_ =
+      base::MakeUnique<Kernel>(name, info, delegate, transaction_observer);
   kernel_->metahandles_to_purge.swap(metahandles_to_purge);
   delete_journal_ = base::MakeUnique<DeleteJournal>(std::move(delete_journals));
   InitializeIndices(&tmp_handles_map);
@@ -224,10 +224,7 @@
 
 void Directory::Close() {
   store_.reset();
-  if (kernel_) {
-    delete kernel_;
-    kernel_ = nullptr;
-  }
+  kernel_.reset();
 }
 
 void Directory::OnUnrecoverableError(const BaseTransaction* trans,
@@ -1632,11 +1629,11 @@
 }
 
 Directory::Kernel* Directory::kernel() {
-  return kernel_;
+  return kernel_.get();
 }
 
 const Directory::Kernel* Directory::kernel() const {
-  return kernel_;
+  return kernel_.get();
 }
 
 }  // namespace syncable
diff --git a/components/sync/syncable/directory.h b/components/sync/syncable/directory.h
index 8204874..7e9ff063 100644
--- a/components/sync/syncable/directory.h
+++ b/components/sync/syncable/directory.h
@@ -254,7 +254,7 @@
   // |report_unrecoverable_error_function| may be null.
   // Takes ownership of |store|.
   Directory(
-      DirectoryBackingStore* store,
+      std::unique_ptr<DirectoryBackingStore> store,
       const WeakHandle<UnrecoverableErrorHandler>& unrecoverable_error_handler,
       const base::Closure& report_unrecoverable_error_function,
       NigoriHandler* nigori_handler,
@@ -648,7 +648,7 @@
   // error on it.
   bool unrecoverable_error_set(const BaseTransaction* trans) const;
 
-  Kernel* kernel_;
+  std::unique_ptr<Kernel> kernel_;
 
   std::unique_ptr<DirectoryBackingStore> store_;
 
diff --git a/components/sync/syncable/directory_unittest.cc b/components/sync/syncable/directory_unittest.cc
index cacf0422..b4b4b3fe 100644
--- a/components/sync/syncable/directory_unittest.cc
+++ b/components/sync/syncable/directory_unittest.cc
@@ -79,7 +79,7 @@
   // data persist across Directory object lifetimes while getting the
   // performance benefits of not writing to disk.
   dir_ = base::MakeUnique<Directory>(
-      new TestDirectoryBackingStore(kDirectoryName, &connection_),
+      base::MakeUnique<TestDirectoryBackingStore>(kDirectoryName, &connection_),
       MakeWeakHandle(handler_.GetWeakPtr()), base::Closure(), nullptr, nullptr);
 
   DirOpenResult open_result =
@@ -2034,9 +2034,10 @@
 // DirectoryBackingStore error is detected.
 TEST_F(SyncableDirectoryTest, CatastrophicError) {
   MockUnrecoverableErrorHandler unrecoverable_error_handler;
-  Directory dir(new InMemoryDirectoryBackingStore("catastrophic_error"),
-                MakeWeakHandle(unrecoverable_error_handler.GetWeakPtr()),
-                base::Closure(), nullptr, nullptr);
+  Directory dir(
+      base::MakeUnique<InMemoryDirectoryBackingStore>("catastrophic_error"),
+      MakeWeakHandle(unrecoverable_error_handler.GetWeakPtr()), base::Closure(),
+      nullptr, nullptr);
   ASSERT_EQ(OPENED, dir.Open(kDirectoryName, directory_change_delegate(),
                              NullTransactionObserver()));
   ASSERT_EQ(0, unrecoverable_error_handler.invocation_count());
diff --git a/components/sync/syncable/syncable_unittest.cc b/components/sync/syncable/syncable_unittest.cc
index 370dee0..6b21916a 100644
--- a/components/sync/syncable/syncable_unittest.cc
+++ b/components/sync/syncable/syncable_unittest.cc
@@ -83,7 +83,7 @@
 class TestDirectory : public Directory {
  public:
   // A factory function used to work around some initialization order issues.
-  static TestDirectory* Create(
+  static std::unique_ptr<TestDirectory> Create(
       Encryptor* encryptor,
       const WeakHandle<UnrecoverableErrorHandler>& handler,
       const std::string& dir_name,
@@ -101,21 +101,25 @@
   TestBackingStore* backing_store_;
 };
 
-TestDirectory* TestDirectory::Create(
+std::unique_ptr<TestDirectory> TestDirectory::Create(
     Encryptor* encryptor,
     const WeakHandle<UnrecoverableErrorHandler>& handler,
     const std::string& dir_name,
     const base::FilePath& backing_filepath) {
   TestBackingStore* backing_store =
       new TestBackingStore(dir_name, backing_filepath);
-  return new TestDirectory(encryptor, handler, backing_store);
+  return base::WrapUnique(new TestDirectory(encryptor, handler, backing_store));
 }
 
 TestDirectory::TestDirectory(
     Encryptor* encryptor,
     const WeakHandle<UnrecoverableErrorHandler>& handler,
     TestBackingStore* backing_store)
-    : Directory(backing_store, handler, base::Closure(), nullptr, nullptr),
+    : Directory(base::WrapUnique(backing_store),
+                handler,
+                base::Closure(),
+                nullptr,
+                nullptr),
       backing_store_(backing_store) {}
 
 TestDirectory::~TestDirectory() {}
@@ -137,8 +141,8 @@
   std::string name = "user@x.com";
   NullDirectoryChangeDelegate delegate;
 
-  std::unique_ptr<TestDirectory> test_dir(TestDirectory::Create(
-      &encryptor, MakeWeakHandle(handler.GetWeakPtr()), name, file_path));
+  std::unique_ptr<TestDirectory> test_dir = TestDirectory::Create(
+      &encryptor, MakeWeakHandle(handler.GetWeakPtr()), name, file_path);
 
   test_dir->StartFailingSaveChanges();
   ASSERT_EQ(FAILED_INITIAL_WRITE,
@@ -168,11 +172,12 @@
 
   // Creates a new directory.  Deletes the old directory, if it exists.
   void CreateDirectory() {
-    test_directory_ = TestDirectory::Create(
+    std::unique_ptr<TestDirectory> test_directory = TestDirectory::Create(
         encryptor(),
         MakeWeakHandle(unrecoverable_error_handler()->GetWeakPtr()),
         kDirectoryName, file_path_);
-    dir().reset(test_directory_);
+    test_directory_ = test_directory.get();
+    dir() = std::move(test_directory);
     ASSERT_TRUE(dir().get());
     ASSERT_EQ(OPENED, dir()->Open(kDirectoryName, directory_change_delegate(),
                                   NullTransactionObserver()));
@@ -344,7 +349,7 @@
 
   dir()->SaveChanges();
   dir() = base::MakeUnique<Directory>(
-      new OnDiskDirectoryBackingStore(kDirectoryName, file_path_),
+      base::MakeUnique<OnDiskDirectoryBackingStore>(kDirectoryName, file_path_),
       MakeWeakHandle(unrecoverable_error_handler()->GetWeakPtr()),
       base::Closure(), nullptr, nullptr);
 
@@ -555,9 +560,10 @@
       temp_dir_.GetPath().Append(Directory::kSyncDatabaseFilename);
 
   {
-    Directory dir(new OnDiskDirectoryBackingStore("ScopeTest", path),
-                  MakeWeakHandle(handler_.GetWeakPtr()), base::Closure(),
-                  nullptr, nullptr);
+    Directory dir(
+        base::MakeUnique<OnDiskDirectoryBackingStore>("ScopeTest", path),
+        MakeWeakHandle(handler_.GetWeakPtr()), base::Closure(), nullptr,
+        nullptr);
     DirOpenResult result =
         dir.Open("ScopeTest", &delegate_, NullTransactionObserver());
     ASSERT_EQ(result, OPENED);
diff --git a/components/sync/syncable/test_user_share.cc b/components/sync/syncable/test_user_share.cc
index 6dbdd47..dc3ba22c 100644
--- a/components/sync/syncable/test_user_share.cc
+++ b/components/sync/syncable/test_user_share.cc
@@ -4,9 +4,12 @@
 
 #include "components/sync/syncable/test_user_share.h"
 
+#include <utility>
+
 #include "base/compiler_specific.h"
 #include "base/memory/ptr_util.h"
 #include "components/sync/syncable/directory.h"
+#include "components/sync/syncable/directory_backing_store.h"
 #include "components/sync/syncable/mutable_entry.h"
 #include "components/sync/syncable/syncable_read_transaction.h"
 #include "components/sync/syncable/syncable_write_transaction.h"
@@ -45,13 +48,13 @@
   if (!user_share_->directory->SaveChanges())
     return false;
 
-  syncable::DirectoryBackingStore* saved_store =
-      user_share_->directory->store_.release();
+  std::unique_ptr<syncable::DirectoryBackingStore> saved_store =
+      std::move(user_share_->directory->store_);
 
   // Ensure the unique_ptr doesn't delete the memory we don't own.
   ignore_result(user_share_->directory.release());
   user_share_ = base::MakeUnique<UserShare>();
-  dir_maker_->SetUpWith(saved_store);
+  dir_maker_->SetUpWith(std::move(saved_store));
   user_share_->directory.reset(dir_maker_->directory());
   return true;
 }
diff --git a/components/sync/test/engine/test_directory_setter_upper.cc b/components/sync/test/engine/test_directory_setter_upper.cc
index baae978..cc9cf18a 100644
--- a/components/sync/test/engine/test_directory_setter_upper.cc
+++ b/components/sync/test/engine/test_directory_setter_upper.cc
@@ -4,6 +4,8 @@
 
 #include "components/sync/test/engine/test_directory_setter_upper.h"
 
+#include <utility>
+
 #include "base/files/file_util.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
@@ -29,7 +31,7 @@
       MakeWeakHandle(test_transaction_observer_->AsWeakPtr());
 
   directory_ = base::MakeUnique<syncable::Directory>(
-      new syncable::InMemoryDirectoryBackingStore(name_),
+      base::MakeUnique<syncable::InMemoryDirectoryBackingStore>(name_),
       MakeWeakHandle(handler_.GetWeakPtr()), base::Closure(),
       &encryption_handler_, encryption_handler_.cryptographer());
   ASSERT_EQ(syncable::OPENED,
@@ -37,7 +39,7 @@
 }
 
 void TestDirectorySetterUpper::SetUpWith(
-    syncable::DirectoryBackingStore* directory_store) {
+    std::unique_ptr<syncable::DirectoryBackingStore> directory_store) {
   CHECK(directory_store);
   test_transaction_observer_ =
       base::MakeUnique<syncable::TestTransactionObserver>();
@@ -45,8 +47,9 @@
       MakeWeakHandle(test_transaction_observer_->AsWeakPtr());
 
   directory_ = base::MakeUnique<syncable::Directory>(
-      directory_store, MakeWeakHandle(handler_.GetWeakPtr()), base::Closure(),
-      &encryption_handler_, encryption_handler_.cryptographer());
+      std::move(directory_store), MakeWeakHandle(handler_.GetWeakPtr()),
+      base::Closure(), &encryption_handler_,
+      encryption_handler_.cryptographer());
   ASSERT_EQ(syncable::OPENED,
             directory_->Open(name_, &delegate_, transaction_observer));
 }
diff --git a/components/sync/test/engine/test_directory_setter_upper.h b/components/sync/test/engine/test_directory_setter_upper.h
index 7dd00e0d..f8915d0 100644
--- a/components/sync/test/engine/test_directory_setter_upper.h
+++ b/components/sync/test/engine/test_directory_setter_upper.h
@@ -56,7 +56,8 @@
 
   // Create a Directory instance using |directory_store| as backend storage.
   // Takes ownership of |directory_store|.
-  virtual void SetUpWith(syncable::DirectoryBackingStore* directory_store);
+  virtual void SetUpWith(
+      std::unique_ptr<syncable::DirectoryBackingStore> directory_store);
 
   // Undo everything done by SetUp(): close the directory and delete the
   // backing files. Before closing the directory, this will run the directory
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 1344ec5..8b0191e 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1829,7 +1829,7 @@
   }
 
   if (is_linux && use_aura) {
-    deps += [ "//build/linux:fontconfig" ]
+    deps += [ "//third_party/fontconfig" ]
   }
 
   if (use_x11) {
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 5587511..3fb2659 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -13,6 +13,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "content/browser/accessibility/browser_accessibility_state_impl.h"
 #include "content/common/accessibility_messages.h"
 #include "ui/accessibility/ax_role_properties.h"
 #include "ui/accessibility/ax_text_utils.h"
@@ -1201,4 +1202,10 @@
   return false;
 }
 
+bool BrowserAccessibility::ShouldIgnoreHoveredStateForTesting() {
+  BrowserAccessibilityStateImpl* accessibility_state =
+      BrowserAccessibilityStateImpl::GetInstance();
+  return accessibility_state->disable_hot_tracking_for_testing();
+}
+
 }  // namespace content
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h
index e9df24c5..b4a6f2c 100644
--- a/content/browser/accessibility/browser_accessibility.h
+++ b/content/browser/accessibility/browser_accessibility.h
@@ -391,6 +391,7 @@
   gfx::NativeViewAccessible GetFocus() override;
   gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
   bool AccessibilityPerformAction(const ui::AXActionData& data) override;
+  bool ShouldIgnoreHoveredStateForTesting() override;
 
  protected:
   using AXPlatformPositionInstance = AXPlatformPosition::AXPositionInstance;
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc
index 46b1cd1..c20cff8 100644
--- a/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -642,23 +642,7 @@
   if (!owner())
     return E_FAIL;
 
-  auto* manager = Manager();
-  if (!manager)
-    return E_FAIL;
-
-  if (!state)
-    return E_INVALIDARG;
-
-  BrowserAccessibilityComWin* target = GetTargetFromChildID(var_id);
-  if (!target)
-    return E_INVALIDARG;
-
-  state->vt = VT_I4;
-  state->lVal = target->ia_state();
-  if (manager->GetFocus() == owner())
-    state->lVal |= STATE_SYSTEM_FOCUSED;
-
-  return S_OK;
+  return AXPlatformNodeWin::get_accState(var_id, state);
 }
 
 bool BrowserAccessibilityComWin::IsRangeValueSupported() {
diff --git a/content/browser/devtools/protocol/target_handler.cc b/content/browser/devtools/protocol/target_handler.cc
index 6ce1066..2d7c6597 100644
--- a/content/browser/devtools/protocol/target_handler.cc
+++ b/content/browser/devtools/protocol/target_handler.cc
@@ -217,7 +217,8 @@
   auto it = reported_hosts_.find(host->GetId());
   if (it == reported_hosts_.end())
     return;
-  frontend_->TargetDestroyed(host->GetId());
+  if (discover_)
+    frontend_->TargetDestroyed(host->GetId());
   reported_hosts_.erase(it);
 }
 
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.cc b/content/browser/dom_storage/dom_storage_context_wrapper.cc
index 8c8a9dec..47b7c9b 100644
--- a/content/browser/dom_storage/dom_storage_context_wrapper.cc
+++ b/content/browser/dom_storage/dom_storage_context_wrapper.cc
@@ -129,7 +129,7 @@
     mojo_task_runner_ =
         BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
     mojo_state_ = new LocalStorageContextMojo(
-        connector, context_->task_runner(),
+        mojo_task_runner_, connector, context_->task_runner(),
         data_path.empty() ? data_path
                           : data_path.AppendASCII(kLocalStorageDirectory),
         storage_dir, special_storage_policy);
diff --git a/content/browser/dom_storage/local_storage_context_mojo.cc b/content/browser/dom_storage/local_storage_context_mojo.cc
index 6c95724..f9413f8e 100644
--- a/content/browser/dom_storage/local_storage_context_mojo.cc
+++ b/content/browser/dom_storage/local_storage_context_mojo.cc
@@ -4,10 +4,14 @@
 
 #include "content/browser/dom_storage/local_storage_context_mojo.h"
 
+#include <inttypes.h>
+#include <cctype>  // for std::isalnum
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "base/trace_event/memory_dump_manager.h"
 #include "components/leveldb/public/cpp/util.h"
 #include "components/leveldb/public/interfaces/leveldb.mojom.h"
 #include "content/browser/dom_storage/dom_storage_area.h"
@@ -235,17 +239,21 @@
 };
 
 LocalStorageContextMojo::LocalStorageContextMojo(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     service_manager::Connector* connector,
-    scoped_refptr<DOMStorageTaskRunner> task_runner,
+    scoped_refptr<DOMStorageTaskRunner> legacy_task_runner,
     const base::FilePath& old_localstorage_path,
     const base::FilePath& subdirectory,
     scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy)
     : connector_(connector ? connector->Clone() : nullptr),
       subdirectory_(subdirectory),
       special_storage_policy_(std::move(special_storage_policy)),
-      task_runner_(std::move(task_runner)),
+      task_runner_(std::move(legacy_task_runner)),
       old_localstorage_path_(old_localstorage_path),
-      weak_ptr_factory_(this) {}
+      weak_ptr_factory_(this) {
+  base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
+      this, "LocalStorage", task_runner);
+}
 
 void LocalStorageContextMojo::OpenLocalStorage(
     const url::Origin& origin,
@@ -349,6 +357,43 @@
   OnDatabaseOpened(true, leveldb::mojom::DatabaseError::OK);
 }
 
+bool LocalStorageContextMojo::OnMemoryDump(
+    const base::trace_event::MemoryDumpArgs& args,
+    base::trace_event::ProcessMemoryDump* pmd) {
+  if (connection_state_ != CONNECTION_FINISHED)
+    return true;
+  // TODO(mek): Somehow account for leveldb memory usage.
+  if (args.level_of_detail ==
+      base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND) {
+    size_t total_cache_size = 0;
+    for (const auto& it : level_db_wrappers_)
+      total_cache_size += it.second->level_db_wrapper()->bytes_used();
+    auto* mad = pmd->CreateAllocatorDump(
+        base::StringPrintf("dom_storage/0x%" PRIXPTR "/cache_size",
+                           reinterpret_cast<uintptr_t>(this)));
+    mad->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+                   base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+                   total_cache_size);
+    mad->AddScalar("total_areas",
+                   base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+                   level_db_wrappers_.size());
+    return true;
+  }
+  for (const auto& it : level_db_wrappers_) {
+    // Limit the url length to 50 and strip special characters.
+    std::string url = it.first.Serialize().substr(0, 50);
+    for (size_t index = 0; index < url.size(); ++index) {
+      if (!std::isalnum(url[index]))
+        url[index] = '_';
+    }
+    std::string name = base::StringPrintf(
+        "dom_storage/%s/0x%" PRIXPTR, url.c_str(),
+        reinterpret_cast<uintptr_t>(it.second->level_db_wrapper()));
+    it.second->level_db_wrapper()->OnMemoryDump(name, pmd);
+  }
+  return true;
+}
+
 // static
 std::vector<uint8_t> LocalStorageContextMojo::MigrateString(
     const base::string16& input) {
@@ -364,6 +409,8 @@
 
 LocalStorageContextMojo::~LocalStorageContextMojo() {
   DCHECK_EQ(connection_state_, CONNECTION_SHUTDOWN);
+  base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
+      this);
 }
 
 void LocalStorageContextMojo::RunWhenConnected(base::OnceClosure callback) {
diff --git a/content/browser/dom_storage/local_storage_context_mojo.h b/content/browser/dom_storage/local_storage_context_mojo.h
index 019e605..d91b5c4 100644
--- a/content/browser/dom_storage/local_storage_context_mojo.h
+++ b/content/browser/dom_storage/local_storage_context_mojo.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/files/file_path.h"
+#include "base/trace_event/memory_dump_provider.h"
 #include "content/common/content_export.h"
 #include "content/common/leveldb_wrapper.mojom.h"
 #include "content/public/browser/browser_thread.h"
@@ -30,18 +31,20 @@
 
 // Used for mojo-based LocalStorage implementation (can be disabled with
 // --disable-mojo-local-storage for now).
-// Created on the UI thread, but all further methods are called on the IO
-// thread. Furthermore since destruction of this class can involve asynchronous
-// steps, it can only be deleted by calling ShutdownAndDelete (on the IO
-// thread),
-class CONTENT_EXPORT LocalStorageContextMojo {
+// Created on the UI thread, but all further methods are called on the task
+// runner passed to the constructor. Furthermore since destruction of this class
+// can involve asynchronous steps, it can only be deleted by calling
+// ShutdownAndDelete (on the correct task runner).
+class CONTENT_EXPORT LocalStorageContextMojo
+    : public base::trace_event::MemoryDumpProvider {
  public:
   using GetStorageUsageCallback =
       base::OnceCallback<void(std::vector<LocalStorageUsageInfo>)>;
 
   LocalStorageContextMojo(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
       service_manager::Connector* connector,
-      scoped_refptr<DOMStorageTaskRunner> task_runner,
+      scoped_refptr<DOMStorageTaskRunner> legacy_task_runner,
       const base::FilePath& old_localstorage_path,
       const base::FilePath& subdirectory,
       scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy);
@@ -73,6 +76,10 @@
   void SetDatabaseForTesting(
       leveldb::mojom::LevelDBDatabaseAssociatedPtr database);
 
+  // base::trace_event::MemoryDumpProvider implementation.
+  bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
+                    base::trace_event::ProcessMemoryDump* pmd) override;
+
   // Converts a string from the old storage format to the new storage format.
   static std::vector<uint8_t> MigrateString(const base::string16& input);
 
@@ -81,7 +88,7 @@
 
   class LevelDBWrapperHolder;
 
-  ~LocalStorageContextMojo();
+  ~LocalStorageContextMojo() override;
 
   // Runs |callback| immediately if already connected to a database, otherwise
   // delays running |callback| untill after a connection has been established.
diff --git a/content/browser/dom_storage/local_storage_context_mojo_unittest.cc b/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
index 2e4db58..a1f5502 100644
--- a/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
+++ b/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
@@ -136,8 +136,8 @@
   LocalStorageContextMojo* context() {
     if (!context_) {
       context_ = new LocalStorageContextMojo(
-          nullptr, task_runner_, temp_path_.GetPath(),
-          base::FilePath(FILE_PATH_LITERAL("leveldb")),
+          base::ThreadTaskRunnerHandle::Get(), nullptr, task_runner_,
+          temp_path_.GetPath(), base::FilePath(FILE_PATH_LITERAL("leveldb")),
           special_storage_policy());
       leveldb::mojom::LevelDBDatabaseAssociatedPtr database_ptr;
       leveldb::mojom::LevelDBDatabaseAssociatedRequest request =
@@ -778,7 +778,8 @@
 
 TEST_F(LocalStorageContextMojoTestWithService, InMemory) {
   auto* context = new LocalStorageContextMojo(
-      connector(), nullptr, base::FilePath(), base::FilePath(), nullptr);
+      base::ThreadTaskRunnerHandle::Get(), connector(), nullptr,
+      base::FilePath(), base::FilePath(), nullptr);
   auto key = StdStringToUint8Vector("key");
   auto value = StdStringToUint8Vector("value");
 
@@ -799,7 +800,8 @@
   EXPECT_TRUE(FirstEntryInDir().empty());
 
   // Re-opening should get fresh data.
-  context = new LocalStorageContextMojo(connector(), nullptr, base::FilePath(),
+  context = new LocalStorageContextMojo(base::ThreadTaskRunnerHandle::Get(),
+                                        connector(), nullptr, base::FilePath(),
                                         base::FilePath(), nullptr);
   EXPECT_FALSE(DoTestGet(context, key, &result));
   context->ShutdownAndDelete();
@@ -807,8 +809,8 @@
 
 TEST_F(LocalStorageContextMojoTestWithService, InMemoryInvalidPath) {
   auto* context = new LocalStorageContextMojo(
-      connector(), nullptr, base::FilePath(),
-      base::FilePath(FILE_PATH_LITERAL("../../")), nullptr);
+      base::ThreadTaskRunnerHandle::Get(), connector(), nullptr,
+      base::FilePath(), base::FilePath(FILE_PATH_LITERAL("../../")), nullptr);
   auto key = StdStringToUint8Vector("key");
   auto value = StdStringToUint8Vector("value");
 
@@ -832,7 +834,8 @@
 TEST_F(LocalStorageContextMojoTestWithService, OnDisk) {
   base::FilePath test_path(FILE_PATH_LITERAL("test_path"));
   auto* context = new LocalStorageContextMojo(
-      connector(), nullptr, base::FilePath(), test_path, nullptr);
+      base::ThreadTaskRunnerHandle::Get(), connector(), nullptr,
+      base::FilePath(), test_path, nullptr);
   auto key = StdStringToUint8Vector("key");
   auto value = StdStringToUint8Vector("value");
 
@@ -849,7 +852,8 @@
   EXPECT_EQ(test_path, FirstEntryInDir().BaseName());
 
   // Should be able to re-open.
-  context = new LocalStorageContextMojo(connector(), nullptr, base::FilePath(),
+  context = new LocalStorageContextMojo(base::ThreadTaskRunnerHandle::Get(),
+                                        connector(), nullptr, base::FilePath(),
                                         test_path, nullptr);
   EXPECT_TRUE(DoTestGet(context, key, &result));
   EXPECT_EQ(value, result);
@@ -861,7 +865,8 @@
 
   // Create context and add some data to it.
   auto* context = new LocalStorageContextMojo(
-      connector(), nullptr, base::FilePath(), test_path, nullptr);
+      base::ThreadTaskRunnerHandle::Get(), connector(), nullptr,
+      base::FilePath(), test_path, nullptr);
   auto key = StdStringToUint8Vector("key");
   auto value = StdStringToUint8Vector("value");
 
@@ -888,7 +893,8 @@
   }
 
   // Make sure data is gone.
-  context = new LocalStorageContextMojo(connector(), nullptr, base::FilePath(),
+  context = new LocalStorageContextMojo(base::ThreadTaskRunnerHandle::Get(),
+                                        connector(), nullptr, base::FilePath(),
                                         test_path, nullptr);
   EXPECT_FALSE(DoTestGet(context, key, &result));
 
@@ -900,7 +906,8 @@
   base::RunLoop().RunUntilIdle();
 
   // Data should have been preserved now.
-  context = new LocalStorageContextMojo(connector(), nullptr, base::FilePath(),
+  context = new LocalStorageContextMojo(base::ThreadTaskRunnerHandle::Get(),
+                                        connector(), nullptr, base::FilePath(),
                                         test_path, nullptr);
   EXPECT_TRUE(DoTestGet(context, key, &result));
   EXPECT_EQ(value, result);
@@ -912,7 +919,8 @@
 
   // Create context and add some data to it.
   auto* context = new LocalStorageContextMojo(
-      connector(), nullptr, base::FilePath(), test_path, nullptr);
+      base::ThreadTaskRunnerHandle::Get(), connector(), nullptr,
+      base::FilePath(), test_path, nullptr);
   auto key = StdStringToUint8Vector("key");
   auto value = StdStringToUint8Vector("value");
 
@@ -936,7 +944,8 @@
   }
 
   // Make sure data is gone.
-  context = new LocalStorageContextMojo(connector(), nullptr, base::FilePath(),
+  context = new LocalStorageContextMojo(base::ThreadTaskRunnerHandle::Get(),
+                                        connector(), nullptr, base::FilePath(),
                                         test_path, nullptr);
   EXPECT_FALSE(DoTestGet(context, key, &result));
 
@@ -948,7 +957,8 @@
   base::RunLoop().RunUntilIdle();
 
   // Data should have been preserved now.
-  context = new LocalStorageContextMojo(connector(), nullptr, base::FilePath(),
+  context = new LocalStorageContextMojo(base::ThreadTaskRunnerHandle::Get(),
+                                        connector(), nullptr, base::FilePath(),
                                         test_path, nullptr);
   EXPECT_TRUE(DoTestGet(context, key, &result));
   EXPECT_EQ(value, result);
diff --git a/content/browser/leveldb_wrapper_impl.cc b/content/browser/leveldb_wrapper_impl.cc
index 8fc9e2f1..487a6401 100644
--- a/content/browser/leveldb_wrapper_impl.cc
+++ b/content/browser/leveldb_wrapper_impl.cc
@@ -7,6 +7,8 @@
 #include "base/bind.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "base/trace_event/memory_dump_manager.h"
+#include "base/trace_event/process_memory_dump.h"
 #include "components/leveldb/public/cpp/util.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -89,6 +91,39 @@
   CommitChanges();
 }
 
+void LevelDBWrapperImpl::OnMemoryDump(
+    const std::string& name,
+    base::trace_event::ProcessMemoryDump* pmd) {
+  if (!map_)
+    return;
+
+  const char* system_allocator_name =
+      base::trace_event::MemoryDumpManager::GetInstance()
+          ->system_allocator_pool_name();
+  if (commit_batch_) {
+    size_t data_size = 0;
+    for (const auto& key : commit_batch_->changed_keys)
+      data_size += key.size();
+    auto* commit_batch_mad = pmd->CreateAllocatorDump(name + "/commit_batch");
+    commit_batch_mad->AddScalar(
+        base::trace_event::MemoryAllocatorDump::kNameSize,
+        base::trace_event::MemoryAllocatorDump::kUnitsBytes, data_size);
+    if (system_allocator_name)
+      pmd->AddSuballocation(commit_batch_mad->guid(), system_allocator_name);
+  }
+
+  // Do not add storage map usage if less than 1KB.
+  if (bytes_used_ < 1024)
+    return;
+
+  auto* map_mad = pmd->CreateAllocatorDump(name + "/storage_map");
+  map_mad->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+                     base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+                     bytes_used_);
+  if (system_allocator_name)
+    pmd->AddSuballocation(map_mad->guid(), system_allocator_name);
+}
+
 void LevelDBWrapperImpl::PurgeMemory() {
   if (!map_ ||          // We're not using any memory.
       commit_batch_ ||  // We leave things alone with changes pending.
diff --git a/content/browser/leveldb_wrapper_impl.h b/content/browser/leveldb_wrapper_impl.h
index 9a59a64..b6d47d1 100644
--- a/content/browser/leveldb_wrapper_impl.h
+++ b/content/browser/leveldb_wrapper_impl.h
@@ -18,6 +18,12 @@
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "mojo/public/cpp/bindings/interface_ptr_set.h"
 
+namespace base {
+namespace trace_event {
+class ProcessMemoryDump;
+}
+}
+
 namespace content {
 
 // This is a wrapper around a leveldb::mojom::LevelDBDatabase. Multiple
@@ -78,6 +84,10 @@
   // are uncommitted changes this method does nothing.
   void PurgeMemory();
 
+  // Adds memory statistics to |pmd| for memory infra.
+  void OnMemoryDump(const std::string& name,
+                    base::trace_event::ProcessMemoryDump* pmd);
+
   // LevelDBWrapper:
   void AddObserver(mojom::LevelDBObserverAssociatedPtrInfo observer) override;
   void Put(const std::vector<uint8_t>& key,
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc
index dfe0fe3..34be8dd 100644
--- a/content/browser/service_worker/service_worker_provider_host.cc
+++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -565,6 +565,7 @@
 
 std::unique_ptr<ServiceWorkerProviderHost>
 ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() {
+  DCHECK(!IsBrowserSideNavigationEnabled());
   DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_);
   DCHECK_NE(MSG_ROUTING_NONE, info_.route_id);
   DCHECK_EQ(kDocumentMainThreadId, render_thread_id_);
@@ -580,8 +581,7 @@
   for (const GURL& pattern : associated_patterns_)
     DecreaseProcessReference(pattern);
 
-  for (auto& key_registration : matching_registrations_)
-    DecreaseProcessReference(key_registration.second->pattern());
+  RemoveAllMatchingRegistrations();
 
   if (associated_registration_.get()) {
     if (dispatcher_host_) {
@@ -598,11 +598,14 @@
 
 void ServiceWorkerProviderHost::CompleteCrossSiteTransfer(
     ServiceWorkerProviderHost* provisional_host) {
+  DCHECK(!IsBrowserSideNavigationEnabled());
   DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_);
   DCHECK_NE(ChildProcessHost::kInvalidUniqueID, provisional_host->process_id());
   DCHECK_NE(MSG_ROUTING_NONE, provisional_host->frame_id());
 
+  render_process_id_ = provisional_host->process_id();
   render_thread_id_ = kDocumentMainThreadId;
+  dispatcher_host_ = provisional_host->dispatcher_host();
   info_ = std::move(provisional_host->info_);
 
   // Take the connection over from the provisional host.
@@ -614,8 +617,11 @@
       base::Bind(&RemoveProviderHost, context_, provisional_host->process_id(),
                  provider_id()));
 
-  FinalizeInitialization(provisional_host->process_id(),
-                         provisional_host->dispatcher_host());
+  for (const GURL& pattern : associated_patterns_)
+    IncreaseProcessReference(pattern);
+  SyncMatchingRegistrations();
+
+  NotifyControllerToAssociatedProvider();
 }
 
 // PlzNavigate
@@ -640,8 +646,17 @@
   binding_.set_connection_error_handler(
       base::Bind(&RemoveProviderHost, context_, process_id, provider_id()));
   info_.route_id = info.route_id;
+  render_process_id_ = process_id;
+  dispatcher_host_ = dispatcher_host;
 
-  FinalizeInitialization(process_id, dispatcher_host);
+  // Increase the references because the process which this provider host will
+  // host has been decided.
+  for (const GURL& pattern : associated_patterns_)
+    IncreaseProcessReference(pattern);
+  for (auto& key_registration : matching_registrations_)
+    IncreaseProcessReference(key_registration.second->pattern());
+
+  NotifyControllerToAssociatedProvider();
 }
 
 void ServiceWorkerProviderHost::SendUpdateFoundMessage(
@@ -808,18 +823,7 @@
   dispatcher_host_->Send(message);
 }
 
-void ServiceWorkerProviderHost::FinalizeInitialization(
-    int process_id,
-    ServiceWorkerDispatcherHost* dispatcher_host) {
-  render_process_id_ = process_id;
-  dispatcher_host_ = dispatcher_host;
-
-  for (const GURL& pattern : associated_patterns_)
-    IncreaseProcessReference(pattern);
-
-  for (auto& key_registration : matching_registrations_)
-    IncreaseProcessReference(key_registration.second->pattern());
-
+void ServiceWorkerProviderHost::NotifyControllerToAssociatedProvider() {
   if (associated_registration_.get()) {
     SendAssociateRegistrationMessage();
     if (dispatcher_host_ && associated_registration_->active_version()) {
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h
index 13ab9aa..f2ed389 100644
--- a/content/browser/service_worker/service_worker_provider_host.h
+++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -373,9 +373,11 @@
   bool IsReadyToSendMessages() const;
   void Send(IPC::Message* message) const;
 
-  // Finalizes cross-site transfers and navigation-initalized hosts.
-  void FinalizeInitialization(int process_id,
-                              ServiceWorkerDispatcherHost* dispatcher_host);
+  // Notifies the information about the controller and associated registration
+  // to the provider on the renderer. This is for cross site transfer and
+  // browser side navigation which need to decide which process will handle the
+  // request later.
+  void NotifyControllerToAssociatedProvider();
 
   // Clears the information of the ServiceWorkerWorkerClient of dedicated (or
   // shared) worker, when the connection to the worker is disconnected.
diff --git a/content/browser/service_worker/service_worker_provider_host_unittest.cc b/content/browser/service_worker/service_worker_provider_host_unittest.cc
index b100d3b..8e1029b 100644
--- a/content/browser/service_worker/service_worker_provider_host_unittest.cc
+++ b/content/browser/service_worker/service_worker_provider_host_unittest.cc
@@ -246,11 +246,44 @@
       provider_host_insecure_parent->IsContextSecureForServiceWorker());
 }
 
+class MockServiceWorkerRegistration : public ServiceWorkerRegistration {
+ public:
+  MockServiceWorkerRegistration(const GURL& pattern,
+                                int64_t registration_id,
+                                base::WeakPtr<ServiceWorkerContextCore> context)
+      : ServiceWorkerRegistration(pattern, registration_id, context) {}
+
+  void AddListener(ServiceWorkerRegistration::Listener* listener) override {
+    listeners_.insert(listener);
+  }
+
+  void RemoveListener(ServiceWorkerRegistration::Listener* listener) override {
+    listeners_.erase(listener);
+  }
+
+  const std::set<ServiceWorkerRegistration::Listener*>& listeners() {
+    return listeners_;
+  }
+
+ protected:
+  ~MockServiceWorkerRegistration() override{};
+
+ private:
+  std::set<ServiceWorkerRegistration::Listener*> listeners_;
+};
+
 TEST_F(ServiceWorkerProviderHostTest, CrossSiteTransfer) {
   if (IsBrowserSideNavigationEnabled())
     return;
+
+  // Create a mock registration before creating the provider host which is in
+  // the scope.
+  scoped_refptr<MockServiceWorkerRegistration> registration =
+      new MockServiceWorkerRegistration(GURL("https://cross.example.com/"), 4L,
+                                        helper_->context()->AsWeakPtr());
+
   ServiceWorkerProviderHost* provider_host =
-      CreateProviderHost(GURL("https://www.example.com/example.html"));
+      CreateProviderHost(GURL("https://cross.example.com/example.html"));
   const int process_id = provider_host->process_id();
   const int provider_id = provider_host->provider_id();
   const int frame_id = provider_host->frame_id();
@@ -259,6 +292,8 @@
   const ServiceWorkerDispatcherHost* dispatcher_host =
       provider_host->dispatcher_host();
 
+  EXPECT_EQ(1u, registration->listeners().count(provider_host));
+
   std::unique_ptr<ServiceWorkerProviderHost> provisional_host =
       provider_host->PrepareForCrossSiteTransfer();
 
@@ -276,6 +311,8 @@
   EXPECT_FALSE(provider_host->is_parent_frame_secure());
   EXPECT_EQ(nullptr, provider_host->dispatcher_host());
 
+  EXPECT_EQ(0u, registration->listeners().size());
+
   provider_host->CompleteCrossSiteTransfer(provisional_host.get());
 
   EXPECT_EQ(process_id, provider_host->process_id());
@@ -290,6 +327,8 @@
   EXPECT_EQ(SERVICE_WORKER_PROVIDER_UNKNOWN, provisional_host->provider_type());
   EXPECT_FALSE(provisional_host->is_parent_frame_secure());
   EXPECT_EQ(nullptr, provisional_host->dispatcher_host());
+
+  EXPECT_EQ(1u, registration->listeners().count(provider_host));
 }
 
 TEST_F(ServiceWorkerProviderHostTest, RemoveProvider) {
diff --git a/content/browser/service_worker/service_worker_registration.h b/content/browser/service_worker/service_worker_registration.h
index bdf2c40..e0f107a 100644
--- a/content/browser/service_worker/service_worker_registration.h
+++ b/content/browser/service_worker/service_worker_registration.h
@@ -101,8 +101,8 @@
 
   ServiceWorkerVersion* GetNewestVersion() const;
 
-  void AddListener(Listener* listener);
-  void RemoveListener(Listener* listener);
+  virtual void AddListener(Listener* listener);
+  virtual void RemoveListener(Listener* listener);
   void NotifyRegistrationFailed();
   void NotifyUpdateFound();
   void NotifyVersionAttributesChanged(ChangedVersionAttributesMask mask);
@@ -157,11 +157,12 @@
   void EnableNavigationPreload(bool enable);
   void SetNavigationPreloadHeader(const std::string& value);
 
+ protected:
+  ~ServiceWorkerRegistration() override;
+
  private:
   friend class base::RefCounted<ServiceWorkerRegistration>;
 
-  ~ServiceWorkerRegistration() override;
-
   void UnsetVersionInternal(
       ServiceWorkerVersion* version,
       ChangedVersionAttributesMask* mask);
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index ac802f9..e80cf92 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -496,7 +496,7 @@
   }
 
   if (is_linux) {
-    deps += [ "//build/linux:fontconfig" ]
+    deps += [ "//third_party/fontconfig" ]
   }
 
   if (is_mac || is_win || is_android) {
diff --git a/content/renderer/media/media_stream_constraints_util.cc b/content/renderer/media/media_stream_constraints_util.cc
index 6af128d..a5c3b0c 100644
--- a/content/renderer/media/media_stream_constraints_util.cc
+++ b/content/renderer/media/media_stream_constraints_util.cc
@@ -111,14 +111,17 @@
     media::VideoCaptureParams capture_params,
     base::Optional<bool> noise_reduction,
     const VideoTrackAdapterSettings& track_adapter_settings,
-    double min_frame_rate)
+    base::Optional<double> min_frame_rate,
+    base::Optional<double> max_frame_rate)
     : failed_constraint_name_(nullptr),
       device_id_(std::move(device_id)),
       capture_params_(capture_params),
       noise_reduction_(noise_reduction),
       track_adapter_settings_(track_adapter_settings),
-      min_frame_rate_(min_frame_rate) {
-  DCHECK_LE(min_frame_rate_, capture_params.requested_format.frame_rate);
+      min_frame_rate_(min_frame_rate),
+      max_frame_rate_(max_frame_rate) {
+  DCHECK(!min_frame_rate ||
+         *min_frame_rate_ <= capture_params.requested_format.frame_rate);
   DCHECK_LE(track_adapter_settings.max_width,
             capture_params.requested_format.frame_size.width());
   DCHECK_LE(track_adapter_settings.max_height,
diff --git a/content/renderer/media/media_stream_constraints_util.h b/content/renderer/media/media_stream_constraints_util.h
index 92c3724..1c666a3 100644
--- a/content/renderer/media/media_stream_constraints_util.h
+++ b/content/renderer/media/media_stream_constraints_util.h
@@ -47,8 +47,9 @@
 //   * noise_reduction: used to control noise reduction for a screen-capture
 //     track sent to a peer connection. Derive from the googNoiseReduction
 //     constraint.
-//   * min_frame_rate: used to control frame refreshes in screen-capture tracks
-//     sent to a peer connection. Derived from the frameRate constraint.
+//   * min_frame_rate and max_frame_rate: used to control frame refreshes in
+//     screen-capture tracks sent to a peer connection. Derived from the
+//     frameRate constraint.
 class CONTENT_EXPORT VideoCaptureSettings {
  public:
   // Creates an object without value and with an empty failed constraint name.
@@ -65,7 +66,8 @@
                        media::VideoCaptureParams capture_params_,
                        base::Optional<bool> noise_reduction_,
                        const VideoTrackAdapterSettings& track_adapter_settings,
-                       double min_frame_rate);
+                       base::Optional<double> min_frame_rate,
+                       base::Optional<double> max_frame_rate);
 
   VideoCaptureSettings(const VideoCaptureSettings& other);
   VideoCaptureSettings& operator=(const VideoCaptureSettings& other);
@@ -119,10 +121,14 @@
     DCHECK(HasValue());
     return track_adapter_settings_;
   }
-  double min_frame_rate() const {
+  const base::Optional<double>& min_frame_rate() const {
     DCHECK(HasValue());
     return min_frame_rate_;
   }
+  const base::Optional<double>& max_frame_rate() const {
+    DCHECK(HasValue());
+    return max_frame_rate_;
+  }
 
  private:
   const char* failed_constraint_name_;
@@ -130,7 +136,8 @@
   media::VideoCaptureParams capture_params_;
   base::Optional<bool> noise_reduction_;
   VideoTrackAdapterSettings track_adapter_settings_;
-  double min_frame_rate_;
+  base::Optional<double> min_frame_rate_;
+  base::Optional<double> max_frame_rate_;
 };
 
 // Method to get boolean value of constraint with |name| from constraints.
diff --git a/content/renderer/media/media_stream_constraints_util_video_content.cc b/content/renderer/media/media_stream_constraints_util_video_content.cc
index d71fe79..82f447f 100644
--- a/content/renderer/media/media_stream_constraints_util_video_content.cc
+++ b/content/renderer/media/media_stream_constraints_util_video_content.cc
@@ -78,6 +78,7 @@
   VideoContentCaptureCandidates()
       : has_explicit_max_height_(false),
         has_explicit_max_width_(false),
+        has_explicit_min_frame_rate_(false),
         has_explicit_max_frame_rate_(false),
         device_id_set_(StringSet::UniversalSet()),
         noise_reduction_set_(BoolSet::UniversalSet()) {}
@@ -92,6 +93,9 @@
                                     kMaxScreenCastDimension),
         frame_rate_set_(
             DoubleRangeSet::FromConstraint(constraint_set.frame_rate)),
+        has_explicit_min_frame_rate_(
+            ConstraintHasMin(constraint_set.frame_rate) &&
+            ConstraintMin(constraint_set.frame_rate) >= 0.0),
         has_explicit_max_frame_rate_(
             ConstraintHasMax(constraint_set.frame_rate) &&
             ConstraintMax(constraint_set.frame_rate) <=
@@ -121,6 +125,8 @@
         has_explicit_max_width_ || other.has_explicit_max_width_;
     intersection.frame_rate_set_ =
         frame_rate_set_.Intersection(other.frame_rate_set_);
+    intersection.has_explicit_min_frame_rate_ =
+        has_explicit_min_frame_rate_ || other.has_explicit_min_frame_rate_;
     intersection.has_explicit_max_frame_rate_ =
         has_explicit_max_frame_rate_ || other.has_explicit_max_frame_rate_;
     intersection.device_id_set_ =
@@ -134,6 +140,9 @@
   bool has_explicit_max_height() const { return has_explicit_max_height_; }
   bool has_explicit_max_width() const { return has_explicit_max_width_; }
   const DoubleRangeSet& frame_rate_set() const { return frame_rate_set_; }
+  bool has_explicit_min_frame_rate() const {
+    return has_explicit_min_frame_rate_;
+  }
   bool has_explicit_max_frame_rate() const {
     return has_explicit_max_frame_rate_;
   }
@@ -147,6 +156,7 @@
   bool has_explicit_max_height_;
   bool has_explicit_max_width_;
   DoubleRangeSet frame_rate_set_;
+  bool has_explicit_min_frame_rate_;
   bool has_explicit_max_frame_rate_;
   StringSet device_id_set_;
   BoolSet noise_reduction_set_;
@@ -350,9 +360,17 @@
       candidates.frame_rate_set(), capture_params.requested_format,
       expect_source_native_size);
 
+  base::Optional<double> min_frame_rate;
+  if (candidates.has_explicit_min_frame_rate())
+    min_frame_rate = candidates.frame_rate_set().Min();
+
+  base::Optional<double> max_frame_rate;
+  if (candidates.has_explicit_max_frame_rate())
+    max_frame_rate = candidates.frame_rate_set().Max();
+
   return VideoCaptureSettings(std::move(device_id), capture_params,
                               noise_reduction, track_adapter_settings,
-                              candidates.frame_rate_set().Min());
+                              min_frame_rate, max_frame_rate);
 }
 
 VideoCaptureSettings UnsatisfiedConstraintsResult(
diff --git a/content/renderer/media/media_stream_constraints_util_video_content_unittest.cc b/content/renderer/media/media_stream_constraints_util_video_content_unittest.cc
index c31bef3..3cdfc7e2 100644
--- a/content/renderer/media/media_stream_constraints_util_video_content_unittest.cc
+++ b/content/renderer/media/media_stream_constraints_util_video_content_unittest.cc
@@ -19,9 +19,11 @@
 
 void CheckNonResolutionDefaults(const VideoCaptureSettings& result) {
   EXPECT_EQ(kDefaultScreenCastFrameRate, result.FrameRate());
+  EXPECT_EQ(base::Optional<double>(), result.min_frame_rate());
+  EXPECT_EQ(base::Optional<double>(), result.max_frame_rate());
   EXPECT_EQ(base::Optional<bool>(), result.noise_reduction());
   EXPECT_EQ(std::string(), result.device_id());
-  EXPECT_EQ(0.0, result.min_frame_rate());
+  EXPECT_FALSE(result.min_frame_rate().has_value());
 }
 
 void CheckNonFrameRateDefaults(const VideoCaptureSettings& result) {
@@ -1252,6 +1254,8 @@
   auto result = SelectSettings();
   EXPECT_TRUE(result.HasValue());
   EXPECT_EQ(kFrameRate, result.FrameRate());
+  EXPECT_EQ(kFrameRate, result.min_frame_rate());
+  EXPECT_EQ(kFrameRate, result.max_frame_rate());
   CheckNonFrameRateDefaults(result);
   CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
 }
@@ -1264,6 +1268,8 @@
   EXPECT_TRUE(result.HasValue());
   // kFrameRate is greater that the default, so expect kFrameRate.
   EXPECT_EQ(kFrameRate, result.FrameRate());
+  EXPECT_EQ(kFrameRate, result.min_frame_rate());
+  EXPECT_EQ(base::Optional<double>(), result.max_frame_rate());
   CheckNonFrameRateDefaults(result);
   CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
 
@@ -1273,6 +1279,8 @@
   EXPECT_TRUE(result.HasValue());
   // kFrameRate is greater that the default, so expect kFrameRate.
   EXPECT_EQ(kDefaultScreenCastFrameRate, result.FrameRate());
+  EXPECT_EQ(kSmallFrameRate, result.min_frame_rate());
+  EXPECT_EQ(base::Optional<double>(), result.max_frame_rate());
   CheckNonFrameRateDefaults(result);
   CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
 }
@@ -1287,6 +1295,8 @@
     EXPECT_TRUE(result.HasValue());
     // If max frame rate is provided, it is used as default.
     EXPECT_EQ(kMaxFrameRate, result.FrameRate());
+    EXPECT_EQ(base::Optional<double>(), result.min_frame_rate());
+    EXPECT_EQ(kMaxFrameRate, result.max_frame_rate());
     CheckNonFrameRateDefaults(result);
     CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
   }
@@ -1299,6 +1309,8 @@
     EXPECT_TRUE(result.HasValue());
     // If max frame rate is provided, it is used as default.
     EXPECT_EQ(kMaxFrameRate, result.FrameRate());
+    EXPECT_EQ(base::Optional<double>(), result.min_frame_rate());
+    EXPECT_EQ(kMaxFrameRate, result.max_frame_rate());
     CheckNonFrameRateDefaults(result);
     CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
   }
@@ -1311,6 +1323,8 @@
     EXPECT_TRUE(result.HasValue());
     // Expect the default, since the given maximum is invalid.
     EXPECT_EQ(kDefaultScreenCastFrameRate, result.FrameRate());
+    EXPECT_EQ(base::Optional<double>(), result.min_frame_rate());
+    EXPECT_EQ(base::Optional<double>(), result.max_frame_rate());
     CheckNonFrameRateDefaults(result);
     CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
   }
@@ -1323,6 +1337,8 @@
     EXPECT_TRUE(result.HasValue());
     // If max frame rate is provided, it is used as default.
     EXPECT_EQ(kMaxFrameRate, result.FrameRate());
+    EXPECT_EQ(base::Optional<double>(), result.min_frame_rate());
+    EXPECT_EQ(kMaxFrameRate, result.max_frame_rate());
     CheckNonFrameRateDefaults(result);
     CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
   }
@@ -1333,12 +1349,14 @@
   {
     const double kMinFrameRate = 15.0;
     const double kMaxFrameRate = 45.0;
-    constraint_factory_.basic().frame_rate.SetMax(kMinFrameRate);
+    constraint_factory_.basic().frame_rate.SetMin(kMinFrameRate);
     constraint_factory_.basic().frame_rate.SetMax(kMaxFrameRate);
     auto result = SelectSettings();
     EXPECT_TRUE(result.HasValue());
     // If max frame rate is provided, it is used as default.
     EXPECT_EQ(kMaxFrameRate, result.FrameRate());
+    EXPECT_EQ(kMinFrameRate, result.min_frame_rate());
+    EXPECT_EQ(kMaxFrameRate, result.max_frame_rate());
     CheckNonFrameRateDefaults(result);
     CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
   }
@@ -1346,12 +1364,14 @@
   {
     const double kMinFrameRate = 45.0;
     const double kMaxFrameRate = 55.0;
-    constraint_factory_.basic().frame_rate.SetMax(kMinFrameRate);
+    constraint_factory_.basic().frame_rate.SetMin(kMinFrameRate);
     constraint_factory_.basic().frame_rate.SetMax(kMaxFrameRate);
     auto result = SelectSettings();
     EXPECT_TRUE(result.HasValue());
     // If max frame rate is provided, it is used as default.
     EXPECT_EQ(kMaxFrameRate, result.FrameRate());
+    EXPECT_EQ(kMinFrameRate, result.min_frame_rate());
+    EXPECT_EQ(kMaxFrameRate, result.max_frame_rate());
     CheckNonFrameRateDefaults(result);
     CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
   }
@@ -1359,12 +1379,14 @@
   {
     const double kMinFrameRate = 10.0;
     const double kMaxFrameRate = 15.0;
-    constraint_factory_.basic().frame_rate.SetMax(kMinFrameRate);
+    constraint_factory_.basic().frame_rate.SetMin(kMinFrameRate);
     constraint_factory_.basic().frame_rate.SetMax(kMaxFrameRate);
     auto result = SelectSettings();
     EXPECT_TRUE(result.HasValue());
     // If max frame rate is provided, it is used as default.
     EXPECT_EQ(kMaxFrameRate, result.FrameRate());
+    EXPECT_EQ(kMinFrameRate, result.min_frame_rate());
+    EXPECT_EQ(kMaxFrameRate, result.max_frame_rate());
     CheckNonFrameRateDefaults(result);
     CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
   }
@@ -1379,6 +1401,8 @@
     auto result = SelectSettings();
     EXPECT_TRUE(result.HasValue());
     EXPECT_EQ(kIdealFrameRate, result.FrameRate());
+    EXPECT_EQ(base::Optional<double>(), result.min_frame_rate());
+    EXPECT_EQ(base::Optional<double>(), result.max_frame_rate());
     CheckNonFrameRateDefaults(result);
     CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
   }
@@ -1393,6 +1417,8 @@
     auto result = SelectSettings();
     EXPECT_TRUE(result.HasValue());
     EXPECT_EQ(kMaxFrameRate, result.FrameRate());
+    EXPECT_EQ(base::Optional<double>(), result.min_frame_rate());
+    EXPECT_EQ(kMaxFrameRate, result.max_frame_rate());
     CheckNonFrameRateDefaults(result);
     CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
   }
@@ -1407,6 +1433,7 @@
     auto result = SelectSettings();
     EXPECT_TRUE(result.HasValue());
     EXPECT_EQ(kMinFrameRate, result.FrameRate());
+    EXPECT_EQ(base::Optional<double>(), result.max_frame_rate());
     CheckNonFrameRateDefaults(result);
     CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
   }
@@ -1423,6 +1450,8 @@
     auto result = SelectSettings();
     EXPECT_TRUE(result.HasValue());
     EXPECT_EQ(kIdealFrameRate, result.FrameRate());
+    EXPECT_EQ(kMinFrameRate, result.min_frame_rate());
+    EXPECT_EQ(kMaxFrameRate, result.max_frame_rate());
     CheckNonFrameRateDefaults(result);
     CheckTrackAdapterSettingsEqualsFormatDefaultAspectRatio(result);
   }
diff --git a/content/renderer/media/media_stream_constraints_util_video_device.cc b/content/renderer/media/media_stream_constraints_util_video_device.cc
index b26be98..f2c361f9 100644
--- a/content/renderer/media/media_stream_constraints_util_video_device.cc
+++ b/content/renderer/media/media_stream_constraints_util_video_device.cc
@@ -185,8 +185,8 @@
 
   return VideoCaptureSettings(
       candidate.device_id(), capture_params, candidate.noise_reduction(),
-      track_adapter_settings,
-      constrained_format.constrained_frame_rate().Min());
+      track_adapter_settings, constrained_format.constrained_frame_rate().Min(),
+      constrained_format.constrained_frame_rate().Max());
 }
 
 // Generic distance function between two numeric values. Based on the fitness
diff --git a/content/renderer/media/media_stream_video_track.cc b/content/renderer/media/media_stream_video_track.cc
index 1d92473c..cc7fc9af 100644
--- a/content/renderer/media/media_stream_video_track.cc
+++ b/content/renderer/media/media_stream_video_track.cc
@@ -228,7 +228,7 @@
     const VideoTrackAdapterSettings& adapter_settings,
     const base::Optional<bool>& noise_reduction,
     bool is_screencast,
-    double min_frame_rate,
+    const base::Optional<double>& min_frame_rate,
     const MediaStreamVideoSource::ConstraintsCallback& callback,
     bool enabled) {
   blink::WebMediaStreamTrack track;
@@ -260,7 +260,6 @@
       adapter_settings_(base::MakeUnique<VideoTrackAdapterSettings>(
           VideoTrackAdapterSettings())),
       is_screencast_(false),
-      min_frame_rate_(0.0),
       source_(source->GetWeakPtr()) {
   if (IsOldVideoConstraints()) {
     blink::WebMediaConstraints constraints;
@@ -304,7 +303,7 @@
     const VideoTrackAdapterSettings& adapter_settings,
     const base::Optional<bool>& noise_reduction,
     bool is_screen_cast,
-    double min_frame_rate,
+    const base::Optional<double>& min_frame_rate,
     const MediaStreamVideoSource::ConstraintsCallback& callback,
     bool enabled)
     : MediaStreamTrack(true),
diff --git a/content/renderer/media/media_stream_video_track.h b/content/renderer/media/media_stream_video_track.h
index 6668585..5bd53b5 100644
--- a/content/renderer/media/media_stream_video_track.h
+++ b/content/renderer/media/media_stream_video_track.h
@@ -52,7 +52,7 @@
       const VideoTrackAdapterSettings& adapter_settings,
       const base::Optional<bool>& noise_reduction,
       bool is_screencast,
-      double min_frame_rate,
+      const base::Optional<double>& min_frame_rate,
       const MediaStreamVideoSource::ConstraintsCallback& callback,
       bool enabled);
 
@@ -76,7 +76,7 @@
       const VideoTrackAdapterSettings& adapter_settings,
       const base::Optional<bool>& noise_reduction,
       bool is_screen_cast,
-      double min_frame_rate,
+      const base::Optional<double>& min_frame_rate,
       const MediaStreamVideoSource::ConstraintsCallback& callback,
       bool enabled);
   ~MediaStreamVideoTrack() override;
@@ -102,10 +102,14 @@
     DCHECK(!IsOldVideoConstraints());
     return is_screencast_;
   }
-  double min_frame_rate() const {
+  const base::Optional<double>& min_frame_rate() const {
     DCHECK(!IsOldVideoConstraints());
     return min_frame_rate_;
   }
+  const base::Optional<double>& max_frame_rate() const {
+    DCHECK(!IsOldVideoConstraints());
+    return max_frame_rate_;
+  }
   const VideoTrackAdapterSettings& adapter_settings() const {
     DCHECK(!IsOldVideoConstraints());
     return *adapter_settings_;
@@ -152,7 +156,8 @@
   std::unique_ptr<VideoTrackAdapterSettings> adapter_settings_;
   base::Optional<bool> noise_reduction_;
   bool is_screencast_;
-  double min_frame_rate_;
+  base::Optional<double> min_frame_rate_;
+  base::Optional<double> max_frame_rate_;
 
   // Weak ref to the source this tracks is connected to.
   base::WeakPtr<MediaStreamVideoSource> source_;
diff --git a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc b/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
index 1aae1b42..1f6f9aa5 100644
--- a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
+++ b/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
@@ -268,8 +268,8 @@
   DCHECK(video_track);
   rtc::Optional<bool> needs_denoising;
   bool is_screencast = false;
-  double min_frame_rate = 0.0;
-  double max_frame_rate = 0.0;
+  base::Optional<double> min_frame_rate;
+  base::Optional<double> max_frame_rate;
 
   if (IsOldVideoConstraints()) {
     const blink::WebMediaConstraints& constraints = video_track->constraints();
@@ -292,17 +292,24 @@
             &denoising_value)) {
       needs_denoising = rtc::Optional<bool>(denoising_value);
     }
-    GetConstraintMinAsDouble(constraints,
-                             &blink::WebMediaTrackConstraintSet::frame_rate,
-                             &min_frame_rate);
-    GetConstraintMaxAsDouble(constraints,
-                             &blink::WebMediaTrackConstraintSet::frame_rate,
-                             &max_frame_rate);
+    double frame_rate_value;
+    if (GetConstraintMinAsDouble(constraints,
+                                 &blink::WebMediaTrackConstraintSet::frame_rate,
+                                 &frame_rate_value) &&
+        frame_rate_value >= 0.0) {
+      min_frame_rate = frame_rate_value;
+    }
+    if (GetConstraintMaxAsDouble(constraints,
+                                 &blink::WebMediaTrackConstraintSet::frame_rate,
+                                 &frame_rate_value) &&
+        frame_rate_value >= 0.0) {
+      max_frame_rate = frame_rate_value;
+    }
   } else {
     needs_denoising = ToRtcOptional(video_track->noise_reduction());
     is_screencast = video_track->is_screencast();
     min_frame_rate = video_track->min_frame_rate();
-    max_frame_rate = video_track->adapter_settings().max_frame_rate;
+    max_frame_rate = video_track->max_frame_rate();
   }
 
   // Enable automatic frame refreshes for the screen capture sources, which will
@@ -315,15 +322,15 @@
     // Start with the default refresh interval, and refine based on constraints.
     refresh_interval =
         base::TimeDelta::FromMicroseconds(kDefaultRefreshIntervalMicros);
-    if (min_frame_rate > 0.0) {
+    if (min_frame_rate.has_value()) {
       refresh_interval =
           base::TimeDelta::FromMicroseconds(base::saturated_cast<int64_t>(
-              base::Time::kMicrosecondsPerSecond / min_frame_rate));
+              base::Time::kMicrosecondsPerSecond / *min_frame_rate));
     }
-    if (max_frame_rate > 0.0) {
+    if (max_frame_rate.has_value()) {
       const base::TimeDelta alternate_refresh_interval =
           base::TimeDelta::FromMicroseconds(base::saturated_cast<int64_t>(
-              base::Time::kMicrosecondsPerSecond / max_frame_rate));
+              base::Time::kMicrosecondsPerSecond / *max_frame_rate));
       refresh_interval = std::max(refresh_interval, alternate_refresh_interval);
     }
     if (refresh_interval.InMicroseconds() < kLowerBoundRefreshIntervalMicros) {
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 02f6d47..920b9d2e 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -300,7 +300,7 @@
 
   if (is_linux) {
     deps += [
-      "//build/linux:fontconfig",
+      "//third_party/fontconfig",
       "//ui/gfx:test_support",
     ]
   }
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index 074361a..1482288a 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -237,34 +237,14 @@
     self.Fail('conformance2/textures/misc/tex-mipmap-levels.html',
         ['sierra'], bug=705865)
 
-    # Fails on all GPU types.
+    # Fails on multiple GPU types.
     self.Fail('conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html',
         ['mac'], bug=709351)
     self.Fail('conformance2/rendering/' +
         'framebuffer-completeness-unaffected.html',
-        ['mac'], bug=630800)
+        ['mac', 'nvidia', 'intel'], bug=630800)
     self.Fail('deqp/functional/gles3/fbocompleteness.html',
-        ['mac'], bug=630800)
-    self.Fail('deqp/functional/gles3/sync.html', ['mac'], bug=676848)
-    # self.Fail('deqp/functional/gles3/fbocompleteness.html',
-    #     ['mac', ('nvidia', 0xfe9)], bug=616562)
-
-    self.Fail('conformance2/renderbuffers/framebuffer-test.html',
-        ['mac'], bug=641149)
-    self.Fail('conformance2/rendering/framebuffer-texture-level1.html',
-        ['mac'], bug=680278)
-
-    self.Fail('deqp/functional/gles3/framebufferblit/conversion_28.html',
-        ['mac'], bug=654187)
-    self.Fail('deqp/functional/gles3/framebufferblit/conversion_30.html',
-        ['mac'], bug=654187)
-    self.Fail('deqp/functional/gles3/framebufferblit/conversion_31.html',
-        ['mac'], bug=654187)
-    self.Fail('deqp/functional/gles3/framebufferblit/conversion_33.html',
-        ['mac'], bug=654187)
-
-    self.Fail('conformance2/reading/format-r11f-g11f-b10f.html',
-        ['mac'], bug=1832) # khronos WebGL issue
+        ['mac', 'nvidia', 'intel'], bug=630800)
 
     # Mac Retina NVIDIA
     self.Fail('deqp/functional/gles3/fbomultisample*',
@@ -289,9 +269,6 @@
     self.Flaky('conformance2/textures/image_bitmap_from_video/' +
         'tex-2d-rgba16f-rgba-half_float.html',
         ['mac', ('nvidia', 0xfe9)], bug=682834)
-    self.Fail('conformance/uniforms/' +
-        'no-over-optimization-on-uniform-array-12.html',
-        ['mac', ('nvidia', 0xfe9)], bug=684903)
 
     self.Fail('deqp/functional/gles3/draw/random.html',
         ['sierra', ('nvidia', 0xfe9)], bug=716652)
@@ -417,30 +394,16 @@
         'multiple_attributes.output.html',
         ['mac', ('nvidia', 0xfe9)], bug=483282)
 
-    # Mac AMD
-    self.Fail('deqp/functional/gles3/fbomultisample.8_samples.html',
-        ['mac', 'amd'], bug=679686)
-    self.Fail('deqp/functional/gles3/fbomultisample.4_samples.html',
-        ['mac', 'amd'], bug=679686)
-    self.Fail('deqp/functional/gles3/fbomultisample.2_samples.html',
-        ['mac', 'amd'], bug=679686)
-    self.Fail('deqp/functional/gles3/pixelbufferobject.html',
-        ['mac', 'amd'], bug=679687)
-    self.Fail('deqp/functional/gles3/instancedrendering.html',
-        ['mac', 'amd'], bug=679689)
-    self.Fail('conformance/glsl/bugs/bool-type-cast-bug-int-float.html',
-        ['mac', 'amd'], bug=643866)
-    self.Fail('conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html',
-        ['mac', 'amd'], bug=643866)
-    self.Fail('deqp/functional/gles3/shadercommonfunction.html',
-        ['mac', 'amd'], bug=643866)
+    self.Fail('deqp/functional/gles3/framebufferblit/conversion_28.html',
+        ['mac', ('nvidia', 0xfe9)], bug=654187)
+    self.Fail('deqp/functional/gles3/framebufferblit/conversion_30.html',
+        ['mac', ('nvidia', 0xfe9)], bug=654187)
+    self.Fail('deqp/functional/gles3/framebufferblit/conversion_31.html',
+        ['mac', ('nvidia', 0xfe9)], bug=654187)
+    self.Fail('deqp/functional/gles3/framebufferblit/conversion_33.html',
+        ['mac', ('nvidia', 0xfe9)], bug=654187)
 
-    self.Fail('deqp/functional/gles3/multisample.html',
-        ['mac', 'amd'], bug=617290)
-    self.Fail('deqp/functional/gles3/primitiverestart/00.html',
-        ['mac', 'amd'], bug=598930)
-    self.Fail('deqp/functional/gles3/primitiverestart/01.html',
-        ['mac', 'amd'], bug=598930)
+    # Mac AMD
     self.Fail('deqp/functional/gles3/transformfeedback/' +
         'array_interleaved_lines.html',
         ['mac', 'amd'], bug=483282)
@@ -510,20 +473,9 @@
     self.Fail('deqp/functional/gles3/transformfeedback/' +
         'random_separate_triangles.html',
         ['mac', 'amd'], bug=483282)
-    self.Fail('deqp/functional/gles3/vertexarrays/' +
-        'single_attribute.normalize.html',
-        ['mac', 'amd'], bug=483282)
 
     self.Flaky('deqp/functional/gles3/shaderoperator/common_functions.html',
         ['mac', 'amd'], bug=702336)
-    self.Fail('deqp/functional/gles3/shaderoperator/' +
-        'angle_and_trigonometry_02.html',
-        ['mac', 'amd'], bug=483282)
-    self.Fail('deqp/functional/gles3/shaderoperator/' +
-        'angle_and_trigonometry_03.html',
-        ['mac', 'amd'], bug=483282)
-    self.Fail('deqp/functional/gles3/shaderoperator/geometric.html',
-        ['mac', 'amd'], bug=483282)
 
     self.Flaky('deqp/functional/gles3/shaderindexing/mat_01.html',
         ['mac', 'amd'], bug=636648)
@@ -542,58 +494,12 @@
 
     self.Fail('conformance2/rendering/clipping-wide-points.html',
         ['mac', 'amd'], bug=642822)
-    self.Fail('conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html',
-        ['mac', 'amd'], bug=646182)
-    self.Fail('conformance2/rendering/instanced-rendering-bug.html',
-        ['mac', 'amd'], bug=645298)
 
     # Mac Pro with AMD GPU
-    self.Fail('deqp/functional/gles3/fborender/recreate_color_02.html',
-        ['mac', ('amd', 0x679e)], bug=679682)
-    self.Fail('deqp/functional/gles3/fborender/resize_01.html',
-        ['mac', ('amd', 0x679e)], bug=679682)
     self.Flaky('deqp/functional/gles3/shaderindexing/tmp.html',
         ['mac', ('amd', 0x679e)], bug=659871)
-    self.Fail('deqp/functional/gles3/uniformbuffers/random.html',
-        ['mac', ('amd', 0x679e)], bug=618464)
-
-    # Mac Multi-vendor failures.
-    self.Fail('deqp/functional/gles3/fragmentoutput/basic.float.html',
-        ['mac', 'nvidia', 'amd'], bug=679684)
-    self.Fail('deqp/functional/gles3/fragmentoutput/array.float.html',
-        ['mac', 'nvidia', 'amd'], bug=679684)
-    self.Fail('deqp/functional/gles3/fragmentoutput/random_00.html',
-        ['mac', 'amd', 'intel'], bug=679690)
-    self.Fail('deqp/functional/gles3/fragmentoutput/random_02.html',
-        ['mac', 'amd', 'intel'], bug=679690)
-    self.Fail('deqp/functional/gles3/fbocolorbuffer/clear.html',
-        ['mac', 'amd', 'intel'], bug=679691)
 
     # Mac Intel
-    self.Fail(
-      'conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html',
-      ['sierra', 'intel'], bug=663188)
-    self.Fail(
-      'conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html',
-      ['sierra', 'intel'], bug=663188)
-    self.Fail(
-      'conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-float.html',
-      ['sierra', 'intel'], bug=663188)
-    self.Fail(
-      'conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-half_float.html',
-      ['sierra', 'intel'], bug=663188)
-    self.Fail(
-      'conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-float.html',
-      ['sierra', 'intel'], bug=663188)
-    self.Fail(
-      'conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-half_float.html',
-      ['sierra', 'intel'], bug=663188)
-    self.Fail(
-      'conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-float.html',
-      ['sierra', 'intel'], bug=663188)
-    self.Fail(
-      'conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-half_float.html',
-      ['sierra', 'intel'], bug=663188)
 
     # Regressions in 10.12.4 on Haswell GPUs.
     self.Fail('deqp/functional/gles3/fbocolorbuffer/tex2d_00.html',
@@ -604,6 +510,8 @@
         'default_framebuffer_05.html',
         ['mac', ('intel', 0x0a2e)], bug=718194)
 
+    self.Fail('conformance2/rendering/framebuffer-texture-level1.html',
+        ['mac', 'intel'], bug=680278)
     self.Fail('conformance2/textures/misc/angle-stuck-depth-textures.html',
         ['mac', 'intel'], bug=679692)
     self.Fail('deqp/functional/gles3/fbomultisample*',
@@ -637,48 +545,16 @@
         'textureprojgrad.html',
         ['mac', 'intel'], bug=483282)
 
-    self.Fail('deqp/functional/gles3/framebufferblit/rect_03.html',
-        ['mac', 'intel'], bug=483282)
-    self.Fail('deqp/functional/gles3/framebufferblit/rect_04.html',
-        ['mac', 'intel'], bug=483282)
-
-    self.Fail('conformance/textures/canvas_sub_rectangle/' +
-              'tex-2d-rgba-rgba-unsigned_byte.html',
-              ['mac', 'intel'], bug=665656)
-    self.Fail('conformance/textures/canvas_sub_rectangle/' +
-              'tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html',
-              ['mac', 'intel'], bug=665656)
-    self.Fail('conformance/textures/canvas_sub_rectangle/' +
-              'tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html',
-              ['mac', 'intel'], bug=665656)
-    self.Fail('conformance/textures/canvas_sub_rectangle/' +
-              'tex-2d-rgb-rgb-unsigned_byte.html',
-              ['mac', 'intel'], bug=665656)
-    self.Fail('conformance/textures/canvas_sub_rectangle/' +
-              'tex-2d-rgb-rgb-unsigned_short_5_6_5.html',
-              ['mac', 'intel'], bug=665656)
-    self.Fail('conformance2/textures/canvas_sub_rectangle/' +
-              'tex-2d-r8-red-unsigned_byte.html',
-              ['mac', 'intel'], bug=665656)
     self.Fail('conformance2/textures/canvas_sub_rectangle/' +
               'tex-2d-r8ui-red_integer-unsigned_byte.html',
               ['yosemite', 'intel'], bug=665656)
     self.Fail('conformance2/textures/canvas_sub_rectangle/' +
-              'tex-2d-rg8-rg-unsigned_byte.html',
-              ['mac', 'intel'], bug=665656)
-    self.Fail('conformance2/textures/canvas_sub_rectangle/' +
               'tex-2d-rg8ui-rg_integer-unsigned_byte.html',
               ['yosemite', 'intel'], bug=665656)
     self.Fail('conformance2/textures/canvas_sub_rectangle/' +
-              'tex-2d-rgb8-rgb-unsigned_byte.html',
-              ['mac', 'intel'], bug=665656)
-    self.Fail('conformance2/textures/canvas_sub_rectangle/' +
               'tex-2d-rgb8ui-rgb_integer-unsigned_byte.html',
               ['yosemite', 'intel'], bug=665656)
     self.Fail('conformance2/textures/canvas_sub_rectangle/' +
-              'tex-2d-rgba8-rgba-unsigned_byte.html',
-              ['mac', 'intel'], bug=665656)
-    self.Fail('conformance2/textures/canvas_sub_rectangle/' +
               'tex-2d-rgba8ui-rgba_integer-unsigned_byte.html',
               ['yosemite', 'intel'], bug=665656)
 
@@ -691,18 +567,11 @@
     self.Fail('conformance2/textures/image_data/' +
         'tex-2d-rg8ui-rg_integer-unsigned_byte.html',
         ['mac', 'intel'], bug=665197)
-    self.Fail('conformance2/textures/image_data/' +
-        'tex-2d-r8ui-red_integer-unsigned_byte.html',
-        ['mac', 'intel'], bug=665197)
 
     self.Fail('conformance2/textures/misc/' +
         'integer-cubemap-texture-sampling.html',
         ['mac', 'intel'], bug=658930)
 
-    # Fixed on OSX 10.11
-    self.Fail('deqp/functional/gles3/uniformbuffers/random.html',
-        ['mac', 'intel'], bug=618464)
-
     # Linux only.
     self.Flaky('conformance/textures/video/' +
                'tex-2d-rgba-rgba-unsigned_byte.html',
diff --git a/extensions/BUILD.gn b/extensions/BUILD.gn
index 2c715643..f19ae04 100644
--- a/extensions/BUILD.gn
+++ b/extensions/BUILD.gn
@@ -60,8 +60,6 @@
 static_library("test_support") {
   testonly = true
   sources = [
-    "browser/api/cast_channel/cast_test_util.cc",
-    "browser/api/cast_channel/cast_test_util.h",
     "browser/api/declarative/test_rules_registry.cc",
     "browser/api/declarative/test_rules_registry.h",
     "browser/api/dns/mock_host_resolver_creator.cc",
@@ -133,6 +131,7 @@
     ":extensions_resources",
     "//base",
     "//components/cast_certificate:test_support",
+    "//components/cast_channel:test_support",
     "//components/guest_view/browser:test_support",
     "//components/prefs:test_support",
     "//components/sync_preferences:test_support",
@@ -151,7 +150,6 @@
 
   public_deps = [
     "//content/public/browser",
-    "//extensions/common/api/cast_channel:cast_channel_proto",
   ]
 }
 
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index ea77fafa..743b2e9 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -401,15 +401,8 @@
     "api/alarms/alarms_api_unittest.cc",
     "api/api_resource_manager_unittest.cc",
     "api/bluetooth/bluetooth_event_router_unittest.cc",
-    "api/cast_channel/cast_auth_util_unittest.cc",
     "api/cast_channel/cast_channel_api_unittest.cc",
     "api/cast_channel/cast_channel_enum_util_unittest.cc",
-    "api/cast_channel/cast_framer_unittest.cc",
-    "api/cast_channel/cast_socket_service_unittest.cc",
-    "api/cast_channel/cast_socket_unittest.cc",
-    "api/cast_channel/cast_transport_unittest.cc",
-    "api/cast_channel/keep_alive_delegate_unittest.cc",
-    "api/cast_channel/logger_unittest.cc",
     "api/declarative/declarative_rule_unittest.cc",
     "api/declarative/deduping_factory_unittest.cc",
     "api/declarative/rules_registry_unittest.cc",
diff --git a/extensions/browser/api/BUILD.gn b/extensions/browser/api/BUILD.gn
index b17d2e2..7394afb3 100644
--- a/extensions/browser/api/BUILD.gn
+++ b/extensions/browser/api/BUILD.gn
@@ -142,7 +142,6 @@
     ":api",
     "//device/serial",
     "//extensions/common/api",
-    "//extensions/common/api/cast_channel:cast_channel_proto",
     "//skia",
   ]
 }
diff --git a/extensions/browser/api/cast_channel/BUILD.gn b/extensions/browser/api/cast_channel/BUILD.gn
index 6ec14193..2f0f9d1 100644
--- a/extensions/browser/api/cast_channel/BUILD.gn
+++ b/extensions/browser/api/cast_channel/BUILD.gn
@@ -4,35 +4,18 @@
 
 source_set("cast_channel") {
   sources = [
-    "cast_auth_util.cc",
-    "cast_auth_util.h",
     "cast_channel_api.cc",
     "cast_channel_api.h",
     "cast_channel_enum_util.cc",
     "cast_channel_enum_util.h",
-    "cast_framer.cc",
-    "cast_framer.h",
     "cast_message_util.cc",
     "cast_message_util.h",
-    "cast_socket.cc",
-    "cast_socket.h",
-    "cast_socket_service.cc",
-    "cast_socket_service.h",
-    "cast_socket_service_factory.cc",
-    "cast_socket_service_factory.h",
-    "cast_transport.cc",
-    "cast_transport.h",
-    "keep_alive_delegate.cc",
-    "keep_alive_delegate.h",
-    "logger.cc",
-    "logger.h",
   ]
 
   deps = [
     "//base",
     "//components/cast_channel",
     "//extensions/common/api",
-    "//extensions/common/api/cast_channel:cast_channel_proto",
     "//net",
   ]
 
diff --git a/extensions/browser/api/cast_channel/cast_channel_api.cc b/extensions/browser/api/cast_channel/cast_channel_api.cc
index 5e5c4b6..b769c395 100644
--- a/extensions/browser/api/cast_channel/cast_channel_api.cc
+++ b/extensions/browser/api/cast_channel/cast_channel_api.cc
@@ -18,17 +18,18 @@
 #include "base/memory/ptr_util.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
+#include "components/cast_channel/cast_message_util.h"
+#include "components/cast_channel/cast_socket.h"
+#include "components/cast_channel/cast_socket_service.h"
+#include "components/cast_channel/cast_socket_service_factory.h"
+#include "components/cast_channel/keep_alive_delegate.h"
+#include "components/cast_channel/logger.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
+#include "components/cast_channel/proto/logging.pb.h"
 #include "content/public/browser/browser_thread.h"
 #include "extensions/browser/api/cast_channel/cast_channel_enum_util.h"
 #include "extensions/browser/api/cast_channel/cast_message_util.h"
-#include "extensions/browser/api/cast_channel/cast_socket.h"
-#include "extensions/browser/api/cast_channel/cast_socket_service.h"
-#include "extensions/browser/api/cast_channel/cast_socket_service_factory.h"
-#include "extensions/browser/api/cast_channel/keep_alive_delegate.h"
-#include "extensions/browser/api/cast_channel/logger.h"
 #include "extensions/browser/event_router.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
-#include "extensions/common/api/cast_channel/logging.pb.h"
 #include "net/base/ip_address.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
@@ -39,24 +40,25 @@
 
 namespace extensions {
 
-namespace Close = cast_channel::Close;
-namespace OnError = cast_channel::OnError;
-namespace OnMessage = cast_channel::OnMessage;
-namespace Open = cast_channel::Open;
-namespace Send = cast_channel::Send;
-using ::cast_channel::ChannelError;
+namespace Close = api::cast_channel::Close;
+namespace OnError = api::cast_channel::OnError;
+namespace OnMessage = api::cast_channel::OnMessage;
+namespace Open = api::cast_channel::Open;
+namespace Send = api::cast_channel::Send;
+using api::cast_channel::ChannelInfo;
+using api::cast_channel::ConnectInfo;
+using api::cast_channel::ErrorInfo;
+using api::cast_channel::MessageInfo;
+using cast_channel::ChannelError;
 using cast_channel::CastDeviceCapability;
 using cast_channel::CastMessage;
 using cast_channel::CastSocket;
 using cast_channel::CastSocketImpl;
 using cast_channel::CastTransport;
-using cast_channel::ChannelInfo;
-using cast_channel::ConnectInfo;
-using cast_channel::ErrorInfo;
 using cast_channel::KeepAliveDelegate;
 using cast_channel::LastErrors;
 using cast_channel::Logger;
-using cast_channel::MessageInfo;
+
 using content::BrowserThread;
 
 namespace {
@@ -78,16 +80,17 @@
   channel_info->connect_info.ip_address = ip_endpoint.ToStringWithoutPort();
   channel_info->connect_info.port = ip_endpoint.port();
   channel_info->connect_info.auth =
-      cast_channel::ToChannelAuthType(socket.channel_auth());
-  channel_info->ready_state = cast_channel::ToReadyState(socket.ready_state());
+      api::cast_channel::ToChannelAuthType(socket.channel_auth());
+  channel_info->ready_state =
+      api::cast_channel::ToReadyState(socket.ready_state());
   channel_info->error_state =
-      cast_channel::ToChannelError(socket.error_state());
+      api::cast_channel::ToChannelError(socket.error_state());
   channel_info->keep_alive = socket.keep_alive();
   channel_info->audio_only = socket.audio_only();
 }
 
 // Fills |error_info| from |error_state| and |last_errors|.
-void FillErrorInfo(cast_channel::ChannelError error_state,
+void FillErrorInfo(api::cast_channel::ChannelError error_state,
                    const LastErrors& last_errors,
                    ErrorInfo* error_info) {
   error_info->error_state = error_state;
@@ -178,7 +181,7 @@
 
 bool CastChannelAsyncApiFunction::PrePrepare() {
   cast_socket_service_ =
-      api::cast_channel::CastSocketServiceFactory::GetForBrowserContext(
+      cast_channel::CastSocketServiceFactory::GetForBrowserContext(
           browser_context());
   DCHECK(cast_socket_service_);
   return true;
@@ -192,9 +195,9 @@
     const CastSocket& socket) {
   ChannelInfo channel_info;
   FillChannelInfo(socket, &channel_info);
-  cast_channel::ChannelError error =
-      cast_channel::ToChannelError(socket.error_state());
-  if (error != cast_channel::CHANNEL_ERROR_NONE) {
+  api::cast_channel::ChannelError error =
+      api::cast_channel::ToChannelError(socket.error_state());
+  if (error != api::cast_channel::CHANNEL_ERROR_NONE) {
     SetError("Channel socket error = " + base::IntToString(error));
   }
   SetResultFromChannelInfo(channel_info);
@@ -202,14 +205,15 @@
 
 void CastChannelAsyncApiFunction::SetResultFromError(
     int channel_id,
-    cast_channel::ChannelError error) {
+    api::cast_channel::ChannelError error) {
   ChannelInfo channel_info;
   channel_info.channel_id = channel_id;
-  channel_info.ready_state = cast_channel::READY_STATE_CLOSED;
+  channel_info.ready_state = api::cast_channel::READY_STATE_CLOSED;
   channel_info.error_state = error;
   channel_info.connect_info.ip_address = "";
   channel_info.connect_info.port = 0;
-  channel_info.connect_info.auth = cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED;
+  channel_info.connect_info.auth =
+      api::cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED;
   SetResultFromChannelInfo(channel_info);
   SetError("Channel error = " + base::IntToString(error));
 }
@@ -274,7 +278,8 @@
     return false;
   }
 
-  channel_auth_ = cast_channel::ToChannelAuthTypeInternal(connect_info.auth);
+  channel_auth_ =
+      api::cast_channel::ToChannelAuthTypeInternal(connect_info.auth);
   ip_endpoint_.reset(ParseConnectInfo(connect_info));
   return true;
 }
@@ -336,7 +341,8 @@
     SetResultFromSocket(*socket);
   } else {
     // The socket is being destroyed.
-    SetResultFromError(new_channel_id_, cast_channel::CHANNEL_ERROR_UNKNOWN);
+    SetResultFromError(new_channel_id_,
+                       api::cast_channel::CHANNEL_ERROR_UNKNOWN);
   }
 
   AsyncWorkCompleted();
@@ -377,14 +383,14 @@
       cast_socket_service_->GetSocket(params_->channel.channel_id);
   if (!socket) {
     SetResultFromError(params_->channel.channel_id,
-                       cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID);
+                       api::cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID);
     AsyncWorkCompleted();
     return;
   }
   CastMessage message_to_send;
   if (!MessageInfoToCastMessage(params_->message, &message_to_send)) {
     SetResultFromError(params_->channel.channel_id,
-                       cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
+                       api::cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
     AsyncWorkCompleted();
     return;
   }
@@ -398,7 +404,7 @@
   CastSocket* socket = cast_socket_service_->GetSocket(channel_id);
   if (result < 0 || !socket) {
     SetResultFromError(channel_id,
-                       cast_channel::CHANNEL_ERROR_SOCKET_ERROR);
+                       api::cast_channel::CHANNEL_ERROR_SOCKET_ERROR);
   } else {
     SetResultFromSocket(*socket);
   }
@@ -425,7 +431,7 @@
       cast_socket_service_->GetSocket(params_->channel.channel_id);
   if (!socket) {
     SetResultFromError(params_->channel.channel_id,
-                       cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID);
+                       api::cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID);
     AsyncWorkCompleted();
   } else {
     socket->Close(base::Bind(&CastChannelCloseFunction::OnClose, this));
@@ -439,7 +445,7 @@
   CastSocket* socket = cast_socket_service_->GetSocket(channel_id);
   if (result < 0 || !socket) {
     SetResultFromError(channel_id,
-                       cast_channel::CHANNEL_ERROR_SOCKET_ERROR);
+                       api::cast_channel::CHANNEL_ERROR_SOCKET_ERROR);
   } else {
     SetResultFromSocket(*socket);
     // This will delete |socket|.
@@ -467,7 +473,7 @@
 
   ChannelInfo channel_info;
   FillChannelInfo(*socket_, &channel_info);
-  channel_info.error_state = cast_channel::ToChannelError(error_state);
+  channel_info.error_state = api::cast_channel::ToChannelError(error_state);
   ErrorInfo error_info;
   FillErrorInfo(channel_info.error_state, logger_->GetLastErrors(socket_->id()),
                 &error_info);
diff --git a/extensions/browser/api/cast_channel/cast_channel_api.h b/extensions/browser/api/cast_channel/cast_channel_api.h
index 21db4b45..0a50bb8b 100644
--- a/extensions/browser/api/cast_channel/cast_channel_api.h
+++ b/extensions/browser/api/cast_channel/cast_channel_api.h
@@ -13,9 +13,9 @@
 #include "base/memory/ref_counted.h"
 #include "base/threading/thread_checker.h"
 #include "components/cast_channel/cast_channel_enum.h"
-#include "extensions/browser/api/api_resource_manager.h"
+#include "components/cast_channel/cast_socket.h"
+#include "components/cast_channel/proto/logging.pb.h"
 #include "extensions/browser/api/async_api_function.h"
-#include "extensions/browser/api/cast_channel/cast_socket.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
 #include "extensions/common/api/cast_channel.h"
 
@@ -29,19 +29,14 @@
 class IPEndPoint;
 }
 
+namespace cast_channel {
+class CastSocketService;
+}  // namespace cast_channel
+
 namespace extensions {
 
 struct Event;
 
-namespace api {
-namespace cast_channel {
-class CastSocketService;
-class Logger;
-}  // namespace cast_channel
-}  // namespace api
-
-namespace cast_channel = api::cast_channel;
-
 class CastChannelAPI : public BrowserContextKeyedAPI,
                        public base::SupportsWeakPtr<CastChannelAPI> {
  public:
@@ -116,14 +111,16 @@
 
   // Sets the function result to a ChannelInfo populated with |channel_id| and
   // |error|.
-  void SetResultFromError(int channel_id, cast_channel::ChannelError error);
+  void SetResultFromError(int channel_id,
+                          api::cast_channel::ChannelError error);
 
   // Manages creating and removing Cast sockets.
-  scoped_refptr<api::cast_channel::CastSocketService> cast_socket_service_;
+  scoped_refptr<cast_channel::CastSocketService> cast_socket_service_;
 
  private:
   // Sets the function result from |channel_info|.
-  void SetResultFromChannelInfo(const cast_channel::ChannelInfo& channel_info);
+  void SetResultFromChannelInfo(
+      const api::cast_channel::ChannelInfo& channel_info);
 };
 
 class CastChannelOpenFunction : public CastChannelAsyncApiFunction {
@@ -152,11 +149,11 @@
    public:
     CastMessageHandler(const EventDispatchCallback& ui_dispatch_cb,
                        cast_channel::CastSocket* socket,
-                       scoped_refptr<api::cast_channel::Logger> logger);
+                       scoped_refptr<cast_channel::Logger> logger);
     ~CastMessageHandler() override;
 
     // CastTransport::Delegate implementation.
-    void OnError(::cast_channel::ChannelError error_state) override;
+    void OnError(cast_channel::ChannelError error_state) override;
     void OnMessage(const cast_channel::CastMessage& message) override;
     void Start() override;
 
@@ -167,7 +164,7 @@
     EventDispatchCallback const ui_dispatch_cb_;
     cast_channel::CastSocket* const socket_;
     // Logger object for reporting error details.
-    scoped_refptr<api::cast_channel::Logger> logger_;
+    scoped_refptr<cast_channel::Logger> logger_;
 
     DISALLOW_COPY_AND_ASSIGN(CastMessageHandler);
   };
@@ -175,16 +172,16 @@
   // Validates that |connect_info| represents a valid IP end point and returns a
   // new IPEndPoint if so.  Otherwise returns nullptr.
   static net::IPEndPoint* ParseConnectInfo(
-      const cast_channel::ConnectInfo& connect_info);
+      const api::cast_channel::ConnectInfo& connect_info);
 
-  void OnOpen(::cast_channel::ChannelError result);
+  void OnOpen(cast_channel::ChannelError result);
 
-  std::unique_ptr<cast_channel::Open::Params> params_;
+  std::unique_ptr<api::cast_channel::Open::Params> params_;
   // The id of the newly opened socket.
   int new_channel_id_;
   CastChannelAPI* api_;
   std::unique_ptr<net::IPEndPoint> ip_endpoint_;
-  ::cast_channel::ChannelAuthType channel_auth_;
+  cast_channel::ChannelAuthType channel_auth_;
   base::TimeDelta liveness_timeout_;
   base::TimeDelta ping_interval_;
 
@@ -208,7 +205,7 @@
 
   void OnSend(int result);
 
-  std::unique_ptr<cast_channel::Send::Params> params_;
+  std::unique_ptr<api::cast_channel::Send::Params> params_;
 
   DISALLOW_COPY_AND_ASSIGN(CastChannelSendFunction);
 };
@@ -230,7 +227,7 @@
 
   void OnClose(int result);
 
-  std::unique_ptr<cast_channel::Close::Params> params_;
+  std::unique_ptr<api::cast_channel::Close::Params> params_;
   CastChannelAPI* api_;
 
   DISALLOW_COPY_AND_ASSIGN(CastChannelCloseFunction);
diff --git a/extensions/browser/api/cast_channel/cast_channel_apitest.cc b/extensions/browser/api/cast_channel/cast_channel_apitest.cc
index 13ad9133..6c7812c 100644
--- a/extensions/browser/api/cast_channel/cast_channel_apitest.cc
+++ b/extensions/browser/api/cast_channel/cast_channel_apitest.cc
@@ -12,13 +12,13 @@
 #include "chrome/browser/extensions/extension_function_test_utils.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/ui/browser.h"
+#include "components/cast_channel/cast_socket.h"
+#include "components/cast_channel/cast_test_util.h"
+#include "components/cast_channel/logger.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
 #include "content/public/browser/browser_thread.h"
 #include "extensions/browser/api/cast_channel/cast_channel_api.h"
-#include "extensions/browser/api/cast_channel/cast_socket.h"
-#include "extensions/browser/api/cast_channel/cast_test_util.h"
-#include "extensions/browser/api/cast_channel/logger.h"
 #include "extensions/common/api/cast_channel.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
 #include "extensions/common/switches.h"
 #include "extensions/common/test_util.h"
 #include "extensions/test/extension_test_message_listener.h"
@@ -30,23 +30,19 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gmock_mutant.h"
 
-// TODO(mfoltz): Mock out the ApiResourceManager to resolve threading issues
-// (crbug.com/398242) and simulate unloading of the extension.
-
+using ::cast_channel::CastMessage;
+using ::cast_channel::CastSocket;
+using ::cast_channel::CastTransport;
 using ::cast_channel::ChannelAuthType;
 using ::cast_channel::ChannelError;
+using ::cast_channel::CreateIPEndPointForTest;
+using ::cast_channel::LastErrors;
+using ::cast_channel::Logger;
+using ::cast_channel::MockCastSocket;
+using ::cast_channel::MockCastTransport;
 using ::cast_channel::ReadyState;
-
-using extensions::api::cast_channel::CastMessage;
-using extensions::api::cast_channel::CastSocket;
-using extensions::api::cast_channel::CastTransport;
-using extensions::api::cast_channel::CreateIPEndPointForTest;
 using extensions::api::cast_channel::ErrorInfo;
-using extensions::api::cast_channel::LastErrors;
-using extensions::api::cast_channel::Logger;
 using extensions::api::cast_channel::MessageInfo;
-using extensions::api::cast_channel::MockCastSocket;
-using extensions::api::cast_channel::MockCastTransport;
 using extensions::Extension;
 
 namespace utils = extension_function_test_utils;
@@ -64,6 +60,8 @@
 
 namespace {
 
+const char kTestExtensionId[] = "ddchlicdkolnonkihahngkmmmjnjlkkf";
+
 static void FillCastMessage(const std::string& message,
                             CastMessage* cast_message) {
   cast_message->set_namespace_("foo");
@@ -88,8 +86,7 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     ExtensionApiTest::SetUpCommandLine(command_line);
     command_line->AppendSwitchASCII(
-        extensions::switches::kWhitelistedExtensionID,
-        extensions::api::cast_channel::kTestExtensionId);
+        extensions::switches::kWhitelistedExtensionID, kTestExtensionId);
   }
 
   void SetUpMockCastSocket() {
@@ -158,9 +155,9 @@
 
   // Logs some bogus error details and calls the OnError handler.
   void DoCallOnError(extensions::CastChannelAPI* api) {
-    api->GetLogger()->LogSocketEventWithRv(
-        mock_cast_socket_->id(),
-        extensions::api::cast_channel::proto::SOCKET_WRITE, net::ERR_FAILED);
+    api->GetLogger()->LogSocketEventWithRv(mock_cast_socket_->id(),
+                                           ::cast_channel::proto::SOCKET_WRITE,
+                                           net::ERR_FAILED);
     message_delegate_->OnError(ChannelError::CONNECT_ERROR);
   }
 
diff --git a/extensions/browser/api/cast_channel/cast_channel_enum_util_unittest.cc b/extensions/browser/api/cast_channel/cast_channel_enum_util_unittest.cc
index a25c6898..d1452b14 100644
--- a/extensions/browser/api/cast_channel/cast_channel_enum_util_unittest.cc
+++ b/extensions/browser/api/cast_channel/cast_channel_enum_util_unittest.cc
@@ -11,7 +11,7 @@
 namespace cast_channel {
 namespace {
 
-TEST(CastChannelTypeUtilTest, TestToReadyState) {
+TEST(CastChannelEnumUtilTest, TestToReadyState) {
   EXPECT_EQ(READY_STATE_NONE, ToReadyState(::cast_channel::ReadyState::NONE));
   EXPECT_EQ(READY_STATE_CONNECTING,
             ToReadyState(::cast_channel::ReadyState::CONNECTING));
@@ -22,7 +22,7 @@
             ToReadyState(::cast_channel::ReadyState::CLOSED));
 }
 
-TEST(CastChannelTypeUtilTest, TestToChannelError) {
+TEST(CastChannelEnumUtilTest, TestToChannelError) {
   EXPECT_EQ(CHANNEL_ERROR_NONE,
             ToChannelError(::cast_channel::ChannelError::NONE));
   EXPECT_EQ(CHANNEL_ERROR_CHANNEL_NOT_OPEN,
@@ -47,14 +47,14 @@
             ToChannelError(::cast_channel::ChannelError::UNKNOWN));
 }
 
-TEST(CastChannelTypeUtilTest, TestToChannelAuthType) {
+TEST(CastChannelEnumUtilTest, TestToChannelAuthType) {
   EXPECT_EQ(CHANNEL_AUTH_TYPE_NONE,
             ToChannelAuthType(::cast_channel::ChannelAuthType::NONE));
   EXPECT_EQ(CHANNEL_AUTH_TYPE_SSL_VERIFIED,
             ToChannelAuthType(::cast_channel::ChannelAuthType::SSL_VERIFIED));
 }
 
-TEST(CastChannelTypeUtilTest, TestToChannelAuthTypeInternal) {
+TEST(CastChannelEnumUtilTest, TestToChannelAuthTypeInternal) {
   EXPECT_EQ(::cast_channel::ChannelAuthType::NONE,
             ToChannelAuthTypeInternal(CHANNEL_AUTH_TYPE_NONE));
   EXPECT_EQ(::cast_channel::ChannelAuthType::SSL_VERIFIED,
diff --git a/extensions/browser/api/cast_channel/cast_message_util.cc b/extensions/browser/api/cast_channel/cast_message_util.cc
index 3b64661..2d15891 100644
--- a/extensions/browser/api/cast_channel/cast_message_util.cc
+++ b/extensions/browser/api/cast_channel/cast_message_util.cc
@@ -9,29 +9,21 @@
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
-#include "extensions/browser/api/cast_channel/cast_auth_util.h"
+#include "components/cast_channel/proto/cast_channel.pb.h"
 #include "extensions/common/api/cast_channel.h"
-#include "extensions/common/api/cast_channel/cast_channel.pb.h"
-
-namespace {
-static const char kAuthNamespace[] =
-    "urn:x-cast:com.google.cast.tp.deviceauth";
-// Sender and receiver IDs to use for platform messages.
-static const char kPlatformSenderId[] = "sender-0";
-static const char kPlatformReceiverId[] = "receiver-0";
-}  // namespace
 
 namespace extensions {
 namespace api {
 namespace cast_channel {
 
 bool MessageInfoToCastMessage(const MessageInfo& message,
-                              CastMessage* message_proto) {
+                              ::cast_channel::CastMessage* message_proto) {
   DCHECK(message_proto);
   if (!message.data)
     return false;
 
-  message_proto->set_protocol_version(CastMessage_ProtocolVersion_CASTV2_1_0);
+  message_proto->set_protocol_version(
+      ::cast_channel::CastMessage_ProtocolVersion_CASTV2_1_0);
   message_proto->set_source_id(message.source_id);
   message_proto->set_destination_id(message.destination_id);
   message_proto->set_namespace_(message.namespace_);
@@ -42,13 +34,15 @@
     // JS string
     case base::Value::Type::STRING:
       if (message.data->GetAsString(&data)) {
-        message_proto->set_payload_type(CastMessage_PayloadType_STRING);
+        message_proto->set_payload_type(
+            ::cast_channel::CastMessage_PayloadType_STRING);
         message_proto->set_payload_utf8(data);
       }
       break;
     // JS ArrayBuffer
     case base::Value::Type::BINARY:
-      message_proto->set_payload_type(CastMessage_PayloadType_BINARY);
+      message_proto->set_payload_type(
+          ::cast_channel::CastMessage_PayloadType_BINARY);
       message_proto->set_payload_binary(message.data->GetBlob().data(),
                                         message.data->GetBlob().size());
       break;
@@ -60,18 +54,7 @@
   return message_proto->IsInitialized();
 }
 
-bool IsCastMessageValid(const CastMessage& message_proto) {
-  if (message_proto.namespace_().empty() || message_proto.source_id().empty() ||
-      message_proto.destination_id().empty()) {
-    return false;
-  }
-  return (message_proto.payload_type() == CastMessage_PayloadType_STRING &&
-          message_proto.has_payload_utf8()) ||
-         (message_proto.payload_type() == CastMessage_PayloadType_BINARY &&
-          message_proto.has_payload_binary());
-}
-
-bool CastMessageToMessageInfo(const CastMessage& message_proto,
+bool CastMessageToMessageInfo(const ::cast_channel::CastMessage& message_proto,
                               MessageInfo* message) {
   DCHECK(message);
   message->source_id = message_proto.source_id();
@@ -80,19 +63,19 @@
   // Determine the type of the payload and fill base::Value appropriately.
   std::unique_ptr<base::Value> value;
   switch (message_proto.payload_type()) {
-  case CastMessage_PayloadType_STRING:
-    if (message_proto.has_payload_utf8())
-      value.reset(new base::Value(message_proto.payload_utf8()));
-    break;
-  case CastMessage_PayloadType_BINARY:
-    if (message_proto.has_payload_binary())
-      value = base::Value::CreateWithCopiedBuffer(
-          message_proto.payload_binary().data(),
-          message_proto.payload_binary().size());
-    break;
-  default:
-    // Unknown payload type. value will remain unset.
-    break;
+    case ::cast_channel::CastMessage_PayloadType_STRING:
+      if (message_proto.has_payload_utf8())
+        value.reset(new base::Value(message_proto.payload_utf8()));
+      break;
+    case ::cast_channel::CastMessage_PayloadType_BINARY:
+      if (message_proto.has_payload_binary())
+        value = base::Value::CreateWithCopiedBuffer(
+            message_proto.payload_binary().data(),
+            message_proto.payload_binary().size());
+      break;
+    default:
+      // Unknown payload type. value will remain unset.
+      break;
   }
   if (value.get()) {
     DCHECK(!message->data.get());
@@ -103,58 +86,6 @@
   }
 }
 
-std::string CastMessageToString(const CastMessage& message_proto) {
-  std::string out("{");
-  out += "namespace = " + message_proto.namespace_();
-  out += ", sourceId = " + message_proto.source_id();
-  out += ", destId = " + message_proto.destination_id();
-  out += ", type = " + base::IntToString(message_proto.payload_type());
-  out += ", str = \"" + message_proto.payload_utf8() + "\"}";
-  return out;
-}
-
-std::string AuthMessageToString(const DeviceAuthMessage& message) {
-  std::string out("{");
-  if (message.has_challenge()) {
-    out += "challenge: {}, ";
-  }
-  if (message.has_response()) {
-    out += "response: {signature: (";
-    out += base::SizeTToString(message.response().signature().length());
-    out += " bytes), certificate: (";
-    out += base::SizeTToString(
-        message.response().client_auth_certificate().length());
-    out += " bytes)}";
-  }
-  if (message.has_error()) {
-    out += ", error: {";
-    out += base::IntToString(message.error().error_type());
-    out += "}";
-  }
-  out += "}";
-  return out;
-}
-
-void CreateAuthChallengeMessage(CastMessage* message_proto,
-                                const AuthContext& auth_context) {
-  CHECK(message_proto);
-  DeviceAuthMessage auth_message;
-  auth_message.mutable_challenge()->set_sender_nonce(auth_context.nonce());
-  std::string auth_message_string;
-  auth_message.SerializeToString(&auth_message_string);
-
-  message_proto->set_protocol_version(CastMessage_ProtocolVersion_CASTV2_1_0);
-  message_proto->set_source_id(kPlatformSenderId);
-  message_proto->set_destination_id(kPlatformReceiverId);
-  message_proto->set_namespace_(kAuthNamespace);
-  message_proto->set_payload_type(CastMessage_PayloadType_BINARY);
-  message_proto->set_payload_binary(auth_message_string);
-}
-
-bool IsAuthMessage(const CastMessage& message) {
-  return message.namespace_() == kAuthNamespace;
-}
-
 }  // namespace cast_channel
 }  // namespace api
 }  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/cast_message_util.h b/extensions/browser/api/cast_channel/cast_message_util.h
index bf1bbbd..f9fe4e5 100644
--- a/extensions/browser/api/cast_channel/cast_message_util.h
+++ b/extensions/browser/api/cast_channel/cast_message_util.h
@@ -7,40 +7,24 @@
 
 #include <string>
 
+namespace cast_channel {
+class CastMessage;
+}  // namespace cast_channel
+
 namespace extensions {
 namespace api {
 namespace cast_channel {
 
-class AuthContext;
-class CastMessage;
-class DeviceAuthMessage;
 struct MessageInfo;
 
 // Fills |message_proto| from |message| and returns true on success.
 bool MessageInfoToCastMessage(const MessageInfo& message,
-                              CastMessage* message_proto);
-
-// Checks if the contents of |message_proto| are valid.
-bool IsCastMessageValid(const CastMessage& message_proto);
+                              ::cast_channel::CastMessage* message_proto);
 
 // Fills |message| from |message_proto| and returns true on success.
-bool CastMessageToMessageInfo(const CastMessage& message_proto,
+bool CastMessageToMessageInfo(const ::cast_channel::CastMessage& message_proto,
                               MessageInfo* message);
 
-// Returns a human readable string for |message_proto|.
-std::string CastMessageToString(const CastMessage& message_proto);
-
-// Returns a human readable string for |message|.
-std::string AuthMessageToString(const DeviceAuthMessage& message);
-
-// Fills |message_proto| appropriately for an auth challenge request message.
-// Uses the nonce challenge in |auth_context|.
-void CreateAuthChallengeMessage(CastMessage* message_proto,
-                                const AuthContext& auth_context);
-
-// Returns whether the given message is an auth handshake message.
-bool IsAuthMessage(const CastMessage& message);
-
 }  // namespace cast_channel
 }  // namespace api
 }  // namespace extensions
diff --git a/extensions/common/api/cast_channel/OWNERS b/extensions/common/api/cast_channel/OWNERS
deleted file mode 100644
index fc1829b..0000000
--- a/extensions/common/api/cast_channel/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-mfoltz@chromium.org
-kmarshall@chromium.org
-wez@chromium.org
-
-# COMPONENT: Internals>Cast>API
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index 0d86ed67..c57d6d7 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -209,7 +209,7 @@
     ]
 
     deps = [
-      "//build/linux:fontconfig",
+      "//third_party/fontconfig",
       "//third_party/freetype",
     ]
 
diff --git a/ios/chrome/browser/web_resource/web_resource_util_unittest.cc b/ios/chrome/browser/web_resource/web_resource_util_unittest.cc
index c9fc9014..ac1950a 100644
--- a/ios/chrome/browser/web_resource/web_resource_util_unittest.cc
+++ b/ios/chrome/browser/web_resource/web_resource_util_unittest.cc
@@ -61,9 +61,7 @@
   bool success_called_;
 };
 
-// TODO(crbug.com/728216): Disabled because
-// ScopedTaskEnvironment::RunUntilIdle() may hang.
-TEST_F(WebResourceUtilTest, DISABLED_Success) {
+TEST_F(WebResourceUtilTest, Success) {
   const std::string kExpectedKey("foo");
   const std::string kExpectedValue("bar");
   std::string json = base::StringPrintf("{\"%s\":\"%s\"}", kExpectedKey.c_str(),
@@ -87,10 +85,8 @@
   EXPECT_EQ(kExpectedValue, actual_value_as_string);
 }
 
-// Only DictionaryValues are expected.
-// TODO(crbug.com/728216): Disabled because
-// ScopedTaskEnvironment::RunUntilIdle() may hang.
-TEST_F(WebResourceUtilTest, DISABLED_UnexpectedValue) {
+// Only DictionartValues are expected.
+TEST_F(WebResourceUtilTest, UnexpectedValue) {
   GetIOSChromeParseJSONCallback().Run("foo", GetSuccessCallback(),
                                       GetErrorCallback());
 
@@ -103,9 +99,7 @@
 }
 
 // Empty data is not expected.
-// TODO(crbug.com/728216): Disabled because
-// ScopedTaskEnvironment::RunUntilIdle() may hang.
-TEST_F(WebResourceUtilTest, DISABLED_EmptyValue) {
+TEST_F(WebResourceUtilTest, EmptyValue) {
   GetIOSChromeParseJSONCallback().Run(std::string(), GetSuccessCallback(),
                                       GetErrorCallback());
 
@@ -118,9 +112,7 @@
 }
 
 // Wrong syntax.
-// TODO(crbug.com/728216): Disabled because
-// ScopedTaskEnvironment::RunUntilIdle() may hang.
-TEST_F(WebResourceUtilTest, DISABLED_SyntaxError) {
+TEST_F(WebResourceUtilTest, SyntaxError) {
   GetIOSChromeParseJSONCallback().Run("%$[", GetSuccessCallback(),
                                       GetErrorCallback());
 
diff --git a/media/filters/vpx_video_decoder.cc b/media/filters/vpx_video_decoder.cc
index ca70546..0229c6ca 100644
--- a/media/filters/vpx_video_decoder.cc
+++ b/media/filters/vpx_video_decoder.cc
@@ -339,7 +339,10 @@
 }
 
 VpxVideoDecoder::VpxVideoDecoder()
-    : state_(kUninitialized), vpx_codec_(nullptr), vpx_codec_alpha_(nullptr) {
+    : state_(kUninitialized),
+      vpx_codec_(nullptr),
+      vpx_codec_alpha_(nullptr),
+      weak_factory_(this) {
   thread_checker_.DetachFromThread();
 }
 
@@ -454,7 +457,7 @@
     offload_task_runner_->PostTask(
         FROM_HERE,
         BindToCurrentLoop(base::Bind(&VpxVideoDecoder::ResetHelper,
-                                     base::Unretained(this), closure)));
+                                     weak_factory_.GetWeakPtr(), closure)));
     return;
   }
 
diff --git a/media/filters/vpx_video_decoder.h b/media/filters/vpx_video_decoder.h
index b307ab0..92cd3f4 100644
--- a/media/filters/vpx_video_decoder.h
+++ b/media/filters/vpx_video_decoder.h
@@ -7,6 +7,7 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "media/base/demuxer_stream.h"
 #include "media/base/video_decoder.h"
@@ -120,6 +121,9 @@
 
   VideoFramePool frame_pool_;
 
+  // NOTE: Weak pointers must be invalidated before all other member variables.
+  base::WeakPtrFactory<VpxVideoDecoder> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(VpxVideoDecoder);
 };
 
diff --git a/net/url_request/url_request_quic_perftest.cc b/net/url_request/url_request_quic_perftest.cc
index 7b881ba..ce545d1 100644
--- a/net/url_request/url_request_quic_perftest.cc
+++ b/net/url_request/url_request_quic_perftest.cc
@@ -19,7 +19,6 @@
 #include "base/test/trace_event_analyzer.h"
 #include "base/time/time.h"
 #include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/memory_dump_manager_test_utils.h"
 #include "base/trace_event/memory_dump_request_args.h"
 #include "base/trace_event/process_memory_dump.h"
 #include "base/trace_event/trace_buffer.h"
@@ -88,12 +87,37 @@
                          static_cast<double>(value), unit, true);
 }
 
+void RequestGlobalDumpCallback(base::Closure quit_closure,
+                               uint64_t,
+                               bool success) {
+  base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure);
+  ASSERT_TRUE(success);
+}
+
+void ProcessDumpCallbackAdapter(
+    base::trace_event::GlobalMemoryDumpCallback callback,
+    uint64_t dump_guid,
+    bool success,
+    const base::Optional<base::trace_event::MemoryDumpCallbackResult>&) {
+  callback.Run(dump_guid, success);
+}
+
+void RequestGlobalMemoryDumpCallback(
+    const base::trace_event::MemoryDumpRequestArgs& args,
+    const base::trace_event::GlobalMemoryDumpCallback& callback) {
+  base::trace_event::ProcessMemoryDumpCallback process_callback =
+      base::Bind(&ProcessDumpCallbackAdapter, callback);
+  base::trace_event::MemoryDumpManager::GetInstance()->CreateProcessDump(
+      args, process_callback);
+}
+
 class URLRequestQuicPerfTest : public ::testing::Test {
  protected:
   URLRequestQuicPerfTest() : message_loop_(new base::MessageLoopForIO()) {
     memory_dump_manager_ =
         base::trace_event::MemoryDumpManager::CreateInstanceForTesting();
-    base::trace_event::InitializeMemoryDumpManagerForInProcessTesting(
+    memory_dump_manager_->Initialize(
+        base::BindRepeating(&RequestGlobalMemoryDumpCallback),
         /*is_coordinator_process=*/false);
     memory_dump_manager_->set_dumper_registrations_ignored_for_testing(false);
     context_ = base::MakeUnique<TestURLRequestContext>(true);
@@ -245,17 +269,11 @@
       base::trace_event::TraceLog::RECORDING_MODE);
 
   base::RunLoop run_loop;
-  base::trace_event::MemoryDumpRequestArgs args{
-      1 /* dump_guid*/, base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED,
-      base::trace_event::MemoryDumpLevelOfDetail::LIGHT};
-  auto on_memory_dump_done =
-      [](base::Closure quit_closure, uint64_t dump_guid, bool success,
-         const base::Optional<base::trace_event::MemoryDumpCallbackResult>&) {
-        base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure);
-        ASSERT_TRUE(success);
-      };
-  base::trace_event::MemoryDumpManager::GetInstance()->CreateProcessDump(
-      args, base::Bind(on_memory_dump_done, run_loop.QuitClosure()));
+  base::trace_event::MemoryDumpManager::GetInstance()->RequestGlobalDump(
+      base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED,
+      base::trace_event::MemoryDumpLevelOfDetail::LIGHT,
+      base::Bind(&RequestGlobalDumpCallback, run_loop.QuitClosure()));
+
   run_loop.Run();
   base::trace_event::TraceLog::GetInstance()->SetDisabled();
   std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer =
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
index 3d8dd34..2d993c7 100644
--- a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
+++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
@@ -117,7 +117,7 @@
       args.dump_type != base::trace_event::MemoryDumpType::SUMMARY_ONLY) {
     for (const auto& request : queued_memory_dump_requests_) {
       if (request.args.level_of_detail == args.level_of_detail) {
-        VLOG(1) << "RequestGlobalMemoryDump("
+        VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix << " ("
                 << base::trace_event::MemoryDumpTypeToString(args.dump_type)
                 << ") skipped because another dump request with the same "
                    "level of detail ("
@@ -219,7 +219,8 @@
 
   if (!success) {
     ++failed_memory_dump_count_;
-    VLOG(1) << "RequestGlobalMemoryDump() FAIL: NACK from client process";
+    VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix
+            << " failed because of NACK from client";
   }
 
   FinalizeGlobalMemoryDumpIfAllManagersReplied();
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index 9ddc75e..aa3cfbef 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -451,8 +451,8 @@
       ]
     }
     deps += [
-      "//build/linux:fontconfig",
       "//third_party/expat",
+      "//third_party/fontconfig",
       "//third_party/icu:icuuc",
     ]
   }
diff --git a/third_party/WebKit/LayoutTests/LeakExpectations b/third_party/WebKit/LayoutTests/LeakExpectations
index 7c09a2a..2302bfac 100644
--- a/third_party/WebKit/LayoutTests/LeakExpectations
+++ b/third_party/WebKit/LayoutTests/LeakExpectations
@@ -36,15 +36,13 @@
 crbug.com/701695 external/wpt/html/webappapis/scripting/events/event-handler-processing-algorithm-error/window-synthetic-errorevent.html [ Leak ]
 
 # -----------------------------------------------------------------
-# Untriaged but known leaks of ActiveDOMObject (fast).
+# Untriaged but known leaks of SuspendableObject (fast).
 # -----------------------------------------------------------------
 crbug.com/661182 fast/loader/open-in-srcdoc-unload.html [ Leak ]
 
 # -----------------------------------------------------------------
-# Untriaged but known leaks of ActiveDOMObject (http).
+# Untriaged but known leaks of SuspendableObject (http).
 # -----------------------------------------------------------------
-crbug.com/506754 http/tests/inspector/service-workers/service-worker-agents.html [ Crash Leak ]
-crbug.com/506754 virtual/mojo-loading/http/tests/inspector/service-workers/service-worker-agents.html [ Crash Leak ]
 crbug.com/506754 http/tests/serviceworker/chromium/resolve-after-window-close.html [ Leak ]
 crbug.com/506754 virtual/mojo-loading/http/tests/serviceworker/chromium/resolve-after-window-close.html [ Leak ]
 crbug.com/506754 virtual/off-main-thread-fetch/http/tests/serviceworker/chromium/resolve-after-window-close.html [ Leak ]
@@ -57,13 +55,6 @@
 crbug.com/506754 virtual/service-worker-navigation-preload-disabled/http/tests/serviceworker/chromium/window-close-during-registration.html [ Leak ]
 
 # -----------------------------------------------------------------
-# Untriaged but known leaks of ActiveDOMObject (Web Audio).
-# -----------------------------------------------------------------
-crbug.com/451577 [ Linux ] inspector/elements/user-properties.html [ Slow ]
-crbug.com/451577 [ Linux ] inspector/extensions/extensions-reload.html [ Slow ]
-crbug.com/451577 [ Linux ] inspector/extensions/extensions-sidebar.html [ Slow ]
-
-# -----------------------------------------------------------------
 # Leaks in external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/*
 # -----------------------------------------------------------------
 crbug.com/594309 [ Linux ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-baseline-align-self-baseline-vert-001.html [ Failure Pass Leak ]
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
index 9dff8b17..616b8ed7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
@@ -72,9 +72,12 @@
 InspectorTest.preloadPanel("timeline");
 Bindings.TempFile = InspectorTest.TempFileMock;
 
-InspectorTest.createTracingModel = function()
+InspectorTest.createTracingModel = function(events)
 {
-    return new SDK.TracingModel(new Bindings.TempFileBackingStorage("tracing"));
+    var model = new SDK.TracingModel(new Bindings.TempFileBackingStorage("tracing"));
+    model.addEvents(events);
+    model.tracingComplete();
+    return model;
 }
 
 InspectorTest.tracingModel = function()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing-browser-thread.html b/third_party/WebKit/LayoutTests/inspector/tracing-browser-thread.html
index f2990a8..8f6eb41 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing-browser-thread.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing-browser-thread.html
@@ -34,8 +34,7 @@
         ]
     };
     for (var testCase of Object.keys(testCases)) {
-        var model = InspectorTest.createTracingModel();
-        model.setEventsForTest(testCases[testCase]);
+        var model = InspectorTest.createTracingModel(testCases[testCase]);
         var browserMain = SDK.TracingModel.browserMainThread(model);
         if (!browserMain) {
             InspectorTest.addResult(`${testCase} failed, no browser main thread found`);
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing-model-async.html b/third_party/WebKit/LayoutTests/inspector/tracing-model-async.html
index 436cbe57..8d3b4e3 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing-model-async.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing-model-async.html
@@ -66,8 +66,7 @@
 
     ];
 
-    var model = InspectorTest.createTracingModel();
-    model.setEventsForTest(testData);
+    var model = InspectorTest.createTracingModel(testData);
     var events = model.sortedProcesses()[0].threadById(mainThread).asyncEvents();
     for (var i = 0; i < events.length; ++i) {
         var stepString = events[i].name + " " + events[i].startTime + "-" + events[i].endTime + ": ";
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing-model-ids.html b/third_party/WebKit/LayoutTests/inspector/tracing-model-ids.html
index c5fe43f..4bc70b2 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing-model-ids.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing-model-ids.html
@@ -43,8 +43,7 @@
         {"cat": "blink.console", "name": "global-scope", "ph": "F", "ts": 220010, "args": {}, "scope": "s2", "id2": { global: 6}, "tid": mainThread, "pid": pid + 2},
     ];
 
-    var model = InspectorTest.createTracingModel();
-    model.setEventsForTest(testData);
+    var model = InspectorTest.createTracingModel(testData);
     var events = model.sortedProcesses()[0].threadById(mainThread).asyncEvents();
     for (var i = 0; i < events.length; ++i) {
         var stepString = `${events[i].name} ${events[i].startTime}-${events[i].endTime}: ` +
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing-model-storage.html b/third_party/WebKit/LayoutTests/inspector/tracing-model-storage.html
index 2cadd42..a10a308 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing-model-storage.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing-model-storage.html
@@ -20,9 +20,7 @@
         return thread.events().filter(function(event) { return event.name === name; })[0];
     }
 
-    var model = InspectorTest.createTracingModel();
-    model.addEvents(testData);
-    model.tracingComplete();
+    var model = InspectorTest.createTracingModel(testData);
     var process = model.sortedProcesses()[0];
     var thread = process.sortedThreads()[0];
     InspectorTest.assertEquals("лет ми спик фром май харт", getEventByName("NonAscii").args["nonascii"]);
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing-model.html b/third_party/WebKit/LayoutTests/inspector/tracing-model.html
index 50fa4cd..9f9c215f 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing-model.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing-model.html
@@ -53,10 +53,8 @@
 
         {"name": "Outer", "ts": 130000, args: {}, "ph": "I", "tid": mainThread, "pid": 100, "cat":"test" }
     ];
-    
-    var model = InspectorTest.createTracingModel();
-    model.addEvents(testData);
-    model.tracingComplete();
+
+    var model = InspectorTest.createTracingModel(testData);
     var events = model.sortedProcesses()[0].threadById(mainThread).events();
     for (var i = 0; i < events.length; ++i) {
         var event = events[i];
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing.html b/third_party/WebKit/LayoutTests/inspector/tracing.html
index 00fc0c71..4c96da1 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing.html
@@ -18,7 +18,7 @@
 InspectorTest.TracingManagerClient = function(callback)
 {
     this._completionCallback = callback;
-    this._tracingModel = InspectorTest.createTracingModel();
+    this._tracingModel = new SDK.TracingModel(new Bindings.TempFileBackingStorage("tracing"));
 }
 
 InspectorTest.TracingManagerClient.prototype = {
@@ -30,6 +30,7 @@
     tracingComplete: function()
     {
         InspectorTest.addResult("Tracing complete");
+        this._tracingModel.tracingComplete();
         this._completionCallback(this._tracingModel);
     },
 
@@ -51,7 +52,6 @@
     var tracingManager = InspectorTest.tracingManager;
     tracingManager.start(tracingClient, "", "").then(() => {
         InspectorTest.addResult("Tracing started");
-        tracingClient._tracingModel.reset();
         InspectorTest.evaluateInPage("doWork()", tracingManager.stop.bind(tracingManager));
     });
 
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/tracing-timeline-load.html b/third_party/WebKit/LayoutTests/inspector/tracing/tracing-timeline-load.html
index 4f1923b..580ab03 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/tracing-timeline-load.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/tracing-timeline-load.html
@@ -27,10 +27,9 @@
             InspectorTest.addResult("TimelineLoaderClient.processingStarted()");
         },
 
-        loadingComplete: function(model, storage)
+        loadingComplete: function(model)
         {
             this.model = model;
-            this.storage = storage;
             InspectorTest.addResult(`TimelineLoaderClient.loadingComplete(${!!model})`);
             this._callback();
         },
@@ -57,7 +56,7 @@
         {
             var saver = new Timeline.TracingTimelineSaver();
             var stream = new InspectorTest.StringOutputStream(InspectorTest.safeWrap(checkSaveData));
-            var storage = delegate.storage;
+            var storage = delegate.model.backingStorage();
             stream.open("", storage.writeToStream.bind(storage, stream, saver));
         };
     }
diff --git a/third_party/WebKit/LayoutTests/webaudio/codec-tests/aac/m4a-short-duration-44khz-expected.wav b/third_party/WebKit/LayoutTests/webaudio/codec-tests/aac/m4a-short-duration-44khz-expected.wav
index 73dba9d..01f2f08 100644
--- a/third_party/WebKit/LayoutTests/webaudio/codec-tests/aac/m4a-short-duration-44khz-expected.wav
+++ b/third_party/WebKit/LayoutTests/webaudio/codec-tests/aac/m4a-short-duration-44khz-expected.wav
Binary files differ
diff --git a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp
index baed2fc..370515f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp
@@ -44,14 +44,6 @@
   DCHECK(scrollable_area_);
 }
 
-LayoutScrollbarPart::~LayoutScrollbarPart() {
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-  // We may not have invalidated the painting layer for now, but the
-  // scrollable area will invalidate during paint invalidation.
-  EndShouldKeepAlive();
-#endif
-}
-
 static void RecordScrollbarPartStats(Document& document, ScrollbarPart part) {
   switch (part) {
     case kBackButtonStartPart:
diff --git a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.h b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.h
index 565e349..b654339 100644
--- a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.h
+++ b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.h
@@ -40,7 +40,6 @@
                                               ScrollableArea*,
                                               LayoutScrollbar* = nullptr,
                                               ScrollbarPart = kNoPart);
-  ~LayoutScrollbarPart() override;
 
   const char* GetName() const override { return "LayoutScrollbarPart"; }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutView.cpp b/third_party/WebKit/Source/core/layout/LayoutView.cpp
index 4ed27c407..5fa6714 100644
--- a/third_party/WebKit/Source/core/layout/LayoutView.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutView.cpp
@@ -838,13 +838,6 @@
 void LayoutView::SetIsInWindow(bool is_in_window) {
   if (compositor_)
     compositor_->SetIsInWindow(is_in_window);
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-  // We don't invalidate layers during Document::detachLayoutTree(), so must
-  // clear the should-keep-alive DisplayItemClients which may be deleted before
-  // the layers being subsequence owners.
-  if (!is_in_window && Layer())
-    Layer()->EndShouldKeepAliveAllClientsRecursive();
-#endif
 }
 
 IntervalArena* LayoutView::GetIntervalArena() {
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
index 8b193e1..1fb2218f 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -3313,14 +3313,6 @@
   needs_repaint_ = false;
 }
 
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-void PaintLayer::EndShouldKeepAliveAllClientsRecursive() {
-  for (PaintLayer* child = FirstChild(); child; child = child->NextSibling())
-    child->EndShouldKeepAliveAllClientsRecursive();
-  DisplayItemClient::EndShouldKeepAliveAllClients(this);
-}
-#endif
-
 DisableCompositingQueryAsserts::DisableCompositingQueryAsserts()
     : disabler_(&g_compositing_query_mode, kCompositingQueriesAreAllowed) {}
 
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.h b/third_party/WebKit/Source/core/paint/PaintLayer.h
index 038802d..e5e7200 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayer.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayer.h
@@ -1021,10 +1021,6 @@
     self_painting_status_changed_ = false;
   }
 
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-  void EndShouldKeepAliveAllClientsRecursive();
-#endif
-
  private:
   void SetNeedsCompositingInputsUpdateInternal();
 
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
index 8c189c3..0153d68 100644
--- a/third_party/WebKit/Source/devtools/BUILD.gn
+++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -862,7 +862,7 @@
   "$resources_out_dir/SupportedCSSProperties.js",
 ]
 
-generated_resources = [
+generated_applications = [
   "$resources_out_dir/inspector.html",
   "$resources_out_dir/inspector.js",
   "$resources_out_dir/toolbox.html",
@@ -871,8 +871,9 @@
   "$resources_out_dir/formatter_worker.js",
   "$resources_out_dir/heap_snapshot_worker.js",
   "$resources_out_dir/utility_shared_worker.js",
+]
 
-  # this contains non-autostart non-remote modules only.
+generated_non_autostart_non_remote_modules = [
   "$resources_out_dir/animation/animation_module.js",
   "$resources_out_dir/audits/audits_module.js",
   "$resources_out_dir/audits2/audits2_module.js",
@@ -905,13 +906,15 @@
   "$resources_out_dir/snippets/snippets_module.js",
   "$resources_out_dir/source_frame/source_frame_module.js",
   "$resources_out_dir/sources/sources_module.js",
-  "$resources_out_dir/terminal/terminal_module.js",
   "$resources_out_dir/text_editor/text_editor_module.js",
   "$resources_out_dir/timeline_model/timeline_model_module.js",
   "$resources_out_dir/timeline/timeline_module.js",
   "$resources_out_dir/workspace_diff/workspace_diff_module.js",
 ]
 
+generated_resources =
+    generated_applications + generated_non_autostart_non_remote_modules
+
 generated_remote_modules = [
   "$resources_out_dir/accessibility/accessibility_module.js",
   "$resources_out_dir/audits2_worker/audits2_worker_module.js",
diff --git a/third_party/WebKit/Source/devtools/PRESUBMIT.py b/third_party/WebKit/Source/devtools/PRESUBMIT.py
index 1623692..bbd0cf4b 100644
--- a/third_party/WebKit/Source/devtools/PRESUBMIT.py
+++ b/third_party/WebKit/Source/devtools/PRESUBMIT.py
@@ -44,6 +44,26 @@
     return [output_api.PresubmitNotifyResult(out)]
 
 
+def _CheckBuildGN(input_api, output_api):
+    original_sys_path = sys.path
+    try:
+        sys.path = sys.path + [input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts")]
+        import install_node_deps
+    finally:
+        sys.path = original_sys_path
+
+    node_path, _ = install_node_deps.resolve_node_paths()
+
+    script_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts", "check_gn.js")
+    process = input_api.subprocess.Popen(
+        [node_path, script_path], stdout=input_api.subprocess.PIPE, stderr=input_api.subprocess.STDOUT)
+    out, _ = process.communicate()
+
+    if process.returncode != 0:
+        return [output_api.PresubmitError(out)]
+    return [output_api.PresubmitNotifyResult(out)]
+
+
 def _CheckFormat(input_api, output_api):
 
     def popen(args):
@@ -185,6 +205,7 @@
 def CheckChangeOnUpload(input_api, output_api):
     results = []
     results.extend(_CheckNodeAndNPMModules(input_api, output_api))
+    results.extend(_CheckBuildGN(input_api, output_api))
     results.extend(_CheckFormat(input_api, output_api))
     results.extend(_CheckDevtoolsStyle(input_api, output_api))
     results.extend(_CompileDevtoolsFrontend(input_api, output_api))
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js b/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
index cc8ee55f..86a7a58 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
@@ -407,7 +407,8 @@
 
     parentTarget.registerTargetDispatcher(this);
     this._targetAgent.invoke_setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true});
-    if (Runtime.experiments.isEnabled('autoAttachToCrossProcessSubframes'))
+    var type = parentTarget[SDK.TargetManager._targetType];
+    if ((type === 'page' || type === 'iframe') && Runtime.experiments.isEnabled('autoAttachToCrossProcessSubframes'))
       this._targetAgent.setAttachToFrames(true);
 
     if (!parentTarget.parentTarget())
@@ -522,7 +523,7 @@
     var target = this._targetManager.createTarget(
         targetInfo.targetId, targetName, this._capabilitiesForType(targetInfo.type),
         this._createChildConnection.bind(this, this._targetAgent, targetInfo.targetId), this._parentTarget);
-    target[SDK.TargetManager._isWorkerSymbol] = targetInfo.type === 'worker';
+    target[SDK.TargetManager._targetType] = targetInfo.type;
 
     // Only pause the new worker if debugging SW - we are going through the pause on start checkbox.
     if (!this._parentTarget.parentTarget() && Runtime.queryParam('isSharedWorker') && waitingForDebugger) {
@@ -610,7 +611,7 @@
   AvailableNodeTargetsChanged: Symbol('AvailableNodeTargetsChanged')
 };
 
-SDK.TargetManager._isWorkerSymbol = Symbol('SDK.TargetManager.IsWorker');
+SDK.TargetManager._targetType = Symbol('SDK.TargetManager.TargetType');
 
 /**
  * @interface
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js
index 996fc50..19a4e305 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js
@@ -4,9 +4,6 @@
  * found in the LICENSE file.
  */
 
-/**
- * @unrestricted
- */
 SDK.TracingModel = class {
   /**
    * @param {!SDK.BackingStorage} backingStorage
@@ -15,7 +12,22 @@
     this._backingStorage = backingStorage;
     // Avoid extra reset of the storage as it's expensive.
     this._firstWritePending = true;
-    this.reset();
+    /** @type {!Map<(number|string), !SDK.TracingModel.Process>} */
+    this._processById = new Map();
+    this._processByName = new Map();
+    this._minimumRecordTime = 0;
+    this._maximumRecordTime = 0;
+    this._devToolsMetadataEvents = [];
+    /** @type {!Array<!SDK.TracingModel.Event>} */
+    this._asyncEvents = [];
+    /** @type {!Map<string, !SDK.TracingModel.AsyncEvent>} */
+    this._openAsyncEvents = new Map();
+    /** @type {!Map<string, !Array<!SDK.TracingModel.AsyncEvent>>} */
+    this._openNestableAsyncEvents = new Map();
+    /** @type {!Map<string, !SDK.TracingModel.ProfileEventsGroup>} */
+    this._profileGroups = new Map();
+    /** @type {!Map<string, !Set<string>>} */
+    this._parsedCategories = new Map();
   }
 
   /**
@@ -120,15 +132,6 @@
   /**
    * @param {!Array.<!SDK.TracingManager.EventPayload>} events
    */
-  setEventsForTest(events) {
-    this.reset();
-    this.addEvents(events);
-    this.tracingComplete();
-  }
-
-  /**
-   * @param {!Array.<!SDK.TracingManager.EventPayload>} events
-   */
   addEvents(events) {
     for (var i = 0; i < events.length; ++i)
       this._addEvent(events[i]);
@@ -145,27 +148,9 @@
     }
   }
 
-  reset() {
-    /** @type {!Map<(number|string), !SDK.TracingModel.Process>} */
-    this._processById = new Map();
-    this._processByName = new Map();
-    this._minimumRecordTime = 0;
-    this._maximumRecordTime = 0;
-    this._devToolsMetadataEvents = [];
+  dispose() {
     if (!this._firstWritePending)
       this._backingStorage.reset();
-
-    this._firstWritePending = true;
-    /** @type {!Array<!SDK.TracingModel.Event>} */
-    this._asyncEvents = [];
-    /** @type {!Map<string, !SDK.TracingModel.AsyncEvent>} */
-    this._openAsyncEvents = new Map();
-    /** @type {!Map<string, !Array<!SDK.TracingModel.AsyncEvent>>} */
-    this._openNestableAsyncEvents = new Map();
-    /** @type {!Map<string, !SDK.TracingModel.ProfileEventsGroup>} */
-    this._profileGroups = new Map();
-    /** @type {!Map<string, !Set<string>>} */
-    this._parsedCategories = new Map();
   }
 
   /**
@@ -424,6 +409,13 @@
   }
 
   /**
+   * @return {!SDK.BackingStorage}
+   */
+  backingStorage() {
+    return this._backingStorage;
+  }
+
+  /**
    * @param {string} str
    * @return {!Set<string>}
    */
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/ExtensionTracingSession.js b/third_party/WebKit/Source/devtools/front_end/timeline/ExtensionTracingSession.js
index 22aa0a8..fffe10f 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/ExtensionTracingSession.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/ExtensionTracingSession.js
@@ -40,9 +40,8 @@
   /**
    * @override
    * @param {?SDK.TracingModel} tracingModel
-   * @param {?Bindings.TempFileBackingStorage} storage
    */
-  loadingComplete(tracingModel, storage) {
+  loadingComplete(tracingModel) {
     if (!tracingModel)
       return;
     this._performanceModel.addExtensionEvents(this._provider.longDisplayName(), tracingModel, this._timeOffset);
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/PerformanceModel.js b/third_party/WebKit/Source/devtools/front_end/timeline/PerformanceModel.js
index 90bffef..e9139e4 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/PerformanceModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/PerformanceModel.js
@@ -136,9 +136,9 @@
 
   dispose() {
     if (this._tracingModel)
-      this._tracingModel.reset();
+      this._tracingModel.dispose();
     for (var extensionEntry of this._extensionTracingModels)
-      extensionEntry.model.reset();
+      extensionEntry.model.dispose();
   }
 
   /**
@@ -151,6 +151,15 @@
     var filmStripFrame = this._filmStripModel.frameByTimestamp(screenshotTime);
     return filmStripFrame && filmStripFrame.timestamp - frame.endTime < 10 ? filmStripFrame : null;
   }
+
+  /**
+   * @param {!Common.OutputStream} stream
+   * @param {!Bindings.OutputStreamDelegate} delegate
+   */
+  save(stream, delegate) {
+    var backingStorage = /** @type {!Bindings.TempFileBackingStorage} */ (this._tracingModel.backingStorage());
+    backingStorage.writeToStream(stream, delegate);
+  }
 };
 
 /**
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineController.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineController.js
index da89f8c2..2984dcb3 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineController.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineController.js
@@ -18,8 +18,8 @@
     this._performanceModel = performanceModel;
     this._client = client;
 
-    this._tracingModelBackingStorage = new Bindings.TempFileBackingStorage('tracing');
-    this._tracingModel = new SDK.TracingModel(this._tracingModelBackingStorage);
+    var backingStorage = new Bindings.TempFileBackingStorage('tracing');
+    this._tracingModel = new SDK.TracingModel(backingStorage);
 
     this._performanceModel.setMainTarget(tracingManager.target());
 
@@ -200,7 +200,7 @@
   _finalizeTrace() {
     this._injectCpuProfileEvents();
     this._tracingModel.tracingComplete();
-    this._client.loadingComplete(this._tracingModel, this._tracingModelBackingStorage);
+    this._client.loadingComplete(this._tracingModel);
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLoader.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLoader.js
index 6b992bc..5158954 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLoader.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLoader.js
@@ -66,7 +66,7 @@
   cancel() {
     this._tracingModel = null;
     this._backingStorage.reset();
-    this._client.loadingComplete(null, null);
+    this._client.loadingComplete(null);
     this._client = null;
     if (this._canceledCallback)
       this._canceledCallback();
@@ -195,7 +195,7 @@
       this._buffer = '';
     }
     this._tracingModel.tracingComplete();
-    this._client.loadingComplete(this._tracingModel, this._backingStorage);
+    this._client.loadingComplete(this._tracingModel);
   }
 
   /**
@@ -274,9 +274,8 @@
 
   /**
    * @param {?SDK.TracingModel} tracingModel
-   * @param {?Bindings.TempFileBackingStorage} backingStorage
    */
-  loadingComplete(tracingModel, backingStorage) {},
+  loadingComplete(tracingModel) {},
 };
 
 /**
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
index f13de1eb..7a77aeaf 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
@@ -348,31 +348,26 @@
     contextMenu.show();
   }
 
-  /**
-   * @return {boolean}
-   */
   _saveToFile() {
     if (this._state !== Timeline.TimelinePanel.State.Idle)
-      return true;
-    if (!this._performanceModel)
-      return true;
+      return;
+    var performanceModel = this._performanceModel;
+    if (!performanceModel)
+      return;
 
     var now = new Date();
     var fileName = 'Profile-' + now.toISO8601Compact() + '.json';
     var stream = new Bindings.FileOutputStream();
+    stream.open(fileName, callback);
 
     /**
      * @param {boolean} accepted
-     * @this {Timeline.TimelinePanel}
      */
     function callback(accepted) {
       if (!accepted)
         return;
-      var saver = new Timeline.TracingTimelineSaver();
-      this._backingStorage.writeToStream(stream, saver);
+      performanceModel.save(stream, new Timeline.TracingTimelineSaver());
     }
-    stream.open(fileName, callback.bind(this));
-    return true;
   }
 
   async _showHistory() {
@@ -792,14 +787,12 @@
   /**
    * @override
    * @param {?SDK.TracingModel} tracingModel
-   * @param {?Bindings.TempFileBackingStorage} backingStorage
    */
-  loadingComplete(tracingModel, backingStorage) {
+  loadingComplete(tracingModel) {
     delete this._loader;
     this._setState(Timeline.TimelinePanel.State.Idle);
     var performanceModel = this._pendingPerformanceModel;
     this._pendingPerformanceModel = null;
-    this._backingStorage = backingStorage;
 
     if (this._statusPane)
       this._statusPane.hide();
@@ -812,7 +805,6 @@
     }
 
     performanceModel.setTracingModel(tracingModel);
-    this._backingStorage = backingStorage;
     this._setModel(performanceModel);
     if (this._historyManager)
       this._historyManager.addRecording(performanceModel);
diff --git a/third_party/WebKit/Source/devtools/package.json b/third_party/WebKit/Source/devtools/package.json
index 39549c2..af41be8 100644
--- a/third_party/WebKit/Source/devtools/package.json
+++ b/third_party/WebKit/Source/devtools/package.json
@@ -13,7 +13,8 @@
     "closure": "python scripts/compile_frontend.py",
     "setup-dtrun": "cd scripts/devtools_run && npm link",
     "format-py": "yapf --exclude scripts/build/rjsmin.py -i --recursive scripts PRESUBMIT.py",
-    "extract": "node scripts/extract_module/extract_module.js"
+    "extract": "node scripts/extract_module/extract_module.js",
+    "check-gn": "node scripts/check_gn.js"
   },
   "repository": {
     "type": "git",
diff --git a/third_party/WebKit/Source/devtools/scripts/check_gn.js b/third_party/WebKit/Source/devtools/scripts/check_gn.js
new file mode 100644
index 0000000..f46e72ca
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/scripts/check_gn.js
@@ -0,0 +1,65 @@
+// 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.
+
+const fs = require('fs');
+const path = require('path');
+
+const inspectorManifest = require('../front_end/inspector.json');
+const utils = require('./utils');
+
+const gnPath = path.resolve(__dirname, '..', 'BUILD.gn');
+const gnFile = fs.readFileSync(gnPath, 'utf-8');
+const gnLines = gnFile.split('\n');
+
+function main() {
+  let errors = [];
+  errors = errors.concat(checkNonAutostartNonRemoteModules());
+  if (errors.length) {
+    console.log('DevTools BUILD.gn checker detected errors!');
+    console.log(`There's an issue with: ${gnPath}`);
+    console.log(errors.join('\n'));
+    process.exit(1);
+  }
+  console.log('DevTools BUILD.gn checker passed');
+}
+
+main();
+
+function checkNonAutostartNonRemoteModules() {
+  const errors = [];
+  const gnVariable = 'generated_non_autostart_non_remote_modules';
+  const lines = selectGNLines(`${gnVariable} = [`, ']');
+  if (!lines.length) {
+    return [
+      'Could not identify non-autostart non-remote modules in gn file',
+      'Please look at: ' + __filename,
+    ];
+  }
+  const text = lines.join('\n');
+  const modules = inspectorManifest.modules.filter(m => m.type !== 'autostart' && m.type !== 'remote').map(m => m.name);
+
+  const missingModules = modules.filter(m => !utils.includes(text, `${m}/${m}_module.js`));
+  if (missingModules.length)
+    errors.push(`Check that you've included [${missingModules.join(', ')}] modules in: ` + gnVariable);
+
+  // e.g. "$resources_out_dir/audits/audits_module.js" => "audits"
+  const mapLineToModuleName = line => line.split('/')[2].split('_module')[0];
+
+  const extraneousModules = lines.map(mapLineToModuleName).filter(module => !utils.includes(modules, module));
+  if (extraneousModules.length)
+    errors.push(`Found extraneous modules [${extraneousModules.join(', ')}] in: ` + gnVariable);
+
+  return errors;
+}
+
+function selectGNLines(startLine, endLine) {
+  let lines = gnLines.map(line => line.trim());
+  let startIndex = lines.indexOf(startLine);
+  if (startIndex === -1)
+    return [];
+  let endIndex = lines.indexOf(endLine, startIndex);
+  if (endIndex === -1)
+    return [];
+  return lines.slice(startIndex + 1, endIndex);
+}
diff --git a/third_party/WebKit/Source/platform/graphics/CompositorMutableState.cpp b/third_party/WebKit/Source/platform/graphics/CompositorMutableState.cpp
index 562fed8..2997a7b 100644
--- a/third_party/WebKit/Source/platform/graphics/CompositorMutableState.cpp
+++ b/third_party/WebKit/Source/platform/graphics/CompositorMutableState.cpp
@@ -53,8 +53,8 @@
   scroll_layer_->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.OnScrollOffsetAnimated(
-          scroll_layer_->id(), scroll_layer_->scroll_tree_index(), offset,
-          scroll_layer_->layer_tree_impl());
+          scroll_layer_->element_id(), scroll_layer_->scroll_tree_index(),
+          offset, scroll_layer_->layer_tree_impl());
   mutation_->SetScrollLeft(scroll_left);
 }
 
@@ -70,8 +70,8 @@
   scroll_layer_->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.OnScrollOffsetAnimated(
-          scroll_layer_->id(), scroll_layer_->scroll_tree_index(), offset,
-          scroll_layer_->layer_tree_impl());
+          scroll_layer_->element_id(), scroll_layer_->scroll_tree_index(),
+          offset, scroll_layer_->layer_tree_impl());
   mutation_->SetScrollTop(scroll_top);
 }
 
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp
index f707e7fd..59e400b 100644
--- a/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PropertyTreeManager.cpp
@@ -344,7 +344,7 @@
         *GetTransformTree().Node(compositor_scroll_node.transform_id);
     // TODO(pdr): Set this in updateScrollAndScrollTranslationNodes once the
     // layer id is no longer needed.
-    GetScrollTree().SetScrollOffset(layer_id,
+    GetScrollTree().SetScrollOffset(transform->GetCompositorElementId(),
                                     compositor_transform_node.scroll_offset);
     if (auto* scroll_client = enclosing_scroll_node->ScrollClient()) {
       layer->set_did_scroll_callback(
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.cpp b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.cpp
index f07ed507..56031d4 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.cpp
@@ -4,7 +4,7 @@
 
 #include "platform/graphics/paint/DisplayItemClient.h"
 
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
+#if DCHECK_IS_ON()
 #include "platform/wtf/HashMap.h"
 #include "platform/wtf/HashSet.h"
 #endif
@@ -15,33 +15,18 @@
     DisplayItemClient::CacheGenerationOrInvalidationReason::next_generation_ =
         kFirstValidGeneration;
 
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
+#if DCHECK_IS_ON()
 
 HashSet<const DisplayItemClient*>* g_live_display_item_clients = nullptr;
-HashMap<const void*, HashMap<const DisplayItemClient*, String>>*
-    g_display_item_clients_should_keep_alive = nullptr;
 
 DisplayItemClient::DisplayItemClient() {
-  if (g_display_item_clients_should_keep_alive) {
-    for (const auto& item : *g_display_item_clients_should_keep_alive)
-      CHECK(!item.value.Contains(this));
-  }
   if (!g_live_display_item_clients)
     g_live_display_item_clients = new HashSet<const DisplayItemClient*>();
   g_live_display_item_clients->insert(this);
 }
 
 DisplayItemClient::~DisplayItemClient() {
-  if (g_display_item_clients_should_keep_alive) {
-    for (const auto& item : *g_display_item_clients_should_keep_alive) {
-      CHECK(!item.value.Contains(this))
-          << "Short-lived DisplayItemClient: " << item.value.at(this)
-          << ". See crbug.com/609218.";
-    }
-  }
   g_live_display_item_clients->erase(this);
-  // In case this object is a subsequence owner.
-  EndShouldKeepAliveAllClients(this);
 }
 
 bool DisplayItemClient::IsAlive() const {
@@ -49,36 +34,6 @@
          g_live_display_item_clients->Contains(this);
 }
 
-void DisplayItemClient::BeginShouldKeepAlive(const void* owner) const {
-  CHECK(IsAlive());
-  if (!g_display_item_clients_should_keep_alive)
-    g_display_item_clients_should_keep_alive =
-        new HashMap<const void*, HashMap<const DisplayItemClient*, String>>();
-  auto add_result =
-      g_display_item_clients_should_keep_alive
-          ->insert(owner, HashMap<const DisplayItemClient*, String>())
-          .stored_value->value.insert(this, "");
-  if (add_result.is_new_entry)
-    add_result.stored_value->value = DebugName();
-}
-
-void DisplayItemClient::EndShouldKeepAlive() const {
-  if (g_display_item_clients_should_keep_alive) {
-    for (auto& item : *g_display_item_clients_should_keep_alive)
-      item.value.erase(this);
-  }
-}
-
-void DisplayItemClient::EndShouldKeepAliveAllClients(const void* owner) {
-  if (g_display_item_clients_should_keep_alive)
-    g_display_item_clients_should_keep_alive->erase(owner);
-}
-
-void DisplayItemClient::EndShouldKeepAliveAllClients() {
-  delete g_display_item_clients_should_keep_alive;
-  g_display_item_clients_should_keep_alive = nullptr;
-}
-
-#endif  // CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
+#endif  // DCHECK_IS_ON()
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.h b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.h
index a743328..0ad29a5 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemClient.h
@@ -11,8 +11,6 @@
 #include "platform/wtf/Assertions.h"
 #include "platform/wtf/text/WTFString.h"
 
-#define CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS DCHECK_IS_ON()
-
 namespace blink {
 
 // The class for objects that can be associated with display items. A
@@ -22,28 +20,13 @@
 // dereferenced unless we can make sure the client is still valid.
 class PLATFORM_EXPORT DisplayItemClient {
  public:
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
+#if DCHECK_IS_ON()
   DisplayItemClient();
   virtual ~DisplayItemClient();
 
   // Tests if this DisplayItemClient object has been created and has not been
   // deleted yet.
   bool IsAlive() const;
-
-  // Called when any DisplayItem of this DisplayItemClient is added into
-  // PaintController using PaintController::createAndAppend() or into a cached
-  // subsequence.
-  void BeginShouldKeepAlive(const void* owner) const;
-
-  // Called when the DisplayItemClient is sure that it can safely die before its
-  // owners have chance to remove it from the aliveness control.
-  void EndShouldKeepAlive() const;
-
-  // Clears all should-keep-alive DisplayItemClients of a PaintController.
-  // Called after PaintController commits new display items or the subsequence
-  // owner is invalidated.
-  static void EndShouldKeepAliveAllClients(const void* owner);
-  static void EndShouldKeepAliveAllClients();
 #else
   DisplayItemClient() {}
   virtual ~DisplayItemClient() {}
@@ -81,11 +64,6 @@
   void SetDisplayItemsUncached(
       PaintInvalidationReason reason = PaintInvalidationReason::kFull) const {
     cache_generation_or_invalidation_reason_.Invalidate(reason);
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-    // Clear should-keep-alive of DisplayItemClients in a subsequence if this
-    // object is a subsequence.
-    EndShouldKeepAliveAllClients(this);
-#endif
   }
 
   PaintInvalidationReason GetPaintInvalidationReason() const {
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp
index 34a7547a..a2fd70da 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItemList.cpp
@@ -53,12 +53,11 @@
 
 #endif
     if (display_item.HasValidClient()) {
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
+#if DCHECK_IS_ON()
       if (!display_item.Client().IsAlive()) {
-        json->SetBoolean("clientIsAlive", true);
+        json->SetBoolean("clientIsAlive", false);
       } else {
 #else
-
       if (options & kShowClientDebugName) {
 #endif
         json->SetString(
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintChunk.h b/third_party/WebKit/Source/platform/graphics/paint/PaintChunk.h
index 41e1be6..413825f 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintChunk.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintChunk.h
@@ -54,8 +54,8 @@
       return false;
     if (*id != *old.id)
       return false;
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-    CHECK(id->client.IsAlive());
+#if DCHECK_IS_ON()
+    DCHECK(id->client.IsAlive());
 #endif
     // A chunk whose client is just created should not match any cached chunk,
     // even if it's id equals the old chunk's id (which may happen if this
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
index 0cabe7bf..9095fb1 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -228,32 +228,9 @@
   return nullptr;
 }
 
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-void PaintController::BeginShouldKeepAlive(const DisplayItemClient& client) {
-  if (!IsSkippingCache()) {
-    // Mark the client shouldKeepAlive under this PaintController.
-    // The status will end after the new display items are committed.
-    client.BeginShouldKeepAlive(this);
-
-    if (!current_subsequence_clients_.IsEmpty()) {
-      // Mark the client shouldKeepAlive under the current subsequence.
-      // The status will end when the subsequence owner is invalidated or
-      // deleted.
-      client.BeginShouldKeepAlive(current_subsequence_clients_.back());
-    }
-  }
-}
-#endif
-
 void PaintController::ProcessNewItem(DisplayItem& display_item) {
   DCHECK(!construction_disabled_);
 
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-  if (display_item.IsCacheable()) {
-    BeginShouldKeepAlive(display_item.Client());
-  }
-#endif
-
   if (IsSkippingCache())
     display_item.SetSkippedCache();
 
@@ -347,8 +324,8 @@
 
 bool PaintController::ClientCacheIsValid(
     const DisplayItemClient& client) const {
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-  CHECK(client.IsAlive());
+#if DCHECK_IS_ON()
+  DCHECK(client.IsAlive());
 #endif
   if (IsSkippingCache())
     return false;
@@ -511,8 +488,8 @@
     // TODO(chrishtr); remove this hack once crbug.com/712660 is resolved.
     if (!cached_item->HasValidClient())
       continue;
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-    CHECK(cached_item->Client().IsAlive());
+#if DCHECK_IS_ON()
+    DCHECK(cached_item->Client().IsAlive());
 #endif
     ++num_cached_new_items_;
     if (!RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) {
@@ -584,13 +561,8 @@
   new_cached_subsequences_.swap(current_cached_subsequences_);
   new_cached_subsequences_.clear();
   last_cached_subsequence_end_ = 0;
-  for (auto& item : current_cached_subsequences_) {
+  for (auto& item : current_cached_subsequences_)
     item.key->SetDisplayItemsCached(current_cache_generation_);
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-    DisplayItemClient::EndShouldKeepAliveAllClients(item.key);
-    DCHECK(current_subsequence_clients_.IsEmpty());
-#endif
-  }
 
   Vector<const DisplayItemClient*> skipped_cache_clients;
   for (const auto& item : new_display_item_list_) {
@@ -633,10 +605,6 @@
   // We'll allocate the initial buffer when we start the next paint.
   new_display_item_list_ = DisplayItemList(0);
 
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-  DisplayItemClient::EndShouldKeepAliveAllClients(this);
-#endif
-
 #ifndef NDEBUG
   num_sequential_matches_ = 0;
   num_out_of_order_matches_ = 0;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
index 1a644ad..5185f436 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.h
@@ -65,9 +65,6 @@
     // New display items should be committed before PaintController is
     // destructed.
     DCHECK(new_display_item_list_.IsEmpty());
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-    DisplayItemClient::EndShouldKeepAliveAllClients(this);
-#endif
   }
 
   void InvalidateAll();
@@ -194,8 +191,6 @@
 #endif
 
 #if DCHECK_IS_ON()
-  void AssertDisplayItemClientsAreLive();
-
   enum Usage { kForNormalUsage, kForPaintRecordBuilder };
   void SetUsage(Usage usage) { usage_ = usage; }
   bool IsForPaintRecordBuilder() const {
@@ -211,17 +206,6 @@
                : nullptr;
   }
 
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-  void BeginShouldKeepAlive(const DisplayItemClient&);
-
-  void BeginSubsequence(const DisplayItemClient& client) {
-    current_subsequence_clients_.push_back(&client);
-    BeginShouldKeepAlive(client);
-  }
-
-  void EndSubsequence() { current_subsequence_clients_.pop_back(); }
-#endif
-
   bool LastDisplayItemIsSubsequenceEnd() const;
 
   void BeginFrame(const void* frame);
@@ -448,11 +432,6 @@
   std::unique_ptr<RasterInvalidationTrackingInfo>
       raster_invalidation_tracking_info_;
 
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-  // A stack recording subsequence clients that are currently painting.
-  Vector<const DisplayItemClient*> current_subsequence_clients_;
-#endif
-
   typedef HashMap<const DisplayItemClient*, SubsequenceMarkers>
       CachedSubsequenceMap;
   CachedSubsequenceMap current_cached_subsequences_;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
index c06c0cc..c5742415 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
@@ -1292,10 +1292,6 @@
   EXPECT_EQ(4u, markers->start);
   EXPECT_EQ(7u, markers->end);
 
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-  DisplayItemClient::EndShouldKeepAliveAllClients();
-#endif
-
   if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
     EXPECT_EQ(2u, GetPaintController().PaintChunks().size());
     EXPECT_EQ(PaintChunk::Id(container2, kBackgroundDrawingType),
@@ -1692,10 +1688,6 @@
     EXPECT_THAT(GetPaintController().PaintChunks()[2].raster_invalidation_rects,
                 UnorderedElementsAre(FloatRect(100, 100, 100, 100)));
   }
-
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-  DisplayItemClient::EndShouldKeepAliveAllClients();
-#endif
 }
 
 TEST_P(PaintControllerTest, SkipCache) {
@@ -2124,10 +2116,6 @@
     EXPECT_TRUE(GetPaintController().LastDisplayItemIsSubsequenceEnd());
 
     GetPaintController().CommitNewDisplayItems();
-
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-    DisplayItemClient::EndShouldKeepAliveAllClients();
-#endif
   }
 
   void TestChangeDrawingInSubsequence() {
@@ -2247,10 +2235,6 @@
                FloatRect(100, 100, 300, 300));
     }
     GetPaintController().CommitNewDisplayItems();
-
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-    DisplayItemClient::EndShouldKeepAliveAllClients();
-#endif
   }
 };
 
diff --git a/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp b/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp
index b35795d6..3c2386c 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/SubsequenceRecorder.cpp
@@ -15,10 +15,6 @@
     : paint_controller_(context.GetPaintController()),
       client_(client),
       begin_subsequence_index_(0) {
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-  paint_controller_.BeginSubsequence(client_);
-#endif
-
   if (paint_controller_.DisplayItemConstructionIsDisabled())
     return;
 
@@ -26,10 +22,6 @@
 }
 
 SubsequenceRecorder::~SubsequenceRecorder() {
-#if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS
-  paint_controller_.EndSubsequence();
-#endif
-
   if (paint_controller_.DisplayItemConstructionIsDisabled())
     return;
 
diff --git a/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp b/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
index c2c3be357..cdc293c6 100644
--- a/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
@@ -265,12 +265,6 @@
   NOTREACHED();
 }
 
-void WebRemoteFrameImpl::DispatchMessageEventWithOriginCheck(
-    const WebSecurityOrigin& intended_target_origin,
-    const WebDOMEvent&) {
-  NOTREACHED();
-}
-
 WebRect WebRemoteFrameImpl::SelectionBoundsRect() const {
   NOTREACHED();
   return WebRect();
diff --git a/third_party/WebKit/Source/web/WebRemoteFrameImpl.h b/third_party/WebKit/Source/web/WebRemoteFrameImpl.h
index e11c0ce..23d9bb7f 100644
--- a/third_party/WebKit/Source/web/WebRemoteFrameImpl.h
+++ b/third_party/WebKit/Source/web/WebRemoteFrameImpl.h
@@ -84,9 +84,6 @@
   void PrintEnd() override;
   bool IsPrintScalingDisabledForPlugin(const WebNode&) override;
   void PrintPagesWithBoundaries(WebCanvas*, const WebSize&) override;
-  void DispatchMessageEventWithOriginCheck(
-      const WebSecurityOrigin& intended_target_origin,
-      const WebDOMEvent&) override;
 
   WebRect SelectionBoundsRect() const override;
 
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index 9beb924..40466d6 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -1024,14 +1024,16 @@
   WebDocument document = web_view_helper.WebView()->MainFrame()->GetDocument();
   WebSerializedScriptValue data(WebSerializedScriptValue::CreateInvalid());
   WebDOMMessageEvent message(data, "http://origin.com");
-  web_view_helper.WebView()->MainFrame()->DispatchMessageEventWithOriginCheck(
-      correct_origin, message);
+  web_view_helper.WebView()
+      ->MainFrameImpl()
+      ->DispatchMessageEventWithOriginCheck(correct_origin, message);
 
   // Send another message with incorrect origin.
   WebSecurityOrigin incorrect_origin(
       WebSecurityOrigin::Create(ToKURL(chrome_url_)));
-  web_view_helper.WebView()->MainFrame()->DispatchMessageEventWithOriginCheck(
-      incorrect_origin, message);
+  web_view_helper.WebView()
+      ->MainFrameImpl()
+      ->DispatchMessageEventWithOriginCheck(incorrect_origin, message);
 
   // Verify that only the first addition is in the body of the page.
   std::string content =
diff --git a/third_party/WebKit/public/web/WebFrame.h b/third_party/WebKit/public/web/WebFrame.h
index 85e63de..30caf918 100644
--- a/third_party/WebKit/public/web/WebFrame.h
+++ b/third_party/WebKit/public/web/WebFrame.h
@@ -56,7 +56,6 @@
 class Visitor;
 class WebAssociatedURLLoader;
 struct WebAssociatedURLLoaderOptions;
-class WebDOMEvent;
 class WebDocument;
 class WebElement;
 class WebLocalFrame;
@@ -360,13 +359,6 @@
   // return true, otherwise return false.
   virtual bool IsPrintScalingDisabledForPlugin(const WebNode& = WebNode()) = 0;
 
-  // Events --------------------------------------------------------------
-
-  // Dispatches a message event on the current DOMWindow in this WebFrame.
-  virtual void DispatchMessageEventWithOriginCheck(
-      const WebSecurityOrigin& intended_target_origin,
-      const WebDOMEvent&) = 0;
-
   // Utility -------------------------------------------------------------
 
   // Prints all of the pages into the canvas, with page boundaries drawn as
diff --git a/third_party/WebKit/public/web/WebLocalFrame.h b/third_party/WebKit/public/web/WebLocalFrame.h
index c81d02b..0196d82 100644
--- a/third_party/WebKit/public/web/WebLocalFrame.h
+++ b/third_party/WebKit/public/web/WebLocalFrame.h
@@ -30,11 +30,13 @@
 class WebDevToolsAgent;
 class WebDevToolsAgentClient;
 class WebDoubleSize;
+class WebDOMEvent;
 class WebFrameClient;
 class WebFrameWidget;
 class WebFrameScheduler;
 class WebInputMethodController;
 class WebRange;
+class WebSecurityOrigin;
 class WebScriptExecutionCallback;
 class WebSharedWorkerRepositoryClient;
 class WebTextCheckClient;
@@ -575,6 +577,13 @@
   // coordinates.
   virtual void SaveImageAt(const WebPoint&) = 0;
 
+  // Events --------------------------------------------------------------
+
+  // Dispatches a message event on the current DOMWindow in this WebFrame.
+  virtual void DispatchMessageEventWithOriginCheck(
+      const WebSecurityOrigin& intended_target_origin,
+      const WebDOMEvent&) = 0;
+
   // Site engagement --------------------------------------------------------
 
   // Sets the site engagement level for this frame's document.
diff --git a/third_party/flatbuffers/flatbuffer.gni b/third_party/flatbuffers/flatbuffer.gni
index f45886d..cc28b1b 100644
--- a/third_party/flatbuffers/flatbuffer.gni
+++ b/third_party/flatbuffers/flatbuffer.gni
@@ -16,14 +16,14 @@
 #
 #   flatc_include_dirs (optional)
 #       Specifies the directories which FlatBuffers compiler uses to find
-#       included .fbs files in.
+#       included .fbs files in. Almost always should be empty.
 #
-#       The directories will be tried in the order given, and if all fail (or,
-#       as by default, none are specified) it will try to load relative to the
-#       directory of the schema file being parsed.
+#       The list always has an implicit first item corresponding to the root of
+#       the source tree. This enables including .fbs files by absolute path.
 #
-#       TODO(pkalinnikov): Add repository root to this list, to allow including
-#       by absolute path.
+#       The compiler will try the directories in the order given, and if all
+#       fail it will try to load relative to the directory of the schema file
+#       being parsed.
 #
 #   deps (optional)
 #       Additional dependencies.
@@ -79,22 +79,25 @@
       "$out_dir/{{source_name_part}}_generated.h",
     ]
 
-    args = [ "-c" ]
+    args = [
+      "-c",
+      "--keep-prefix",
+      "-o",
+      "$out_dir",
+      "-I",
+      rebase_path("//", root_build_dir),
+    ]
 
     if (defined(invoker.flatc_include_dirs)) {
       foreach(include_dir, invoker.flatc_include_dirs) {
         args += [
           "-I",
-          rebase_path(include_dir, "$root_build_dir"),
+          rebase_path(include_dir, root_build_dir),
         ]
       }
     }
 
-    args += [
-      "-o",
-      "$out_dir",
-      "{{source}}",
-    ]
+    args += [ "{{source}}" ]
 
     # The deps may have steps that have to run before running flatc.
     if (defined(invoker.deps)) {
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 7d680c5f..1238161 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -178,6 +178,7 @@
       'CrWinClngLLDdbg': 'clang_tot_full_symbols_shared_debug_use_lld_x86',
       'EarlGreyiOS': 'ios',
       'Fuchsia': 'release_bot_fuchsia',
+      'Fuchsia (dbg)': 'debug_bot_fuchsia',
       'GomaCanaryiOS': 'ios',
       'ios-simulator': 'ios',
       'Headless Linux (dbg)': 'headless_linux_debug_bot',
@@ -1180,6 +1181,10 @@
       'debug_bot',
     ],
 
+    'debug_bot_fuchsia': [
+      'debug_bot', 'fuchsia',
+    ],
+
     'debug_bot_x86': [
       'debug_bot', 'x86',
     ],
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 4d4dae7..ded4fc89f 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -15401,6 +15401,14 @@
   </description>
 </action>
 
+<action name="Signin_Signin_FromForceSigninWarning">
+  <owner>zmin@chromium.org</owner>
+  <description>
+    Record when a user signs in again from the force sign in auth error warning
+    modal dialog.
+  </description>
+</action>
+
 <action name="Signin_Signin_FromMenu">
   <owner>gogerald@chromium.org</owner>
   <description>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 0746325..28241ea3 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -33220,6 +33220,7 @@
   <int value="20" label="NTP Content Suggestions"/>
   <int value="21" label="Re-signin infobar"/>
   <int value="22" label="Tab switcher"/>
+  <int value="23" label="Force signin warning"/>
 </enum>
 
 <enum name="SigninAccountEquality" type="int">
diff --git a/ui/accessibility/platform/ax_fake_caret_win.cc b/ui/accessibility/platform/ax_fake_caret_win.cc
index 8b645dc..d15b180 100644
--- a/ui/accessibility/platform/ax_fake_caret_win.cc
+++ b/ui/accessibility/platform/ax_fake_caret_win.cc
@@ -99,4 +99,8 @@
   return false;
 }
 
+bool AXFakeCaretWin::ShouldIgnoreHoveredStateForTesting() {
+  return true;
+}
+
 }  // namespace ui
diff --git a/ui/accessibility/platform/ax_fake_caret_win.h b/ui/accessibility/platform/ax_fake_caret_win.h
index d2a5bba..a23f376 100644
--- a/ui/accessibility/platform/ax_fake_caret_win.h
+++ b/ui/accessibility/platform/ax_fake_caret_win.h
@@ -43,6 +43,7 @@
   gfx::NativeViewAccessible GetFocus() override;
   gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
   bool AccessibilityPerformAction(const ui::AXActionData& data) override;
+  bool ShouldIgnoreHoveredStateForTesting() override;
 
   AXPlatformNodeWin* caret_;
   gfx::AcceleratedWidget event_target_;
diff --git a/ui/accessibility/platform/ax_platform_node_delegate.h b/ui/accessibility/platform/ax_platform_node_delegate.h
index 6960a44..7629ea5 100644
--- a/ui/accessibility/platform/ax_platform_node_delegate.h
+++ b/ui/accessibility/platform/ax_platform_node_delegate.h
@@ -84,6 +84,16 @@
   // Perform an accessibility action, switching on the ui::AXAction
   // provided in |data|.
   virtual bool AccessibilityPerformAction(const ui::AXActionData& data) = 0;
+
+  //
+  // Testing.
+  //
+
+  // Accessibility objects can have the "hot tracked" state set when
+  // the mouse is hovering over them, but this makes tests flaky because
+  // the test behaves differently when the mouse happens to be over an
+  // element. The default value should be falses if not in testing mode.
+  virtual bool ShouldIgnoreHoveredStateForTesting() = 0;
 };
 
 }  // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index 1a54321c..7d385a6 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -1438,8 +1438,7 @@
     msaa_state |= STATE_SYSTEM_FOCUSABLE;
   if (state & (1 << ui::AX_STATE_HASPOPUP))
     msaa_state |= STATE_SYSTEM_HASPOPUP;
-  if (state & (1 << ui::AX_STATE_HOVERED))
-    msaa_state |= STATE_SYSTEM_HOTTRACKED;
+
   if (state & (1 << ui::AX_STATE_INVISIBLE) ||
       GetData().role == ui::AX_ROLE_IGNORED) {
     msaa_state |= STATE_SYSTEM_INVISIBLE;
@@ -1458,6 +1457,23 @@
     msaa_state |= STATE_SYSTEM_SELECTED;
   if (state & (1 << ui::AX_STATE_DISABLED))
     msaa_state |= STATE_SYSTEM_UNAVAILABLE;
+  if (state & (1 << ui::AX_STATE_BUSY))
+    msaa_state |= STATE_SYSTEM_BUSY;
+  if (state & (1 << ui::AX_STATE_VISITED))
+    msaa_state |= STATE_SYSTEM_TRAVERSED;
+
+  if (state & (1 << ui::AX_STATE_MULTISELECTABLE)) {
+    msaa_state |= STATE_SYSTEM_EXTSELECTABLE;
+    msaa_state |= STATE_SYSTEM_MULTISELECTABLE;
+  }
+
+  // Expose whether or not the mouse is over an element, but suppress
+  // this for tests because it can make the test results flaky depending
+  // on the position of the mouse.
+  if (delegate_->ShouldIgnoreHoveredStateForTesting()) {
+    if (state & (1 << ui::AX_STATE_HOVERED))
+      msaa_state |= STATE_SYSTEM_HOTTRACKED;
+  }
 
   // Checked state
   const auto checked_state = static_cast<ui::AXCheckedState>(
@@ -1490,6 +1506,89 @@
     msaa_state |= STATE_SYSTEM_FOCUSED;
   }
 
+  switch (GetData().role) {
+    case ui::AX_ROLE_ARTICLE:
+    case ui::AX_ROLE_BUSY_INDICATOR:
+    case ui::AX_ROLE_DEFINITION:
+    case ui::AX_ROLE_DESCRIPTION_LIST:
+    case ui::AX_ROLE_DESCRIPTION_LIST_TERM:
+    case ui::AX_ROLE_IFRAME:
+    case ui::AX_ROLE_IMAGE:
+    case ui::AX_ROLE_IMAGE_MAP:
+    case ui::AX_ROLE_LIST:
+    case ui::AX_ROLE_LIST_ITEM:
+    case ui::AX_ROLE_PROGRESS_INDICATOR:
+    case ui::AX_ROLE_RULER:
+    case ui::AX_ROLE_SCROLL_AREA:
+    case ui::AX_ROLE_TABLE_HEADER_CONTAINER:
+    case ui::AX_ROLE_TERM:
+    case ui::AX_ROLE_TIMER:
+    case ui::AX_ROLE_TOOLBAR:
+    case ui::AX_ROLE_TOOLTIP:
+      msaa_state |= STATE_SYSTEM_READONLY;
+      break;
+
+    case ui::AX_ROLE_DOCUMENT:
+    case ui::AX_ROLE_ROOT_WEB_AREA:
+    case ui::AX_ROLE_WEB_AREA:
+      msaa_state |= STATE_SYSTEM_READONLY;
+      msaa_state |= STATE_SYSTEM_FOCUSABLE;
+      break;
+
+    case ui::AX_ROLE_GRID:
+      // TODO(aleventhal) this changed between ARIA 1.0 and 1.1,
+      // need to determine whether grids/treegrids should really be readonly
+      // or editable by default
+      // msaa_state |= STATE_SYSTEM_READONLY;
+      break;
+
+    case ui::AX_ROLE_IMAGE_MAP_LINK:
+      msaa_state |= STATE_SYSTEM_LINKED;
+      msaa_state |= STATE_SYSTEM_READONLY;
+      break;
+
+    case ui::AX_ROLE_LINK:
+      msaa_state |= STATE_SYSTEM_LINKED;
+      break;
+
+    case ui::AX_ROLE_LIST_BOX_OPTION:
+      if (msaa_state & STATE_SYSTEM_SELECTABLE) {
+        msaa_state |= STATE_SYSTEM_FOCUSABLE;
+      }
+      break;
+
+    case ui::AX_ROLE_MENU_LIST_OPTION:
+      if (msaa_state & STATE_SYSTEM_SELECTABLE) {
+        msaa_state |= STATE_SYSTEM_FOCUSABLE;
+      }
+      break;
+
+    case ui::AX_ROLE_TEXT_FIELD:
+    case ui::AX_ROLE_SEARCH_BOX:
+      if (state & (1 << ui::AX_STATE_READ_ONLY))
+        msaa_state |= STATE_SYSTEM_READONLY;
+      break;
+    default:
+      break;
+  }
+
+  // Compute the final value of READONLY for MSAA.
+  //
+  // We always set the READONLY state for elements that have the
+  // aria-readonly attribute and for a few roles (in the switch above),
+  // including read-only text fields.
+  // The majority of focusable controls should not have the read-only state set.
+  if (state & (1 << ui::AX_STATE_FOCUSABLE) &&
+      GetData().role != ROLE_SYSTEM_DOCUMENT &&
+      GetData().role != ROLE_SYSTEM_TEXT) {
+    msaa_state &= ~(STATE_SYSTEM_READONLY);
+  }
+  if (!(state & (1 << ui::AX_STATE_READ_ONLY)))
+    msaa_state &= ~(STATE_SYSTEM_READONLY);
+
+  if (GetData().GetBoolAttribute(ui::AX_ATTR_ARIA_READONLY))
+    msaa_state |= STATE_SYSTEM_READONLY;
+
   return msaa_state;
 }
 
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc
index 10ab594..94ddc84 100644
--- a/ui/accessibility/platform/test_ax_node_wrapper.cc
+++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -125,6 +125,10 @@
   return true;
 }
 
+bool TestAXNodeWrapper::ShouldIgnoreHoveredStateForTesting() {
+  return true;
+}
+
 TestAXNodeWrapper::TestAXNodeWrapper(AXTree* tree, AXNode* node)
     : tree_(tree),
       node_(node),
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.h b/ui/accessibility/platform/test_ax_node_wrapper.h
index 4d3f2b9..a0c5440 100644
--- a/ui/accessibility/platform/test_ax_node_wrapper.h
+++ b/ui/accessibility/platform/test_ax_node_wrapper.h
@@ -39,6 +39,7 @@
   gfx::NativeViewAccessible GetFocus() override;
   gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
   bool AccessibilityPerformAction(const ui::AXActionData& data) override;
+  bool ShouldIgnoreHoveredStateForTesting() override;
 
  private:
   TestAXNodeWrapper(AXTree* tree, AXNode* node);
diff --git a/ui/android/java/src/org/chromium/ui/UiUtils.java b/ui/android/java/src/org/chromium/ui/UiUtils.java
index 279ff70..861320d 100644
--- a/ui/android/java/src/org/chromium/ui/UiUtils.java
+++ b/ui/android/java/src/org/chromium/ui/UiUtils.java
@@ -83,8 +83,10 @@
          * @param listener The listener that will be notified of the action the user took in the
          *                 picker.
          * @param allowMultiple Whether the dialog should allow multiple images to be selected.
+         * @param mimeTypes A list of mime types to show in the dialog.
          */
-        void showPhotoPicker(Context context, PhotoPickerListener listener, boolean allowMultiple);
+        void showPhotoPicker(Context context, PhotoPickerListener listener, boolean allowMultiple,
+                List<String> mimeTypes);
 
         /**
          * Called when the photo picker dialog should be dismissed.
@@ -115,11 +117,12 @@
      * @param listener The listener that will be notified of the action the user took in the
      *                 picker.
      * @param allowMultiple Whether the dialog should allow multiple images to be selected.
+     * @param mimeTypes A list of mime types to show in the dialog.
      */
-    public static boolean showPhotoPicker(
-            Context context, PhotoPickerListener listener, boolean allowMultiple) {
+    public static boolean showPhotoPicker(Context context, PhotoPickerListener listener,
+            boolean allowMultiple, List<String> mimeTypes) {
         if (sPhotoPickerDelegate == null) return false;
-        sPhotoPickerDelegate.showPhotoPicker(context, listener, allowMultiple);
+        sPhotoPickerDelegate.showPhotoPicker(context, listener, allowMultiple, mimeTypes);
         return true;
     }
 
diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java
index 7d95743d..c82004f 100644
--- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java
+++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java
@@ -218,10 +218,11 @@
             if (mWindowAndroid.showIntent(soundRecorder, this, R.string.low_memory_error)) return;
         }
 
-        // Use new photo picker, if available.
+        // Use the new photo picker, if available.
         Activity activity = mWindowAndroid.getActivity().get();
-        if (activity != null && usePhotoPicker(mFileTypes)
-                && UiUtils.showPhotoPicker(activity, this, mAllowMultiple)) {
+        List<String> imageMimeTypes = convertToImageMimeTypes(mFileTypes);
+        if (activity != null && imageMimeTypes != null
+                && UiUtils.showPhotoPicker(activity, this, mAllowMultiple, imageMimeTypes)) {
             return;
         }
 
@@ -273,16 +274,23 @@
     }
 
     /**
-     * Determines if a photo picker can be used instead of the stock Android picker.
-     * @return True if only images types are being requested.
+     * Converts a list of extensions and Mime types to a list of de-duped Mime types containing
+     * image types only. If the input list contains a non-image type, then null is returned.
+     * @param fileTypes the list of filetypes (extensions and Mime types) to convert.
+     * @return A de-duped list of Image Mime types only, or null if one or more non-image types were
+     *         given as input.
      */
     @VisibleForTesting
-    public static boolean usePhotoPicker(List<String> fileTypes) {
+    public static List<String> convertToImageMimeTypes(List<String> fileTypes) {
+        List<String> mimeTypes = new ArrayList<>();
         for (String type : fileTypes) {
             String mimeType = ensureMimeType(type);
-            if (!mimeType.startsWith("image/")) return false;
+            if (!mimeType.startsWith("image/")) {
+                return null;
+            }
+            if (!mimeTypes.contains(mimeType)) mimeTypes.add(mimeType);
         }
-        return true;
+        return mimeTypes;
     }
 
     /**
diff --git a/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java b/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java
index 0ad984b..fac9e83 100644
--- a/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java
+++ b/ui/android/junit/src/org/chromium/ui/base/SelectFileDialogTest.java
@@ -5,8 +5,6 @@
 package org.chromium.ui.base;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 
 import android.webkit.MimeTypeMap;
 
@@ -108,14 +106,24 @@
         // Unknown extension, expect default response:
         assertEquals("application/octet-stream", SelectFileDialog.ensureMimeType(".flv"));
 
-        assertFalse(SelectFileDialog.usePhotoPicker(Arrays.asList("")));
-        assertTrue(SelectFileDialog.usePhotoPicker(Arrays.asList(".jpg")));
-        assertTrue(SelectFileDialog.usePhotoPicker(Arrays.asList("image/jpeg")));
-        assertTrue(SelectFileDialog.usePhotoPicker(Arrays.asList(".jpg", "image/jpeg")));
-        assertTrue(SelectFileDialog.usePhotoPicker(Arrays.asList(".gif", "image/jpeg")));
-        // Returns false because generic picker is required (due to addition of .txt file).
-        assertFalse(SelectFileDialog.usePhotoPicker(Arrays.asList(".txt", ".jpg", "image/jpeg")));
-        // Returns false because video file is included.
-        assertFalse(SelectFileDialog.usePhotoPicker(Arrays.asList(".jpg", "image/jpeg", ".mpg")));
+        assertEquals(null, SelectFileDialog.convertToImageMimeTypes(Arrays.asList("")));
+        assertEquals(null, SelectFileDialog.convertToImageMimeTypes(Arrays.asList("foo/bar")));
+        assertEquals(Arrays.asList("image/jpeg"),
+                SelectFileDialog.convertToImageMimeTypes(Arrays.asList(".jpg")));
+        assertEquals(Arrays.asList("image/jpeg"),
+                SelectFileDialog.convertToImageMimeTypes(Arrays.asList("image/jpeg")));
+        assertEquals(Arrays.asList("image/jpeg"),
+                SelectFileDialog.convertToImageMimeTypes(Arrays.asList(".jpg", "image/jpeg")));
+        assertEquals(Arrays.asList("image/gif", "image/jpeg"),
+                SelectFileDialog.convertToImageMimeTypes(Arrays.asList(".gif", "image/jpeg")));
+
+        // Returns null because generic picker is required (due to addition of .txt file).
+        assertEquals(null,
+                SelectFileDialog.convertToImageMimeTypes(
+                        Arrays.asList(".txt", ".jpg", "image/jpeg")));
+        // Returns null because video file is included.
+        assertEquals(null,
+                SelectFileDialog.convertToImageMimeTypes(
+                        Arrays.asList(".jpg", "image/jpeg", ".mpg")));
     }
 }
diff --git a/ui/aura/test/ui_controls_factory_aurax11.cc b/ui/aura/test/ui_controls_factory_aurax11.cc
index 1342645..3dd019980 100644
--- a/ui/aura/test/ui_controls_factory_aurax11.cc
+++ b/ui/aura/test/ui_controls_factory_aurax11.cc
@@ -16,10 +16,10 @@
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/base/test/ui_controls_aura.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/compositor/dip_util.h"
 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
 #include "ui/events/test/platform_event_waiter.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 
 namespace aura {
 namespace test {
@@ -38,7 +38,7 @@
 
 // Returns atom that indidates that the XEvent is marker event.
 Atom MarkerEventAtom() {
-  return ui::GetAtom("marker_event");
+  return gfx::GetAtom("marker_event");
 }
 
 // Returns true when the event is a marker event.
diff --git a/ui/aura/window.cc b/ui/aura/window.cc
index 7c1d01a..2712b066 100644
--- a/ui/aura/window.cc
+++ b/ui/aura/window.cc
@@ -266,7 +266,6 @@
   port_->OnDidChangeTransform(old_transform, transform);
   for (WindowObserver& observer : observers_)
     observer.OnWindowTransformed(this);
-  NotifyAncestorWindowTransformed(this);
 }
 
 void Window::SetLayoutManager(LayoutManager* layout_manager) {
@@ -971,15 +970,6 @@
   }
 }
 
-void Window::NotifyAncestorWindowTransformed(Window* source) {
-  for (WindowObserver& observer : observers_)
-    observer.OnAncestorWindowTransformed(source, this);
-  for (Window::Windows::const_iterator it = children_.begin();
-       it != children_.end(); ++it) {
-    (*it)->NotifyAncestorWindowTransformed(source);
-  }
-}
-
 bool Window::CleanupGestureState() {
   bool state_modified = false;
   state_modified |= ui::GestureRecognizer::Get()->CancelActiveTouches(this);
diff --git a/ui/aura/window.h b/ui/aura/window.h
index 5f2cab94..22794c7 100644
--- a/ui/aura/window.h
+++ b/ui/aura/window.h
@@ -418,10 +418,6 @@
   // Notifies this window and its parent hierarchy.
   void NotifyWindowVisibilityChangedUp(aura::Window* target, bool visible);
 
-  // Notifies this window and its child hierarchy of a transform applied to
-  // |source|.
-  void NotifyAncestorWindowTransformed(Window* source);
-
   // Overridden from ui::LayerDelegate:
   void OnPaintLayer(const ui::PaintContext& context) override;
   void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override;
diff --git a/ui/aura/window_observer.h b/ui/aura/window_observer.h
index 15292fc5..ea887a0 100644
--- a/ui/aura/window_observer.h
+++ b/ui/aura/window_observer.h
@@ -88,10 +88,6 @@
   virtual void OnWindowTransforming(Window* window) {}
   virtual void OnWindowTransformed(Window* window) {}
 
-  // Invoked when SetTransform() is invoked on an ancestor of the window being
-  // observed (including the window itself).
-  virtual void OnAncestorWindowTransformed(Window* source, Window* window) {}
-
   // Invoked when |window|'s position among its siblings in the stacking order
   // has changed.
   virtual void OnWindowStackingChanged(Window* window) {}
diff --git a/ui/aura/window_tree_host_x11.cc b/ui/aura/window_tree_host_x11.cc
index f59d99e..0635b7a 100644
--- a/ui/aura/window_tree_host_x11.cc
+++ b/ui/aura/window_tree_host_x11.cc
@@ -51,6 +51,7 @@
 #include "ui/events/platform/platform_event_observer.h"
 #include "ui/events/platform/platform_event_source.h"
 #include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 
 using std::max;
 using std::min;
@@ -145,8 +146,8 @@
   // should listen for activation events and anything else that GTK+ listens
   // for, and do something useful.
   ::Atom protocols[2];
-  protocols[0] = ui::GetAtom("WM_DELETE_WINDOW");
-  protocols[1] = ui::GetAtom("_NET_WM_PING");
+  protocols[0] = gfx::GetAtom("WM_DELETE_WINDOW");
+  protocols[1] = gfx::GetAtom("_NET_WM_PING");
   XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
 
   // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
@@ -160,7 +161,7 @@
   static_assert(sizeof(long) >= sizeof(pid_t),
                 "pid_t should not be larger than long");
   long pid = getpid();
-  XChangeProperty(xdisplay_, xwindow_, ui::GetAtom("_NET_WM_PID"), XA_CARDINAL,
+  XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_PID"), XA_CARDINAL,
                   32, PropModeReplace, reinterpret_cast<unsigned char*>(&pid),
                   1);
 
@@ -307,10 +308,10 @@
       break;
     case ClientMessage: {
       Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]);
-      if (message_type == ui::GetAtom("WM_DELETE_WINDOW")) {
+      if (message_type == gfx::GetAtom("WM_DELETE_WINDOW")) {
         // We have received a close message from the window manager.
         OnHostCloseRequested();
-      } else if (message_type == ui::GetAtom("_NET_WM_PING")) {
+      } else if (message_type == gfx::GetAtom("_NET_WM_PING")) {
         XEvent reply_event = *xev;
         reply_event.xclient.window = x_root_window_;
 
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index 5bb5d8a..afe9120 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -1771,18 +1771,6 @@
     return result;
   }
 
-  std::string TransformNotificationsAndClear() {
-    std::string result;
-    for (std::vector<std::pair<int, int> >::iterator it =
-            transform_notifications_.begin();
-        it != transform_notifications_.end();
-        ++it) {
-      base::StringAppendF(&result, "(%d,%d)", it->first, it->second);
-    }
-    transform_notifications_.clear();
-    return result;
-  }
-
  private:
   void OnWindowAdded(Window* new_window) override { added_count_++; }
 
@@ -1810,11 +1798,6 @@
     old_property_value_ = old;
   }
 
-  void OnAncestorWindowTransformed(Window* source, Window* window) override {
-    transform_notifications_.push_back(
-        std::make_pair(source->id(), window->id()));
-  }
-
   int added_count_;
   int removed_count_;
   int destroyed_count_;
@@ -1949,33 +1932,6 @@
       reinterpret_cast<const void*>(NULL), -3), PropertyChangeInfoAndClear());
 }
 
-TEST_P(WindowObserverTest, AncestorTransformed) {
-  // Create following window hierarchy:
-  //   root_window
-  //   +-- w1
-  //       +-- w2
-  //       +-- w3
-  //           +-- w4
-  // Then, apply a transform to |w1| and ensure all its descendants are
-  // notified.
-  std::unique_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
-  w1->AddObserver(this);
-  std::unique_ptr<Window> w2(CreateTestWindowWithId(2, w1.get()));
-  w2->AddObserver(this);
-  std::unique_ptr<Window> w3(CreateTestWindowWithId(3, w1.get()));
-  w3->AddObserver(this);
-  std::unique_ptr<Window> w4(CreateTestWindowWithId(4, w3.get()));
-  w4->AddObserver(this);
-
-  EXPECT_EQ(std::string(), TransformNotificationsAndClear());
-
-  gfx::Transform transform;
-  transform.Translate(10, 10);
-  w1->SetTransform(transform);
-
-  EXPECT_EQ("(1,1)(1,2)(1,3)(1,4)", TransformNotificationsAndClear());
-}
-
 TEST_P(WindowTest, AcquireLayer) {
   std::unique_ptr<Window> window1(CreateTestWindowWithId(1, root_window()));
   std::unique_ptr<Window> window2(CreateTestWindowWithId(2, root_window()));
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index 4de2529..0de3faf9 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -483,7 +483,7 @@
   }
 
   if (is_linux) {
-    deps += [ "//build/linux:fontconfig" ]
+    deps += [ "//third_party/fontconfig" ]
   }
 
   if (use_glib) {
diff --git a/ui/base/clipboard/clipboard_aurax11.cc b/ui/base/clipboard/clipboard_aurax11.cc
index 3def226..f7f2d74d 100644
--- a/ui/base/clipboard/clipboard_aurax11.cc
+++ b/ui/base/clipboard/clipboard_aurax11.cc
@@ -34,6 +34,7 @@
 #include "ui/events/platform/platform_event_source.h"
 #include "ui/gfx/codec/png_codec.h"
 #include "ui/gfx/geometry/size.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 
 namespace ui {
 
@@ -82,7 +83,7 @@
       primary_sequence_number_(0) {
   int ignored;
   if (XFixesQueryExtension(gfx::GetXDisplay(), &event_base_, &ignored)) {
-    clipboard_atom_ = GetAtom(kClipboard);
+    clipboard_atom_ = gfx::GetAtom(kClipboard);
     XFixesSelectSelectionInput(gfx::GetXDisplay(), GetX11RootWindow(),
                                clipboard_atom_,
                                XFixesSetSelectionOwnerNotifyMask |
@@ -159,7 +160,7 @@
 
 bool TargetList::ContainsFormat(
     const Clipboard::FormatType& format_type) const {
-  ::Atom atom = GetAtom(format_type.ToString().c_str());
+  ::Atom atom = gfx::GetAtom(format_type.ToString().c_str());
   return ContainsAtom(atom);
 }
 
@@ -314,7 +315,7 @@
                               0,
                               NULL)),
       selection_requestor_(x_display_, x_window_, this),
-      clipboard_owner_(x_display_, x_window_, GetAtom(kClipboard)),
+      clipboard_owner_(x_display_, x_window_, gfx::GetAtom(kClipboard)),
       primary_owner_(x_display_, x_window_, XA_PRIMARY) {
   XStoreName(x_display_, x_window_, "Chromium clipboard");
   x_window_events_.reset(
@@ -340,7 +341,7 @@
 }
 
 ::Atom ClipboardAuraX11::AuraX11Details::GetCopyPasteSelection() const {
-  return GetAtom(kClipboard);
+  return gfx::GetAtom(kClipboard);
 }
 
 const SelectionFormatMap&
@@ -359,7 +360,7 @@
 void ClipboardAuraX11::AuraX11Details::InsertMapping(
     const std::string& key,
     const scoped_refptr<base::RefCountedMemory>& memory) {
-  ::Atom atom_key = GetAtom(key.c_str());
+  ::Atom atom_key = gfx::GetAtom(key.c_str());
   clipboard_data_.Insert(atom_key, memory);
 }
 
@@ -391,7 +392,7 @@
 
     ::Atom selection_name = LookupSelectionForClipboardType(type);
     std::vector< ::Atom> intersection;
-    ui::GetAtomIntersection(types, targets.target_list(), &intersection);
+    GetAtomIntersection(types, targets.target_list(), &intersection);
     return selection_requestor_.RequestAndWaitForTypes(selection_name,
                                                        intersection);
   }
@@ -417,10 +418,10 @@
     ::Atom out_type = None;
 
     if (selection_requestor_.PerformBlockingConvertSelection(
-            selection_name, GetAtom(kTargets), &data, &out_data_items,
+            selection_name, gfx::GetAtom(kTargets), &data, &out_data_items,
             &out_type)) {
       // Some apps return an |out_type| of "TARGETS". (crbug.com/377893)
-      if (out_type == XA_ATOM || out_type == GetAtom(kTargets)) {
+      if (out_type == XA_ATOM || out_type == gfx::GetAtom(kTargets)) {
         const ::Atom* atom_array =
             reinterpret_cast<const ::Atom*>(data->front());
         for (size_t i = 0; i < out_data_items; ++i)
@@ -459,7 +460,7 @@
 std::vector<::Atom> ClipboardAuraX11::AuraX11Details::GetAtomsForFormat(
     const Clipboard::FormatType& format) {
   std::vector< ::Atom> atoms;
-  atoms.push_back(GetAtom(format.ToString().c_str()));
+  atoms.push_back(gfx::GetAtom(format.ToString().c_str()));
   return atoms;
 }
 
@@ -475,7 +476,7 @@
   if (XGetSelectionOwner(x_display_, selection) != x_window_)
     return;
 
-  ::Atom clipboard_manager_atom = GetAtom(kClipboardManager);
+  ::Atom clipboard_manager_atom = gfx::GetAtom(kClipboardManager);
   if (XGetSelectionOwner(x_display_, clipboard_manager_atom) == None)
     return;
 
@@ -486,7 +487,7 @@
 
   base::TimeTicks start = base::TimeTicks::Now();
   selection_requestor_.PerformBlockingConvertSelectionWithParameter(
-      GetAtom(kClipboardManager), GetAtom(kSaveTargets), targets);
+      gfx::GetAtom(kClipboardManager), gfx::GetAtom(kSaveTargets), targets);
   UMA_HISTOGRAM_TIMES("Clipboard.X11StoreCopyPasteDuration",
                       base::TimeTicks::Now() - start);
 }
diff --git a/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc b/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc
index 8123d38..1a6e9a1 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc
+++ b/ui/base/dragdrop/os_exchange_data_provider_aurax11.cc
@@ -16,8 +16,8 @@
 #include "ui/base/clipboard/scoped_clipboard_writer.h"
 #include "ui/base/dragdrop/file_info.h"
 #include "ui/base/x/selection_utils.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/events/platform/platform_event_source.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 
 // Note: the GetBlah() methods are used immediately by the
 // web_contents_view_aura.cc:PrepareDropData(), while the omnibox is a
@@ -43,7 +43,7 @@
       own_window_(false),
       x_window_(x_window),
       format_map_(selection),
-      selection_owner_(x_display_, x_window_, GetAtom(kDndSelection)) {}
+      selection_owner_(x_display_, x_window_, gfx::GetAtom(kDndSelection)) {}
 
 OSExchangeDataProviderAuraX11::OSExchangeDataProviderAuraX11()
     : x_display_(gfx::GetXDisplay()),
@@ -62,7 +62,7 @@
                               0,
                               NULL)),
       format_map_(),
-      selection_owner_(x_display_, x_window_, GetAtom(kDndSelection)) {
+      selection_owner_(x_display_, x_window_, gfx::GetAtom(kDndSelection)) {
   XStoreName(x_display_, x_window_, "Chromium Drag & Drop Window");
 
   PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
@@ -100,13 +100,13 @@
 
 void OSExchangeDataProviderAuraX11::MarkOriginatedFromRenderer() {
   std::string empty;
-  format_map_.Insert(GetAtom(kRendererTaint),
+  format_map_.Insert(gfx::GetAtom(kRendererTaint),
                      scoped_refptr<base::RefCountedMemory>(
                          base::RefCountedString::TakeString(&empty)));
 }
 
 bool OSExchangeDataProviderAuraX11::DidOriginateFromRenderer() const {
-  return format_map_.find(GetAtom(kRendererTaint)) != format_map_.end();
+  return format_map_.find(gfx::GetAtom(kRendererTaint)) != format_map_.end();
 }
 
 void OSExchangeDataProviderAuraX11::SetString(const base::string16& text_data) {
@@ -117,10 +117,10 @@
   scoped_refptr<base::RefCountedMemory> mem(
       base::RefCountedString::TakeString(&utf8));
 
-  format_map_.Insert(GetAtom(Clipboard::kMimeTypeText), mem);
-  format_map_.Insert(GetAtom(kText), mem);
-  format_map_.Insert(GetAtom(kString), mem);
-  format_map_.Insert(GetAtom(kUtf8String), mem);
+  format_map_.Insert(gfx::GetAtom(Clipboard::kMimeTypeText), mem);
+  format_map_.Insert(gfx::GetAtom(kText), mem);
+  format_map_.Insert(gfx::GetAtom(kString), mem);
+  format_map_.Insert(gfx::GetAtom(kUtf8String), mem);
 }
 
 void OSExchangeDataProviderAuraX11::SetURL(const GURL& url,
@@ -138,7 +138,7 @@
     scoped_refptr<base::RefCountedMemory> mem(
         base::RefCountedBytes::TakeVector(&data));
 
-    format_map_.Insert(GetAtom(Clipboard::kMimeTypeMozillaURL), mem);
+    format_map_.Insert(gfx::GetAtom(Clipboard::kMimeTypeMozillaURL), mem);
 
     // Set a string fallback as well.
     SetString(spec);
@@ -158,7 +158,7 @@
     std::string netscape_url = url.spec();
     netscape_url += "\n";
     netscape_url += base::UTF16ToUTF8(title);
-    format_map_.Insert(GetAtom(kNetscapeURL),
+    format_map_.Insert(gfx::GetAtom(kNetscapeURL),
                        scoped_refptr<base::RefCountedMemory>(
                            base::RefCountedString::TakeString(&netscape_url)));
   }
@@ -184,7 +184,7 @@
   std::string joined_data = base::JoinString(paths, "\n");
   scoped_refptr<base::RefCountedMemory> mem(
       base::RefCountedString::TakeString(&joined_data));
-  format_map_.Insert(GetAtom(Clipboard::kMimeTypeURIList), mem);
+  format_map_.Insert(gfx::GetAtom(Clipboard::kMimeTypeURIList), mem);
 }
 
 void OSExchangeDataProviderAuraX11::SetPickledData(
@@ -198,7 +198,7 @@
   scoped_refptr<base::RefCountedMemory> mem(
       base::RefCountedBytes::TakeVector(&bytes));
 
-  format_map_.Insert(GetAtom(format.ToString().c_str()), mem);
+  format_map_.Insert(gfx::GetAtom(format.ToString().c_str()), mem);
 }
 
 bool OSExchangeDataProviderAuraX11::GetString(base::string16* result) const {
@@ -211,7 +211,7 @@
 
   std::vector<::Atom> text_atoms = ui::GetTextAtomsFrom();
   std::vector< ::Atom> requested_types;
-  ui::GetAtomIntersection(text_atoms, GetTargets(), &requested_types);
+  GetAtomIntersection(text_atoms, GetTargets(), &requested_types);
 
   ui::SelectionData data(format_map_.GetFirstOf(requested_types));
   if (data.IsValid()) {
@@ -229,7 +229,7 @@
     base::string16* title) const {
   std::vector<::Atom> url_atoms = ui::GetURLAtomsFrom();
   std::vector< ::Atom> requested_types;
-  ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
+  GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
 
   ui::SelectionData data(format_map_.GetFirstOf(requested_types));
   if (data.IsValid()) {
@@ -237,7 +237,7 @@
     // but that doesn't match the assumptions of the rest of the system which
     // expect single types.
 
-    if (data.GetType() == GetAtom(Clipboard::kMimeTypeMozillaURL)) {
+    if (data.GetType() == gfx::GetAtom(Clipboard::kMimeTypeMozillaURL)) {
       // Mozilla URLs are (UTF16: URL, newline, title).
       base::string16 unparsed;
       data.AssignTo(&unparsed);
@@ -254,7 +254,7 @@
         *url = GURL(tokens[0]);
         return true;
       }
-    } else if (data.GetType() == GetAtom(Clipboard::kMimeTypeURIList)) {
+    } else if (data.GetType() == gfx::GetAtom(Clipboard::kMimeTypeURIList)) {
       std::vector<std::string> tokens = ui::ParseURIList(data);
       for (std::vector<std::string>::const_iterator it = tokens.begin();
            it != tokens.end(); ++it) {
@@ -286,7 +286,7 @@
     std::vector<FileInfo>* filenames) const {
   std::vector<::Atom> url_atoms = ui::GetURIListAtomsFrom();
   std::vector< ::Atom> requested_types;
-  ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
+  GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
 
   filenames->clear();
   ui::SelectionData data(format_map_.GetFirstOf(requested_types));
@@ -309,7 +309,7 @@
     const Clipboard::FormatType& format,
     base::Pickle* pickle) const {
   std::vector< ::Atom> requested_types;
-  requested_types.push_back(GetAtom(format.ToString().c_str()));
+  requested_types.push_back(gfx::GetAtom(format.ToString().c_str()));
 
   ui::SelectionData data(format_map_.GetFirstOf(requested_types));
   if (data.IsValid()) {
@@ -326,7 +326,7 @@
 bool OSExchangeDataProviderAuraX11::HasString() const {
   std::vector<::Atom> text_atoms = ui::GetTextAtomsFrom();
   std::vector< ::Atom> requested_types;
-  ui::GetAtomIntersection(text_atoms, GetTargets(), &requested_types);
+  GetAtomIntersection(text_atoms, GetTargets(), &requested_types);
   return !requested_types.empty() && !HasFile();
 }
 
@@ -334,7 +334,7 @@
     OSExchangeData::FilenameToURLPolicy policy) const {
   std::vector<::Atom> url_atoms = ui::GetURLAtomsFrom();
   std::vector< ::Atom> requested_types;
-  ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
+  GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
 
   if (requested_types.empty())
     return false;
@@ -343,10 +343,11 @@
   // Windows does and stuffs all the data into one mime type.
   ui::SelectionData data(format_map_.GetFirstOf(requested_types));
   if (data.IsValid()) {
-    if (data.GetType() == GetAtom(Clipboard::kMimeTypeMozillaURL)) {
+    if (data.GetType() == gfx::GetAtom(Clipboard::kMimeTypeMozillaURL)) {
       // File managers shouldn't be using this type, so this is a URL.
       return true;
-    } else if (data.GetType() == GetAtom(ui::Clipboard::kMimeTypeURIList)) {
+    } else if (data.GetType() ==
+               gfx::GetAtom(ui::Clipboard::kMimeTypeURIList)) {
       std::vector<std::string> tokens = ui::ParseURIList(data);
       for (std::vector<std::string>::const_iterator it = tokens.begin();
            it != tokens.end(); ++it) {
@@ -365,7 +366,7 @@
 bool OSExchangeDataProviderAuraX11::HasFile() const {
   std::vector<::Atom> url_atoms = ui::GetURIListAtomsFrom();
   std::vector< ::Atom> requested_types;
-  ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
+  GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
 
   if (requested_types.empty())
     return false;
@@ -391,9 +392,9 @@
 bool OSExchangeDataProviderAuraX11::HasCustomFormat(
     const Clipboard::FormatType& format) const {
   std::vector< ::Atom> url_atoms;
-  url_atoms.push_back(GetAtom(format.ToString().c_str()));
+  url_atoms.push_back(gfx::GetAtom(format.ToString().c_str()));
   std::vector< ::Atom> requested_types;
-  ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
+  GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
 
   return !requested_types.empty();
 }
@@ -403,7 +404,7 @@
     const std::string& file_contents) {
   DCHECK(!filename.empty());
   DCHECK(format_map_.end() ==
-         format_map_.find(GetAtom(Clipboard::kMimeTypeMozillaURL)));
+         format_map_.find(gfx::GetAtom(Clipboard::kMimeTypeMozillaURL)));
 
   file_contents_name_ = filename;
 
@@ -423,12 +424,12 @@
   //   things simpler for Chrome, we always 'fail' and let the destination do
   //   the work.
   std::string failure("F");
-  format_map_.Insert(GetAtom("XdndDirectSave0"),
+  format_map_.Insert(gfx::GetAtom("XdndDirectSave0"),
                      scoped_refptr<base::RefCountedMemory>(
                          base::RefCountedString::TakeString(&failure)));
   std::string file_contents_copy = file_contents;
   format_map_.Insert(
-      GetAtom("application/octet-stream"),
+      gfx::GetAtom("application/octet-stream"),
       scoped_refptr<base::RefCountedMemory>(
           base::RefCountedString::TakeString(&file_contents_copy)));
 }
@@ -444,15 +445,15 @@
   scoped_refptr<base::RefCountedMemory> mem(
       base::RefCountedBytes::TakeVector(&bytes));
 
-  format_map_.Insert(GetAtom(Clipboard::kMimeTypeHTML), mem);
+  format_map_.Insert(gfx::GetAtom(Clipboard::kMimeTypeHTML), mem);
 }
 
 bool OSExchangeDataProviderAuraX11::GetHtml(base::string16* html,
                                             GURL* base_url) const {
   std::vector< ::Atom> url_atoms;
-  url_atoms.push_back(GetAtom(Clipboard::kMimeTypeHTML));
+  url_atoms.push_back(gfx::GetAtom(Clipboard::kMimeTypeHTML));
   std::vector< ::Atom> requested_types;
-  ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
+  GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
 
   ui::SelectionData data(format_map_.GetFirstOf(requested_types));
   if (data.IsValid()) {
@@ -466,9 +467,9 @@
 
 bool OSExchangeDataProviderAuraX11::HasHtml() const {
   std::vector< ::Atom> url_atoms;
-  url_atoms.push_back(GetAtom(Clipboard::kMimeTypeHTML));
+  url_atoms.push_back(gfx::GetAtom(Clipboard::kMimeTypeHTML));
   std::vector< ::Atom> requested_types;
-  ui::GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
+  GetAtomIntersection(url_atoms, GetTargets(), &requested_types);
 
   return !requested_types.empty();
 }
diff --git a/ui/base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc b/ui/base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc
index c96661c4..8714f03 100644
--- a/ui/base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc
+++ b/ui/base/dragdrop/os_exchange_data_provider_aurax11_unittest.cc
@@ -13,8 +13,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/dragdrop/file_info.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/events/platform/x11/x11_event_source_glib.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "url/gurl.h"
 
 const char kFileURL[] = "file:///home/user/file.txt";
@@ -33,7 +33,8 @@
     scoped_refptr<base::RefCountedMemory> mem(
         base::RefCountedString::TakeString(&contents_copy));
 
-    provider.format_map_.Insert(GetAtom(ui::Clipboard::kMimeTypeURIList), mem);
+    provider.format_map_.Insert(gfx::GetAtom(ui::Clipboard::kMimeTypeURIList),
+                                mem);
   }
 
  protected:
diff --git a/ui/base/idle/screensaver_window_finder_x11.cc b/ui/base/idle/screensaver_window_finder_x11.cc
index 74228ba4..e01cd247 100644
--- a/ui/base/idle/screensaver_window_finder_x11.cc
+++ b/ui/base/idle/screensaver_window_finder_x11.cc
@@ -7,6 +7,7 @@
 #include <X11/extensions/scrnsaver.h>
 
 #include "ui/base/x/x11_util.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_error_tracker.h"
 
 namespace ui {
@@ -32,7 +33,7 @@
   // info.state == ScreenSaverOff or info.state == ScreenSaverDisabled does not
   // necessarily mean that a screensaver is not active, so add a special check
   // for xscreensaver.
-  static XAtom lock_atom = GetAtom("LOCK");
+  XAtom lock_atom = gfx::GetAtom("LOCK");
   std::vector<int> atom_properties;
   if (GetIntArrayProperty(root, "_SCREENSAVER_STATUS", &atom_properties) &&
       atom_properties.size() > 0) {
diff --git a/ui/base/x/selection_owner.cc b/ui/base/x/selection_owner.cc
index fa8c321..76e6d9f 100644
--- a/ui/base/x/selection_owner.cc
+++ b/ui/base/x/selection_owner.cc
@@ -11,9 +11,9 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "ui/base/x/selection_utils.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/base/x/x11_window_event_manager.h"
 #include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 
 namespace ui {
 
@@ -144,7 +144,7 @@
   reply.xselection.property = None;  // Indicates failure
   reply.xselection.time = event.xselectionrequest.time;
 
-  if (requested_target == GetAtom(kMultiple)) {
+  if (requested_target == gfx::GetAtom(kMultiple)) {
     // The contents of |requested_property| should be a list of
     // <target,property> pairs.
     std::vector<std::pair<XAtom,XAtom> > conversions;
@@ -164,8 +164,8 @@
       // Set the property to indicate which conversions succeeded. This matches
       // what GTK does.
       XChangeProperty(
-          x_display_, requestor, requested_property, GetAtom(kAtomPair), 32,
-          PropModeReplace,
+          x_display_, requestor, requested_property, gfx::GetAtom(kAtomPair),
+          32, PropModeReplace,
           reinterpret_cast<const unsigned char*>(&conversion_results.front()),
           conversion_results.size());
 
@@ -206,10 +206,10 @@
 bool SelectionOwner::ProcessTarget(XAtom target,
                                    XID requestor,
                                    XAtom property) {
-  XAtom multiple_atom = GetAtom(kMultiple);
-  XAtom save_targets_atom = GetAtom(kSaveTargets);
-  XAtom targets_atom = GetAtom(kTargets);
-  XAtom timestamp_atom = GetAtom(kTimestamp);
+  XAtom multiple_atom = gfx::GetAtom(kMultiple);
+  XAtom save_targets_atom = gfx::GetAtom(kSaveTargets);
+  XAtom targets_atom = gfx::GetAtom(kTargets);
+  XAtom timestamp_atom = gfx::GetAtom(kTimestamp);
 
   if (target == multiple_atom || target == save_targets_atom)
     return false;
@@ -246,7 +246,7 @@
       // the size of X requests. Notify the selection requestor that the data
       // will be sent incrementally by returning data of type "INCR".
       long length = it->second->size();
-      XChangeProperty(x_display_, requestor, property, GetAtom(kIncr), 32,
+      XChangeProperty(x_display_, requestor, property, gfx::GetAtom(kIncr), 32,
                       PropModeReplace,
                       reinterpret_cast<unsigned char*>(&length), 1);
 
diff --git a/ui/base/x/selection_requestor.cc b/ui/base/x/selection_requestor.cc
index a6e402c..c4b8a7ec 100644
--- a/ui/base/x/selection_requestor.cc
+++ b/ui/base/x/selection_requestor.cc
@@ -13,6 +13,7 @@
 #include "ui/base/x/x11_util.h"
 #include "ui/events/platform/platform_event_dispatcher.h"
 #include "ui/events/platform/platform_event_source.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_types.h"
 
 namespace ui {
@@ -62,7 +63,7 @@
       x_property_(None),
       dispatcher_(dispatcher),
       current_request_index_(0u) {
-  x_property_ = GetAtom(kChromeSelection);
+  x_property_ = gfx::GetAtom(kChromeSelection);
 }
 
 SelectionRequestor::~SelectionRequestor() {}
@@ -162,7 +163,7 @@
   if (event_property != None)
     XDeleteProperty(x_display_, x_window_, event_property);
 
-  if (request->out_type == GetAtom(kIncr)) {
+  if (request->out_type == gfx::GetAtom(kIncr)) {
     request->data_sent_incrementally = true;
     request->out_data.clear();
     request->out_data_items = 0u;
diff --git a/ui/base/x/selection_requestor_unittest.cc b/ui/base/x/selection_requestor_unittest.cc
index 5a94412..d1b14674 100644
--- a/ui/base/x/selection_requestor_unittest.cc
+++ b/ui/base/x/selection_requestor_unittest.cc
@@ -15,6 +15,7 @@
 #include "ui/base/x/selection_utils.h"
 #include "ui/base/x/x11_util.h"
 #include "ui/events/platform/platform_event_source.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_types.h"
 
 #include <X11/Xlib.h>
@@ -34,8 +35,8 @@
   void SendSelectionNotify(XAtom selection,
                            XAtom target,
                            const std::string& value) {
-    ui::SetStringProperty(x_window_, requestor_->x_property_, GetAtom("STRING"),
-                          value);
+    ui::SetStringProperty(x_window_, requestor_->x_property_,
+                          gfx::GetAtom("STRING"), value);
 
     XEvent xev;
     xev.type = SelectionNotify;
@@ -106,7 +107,7 @@
       selection, target, &out_data, &out_data_items, &out_type));
   EXPECT_EQ(expected_data, ui::RefCountedMemoryToString(out_data));
   EXPECT_EQ(expected_data.size(), out_data_items);
-  EXPECT_EQ(GetAtom("STRING"), out_type);
+  EXPECT_EQ(gfx::GetAtom("STRING"), out_type);
 }
 
 }  // namespace
@@ -117,10 +118,10 @@
   // Assume that |selection| will have no owner. If there is an owner, the owner
   // will set the property passed into the XConvertSelection() request which is
   // undesirable.
-  XAtom selection = GetAtom("FAKE_SELECTION");
+  XAtom selection = gfx::GetAtom("FAKE_SELECTION");
 
-  XAtom target1 = GetAtom("TARGET1");
-  XAtom target2 = GetAtom("TARGET2");
+  XAtom target1 = gfx::GetAtom("TARGET1");
+  XAtom target2 = gfx::GetAtom("TARGET2");
 
   base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
   loop->task_runner()->PostTask(
diff --git a/ui/base/x/selection_utils.cc b/ui/base/x/selection_utils.cc
index 48eff62..3ab3c842 100644
--- a/ui/base/x/selection_utils.cc
+++ b/ui/base/x/selection_utils.cc
@@ -15,7 +15,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "ui/base/clipboard/clipboard.h"
-#include "ui/base/x/x11_util.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 
 namespace ui {
 
@@ -27,24 +27,24 @@
 
 std::vector<::Atom> GetTextAtomsFrom() {
   std::vector< ::Atom> atoms;
-  atoms.push_back(GetAtom(kUtf8String));
-  atoms.push_back(GetAtom(kString));
-  atoms.push_back(GetAtom(kText));
-  atoms.push_back(GetAtom(kTextPlain));
-  atoms.push_back(GetAtom(kTextPlainUtf8));
+  atoms.push_back(gfx::GetAtom(kUtf8String));
+  atoms.push_back(gfx::GetAtom(kString));
+  atoms.push_back(gfx::GetAtom(kText));
+  atoms.push_back(gfx::GetAtom(kTextPlain));
+  atoms.push_back(gfx::GetAtom(kTextPlainUtf8));
   return atoms;
 }
 
 std::vector<::Atom> GetURLAtomsFrom() {
   std::vector< ::Atom> atoms;
-  atoms.push_back(GetAtom(Clipboard::kMimeTypeURIList));
-  atoms.push_back(GetAtom(Clipboard::kMimeTypeMozillaURL));
+  atoms.push_back(gfx::GetAtom(Clipboard::kMimeTypeURIList));
+  atoms.push_back(gfx::GetAtom(Clipboard::kMimeTypeMozillaURL));
   return atoms;
 }
 
 std::vector<::Atom> GetURIListAtomsFrom() {
   std::vector< ::Atom> atoms;
-  atoms.push_back(GetAtom(Clipboard::kMimeTypeURIList));
+  atoms.push_back(gfx::GetAtom(Clipboard::kMimeTypeURIList));
   return atoms;
 }
 
@@ -181,10 +181,11 @@
 }
 
 std::string SelectionData::GetText() const {
-  if (type_ == GetAtom(kUtf8String) || type_ == GetAtom(kText) ||
-      type_ == GetAtom(kTextPlainUtf8)) {
+  if (type_ == gfx::GetAtom(kUtf8String) || type_ == gfx::GetAtom(kText) ||
+      type_ == gfx::GetAtom(kTextPlainUtf8)) {
     return RefCountedMemoryToString(memory_);
-  } else if (type_ == GetAtom(kString) || type_ == GetAtom(kTextPlain)) {
+  } else if (type_ == gfx::GetAtom(kString) ||
+             type_ == gfx::GetAtom(kTextPlain)) {
     std::string result;
     base::ConvertToUtf8AndNormalize(RefCountedMemoryToString(memory_),
                                     base::kCodepageLatin1,
@@ -201,7 +202,7 @@
 base::string16 SelectionData::GetHtml() const {
   base::string16 markup;
 
-  if (type_ == GetAtom(Clipboard::kMimeTypeHTML)) {
+  if (type_ == gfx::GetAtom(Clipboard::kMimeTypeHTML)) {
     const unsigned char* data = GetData();
     size_t size = GetSize();
 
diff --git a/ui/base/x/x11_menu_list.cc b/ui/base/x/x11_menu_list.cc
index a7c2fda..876865b 100644
--- a/ui/base/x/x11_menu_list.cc
+++ b/ui/base/x/x11_menu_list.cc
@@ -8,6 +8,7 @@
 
 #include "base/memory/singleton.h"
 #include "ui/base/x/x11_util.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 
 namespace ui {
 
@@ -17,8 +18,7 @@
 }
 
 XMenuList::XMenuList()
-    : menu_type_atom_(GetAtom("_NET_WM_WINDOW_TYPE_MENU")) {
-}
+    : menu_type_atom_(gfx::GetAtom("_NET_WM_WINDOW_TYPE_MENU")) {}
 
 XMenuList::~XMenuList() {
   menus_.clear();
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc
index bf3231c..c2ff09a0 100644
--- a/ui/base/x/x11_util.cc
+++ b/ui/base/x/x11_util.cc
@@ -94,7 +94,7 @@
 bool GetProperty(XID window, const std::string& property_name, long max_length,
                  XAtom* type, int* format, unsigned long* num_items,
                  unsigned char** property) {
-  XAtom property_atom = GetAtom(property_name.c_str());
+  XAtom property_atom = gfx::GetAtom(property_name.c_str());
   unsigned long remaining_bytes = 0;
   return XGetWindowProperty(gfx::GetXDisplay(),
                             window,
@@ -442,7 +442,7 @@
   motif_hints.flags = (1L << 1);
   motif_hints.decorations = use_os_window_frame ? 1 : 0;
 
-  XAtom hint_atom = GetAtom("_MOTIF_WM_HINTS");
+  XAtom hint_atom = gfx::GetAtom("_MOTIF_WM_HINTS");
   XChangeProperty(gfx::GetXDisplay(),
                   window,
                   hint_atom,
@@ -472,14 +472,11 @@
                                           HideTitlebarWhenMaximized property) {
   // XChangeProperty() expects "hide" to be long.
   unsigned long hide = property;
-  XChangeProperty(gfx::GetXDisplay(),
-      window,
-      GetAtom("_GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED"),
-      XA_CARDINAL,
-      32,  // size in bits
-      PropModeReplace,
-      reinterpret_cast<unsigned char*>(&hide),
-      1);
+  XChangeProperty(gfx::GetXDisplay(), window,
+                  gfx::GetAtom("_GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED"),
+                  XA_CARDINAL,
+                  32,  // size in bits
+                  PropModeReplace, reinterpret_cast<unsigned char*>(&hide), 1);
 }
 
 void ClearX11DefaultRootWindow() {
@@ -514,7 +511,7 @@
   // Minimized windows are not visible.
   std::vector<XAtom> wm_states;
   if (GetAtomArrayProperty(window, "_NET_WM_STATE", &wm_states)) {
-    XAtom hidden_atom = GetAtom("_NET_WM_STATE_HIDDEN");
+    XAtom hidden_atom = gfx::GetAtom("_NET_WM_STATE_HIDDEN");
     if (base::ContainsValue(wm_states, hidden_atom))
       return false;
   }
@@ -825,8 +822,8 @@
                          const std::string& type,
                          const std::vector<int>& value) {
   DCHECK(!value.empty());
-  XAtom name_atom = GetAtom(name.c_str());
-  XAtom type_atom = GetAtom(type.c_str());
+  XAtom name_atom = gfx::GetAtom(name.c_str());
+  XAtom type_atom = gfx::GetAtom(type.c_str());
 
   // XChangeProperty() expects values of type 32 to be longs.
   std::unique_ptr<long[]> data(new long[value.size()]);
@@ -858,8 +855,8 @@
                           const std::string& type,
                           const std::vector<XAtom>& value) {
   DCHECK(!value.empty());
-  XAtom name_atom = GetAtom(name.c_str());
-  XAtom type_atom = GetAtom(type.c_str());
+  XAtom name_atom = gfx::GetAtom(name.c_str());
+  XAtom type_atom = gfx::GetAtom(type.c_str());
 
   // XChangeProperty() expects values of type 32 to be longs.
   std::unique_ptr<XAtom[]> data(new XAtom[value.size()]);
@@ -894,10 +891,6 @@
   return !err_tracker.FoundNewError();
 }
 
-XAtom GetAtom(const char* name) {
-  return X11AtomCache::GetInstance()->GetAtom(name);
-}
-
 void SetWindowClassHint(XDisplay* display,
                         XID window,
                         const std::string& res_name,
@@ -913,13 +906,12 @@
 
 void SetWindowRole(XDisplay* display, XID window, const std::string& role) {
   if (role.empty()) {
-    XDeleteProperty(display, window, GetAtom("WM_WINDOW_ROLE"));
+    XDeleteProperty(display, window, gfx::GetAtom("WM_WINDOW_ROLE"));
   } else {
     char* role_c = const_cast<char*>(role.c_str());
-    XChangeProperty(display, window, GetAtom("WM_WINDOW_ROLE"), XA_STRING, 8,
-                    PropModeReplace,
-                    reinterpret_cast<unsigned char*>(role_c),
-                    role.size());
+    XChangeProperty(display, window, gfx::GetAtom("WM_WINDOW_ROLE"), XA_STRING,
+                    8, PropModeReplace,
+                    reinterpret_cast<unsigned char*>(role_c), role.size());
   }
 }
 
@@ -1185,7 +1177,8 @@
 
 bool IsCompositingManagerPresent() {
   static bool is_compositing_manager_present =
-      XGetSelectionOwner(gfx::GetXDisplay(), GetAtom("_NET_WM_CM_S0")) != None;
+      XGetSelectionOwner(gfx::GetXDisplay(), gfx::GetAtom("_NET_WM_CM_S0")) !=
+      None;
   return is_compositing_manager_present;
 }
 
@@ -1197,7 +1190,7 @@
   // If _NET_WM_STATE_FULLSCREEN is in _NET_SUPPORTED, use the presence or
   // absence of _NET_WM_STATE_FULLSCREEN in _NET_WM_STATE to determine
   // whether we're fullscreen.
-  XAtom fullscreen_atom = GetAtom("_NET_WM_STATE_FULLSCREEN");
+  XAtom fullscreen_atom = gfx::GetAtom("_NET_WM_STATE_FULLSCREEN");
   if (WmSupportsHint(fullscreen_atom)) {
     std::vector<XAtom> atom_properties;
     if (GetAtomArrayProperty(window,
@@ -1391,7 +1384,7 @@
   for (int i = 0; i < visuals_len; ++i)
     visuals_[visual_list[i].visualid].reset(new XVisualData(visual_list[i]));
 
-  XAtom NET_WM_CM_S0 = GetAtom("_NET_WM_CM_S0");
+  XAtom NET_WM_CM_S0 = gfx::GetAtom("_NET_WM_CM_S0");
   using_compositing_wm_ = XGetSelectionOwner(display_, NET_WM_CM_S0) != None;
 
   // Choose the opaque visual.
diff --git a/ui/base/x/x11_util.h b/ui/base/x/x11_util.h
index 3dfdcb1..c47ce28 100644
--- a/ui/base/x/x11_util.h
+++ b/ui/base/x/x11_util.h
@@ -177,9 +177,6 @@
                                         XAtom type,
                                         const std::string& value);
 
-// Gets the X atom for default display corresponding to atom_name.
-UI_BASE_X_EXPORT XAtom GetAtom(const char* atom_name);
-
 // Sets the WM_CLASS attribute for a given X11 window.
 UI_BASE_X_EXPORT void SetWindowClassHint(XDisplay* display,
                                          XID window,
diff --git a/ui/display/manager/chromeos/x11/native_display_delegate_x11.cc b/ui/display/manager/chromeos/x11/native_display_delegate_x11.cc
index d94e618a..df9af54 100644
--- a/ui/display/manager/chromeos/x11/native_display_delegate_x11.cc
+++ b/ui/display/manager/chromeos/x11/native_display_delegate_x11.cc
@@ -16,7 +16,6 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/display/manager/chromeos/x11/display_mode_x11.h"
 #include "ui/display/manager/chromeos/x11/display_snapshot_x11.h"
 #include "ui/display/manager/chromeos/x11/display_util_x11.h"
@@ -25,6 +24,7 @@
 #include "ui/display/util/x11/edid_parser_x11.h"
 #include "ui/events/platform/platform_event_source.h"
 #include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_error_tracker.h"
 #include "ui/gfx/x/x11_types.h"
 
@@ -403,7 +403,7 @@
   Atom actual_type = None;
   int success = 0;
   RROutput output_id = static_cast<const DisplaySnapshotX11&>(output).output();
-  Atom prop = ui::GetAtom(kContentProtectionAtomName);
+  Atom prop = gfx::GetAtom(kContentProtectionAtomName);
 
   // TODO(kcwu): Move this to x11_util (similar method calls in this file and
   // output_util.cc)
@@ -430,11 +430,11 @@
   if (success == Success && actual_type == XA_ATOM && actual_format == 32 &&
       nitems == 1) {
     Atom value = reinterpret_cast<Atom*>(values)[0];
-    if (value == ui::GetAtom(kProtectionUndesiredAtomName)) {
+    if (value == gfx::GetAtom(kProtectionUndesiredAtomName)) {
       *state = HDCP_STATE_UNDESIRED;
-    } else if (value == ui::GetAtom(kProtectionDesiredAtomName)) {
+    } else if (value == gfx::GetAtom(kProtectionDesiredAtomName)) {
       *state = HDCP_STATE_DESIRED;
-    } else if (value == ui::GetAtom(kProtectionEnabledAtomName)) {
+    } else if (value == gfx::GetAtom(kProtectionEnabledAtomName)) {
       *state = HDCP_STATE_ENABLED;
     } else {
       LOG(ERROR) << "Unknown " << kContentProtectionAtomName
@@ -459,14 +459,14 @@
 
 bool NativeDisplayDelegateX11::SetHDCPState(const DisplaySnapshot& output,
                                             HDCPState state) {
-  Atom name = ui::GetAtom(kContentProtectionAtomName);
+  Atom name = gfx::GetAtom(kContentProtectionAtomName);
   Atom value = None;
   switch (state) {
     case HDCP_STATE_UNDESIRED:
-      value = ui::GetAtom(kProtectionUndesiredAtomName);
+      value = gfx::GetAtom(kProtectionUndesiredAtomName);
       break;
     case HDCP_STATE_DESIRED:
-      value = ui::GetAtom(kProtectionDesiredAtomName);
+      value = gfx::GetAtom(kProtectionDesiredAtomName);
       break;
     default:
       NOTREACHED() << "Invalid HDCP state: " << state;
@@ -543,8 +543,8 @@
 }
 
 bool NativeDisplayDelegateX11::IsOutputAspectPreservingScaling(RROutput id) {
-  Atom scaling_prop = ui::GetAtom("scaling mode");
-  Atom full_aspect_atom = ui::GetAtom("Full aspect");
+  Atom scaling_prop = gfx::GetAtom("scaling mode");
+  Atom full_aspect_atom = gfx::GetAtom("Full aspect");
   if (scaling_prop == None || full_aspect_atom == None)
     return false;
 
diff --git a/ui/display/util/x11/edid_parser_x11.cc b/ui/display/util/x11/edid_parser_x11.cc
index a394708..4c5f682 100644
--- a/ui/display/util/x11/edid_parser_x11.cc
+++ b/ui/display/util/x11/edid_parser_x11.cc
@@ -34,8 +34,7 @@
 
   Display* display = gfx::GetXDisplay();
 
-  static Atom edid_property =
-      ui::X11AtomCache::GetInstance()->GetAtom(RR_PROPERTY_RANDR_EDID);
+  Atom edid_property = gfx::GetAtom(RR_PROPERTY_RANDR_EDID);
 
   bool has_edid_property = false;
   int num_properties = 0;
diff --git a/ui/events/devices/x11/device_data_manager_x11.cc b/ui/events/devices/x11/device_data_manager_x11.cc
index abc70fc..f218275 100644
--- a/ui/events/devices/x11/device_data_manager_x11.cc
+++ b/ui/events/devices/x11/device_data_manager_x11.cc
@@ -243,7 +243,7 @@
   // Find all the touchpad devices.
   const XDeviceList& dev_list =
       ui::DeviceListCacheX11::GetInstance()->GetXDeviceList(display);
-  Atom xi_touchpad = ui::X11AtomCache::GetInstance()->GetAtom(XI_TOUCHPAD);
+  Atom xi_touchpad = gfx::GetAtom(XI_TOUCHPAD);
   for (int i = 0; i < dev_list.count; ++i)
     if (dev_list[i].type == xi_touchpad)
       touchpads_[dev_list[i].id] = true;
@@ -256,8 +256,7 @@
       ui::DeviceListCacheX11::GetInstance()->GetXI2DeviceList(display);
   Atom atoms[DT_LAST_ENTRY];
   for (int data_type = 0; data_type < DT_LAST_ENTRY; ++data_type)
-    atoms[data_type] =
-        ui::X11AtomCache::GetInstance()->GetAtom(kCachedAtoms[data_type]);
+    atoms[data_type] = gfx::GetAtom(kCachedAtoms[data_type]);
 
   for (int i = 0; i < info_list.count; ++i) {
     const XIDeviceInfo& info = info_list[i];
diff --git a/ui/events/ozone/gamepad/static_gamepad_mapping.cc b/ui/events/ozone/gamepad/static_gamepad_mapping.cc
index 2c01d40..2482b12 100644
--- a/ui/events/ozone/gamepad/static_gamepad_mapping.cc
+++ b/ui/events/ozone/gamepad/static_gamepad_mapping.cc
@@ -131,6 +131,56 @@
   return DO_MAPPING;
 }
 
+bool DualShock4Mapper(uint16_t type,
+                      uint16_t code,
+                      GamepadEventType* mapped_type,
+                      uint16_t* mapped_code) {
+  static const KeyMapType key_mapping = {
+      {BTN_A, WG_BUTTON_A},           {BTN_B, WG_BUTTON_B},
+      {BTN_C, WG_BUTTON_X},           {BTN_X, WG_BUTTON_Y},
+      {BTN_Y, WG_BUTTON_L1},          {BTN_Z, WG_BUTTON_R1},
+      {BTN_TL, WG_BUTTON_LT},         {BTN_TR, WG_BUTTON_RT},
+      {BTN_TL2, WG_BUTTON_SELECT},    {BTN_TR2, WG_BUTTON_START},
+      {BTN_SELECT, WG_BUTTON_THUMBL}, {BTN_START, WG_BUTTON_THUMBR}};
+
+  static const AbsMapType abs_mapping = {
+      TO_ABS(ABS_X, WG_ABS_X),      TO_ABS(ABS_Y, WG_ABS_Y),
+      TO_ABS(ABS_RX, WG_BUTTON_LT), TO_ABS(ABS_RY, WG_BUTTON_RT),
+      TO_ABS(ABS_Z, WG_ABS_RX),     TO_ABS(ABS_RZ, WG_ABS_RY),
+      TO_BTN(ABS_HAT0X, kHAT_X),    TO_BTN(ABS_HAT0Y, kHAT_Y)};
+  return DO_MAPPING;
+}
+
+bool NintendoSwitchLeft(uint16_t type,
+                        uint16_t code,
+                        GamepadEventType* mapped_type,
+                        uint16_t* mapped_code) {
+  static const KeyMapType key_mapping = {
+      {BTN_A, WG_BUTTON_A},        {BTN_B, WG_BUTTON_B},
+      {BTN_C, WG_BUTTON_X},        {BTN_X, WG_BUTTON_Y},
+      {BTN_Y, WG_BUTTON_L1},       {BTN_Z, WG_BUTTON_R1},
+      {BTN_TL2, WG_BUTTON_SELECT}, {BTN_THUMBL, WG_BUTTON_START}};
+
+  static const AbsMapType abs_mapping = {TO_BTN(ABS_HAT0X, kHAT_X),
+                                         TO_BTN(ABS_HAT0Y, kHAT_Y)};
+  return DO_MAPPING;
+}
+
+bool NintendoSwitchRight(uint16_t type,
+                         uint16_t code,
+                         GamepadEventType* mapped_type,
+                         uint16_t* mapped_code) {
+  static const KeyMapType key_mapping = {
+      {BTN_A, WG_BUTTON_A},         {BTN_B, WG_BUTTON_B},
+      {BTN_C, WG_BUTTON_X},         {BTN_X, WG_BUTTON_Y},
+      {BTN_Y, WG_BUTTON_L1},        {BTN_Z, WG_BUTTON_R1},
+      {BTN_MODE, WG_BUTTON_SELECT}, {BTN_TR2, WG_BUTTON_START}};
+
+  static const AbsMapType abs_mapping = {TO_BTN(ABS_HAT0X, kHAT_X),
+                                         TO_BTN(ABS_HAT0Y, kHAT_Y)};
+  return DO_MAPPING;
+}
+
 bool IBuffalocClassicMapper(uint16_t type,
                             uint16_t code,
                             GamepadEventType* mapped_type,
@@ -360,23 +410,23 @@
   return DO_MAPPING;
 }
 
-bool DualShock4(uint16_t type,
-                uint16_t code,
-                GamepadEventType* mapped_type,
-                uint16_t* mapped_code) {
+bool NvidiaShieldMapper(uint16_t type,
+                        uint16_t code,
+                        GamepadEventType* mapped_type,
+                        uint16_t* mapped_code) {
   static const KeyMapType key_mapping = {
       {BTN_A, WG_BUTTON_A},           {BTN_B, WG_BUTTON_B},
-      {BTN_C, WG_BUTTON_X},           {BTN_X, WG_BUTTON_Y},
-      {BTN_Y, WG_BUTTON_L1},          {BTN_Z, WG_BUTTON_R1},
-      {BTN_TL, WG_BUTTON_LT},         {BTN_TR, WG_BUTTON_RT},
-      {BTN_TL2, WG_BUTTON_SELECT},    {BTN_TR2, WG_BUTTON_START},
-      {BTN_SELECT, WG_BUTTON_THUMBL}, {BTN_START, WG_BUTTON_THUMBR}};
+      {BTN_X, WG_BUTTON_X},           {BTN_Y, WG_BUTTON_Y},
+      {BTN_TL, WG_BUTTON_L1},         {BTN_TR, WG_BUTTON_R1},
+      {KEY_BACK, WG_BUTTON_SELECT},   {BTN_START, WG_BUTTON_START},
+      {KEY_HOMEPAGE, WG_BUTTON_MODE}, {BTN_THUMBL, WG_BUTTON_THUMBL},
+      {BTN_THUMBR, WG_BUTTON_THUMBR}};
 
   static const AbsMapType abs_mapping = {
-      TO_ABS(ABS_X, WG_ABS_X),      TO_ABS(ABS_Y, WG_ABS_Y),
-      TO_ABS(ABS_RX, WG_BUTTON_LT), TO_ABS(ABS_RY, WG_BUTTON_RT),
-      TO_ABS(ABS_Z, WG_ABS_RX),     TO_ABS(ABS_RZ, WG_ABS_RY),
-      TO_BTN(ABS_HAT0X, kHAT_X),    TO_BTN(ABS_HAT0Y, kHAT_Y)};
+      TO_ABS(ABS_X, WG_ABS_X),         TO_ABS(ABS_Y, WG_ABS_Y),
+      TO_ABS(ABS_Z, WG_ABS_RX),        TO_ABS(ABS_RZ, WG_ABS_RY),
+      TO_BTN(ABS_BRAKE, WG_BUTTON_LT), TO_BTN(ABS_GAS, WG_BUTTON_RT),
+      TO_BTN(ABS_HAT0X, kHAT_X),       TO_BTN(ABS_HAT0Y, kHAT_Y)};
   return DO_MAPPING;
 }
 
@@ -407,7 +457,10 @@
     {0x1689, 0xfe00, XInputStyleMapper},  // Razer sabertooth elite.
     // Sony gamepads.
     {0x054c, 0x0268, PlaystationSixAxisMapper},  // Playstation 3.
-    {0x054c, 0x05c4, DualShock4},                // Dualshock 4.
+    {0x054c, 0x05c4, DualShock4Mapper},          // Dualshock 4.
+    // Nintendo switch.
+    {0x057e, 0x2006, NintendoSwitchLeft},   // Nintendo switch left.
+    {0x057e, 0x2007, NintendoSwitchRight},  // Nintendo switch right.
     // NES style gamepad.
     {0x0583, 0x2060, IBuffalocClassicMapper},  // iBuffalo Classic.
     {0x0079, 0x0011, ClassicNESMapper},        // Classic NES controller.
@@ -427,7 +480,8 @@
     {0x1038, 0x1412, Vendor_1038Product_1412Mapper},  // Steelseries free.
     // Razer onza tournment edition.
     {0x1689, 0xfd00, Vendor_1689Product_fd00Mapper},
-    {0x11c5, 0x5506, JoydevLikeMapper}  // HJC Game ZD-V
+    {0x0955, 0x7214, NvidiaShieldMapper},  // Nvidia shield.
+    {0x11c5, 0x5506, JoydevLikeMapper}     // HJC Game ZD-V
 };
 
 class StaticGamepadMapper : public GamepadMapper {
diff --git a/ui/events/platform/x11/x11_event_source.cc b/ui/events/platform/x11/x11_event_source.cc
index 6f2d835..b27acd8 100644
--- a/ui/events/platform/x11/x11_event_source.cc
+++ b/ui/events/platform/x11/x11_event_source.cc
@@ -157,7 +157,7 @@
     // Create a new Window and Atom that will be used for the property change.
     dummy_window_ = XCreateSimpleWindow(display_, DefaultRootWindow(display_),
                                         0, 0, 1, 1, 0, 0, 0);
-    dummy_atom_ = X11AtomCache::GetInstance()->GetAtom("CHROMIUM_TIMESTAMP");
+    dummy_atom_ = gfx::GetAtom("CHROMIUM_TIMESTAMP");
     dummy_window_events_.reset(
         new XScopedEventSelector(dummy_window_, PropertyChangeMask));
     dummy_initialized_ = true;
diff --git a/ui/events/platform/x11/x11_hotplug_event_handler.cc b/ui/events/platform/x11/x11_hotplug_event_handler.cc
index f6f6b15..0cb25684 100644
--- a/ui/events/platform/x11/x11_hotplug_event_handler.cc
+++ b/ui/events/platform/x11/x11_hotplug_event_handler.cc
@@ -25,7 +25,6 @@
 #include "base/sys_info.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/threading/worker_pool.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/events/devices/device_data_manager.h"
 #include "ui/events/devices/device_hotplug_event_observer.h"
 #include "ui/events/devices/device_util_linux.h"
@@ -197,7 +196,7 @@
 
   // Input device has a property "Device Node" pointing to its dev input node,
   // e.g.   Device Node (250): "/dev/input/event8"
-  Atom device_node = ui::X11AtomCache::GetInstance()->GetAtom("Device Node");
+  Atom device_node = gfx::GetAtom("Device Node");
   if (device_node == None)
     return base::FilePath();
 
@@ -423,13 +422,13 @@
       continue;
 
     Atom type = device_list_xi[i].type;
-    if (type == GetAtom(XI_KEYBOARD))
+    if (type == gfx::GetAtom(XI_KEYBOARD))
       device_types[id] = DEVICE_TYPE_KEYBOARD;
-    else if (type == GetAtom(XI_MOUSE))
+    else if (type == gfx::GetAtom(XI_MOUSE))
       device_types[id] = DEVICE_TYPE_MOUSE;
-    else if (type == GetAtom(XI_TOUCHPAD))
+    else if (type == gfx::GetAtom(XI_TOUCHPAD))
       device_types[id] = DEVICE_TYPE_TOUCHPAD;
-    else if (type == GetAtom(XI_TOUCHSCREEN))
+    else if (type == gfx::GetAtom(XI_TOUCHSCREEN))
       device_types[id] = DEVICE_TYPE_TOUCHSCREEN;
   }
 
@@ -454,8 +453,9 @@
     uint16_t vendor = 0;
     uint16_t product = 0;
     if (XIGetProperty(gfx::GetXDisplay(), device.deviceid,
-                      GetAtom(XI_PROP_PRODUCT_ID), 0, 2, 0, XA_INTEGER, &type,
-                      &format_return, &num_items_return, &bytes_after_return,
+                      gfx::GetAtom(XI_PROP_PRODUCT_ID), 0, 2, 0, XA_INTEGER,
+                      &type, &format_return, &num_items_return,
+                      &bytes_after_return,
                       reinterpret_cast<unsigned char**>(&product_info)) == 0 &&
         product_info) {
       if (num_items_return == 2) {
@@ -471,8 +471,8 @@
 
   // X11 is not thread safe, so first get all the required state.
   DisplayState display_state;
-  display_state.mt_position_x = GetAtom("Abs MT Position X");
-  display_state.mt_position_y = GetAtom("Abs MT Position Y");
+  display_state.mt_position_x = gfx::GetAtom("Abs MT Position X");
+  display_state.mt_position_y = gfx::GetAtom("Abs MT Position Y");
 
   UiCallbacks callbacks;
   callbacks.keyboard_callback = base::Bind(&OnKeyboardDevices);
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index 8b34733..cf8e1d3 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -363,7 +363,7 @@
 
   # Linux.
   if (is_linux) {
-    deps += [ "//build/linux:fontconfig" ]
+    deps += [ "//third_party/fontconfig" ]
   }
 
   if (is_mac) {
@@ -604,7 +604,7 @@
     ]
   }
   if (is_linux) {
-    deps += [ "//build/linux:fontconfig" ]
+    deps += [ "//third_party/fontconfig" ]
   }
 }
 
diff --git a/ui/gfx/icc_profile_x11.cc b/ui/gfx/icc_profile_x11.cc
index b2d7ca1..819c8a6d 100644
--- a/ui/gfx/icc_profile_x11.cc
+++ b/ui/gfx/icc_profile_x11.cc
@@ -25,7 +25,7 @@
   ICCProfile icc_profile;
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kHeadless))
     return icc_profile;
-  Atom property = ui::X11AtomCache::GetInstance()->GetAtom("_ICC_PROFILE");
+  Atom property = GetAtom("_ICC_PROFILE");
   if (property != None) {
     Atom prop_type = None;
     int prop_format = 0;
diff --git a/ui/gfx/x/x11_atom_cache.cc b/ui/gfx/x/x11_atom_cache.cc
index a5ce809..893d6ad 100644
--- a/ui/gfx/x/x11_atom_cache.cc
+++ b/ui/gfx/x/x11_atom_cache.cc
@@ -156,7 +156,11 @@
 
 }  // namespace
 
-namespace ui {
+namespace gfx {
+
+XAtom GetAtom(const char* name) {
+  return X11AtomCache::GetInstance()->GetAtom(name);
+}
 
 X11AtomCache* X11AtomCache::GetInstance() {
   return base::Singleton<X11AtomCache>::get();
@@ -191,4 +195,4 @@
   return it->second;
 }
 
-}  // namespace ui
+}  // namespace gfx
diff --git a/ui/gfx/x/x11_atom_cache.h b/ui/gfx/x/x11_atom_cache.h
index 91e68786..19bebbe 100644
--- a/ui/gfx/x/x11_atom_cache.h
+++ b/ui/gfx/x/x11_atom_cache.h
@@ -17,7 +17,10 @@
 struct DefaultSingletonTraits;
 }
 
-namespace ui {
+namespace gfx {
+
+// Gets the X atom for default display corresponding to atom_name.
+GFX_EXPORT XAtom GetAtom(const char* atom_name);
 
 // Pre-caches all Atoms on first use to minimize roundtrips to the X11
 // server. By default, GetAtom() will CHECK() that atoms accessed through
@@ -27,15 +30,16 @@
  public:
   static X11AtomCache* GetInstance();
 
-  // Returns the pre-interned Atom without having to go to the x server.
-  XAtom GetAtom(const char*) const;
-
  private:
+  friend XAtom GetAtom(const char* atom_name);
   friend struct base::DefaultSingletonTraits<X11AtomCache>;
 
   X11AtomCache();
   ~X11AtomCache();
 
+  // Returns the pre-interned Atom without having to go to the x server.
+  XAtom GetAtom(const char*) const;
+
   XDisplay* xdisplay_;
 
   mutable std::map<std::string, XAtom> cached_atoms_;
@@ -43,6 +47,6 @@
   DISALLOW_COPY_AND_ASSIGN(X11AtomCache);
 };
 
-}  // namespace ui
+}  // namespace gfx
 
 #endif  // UI_GFX_X_X11_ATOM_CACHE_H_
diff --git a/ui/platform_window/x11/x11_window_base.cc b/ui/platform_window/x11/x11_window_base.cc
index 61d555d..4e8de81 100644
--- a/ui/platform_window/x11/x11_window_base.cc
+++ b/ui/platform_window/x11/x11_window_base.cc
@@ -13,7 +13,6 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "ui/base/platform_window_defaults.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/base/x/x11_window_event_manager.h"
 #include "ui/events/devices/x11/touch_factory_x11.h"
 #include "ui/events/event.h"
@@ -22,6 +21,7 @@
 #include "ui/events/platform/platform_event_source.h"
 #include "ui/events/platform/x11/x11_event_source.h"
 #include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/platform_window/platform_window_delegate.h"
 
 namespace ui {
@@ -113,8 +113,8 @@
   XFlush(xdisplay_);
 
   ::Atom protocols[2];
-  protocols[0] = GetAtom("WM_DELETE_WINDOW");
-  protocols[1] = GetAtom("_NET_WM_PING");
+  protocols[0] = gfx::GetAtom("WM_DELETE_WINDOW");
+  protocols[1] = gfx::GetAtom("_NET_WM_PING");
   XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
 
   // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
@@ -127,8 +127,9 @@
   static_assert(sizeof(long) >= sizeof(pid_t),
                 "pid_t should not be larger than long");
   long pid = getpid();
-  XChangeProperty(xdisplay_, xwindow_, GetAtom("_NET_WM_PID"), XA_CARDINAL, 32,
-                  PropModeReplace, reinterpret_cast<unsigned char*>(&pid), 1);
+  XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_PID"), XA_CARDINAL,
+                  32, PropModeReplace, reinterpret_cast<unsigned char*>(&pid),
+                  1);
   // Before we map the window, set size hints. Otherwise, some window managers
   // will ignore toplevel XMoveWindow commands.
   XSizeHints size_hints;
@@ -214,8 +215,8 @@
     return;
   window_title_ = title;
   std::string utf8str = base::UTF16ToUTF8(title);
-  XChangeProperty(xdisplay_, xwindow_, GetAtom("_NET_WM_NAME"),
-                  GetAtom("UTF8_STRING"), 8, PropModeReplace,
+  XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_NAME"),
+                  gfx::GetAtom("UTF8_STRING"), 8, PropModeReplace,
                   reinterpret_cast<const unsigned char*>(utf8str.c_str()),
                   utf8str.size());
   XTextProperty xtp;
@@ -293,9 +294,9 @@
 
     case ClientMessage: {
       Atom message = static_cast<Atom>(xev->xclient.data.l[0]);
-      if (message == GetAtom("WM_DELETE_WINDOW")) {
+      if (message == gfx::GetAtom("WM_DELETE_WINDOW")) {
         delegate_->OnCloseRequest();
-      } else if (message == GetAtom("_NET_WM_PING")) {
+      } else if (message == gfx::GetAtom("_NET_WM_PING")) {
         XEvent reply_event = *xev;
         reply_event.xclient.window = xroot_window_;
 
diff --git a/ui/views/accessibility/native_view_accessibility_auralinux.cc b/ui/views/accessibility/native_view_accessibility_auralinux.cc
index 89b42737..316bd4f 100644
--- a/ui/views/accessibility/native_view_accessibility_auralinux.cc
+++ b/ui/views/accessibility/native_view_accessibility_auralinux.cc
@@ -109,6 +109,8 @@
     return false;
   }
 
+  bool ShouldIgnoreHoveredStateForTesting() override { return false; }
+
  private:
   friend struct base::DefaultSingletonTraits<AuraLinuxApplication>;
 
diff --git a/ui/views/accessibility/native_view_accessibility_base.cc b/ui/views/accessibility/native_view_accessibility_base.cc
index 300e86a0..3eca6e3 100644
--- a/ui/views/accessibility/native_view_accessibility_base.cc
+++ b/ui/views/accessibility/native_view_accessibility_base.cc
@@ -199,6 +199,10 @@
   return view_->HandleAccessibleAction(data);
 }
 
+bool NativeViewAccessibilityBase::ShouldIgnoreHoveredStateForTesting() {
+  return false;
+}
+
 void NativeViewAccessibilityBase::OnWidgetDestroying(Widget* widget) {
   if (parent_widget_ == widget) {
     parent_widget_->RemoveObserver(this);
diff --git a/ui/views/accessibility/native_view_accessibility_base.h b/ui/views/accessibility/native_view_accessibility_base.h
index fb0d0fe..cc8acfb9 100644
--- a/ui/views/accessibility/native_view_accessibility_base.h
+++ b/ui/views/accessibility/native_view_accessibility_base.h
@@ -47,6 +47,7 @@
   gfx::NativeViewAccessible GetFocus() override;
   gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
   bool AccessibilityPerformAction(const ui::AXActionData& data) override;
+  bool ShouldIgnoreHoveredStateForTesting() override;
 
   // WidgetObserver
   void OnWidgetDestroying(Widget* widget) override;
diff --git a/ui/views/test/ui_controls_factory_desktop_aurax11.cc b/ui/views/test/ui_controls_factory_desktop_aurax11.cc
index c43e67b5..534e0c4 100644
--- a/ui/views/test/ui_controls_factory_desktop_aurax11.cc
+++ b/ui/views/test/ui_controls_factory_desktop_aurax11.cc
@@ -24,6 +24,7 @@
 #include "ui/compositor/dip_util.h"
 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
 #include "ui/events/test/platform_event_waiter.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_connection.h"
 #include "ui/views/test/test_desktop_screen_x11.h"
 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
@@ -45,7 +46,7 @@
 
 // Returns atom that indidates that the XEvent is marker event.
 Atom MarkerEventAtom() {
-  return ui::GetAtom("marker_event");
+  return gfx::GetAtom("marker_event");
 }
 
 // Returns true when the event is a marker event.
diff --git a/ui/views/test/x11_property_change_waiter.cc b/ui/views/test/x11_property_change_waiter.cc
index b9937b3..d267b82 100644
--- a/ui/views/test/x11_property_change_waiter.cc
+++ b/ui/views/test/x11_property_change_waiter.cc
@@ -7,10 +7,10 @@
 #include <X11/Xlib.h>
 
 #include "base/run_loop.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/base/x/x11_window_event_manager.h"
 #include "ui/events/platform/platform_event_source.h"
 #include "ui/events/platform/scoped_event_dispatcher.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 
 namespace views {
 
@@ -58,7 +58,7 @@
     const ui::PlatformEvent& event) {
   if (!wait_ || event->type != PropertyNotify ||
       event->xproperty.window != x_window_ ||
-      event->xproperty.atom != ui::GetAtom(property_) ||
+      event->xproperty.atom != gfx::GetAtom(property_) ||
       ShouldKeepOnWaiting(event)) {
     return ui::POST_DISPATCH_PERFORM_DEFAULT;
   }
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
index 175ae23..d53d9c7 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
@@ -26,13 +26,13 @@
 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h"
 #include "ui/base/layout.h"
 #include "ui/base/x/selection_utils.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/base/x/x11_window_event_manager.h"
 #include "ui/display/screen.h"
 #include "ui/events/event.h"
 #include "ui/events/event_utils.h"
 #include "ui/events/platform/platform_event_source.h"
 #include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
 #include "ui/views/widget/desktop_aura/x11_topmost_window_finder.h"
@@ -312,8 +312,7 @@
     bool get_types_from_property = ((event.data.l[1] & 1) != 0);
 
     if (get_types_from_property) {
-      if (!ui::GetAtomArrayProperty(source_window_,
-                                    kXdndTypeList,
+      if (!ui::GetAtomArrayProperty(source_window_, kXdndTypeList,
                                     &unfetched_targets_)) {
         return;
       }
@@ -391,8 +390,8 @@
   ::Atom target = unfetched_targets_.back();
   unfetched_targets_.pop_back();
 
-  XConvertSelection(gfx::GetXDisplay(), ui::GetAtom(kXdndSelection), target,
-                    ui::GetAtom(kChromiumDragReciever), local_window_,
+  XConvertSelection(gfx::GetXDisplay(), gfx::GetAtom(kXdndSelection), target,
+                    gfx::GetAtom(kChromiumDragReciever), local_window_,
                     position_time_stamp_);
 }
 
@@ -408,7 +407,7 @@
   DVLOG(1) << "SelectionNotify, format " << event.target;
 
   if (event.property != None) {
-    DCHECK_EQ(event.property, ui::GetAtom(kChromiumDragReciever));
+    DCHECK_EQ(event.property, gfx::GetAtom(kChromiumDragReciever));
 
     scoped_refptr<base::RefCountedMemory> data;
     ::Atom type = None;
@@ -436,8 +435,7 @@
 void DesktopDragDropClientAuraX11::X11DragContext::ReadActions() {
   if (!source_client_) {
     std::vector<::Atom> atom_array;
-    if (!ui::GetAtomArrayProperty(source_window_,
-                                  kXdndActionList,
+    if (!ui::GetAtomArrayProperty(source_window_, kXdndActionList,
                                   &atom_array)) {
       actions_.clear();
     } else {
@@ -466,11 +464,11 @@
 void DesktopDragDropClientAuraX11::X11DragContext::MaskOperation(
     ::Atom xdnd_operation,
     int* drag_operation) const {
-  if (xdnd_operation == ui::GetAtom(kXdndActionCopy))
+  if (xdnd_operation == gfx::GetAtom(kXdndActionCopy))
     *drag_operation |= ui::DragDropTypes::DRAG_COPY;
-  else if (xdnd_operation == ui::GetAtom(kXdndActionMove))
+  else if (xdnd_operation == gfx::GetAtom(kXdndActionMove))
     *drag_operation |= ui::DragDropTypes::DRAG_MOVE;
-  else if (xdnd_operation == ui::GetAtom(kXdndActionLink))
+  else if (xdnd_operation == gfx::GetAtom(kXdndActionLink))
     *drag_operation |= ui::DragDropTypes::DRAG_LINK;
 }
 
@@ -482,7 +480,7 @@
 uint32_t DesktopDragDropClientAuraX11::X11DragContext::DispatchEvent(
     const ui::PlatformEvent& event) {
   if (event->type == PropertyNotify &&
-      event->xproperty.atom == ui::GetAtom(kXdndActionList)) {
+      event->xproperty.atom == gfx::GetAtom(kXdndActionList)) {
     ReadActions();
     return ui::POST_DISPATCH_STOP_PROPAGATION;
   }
@@ -516,7 +514,7 @@
 
   // Mark that we are aware of drag and drop concepts.
   unsigned long xdnd_version = kMaxXdndVersion;
-  XChangeProperty(xdisplay_, xwindow_, ui::GetAtom(kXdndAware), XA_ATOM, 32,
+  XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom(kXdndAware), XA_ATOM, 32,
                   PropModeReplace,
                   reinterpret_cast<unsigned char*>(&xdnd_version), 1);
 }
@@ -726,7 +724,7 @@
 
   XEvent xev;
   xev.xclient.type = ClientMessage;
-  xev.xclient.message_type = ui::GetAtom(kXdndFinished);
+  xev.xclient.message_type = gfx::GetAtom(kXdndFinished);
   xev.xclient.format = 32;
   xev.xclient.window = source_window;
   xev.xclient.data.l[0] = xwindow_;
@@ -775,10 +773,10 @@
 
   std::vector<::Atom> actions = GetOfferedDragOperations();
   if (!source_provider_->file_contents_name().empty()) {
-    actions.push_back(ui::GetAtom(kXdndActionDirectSave));
+    actions.push_back(gfx::GetAtom(kXdndActionDirectSave));
     ui::SetStringProperty(
-        xwindow_, ui::GetAtom(kXdndDirectSave0),
-        ui::GetAtom(ui::Clipboard::kMimeTypeText),
+        xwindow_, gfx::GetAtom(kXdndDirectSave0),
+        gfx::GetAtom(ui::Clipboard::kMimeTypeText),
         source_provider_->file_contents_name().AsUTF8Unsafe());
   }
   ui::SetAtomArrayProperty(xwindow_, kXdndActionList, "ATOM", actions);
@@ -820,8 +818,8 @@
     source_provider_ = NULL;
     g_current_drag_drop_client = NULL;
     drag_operation_ = 0;
-    XDeleteProperty(xdisplay_, xwindow_, ui::GetAtom(kXdndActionList));
-    XDeleteProperty(xdisplay_, xwindow_, ui::GetAtom(kXdndDirectSave0));
+    XDeleteProperty(xdisplay_, xwindow_, gfx::GetAtom(kXdndActionList));
+    XDeleteProperty(xdisplay_, xwindow_, gfx::GetAtom(kXdndDirectSave0));
 
     return negotiated_operation_;
   }
@@ -962,22 +960,22 @@
   DesktopDragDropClientAuraX11* short_circuit = GetForWindow(xid);
   if (short_circuit) {
     Atom message_type = xev->xclient.message_type;
-    if (message_type == ui::GetAtom(kXdndEnter)) {
+    if (message_type == gfx::GetAtom(kXdndEnter)) {
       short_circuit->OnXdndEnter(xev->xclient);
       return;
-    } else if (message_type == ui::GetAtom(kXdndLeave)) {
+    } else if (message_type == gfx::GetAtom(kXdndLeave)) {
       short_circuit->OnXdndLeave(xev->xclient);
       return;
-    } else if (message_type == ui::GetAtom(kXdndPosition)) {
+    } else if (message_type == gfx::GetAtom(kXdndPosition)) {
       short_circuit->OnXdndPosition(xev->xclient);
       return;
-    } else if (message_type == ui::GetAtom(kXdndStatus)) {
+    } else if (message_type == gfx::GetAtom(kXdndStatus)) {
       short_circuit->OnXdndStatus(xev->xclient);
       return;
-    } else if (message_type == ui::GetAtom(kXdndFinished)) {
+    } else if (message_type == gfx::GetAtom(kXdndFinished)) {
       short_circuit->OnXdndFinished(xev->xclient);
       return;
-    } else if (message_type == ui::GetAtom(kXdndDrop)) {
+    } else if (message_type == gfx::GetAtom(kXdndDrop)) {
       short_circuit->OnXdndDrop(xev->xclient);
       return;
     }
@@ -1115,22 +1113,22 @@
 ::Atom DesktopDragDropClientAuraX11::DragOperationToAtom(
     int drag_operation) {
   if (drag_operation & ui::DragDropTypes::DRAG_COPY)
-    return ui::GetAtom(kXdndActionCopy);
+    return gfx::GetAtom(kXdndActionCopy);
   if (drag_operation & ui::DragDropTypes::DRAG_MOVE)
-    return ui::GetAtom(kXdndActionMove);
+    return gfx::GetAtom(kXdndActionMove);
   if (drag_operation & ui::DragDropTypes::DRAG_LINK)
-    return ui::GetAtom(kXdndActionLink);
+    return gfx::GetAtom(kXdndActionLink);
 
   return None;
 }
 
 ui::DragDropTypes::DragOperation
 DesktopDragDropClientAuraX11::AtomToDragOperation(::Atom atom) {
-  if (atom == ui::GetAtom(kXdndActionCopy))
+  if (atom == gfx::GetAtom(kXdndActionCopy))
     return ui::DragDropTypes::DRAG_COPY;
-  if (atom == ui::GetAtom(kXdndActionMove))
+  if (atom == gfx::GetAtom(kXdndActionMove))
     return ui::DragDropTypes::DRAG_MOVE;
-  if (atom == ui::GetAtom(kXdndActionLink))
+  if (atom == gfx::GetAtom(kXdndActionLink))
     return ui::DragDropTypes::DRAG_LINK;
 
   return ui::DragDropTypes::DRAG_NONE;
@@ -1139,11 +1137,11 @@
 std::vector<::Atom> DesktopDragDropClientAuraX11::GetOfferedDragOperations() {
   std::vector<::Atom> operations;
   if (drag_operation_ & ui::DragDropTypes::DRAG_COPY)
-    operations.push_back(ui::GetAtom(kXdndActionCopy));
+    operations.push_back(gfx::GetAtom(kXdndActionCopy));
   if (drag_operation_ & ui::DragDropTypes::DRAG_MOVE)
-    operations.push_back(ui::GetAtom(kXdndActionMove));
+    operations.push_back(gfx::GetAtom(kXdndActionMove));
   if (drag_operation_ & ui::DragDropTypes::DRAG_LINK)
-    operations.push_back(ui::GetAtom(kXdndActionLink));
+    operations.push_back(gfx::GetAtom(kXdndActionLink));
   return operations;
 }
 
@@ -1171,7 +1169,7 @@
   // sets this nor respects it if set.
   XEvent xev;
   xev.xclient.type = ClientMessage;
-  xev.xclient.message_type = ui::GetAtom(kXdndStatus);
+  xev.xclient.message_type = gfx::GetAtom(kXdndStatus);
   xev.xclient.format = 32;
   xev.xclient.window = source_window;
   xev.xclient.data.l[0] = xwindow_;
@@ -1187,7 +1185,7 @@
 void DesktopDragDropClientAuraX11::SendXdndEnter(::Window dest_window) {
   XEvent xev;
   xev.xclient.type = ClientMessage;
-  xev.xclient.message_type = ui::GetAtom(kXdndEnter);
+  xev.xclient.message_type = gfx::GetAtom(kXdndEnter);
   xev.xclient.format = 32;
   xev.xclient.window = dest_window;
   xev.xclient.data.l[0] = xwindow_;
@@ -1214,7 +1212,7 @@
 void DesktopDragDropClientAuraX11::SendXdndLeave(::Window dest_window) {
   XEvent xev;
   xev.xclient.type = ClientMessage;
-  xev.xclient.message_type = ui::GetAtom(kXdndLeave);
+  xev.xclient.message_type = gfx::GetAtom(kXdndLeave);
   xev.xclient.format = 32;
   xev.xclient.window = dest_window;
   xev.xclient.data.l[0] = xwindow_;
@@ -1233,7 +1231,7 @@
 
   XEvent xev;
   xev.xclient.type = ClientMessage;
-  xev.xclient.message_type = ui::GetAtom(kXdndPosition);
+  xev.xclient.message_type = gfx::GetAtom(kXdndPosition);
   xev.xclient.format = 32;
   xev.xclient.window = dest_window;
   xev.xclient.data.l[0] = xwindow_;
@@ -1258,7 +1256,7 @@
 void DesktopDragDropClientAuraX11::SendXdndDrop(::Window dest_window) {
   XEvent xev;
   xev.xclient.type = ClientMessage;
-  xev.xclient.message_type = ui::GetAtom(kXdndDrop);
+  xev.xclient.message_type = gfx::GetAtom(kXdndDrop);
   xev.xclient.format = 32;
   xev.xclient.window = dest_window;
   xev.xclient.data.l[0] = xwindow_;
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
index 862d806..b2ee3f926a 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11_unittest.cc
@@ -24,6 +24,7 @@
 #include "ui/base/dragdrop/os_exchange_data.h"
 #include "ui/base/x/x11_util.h"
 #include "ui/events/event_utils.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_types.h"
 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h"
 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
@@ -301,7 +302,7 @@
 }
 
 Atom TestDragDropClient::GetAtom(const char* name) {
-  return ui::GetAtom(name);
+  return gfx::GetAtom(name);
 }
 
 bool TestDragDropClient::MessageHasType(const XClientMessageEvent& event,
diff --git a/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
index 17145e38..d7b8a33 100644
--- a/ui/views/widget/desktop_aura/desktop_screen_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
@@ -27,6 +27,7 @@
 #include "ui/gfx/geometry/point_conversions.h"
 #include "ui/gfx/geometry/size_conversions.h"
 #include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_types.h"
 #include "ui/views/linux_ui/linux_ui.h"
 #include "ui/views/widget/desktop_aura/desktop_screen.h"
@@ -235,7 +236,7 @@
          event->type - xrandr_event_base_ == RRNotify ||
          (event->type == PropertyNotify &&
           event->xproperty.window == x_root_window_ &&
-          event->xproperty.atom == ui::GetAtom("_NET_WORKAREA"));
+          event->xproperty.atom == gfx::GetAtom("_NET_WORKAREA"));
 }
 
 uint32_t DesktopScreenX11::DispatchEvent(const ui::PlatformEvent& event) {
@@ -244,7 +245,7 @@
     XRRUpdateConfiguration(event);
   } else if (event->type - xrandr_event_base_ == RRNotify ||
              (event->type == PropertyNotify &&
-              event->xproperty.atom == ui::GetAtom("_NET_WORKAREA"))) {
+              event->xproperty.atom == gfx::GetAtom("_NET_WORKAREA"))) {
     // There's some sort of observer dispatch going on here, but I don't think
     // it's the screen's?
     if (configure_timer_.get() && configure_timer_->IsRunning()) {
diff --git a/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc b/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc
index 15d8bd4..25c923b 100644
--- a/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_screen_x11_unittest.cc
@@ -15,10 +15,10 @@
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
 #include "ui/base/hit_test.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/display/display_observer.h"
 #include "ui/events/test/event_generator.h"
 #include "ui/gfx/font_render_params.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_types.h"
 #include "ui/views/test/views_test_base.h"
 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
@@ -304,7 +304,7 @@
 
 // Tests that the window is maximized in response to a double click event.
 TEST_F(DesktopScreenX11Test, DoubleClickHeaderMaximizes) {
-  if (!ui::WmSupportsHint(ui::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT")))
+  if (!ui::WmSupportsHint(gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT")))
     return;
 
   Widget* widget = BuildTopLevelDesktopWidget(gfx::Rect(0, 0, 100, 100), true);
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index aacca36ce..1414ba2 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -48,6 +48,7 @@
 #include "ui/gfx/image/image_skia_rep.h"
 #include "ui/gfx/path.h"
 #include "ui/gfx/path_x11.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/views/corewm/tooltip_aura.h"
 #include "ui/views/linux_ui/linux_ui.h"
 #include "ui/views/views_delegate.h"
@@ -731,7 +732,7 @@
   // https://code.google.com/p/wmii/issues/detail?id=266
   static bool wm_supports_active_window =
       ui::GuessWindowManager() != ui::WM_WMII &&
-      ui::WmSupportsHint(ui::GetAtom("_NET_ACTIVE_WINDOW"));
+      ui::WmSupportsHint(gfx::GetAtom("_NET_ACTIVE_WINDOW"));
 
   Time timestamp = ui::X11EventSource::GetInstance()->GetTimestamp();
 
@@ -740,7 +741,7 @@
     memset(&xclient, 0, sizeof(xclient));
     xclient.type = ClientMessage;
     xclient.xclient.window = xwindow_;
-    xclient.xclient.message_type = ui::GetAtom("_NET_ACTIVE_WINDOW");
+    xclient.xclient.message_type = gfx::GetAtom("_NET_ACTIVE_WINDOW");
     xclient.xclient.format = 32;
     xclient.xclient.data.l[0] = 1;  // Specified we are an app.
     xclient.xclient.data.l[1] = timestamp;
@@ -797,7 +798,7 @@
 void DesktopWindowTreeHostX11::Maximize() {
   if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) {
     // Unfullscreen the window if it is fullscreen.
-    SetWMSpecState(false, ui::GetAtom("_NET_WM_STATE_FULLSCREEN"), None);
+    SetWMSpecState(false, gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"), None);
 
     // Resize the window so that it does not have the same size as a monitor.
     // (Otherwise, some window managers immediately put the window back in
@@ -817,8 +818,8 @@
   // heuristics that are in the PropertyNotify and ConfigureNotify handlers.
   restored_bounds_in_pixels_ = bounds_in_pixels_;
 
-  SetWMSpecState(true, ui::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
-                 ui::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
+  SetWMSpecState(true, gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
+                 gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
   if (IsMinimized())
     ShowWindowWithState(ui::SHOW_STATE_NORMAL);
 }
@@ -830,8 +831,8 @@
 
 void DesktopWindowTreeHostX11::Restore() {
   should_maximize_after_map_ = false;
-  SetWMSpecState(false, ui::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
-                 ui::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
+  SetWMSpecState(false, gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"),
+                 gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ"));
   if (IsMinimized())
     ShowWindowWithState(ui::SHOW_STATE_NORMAL);
 }
@@ -851,7 +852,7 @@
 
 void DesktopWindowTreeHostX11::SetAlwaysOnTop(bool always_on_top) {
   is_always_on_top_ = always_on_top;
-  SetWMSpecState(always_on_top, ui::GetAtom("_NET_WM_STATE_ABOVE"), None);
+  SetWMSpecState(always_on_top, gfx::GetAtom("_NET_WM_STATE_ABOVE"), None);
 }
 
 bool DesktopWindowTreeHostX11::IsAlwaysOnTop() const {
@@ -859,7 +860,7 @@
 }
 
 void DesktopWindowTreeHostX11::SetVisibleOnAllWorkspaces(bool always_visible) {
-  SetWMSpecState(always_visible, ui::GetAtom("_NET_WM_STATE_STICKY"), None);
+  SetWMSpecState(always_visible, gfx::GetAtom("_NET_WM_STATE_STICKY"), None);
 
   int new_desktop = 0;
   if (always_visible) {
@@ -874,7 +875,7 @@
   memset (&xevent, 0, sizeof (xevent));
   xevent.type = ClientMessage;
   xevent.xclient.window = xwindow_;
-  xevent.xclient.message_type = ui::GetAtom("_NET_WM_DESKTOP");
+  xevent.xclient.message_type = gfx::GetAtom("_NET_WM_DESKTOP");
   xevent.xclient.format = 32;
   xevent.xclient.data.l[0] = new_desktop;
   xevent.xclient.data.l[1] = 0;
@@ -899,8 +900,8 @@
     return false;
   window_title_ = title;
   std::string utf8str = base::UTF16ToUTF8(title);
-  XChangeProperty(xdisplay_, xwindow_, ui::GetAtom("_NET_WM_NAME"),
-                  ui::GetAtom("UTF8_STRING"), 8, PropModeReplace,
+  XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_NAME"),
+                  gfx::GetAtom("UTF8_STRING"), 8, PropModeReplace,
                   reinterpret_cast<const unsigned char*>(utf8str.c_str()),
                   utf8str.size());
   XTextProperty xtp;
@@ -997,7 +998,7 @@
 
   if (unmaximize_and_remaximize)
     Restore();
-  SetWMSpecState(fullscreen, ui::GetAtom("_NET_WM_STATE_FULLSCREEN"), None);
+  SetWMSpecState(fullscreen, gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"), None);
   if (unmaximize_and_remaximize)
     Maximize();
 
@@ -1042,9 +1043,10 @@
   unsigned long cardinality = opacity_8bit * channel_multiplier;
 
   if (cardinality == 0xffffffff) {
-    XDeleteProperty(xdisplay_, xwindow_, ui::GetAtom("_NET_WM_WINDOW_OPACITY"));
+    XDeleteProperty(xdisplay_, xwindow_,
+                    gfx::GetAtom("_NET_WM_WINDOW_OPACITY"));
   } else {
-    XChangeProperty(xdisplay_, xwindow_, ui::GetAtom("_NET_WM_WINDOW_OPACITY"),
+    XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_WINDOW_OPACITY"),
                     XA_CARDINAL, 32, PropModeReplace,
                     reinterpret_cast<unsigned char*>(&cardinality), 1);
   }
@@ -1302,22 +1304,22 @@
   switch (params.type) {
     case Widget::InitParams::TYPE_MENU:
       swa.override_redirect = True;
-      window_type = ui::GetAtom("_NET_WM_WINDOW_TYPE_MENU");
+      window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_MENU");
       break;
     case Widget::InitParams::TYPE_TOOLTIP:
       swa.override_redirect = True;
-      window_type = ui::GetAtom("_NET_WM_WINDOW_TYPE_TOOLTIP");
+      window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_TOOLTIP");
       break;
     case Widget::InitParams::TYPE_POPUP:
       swa.override_redirect = True;
-      window_type = ui::GetAtom("_NET_WM_WINDOW_TYPE_NOTIFICATION");
+      window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_NOTIFICATION");
       break;
     case Widget::InitParams::TYPE_DRAG:
       swa.override_redirect = True;
-      window_type = ui::GetAtom("_NET_WM_WINDOW_TYPE_DND");
+      window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_DND");
       break;
     default:
-      window_type = ui::GetAtom("_NET_WM_WINDOW_TYPE_NORMAL");
+      window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_NORMAL");
       break;
   }
   // An in-activatable window should not interact with the system wm.
@@ -1386,8 +1388,8 @@
   // should listen for activation events and anything else that GTK+ listens
   // for, and do something useful.
   ::Atom protocols[2];
-  protocols[0] = ui::GetAtom("WM_DELETE_WINDOW");
-  protocols[1] = ui::GetAtom("_NET_WM_PING");
+  protocols[0] = gfx::GetAtom("WM_DELETE_WINDOW");
+  protocols[1] = gfx::GetAtom("_NET_WM_PING");
   XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
 
   // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
@@ -1400,11 +1402,11 @@
   static_assert(sizeof(long) >= sizeof(pid_t),
                 "pid_t should not be larger than long");
   long pid = getpid();
-  XChangeProperty(xdisplay_, xwindow_, ui::GetAtom("_NET_WM_PID"), XA_CARDINAL,
+  XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_PID"), XA_CARDINAL,
                   32, PropModeReplace, reinterpret_cast<unsigned char*>(&pid),
                   1);
 
-  XChangeProperty(xdisplay_, xwindow_, ui::GetAtom("_NET_WM_WINDOW_TYPE"),
+  XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_WINDOW_TYPE"),
                   XA_ATOM, 32, PropModeReplace,
                   reinterpret_cast<unsigned char*>(&window_type), 1);
 
@@ -1415,18 +1417,18 @@
   if ((params.type == Widget::InitParams::TYPE_POPUP ||
        params.type == Widget::InitParams::TYPE_BUBBLE) &&
       !params.force_show_in_taskbar) {
-    state_atom_list.push_back(ui::GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
+    state_atom_list.push_back(gfx::GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
   }
 
   // If the window should stay on top of other windows, add the
   // _NET_WM_STATE_ABOVE property.
   is_always_on_top_ = params.keep_on_top;
   if (is_always_on_top_)
-    state_atom_list.push_back(ui::GetAtom("_NET_WM_STATE_ABOVE"));
+    state_atom_list.push_back(gfx::GetAtom("_NET_WM_STATE_ABOVE"));
 
   workspace_.clear();
   if (params.visible_on_all_workspaces) {
-    state_atom_list.push_back(ui::GetAtom("_NET_WM_STATE_STICKY"));
+    state_atom_list.push_back(gfx::GetAtom("_NET_WM_STATE_STICKY"));
     ui::SetIntProperty(xwindow_, "_NET_WM_DESKTOP", "CARDINAL", kAllDesktops);
   } else if (!params.workspace.empty()) {
     int workspace;
@@ -1521,7 +1523,7 @@
 
 void DesktopWindowTreeHostX11::OnWMStateUpdated() {
   std::vector< ::Atom> atom_list;
-  // Ignore the return value of ui::GetAtomArrayProperty(). Fluxbox removes the
+  // Ignore the return value of gfx::GetAtomArrayProperty(). Fluxbox removes the
   // _NET_WM_STATE property when no _NET_WM_STATE atoms are set.
   ui::GetAtomArrayProperty(xwindow_, "_NET_WM_STATE", &atom_list);
 
@@ -1643,7 +1645,7 @@
       type == ui::ET_TOUCH_PRESSED) {
     unsigned long wm_user_time_ms = static_cast<unsigned long>(
         (ui::EventTimeFromNative(event) - base::TimeTicks()).InMilliseconds());
-    XChangeProperty(xdisplay_, xwindow_, ui::GetAtom("_NET_WM_USER_TIME"),
+    XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_USER_TIME"),
                     XA_CARDINAL, 32, PropModeReplace,
                     reinterpret_cast<const unsigned char*>(&wm_user_time_ms),
                     1);
@@ -1657,7 +1659,7 @@
   memset(&xclient, 0, sizeof(xclient));
   xclient.type = ClientMessage;
   xclient.xclient.window = xwindow_;
-  xclient.xclient.message_type = ui::GetAtom("_NET_WM_STATE");
+  xclient.xclient.message_type = gfx::GetAtom("_NET_WM_STATE");
   xclient.xclient.format = 32;
   xclient.xclient.data.l[0] =
       enabled ? k_NET_WM_STATE_ADD : k_NET_WM_STATE_REMOVE;
@@ -1672,7 +1674,7 @@
 }
 
 bool DesktopWindowTreeHostX11::HasWMSpecProperty(const char* property) const {
-  return window_properties_.find(ui::GetAtom(property)) !=
+  return window_properties_.find(gfx::GetAtom(property)) !=
          window_properties_.end();
 }
 
@@ -1853,7 +1855,7 @@
           ? 0
           : ui::X11EventSource::GetInstance()->GetTimestamp();
   if (show_state == ui::SHOW_STATE_INACTIVE || wm_user_time_ms != 0) {
-    XChangeProperty(xdisplay_, xwindow_, ui::GetAtom("_NET_WM_USER_TIME"),
+    XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_USER_TIME"),
                     XA_CARDINAL, 32, PropModeReplace,
                     reinterpret_cast<const unsigned char*>(&wm_user_time_ms),
                     1);
@@ -2114,12 +2116,12 @@
     }
     case ClientMessage: {
       Atom message_type = xev->xclient.message_type;
-      if (message_type == ui::GetAtom("WM_PROTOCOLS")) {
+      if (message_type == gfx::GetAtom("WM_PROTOCOLS")) {
         Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]);
-        if (protocol == ui::GetAtom("WM_DELETE_WINDOW")) {
+        if (protocol == gfx::GetAtom("WM_DELETE_WINDOW")) {
           // We have received a close message from the window manager.
           OnHostCloseRequested();
-        } else if (protocol == ui::GetAtom("_NET_WM_PING")) {
+        } else if (protocol == gfx::GetAtom("_NET_WM_PING")) {
           XEvent reply_event = *xev;
           reply_event.xclient.window = x_root_window_;
 
@@ -2129,17 +2131,17 @@
                      SubstructureRedirectMask | SubstructureNotifyMask,
                      &reply_event);
         }
-      } else if (message_type == ui::GetAtom("XdndEnter")) {
+      } else if (message_type == gfx::GetAtom("XdndEnter")) {
         drag_drop_client_->OnXdndEnter(xev->xclient);
-      } else if (message_type == ui::GetAtom("XdndLeave")) {
+      } else if (message_type == gfx::GetAtom("XdndLeave")) {
         drag_drop_client_->OnXdndLeave(xev->xclient);
-      } else if (message_type == ui::GetAtom("XdndPosition")) {
+      } else if (message_type == gfx::GetAtom("XdndPosition")) {
         drag_drop_client_->OnXdndPosition(xev->xclient);
-      } else if (message_type == ui::GetAtom("XdndStatus")) {
+      } else if (message_type == gfx::GetAtom("XdndStatus")) {
         drag_drop_client_->OnXdndStatus(xev->xclient);
-      } else if (message_type == ui::GetAtom("XdndFinished")) {
+      } else if (message_type == gfx::GetAtom("XdndFinished")) {
         drag_drop_client_->OnXdndFinished(xev->xclient);
-      } else if (message_type == ui::GetAtom("XdndDrop")) {
+      } else if (message_type == gfx::GetAtom("XdndDrop")) {
         drag_drop_client_->OnXdndDrop(xev->xclient);
       }
       break;
@@ -2183,11 +2185,11 @@
     }
     case PropertyNotify: {
       ::Atom changed_atom = xev->xproperty.atom;
-      if (changed_atom == ui::GetAtom("_NET_WM_STATE")) {
+      if (changed_atom == gfx::GetAtom("_NET_WM_STATE")) {
         OnWMStateUpdated();
-      } else if (changed_atom == ui::GetAtom("_NET_FRAME_EXTENTS")) {
+      } else if (changed_atom == gfx::GetAtom("_NET_FRAME_EXTENTS")) {
         OnFrameExtentsUpdated();
-      } else if (changed_atom == ui::GetAtom("_NET_WM_DESKTOP")) {
+      } else if (changed_atom == gfx::GetAtom("_NET_WM_DESKTOP")) {
         if (UpdateWorkspace())
           OnHostWorkspaceChanged();
       }
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
index f071e756..612b41f5 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
@@ -31,6 +31,7 @@
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/path.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/views/test/views_test_base.h"
 #include "ui/views/test/x11_property_change_waiter.h"
 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
@@ -59,7 +60,7 @@
   bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override {
     std::vector<Atom> hints;
     if (ui::GetAtomArrayProperty(xwindow(), "_NET_WM_STATE", &hints)) {
-      auto it = std::find(hints.cbegin(), hints.cend(), ui::GetAtom(hint_));
+      auto it = std::find(hints.cbegin(), hints.cend(), gfx::GetAtom(hint_));
       bool hint_set = (it != hints.cend());
       return hint_set != wait_till_set_;
     }
@@ -238,7 +239,7 @@
     EXPECT_FALSE(ShapeRectContainsPoint(shape_rects, 205, 15));
   }
 
-  if (ui::WmSupportsHint(ui::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"))) {
+  if (ui::WmSupportsHint(gfx::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT"))) {
     // The shape should be changed to a rectangle which fills the entire screen
     // when |widget1| is maximized.
     {
@@ -315,7 +316,7 @@
 // Test that the widget ignores changes in fullscreen state initiated by the
 // window manager (e.g. via a window manager accelerator key).
 TEST_F(DesktopWindowTreeHostX11Test, WindowManagerTogglesFullscreen) {
-  if (!ui::WmSupportsHint(ui::GetAtom("_NET_WM_STATE_FULLSCREEN")))
+  if (!ui::WmSupportsHint(gfx::GetAtom("_NET_WM_STATE_FULLSCREEN")))
     return;
 
   std::unique_ptr<Widget> widget = CreateWidget(new ShapedWidgetDelegate());
@@ -340,10 +341,10 @@
     memset(&xclient, 0, sizeof(xclient));
     xclient.type = ClientMessage;
     xclient.xclient.window = xid;
-    xclient.xclient.message_type = ui::GetAtom("_NET_WM_STATE");
+    xclient.xclient.message_type = gfx::GetAtom("_NET_WM_STATE");
     xclient.xclient.format = 32;
     xclient.xclient.data.l[0] = 0;
-    xclient.xclient.data.l[1] = ui::GetAtom("_NET_WM_STATE_FULLSCREEN");
+    xclient.xclient.data.l[1] = gfx::GetAtom("_NET_WM_STATE_FULLSCREEN");
     xclient.xclient.data.l[2] = 0;
     xclient.xclient.data.l[3] = 1;
     xclient.xclient.data.l[4] = 0;
@@ -380,7 +381,7 @@
   // Minimize by sending _NET_WM_STATE_HIDDEN
   {
     std::vector< ::Atom> atom_list;
-    atom_list.push_back(ui::GetAtom("_NET_WM_STATE_HIDDEN"));
+    atom_list.push_back(gfx::GetAtom("_NET_WM_STATE_HIDDEN"));
     ui::SetAtomArrayProperty(xid, "_NET_WM_STATE", "ATOM", atom_list);
 
     XEvent xevent;
@@ -390,7 +391,7 @@
     xevent.xproperty.send_event = 1;
     xevent.xproperty.display = display;
     xevent.xproperty.window = xid;
-    xevent.xproperty.atom = ui::GetAtom("_NET_WM_STATE");
+    xevent.xproperty.atom = gfx::GetAtom("_NET_WM_STATE");
     xevent.xproperty.state = 0;
     XSendEvent(display, DefaultRootWindow(display), False,
         SubstructureRedirectMask | SubstructureNotifyMask,
@@ -404,7 +405,7 @@
   // Show from minimized by sending _NET_WM_STATE_FOCUSED
   {
     std::vector< ::Atom> atom_list;
-    atom_list.push_back(ui::GetAtom("_NET_WM_STATE_FOCUSED"));
+    atom_list.push_back(gfx::GetAtom("_NET_WM_STATE_FOCUSED"));
     ui::SetAtomArrayProperty(xid, "_NET_WM_STATE", "ATOM", atom_list);
 
     XEvent xevent;
@@ -414,7 +415,7 @@
     xevent.xproperty.send_event = 1;
     xevent.xproperty.display = display;
     xevent.xproperty.window = xid;
-    xevent.xproperty.atom = ui::GetAtom("_NET_WM_STATE");
+    xevent.xproperty.atom = gfx::GetAtom("_NET_WM_STATE");
     xevent.xproperty.state = 0;
     XSendEvent(display, DefaultRootWindow(display), False,
         SubstructureRedirectMask | SubstructureNotifyMask,
diff --git a/ui/views/widget/desktop_aura/x11_desktop_handler.cc b/ui/views/widget/desktop_aura/x11_desktop_handler.cc
index 3ee269bb..f5e7f20 100644
--- a/ui/views/widget/desktop_aura/x11_desktop_handler.cc
+++ b/ui/views/widget/desktop_aura/x11_desktop_handler.cc
@@ -12,9 +12,9 @@
 #include "ui/aura/env.h"
 #include "ui/aura/window_event_dispatcher.h"
 #include "ui/base/x/x11_menu_list.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/base/x/x11_window_event_manager.h"
 #include "ui/events/platform/platform_event_source.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_error_tracker.h"
 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
 
@@ -90,7 +90,7 @@
 uint32_t X11DesktopHandler::DispatchEvent(const ui::PlatformEvent& event) {
   switch (event->type) {
     case PropertyNotify: {
-      if (event->xproperty.atom == ui::GetAtom("_NET_CURRENT_DESKTOP")) {
+      if (event->xproperty.atom == gfx::GetAtom("_NET_CURRENT_DESKTOP")) {
         if (UpdateWorkspace()) {
           for (views::X11DesktopHandlerObserver& observer : observers_)
             observer.OnWorkspaceChanged(workspace_);
diff --git a/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc b/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
index 35509301..d94a8789 100644
--- a/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
+++ b/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
@@ -26,6 +26,7 @@
 #include "ui/events/platform/x11/x11_event_source.h"
 #include "ui/gfx/path.h"
 #include "ui/gfx/path_x11.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/views/test/views_interactive_ui_test_base.h"
 #include "ui/views/test/x11_property_change_waiter.h"
 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
@@ -50,7 +51,7 @@
     std::vector<Atom> wm_states;
     if (ui::GetAtomArrayProperty(xwindow(), "_NET_WM_STATE", &wm_states)) {
       auto it = std::find(wm_states.cbegin(), wm_states.cend(),
-                          ui::GetAtom("_NET_WM_STATE_HIDDEN"));
+                          gfx::GetAtom("_NET_WM_STATE_HIDDEN"));
       return it == wm_states.cend();
     }
     return true;
@@ -395,7 +396,7 @@
                                &swa);
   {
     ui::SetAtomProperty(menu_xid, "_NET_WM_WINDOW_TYPE", "ATOM",
-                        ui::GetAtom("_NET_WM_WINDOW_TYPE_MENU"));
+                        gfx::GetAtom("_NET_WM_WINDOW_TYPE_MENU"));
   }
   ui::SetUseOSWindowFrame(menu_xid, false);
   ShowAndSetXWindowBounds(menu_xid, gfx::Rect(140, 110, 100, 100));
diff --git a/ui/views/widget/desktop_aura/x11_window_event_filter.cc b/ui/views/widget/desktop_aura/x11_window_event_filter.cc
index b1bee28..5e01cd6 100644
--- a/ui/views/widget/desktop_aura/x11_window_event_filter.cc
+++ b/ui/views/widget/desktop_aura/x11_window_event_filter.cc
@@ -15,11 +15,11 @@
 #include "ui/aura/window_delegate.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/base/hit_test.h"
-#include "ui/base/x/x11_util.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
 #include "ui/events/event.h"
 #include "ui/events/event_utils.h"
+#include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_types.h"
 #include "ui/views/linux_ui/linux_ui.h"
 #include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
@@ -220,7 +220,7 @@
   event.xclient.type = ClientMessage;
   event.xclient.display = xdisplay_;
   event.xclient.window = xwindow_;
-  event.xclient.message_type = ui::GetAtom("_NET_WM_MOVERESIZE");
+  event.xclient.message_type = gfx::GetAtom("_NET_WM_MOVERESIZE");
   event.xclient.format = 32;
   event.xclient.data.l[0] = screen_location.x();
   event.xclient.data.l[1] = screen_location.y();